2020-06-26 18:14:16 +02:00
|
|
|
<template>
|
2020-08-07 17:26:02 +02:00
|
|
|
<div class="tr" @click="selectRow($event, row._id)">
|
|
|
|
<div
|
|
|
|
v-for="(col, cKey) in row"
|
2020-08-10 16:06:11 +02:00
|
|
|
v-show="cKey !== '_id'"
|
2020-08-07 17:26:02 +02:00
|
|
|
:key="cKey"
|
|
|
|
class="td p-0"
|
|
|
|
tabindex="0"
|
|
|
|
@contextmenu.prevent="$emit('contextmenu', $event, {id: row._id, field: cKey})"
|
|
|
|
>
|
|
|
|
<template v-if="cKey !== '_id'">
|
|
|
|
<span
|
|
|
|
v-if="!isInlineEditor[cKey]"
|
|
|
|
class="cell-content px-2"
|
2020-09-01 19:23:13 +02:00
|
|
|
:class="`${isNull(col)} type-${getFieldType(cKey)}`"
|
2020-08-07 17:26:02 +02:00
|
|
|
@dblclick="editON($event, col, cKey)"
|
2020-09-01 19:23:13 +02:00
|
|
|
>{{ col | typeFormat(getFieldType(cKey), getFieldPrecision(cKey)) | cutText }}</span>
|
2020-08-17 15:10:19 +02:00
|
|
|
<ForeignKeySelect
|
2021-02-17 14:17:50 +01:00
|
|
|
v-else-if="isForeignKey(cKey)"
|
2020-08-17 15:10:19 +02:00
|
|
|
class="editable-field"
|
|
|
|
:value.sync="editingContent"
|
|
|
|
:key-usage="getKeyUsage(cKey)"
|
2020-12-15 17:08:36 +01:00
|
|
|
size="small"
|
2020-08-17 15:10:19 +02:00
|
|
|
@blur="editOFF"
|
|
|
|
/>
|
2020-08-07 17:26:02 +02:00
|
|
|
<template v-else>
|
|
|
|
<input
|
|
|
|
v-if="inputProps.mask"
|
|
|
|
ref="editField"
|
|
|
|
v-model="editingContent"
|
|
|
|
v-mask="inputProps.mask"
|
|
|
|
:type="inputProps.type"
|
|
|
|
autofocus
|
|
|
|
class="editable-field px-2"
|
|
|
|
@blur="editOFF"
|
|
|
|
>
|
|
|
|
<input
|
|
|
|
v-else
|
|
|
|
ref="editField"
|
|
|
|
v-model="editingContent"
|
|
|
|
:type="inputProps.type"
|
|
|
|
autofocus
|
|
|
|
class="editable-field px-2"
|
|
|
|
@blur="editOFF"
|
|
|
|
>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
</div>
|
2020-07-30 19:12:29 +02:00
|
|
|
<ConfirmModal
|
|
|
|
v-if="isTextareaEditor"
|
2020-08-04 17:54:19 +02:00
|
|
|
:confirm-text="$t('word.update')"
|
2020-07-30 19:12:29 +02:00
|
|
|
size="medium"
|
|
|
|
@confirm="editOFF"
|
|
|
|
@hide="hideEditorModal"
|
|
|
|
>
|
|
|
|
<template :slot="'header'">
|
2020-08-13 12:42:19 +02:00
|
|
|
<div class="d-flex">
|
|
|
|
<i class="mdi mdi-24px mdi-playlist-edit mr-1" /> {{ $t('word.edit') }} "{{ editingField }}"
|
|
|
|
</div>
|
2020-07-30 19:12:29 +02:00
|
|
|
</template>
|
|
|
|
<div :slot="'body'">
|
|
|
|
<div class="mb-2">
|
|
|
|
<div>
|
|
|
|
<textarea
|
2020-08-07 17:26:02 +02:00
|
|
|
v-model="editingContent"
|
2020-07-30 19:12:29 +02:00
|
|
|
class="form-input textarea-editor"
|
|
|
|
/>
|
|
|
|
</div>
|
2020-07-31 15:45:32 +02:00
|
|
|
<div class="editor-field-info">
|
2020-11-13 12:39:40 +01:00
|
|
|
<div><b>{{ $t('word.size') }}</b>: {{ editingContent ? editingContent.length : 0 }}</div>
|
2020-08-07 17:26:02 +02:00
|
|
|
<div><b>{{ $t('word.type') }}</b>: {{ editingType.toUpperCase() }}</div>
|
2020-07-30 19:12:29 +02:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</ConfirmModal>
|
2020-08-03 18:07:08 +02:00
|
|
|
<ConfirmModal
|
|
|
|
v-if="isBlobEditor"
|
2020-08-04 17:54:19 +02:00
|
|
|
:confirm-text="$t('word.update')"
|
2020-08-03 18:07:08 +02:00
|
|
|
@confirm="editOFF"
|
|
|
|
@hide="hideEditorModal"
|
|
|
|
>
|
|
|
|
<template :slot="'header'">
|
2020-08-13 12:42:19 +02:00
|
|
|
<div class="d-flex">
|
|
|
|
<i class="mdi mdi-24px mdi-playlist-edit mr-1" /> {{ $t('word.edit') }} "{{ editingField }}"
|
|
|
|
</div>
|
2020-08-03 18:07:08 +02:00
|
|
|
</template>
|
|
|
|
<div :slot="'body'">
|
|
|
|
<div class="mb-2">
|
2020-08-04 17:54:19 +02:00
|
|
|
<transition name="jump-down">
|
|
|
|
<div v-if="contentInfo.size">
|
|
|
|
<img
|
|
|
|
v-if="isImage"
|
2020-08-07 17:26:02 +02:00
|
|
|
:src="`data:${contentInfo.mime};base64, ${bufferToBase64(editingContent)}`"
|
2020-08-04 17:54:19 +02:00
|
|
|
class="img-responsive p-centered bg-checkered"
|
|
|
|
>
|
|
|
|
<div v-else class="text-center">
|
2020-08-12 10:48:18 +02:00
|
|
|
<i class="mdi mdi-36px mdi-file" />
|
2020-08-04 17:54:19 +02:00
|
|
|
</div>
|
|
|
|
<div class="editor-buttons mt-2">
|
|
|
|
<button class="btn btn-link btn-sm" @click="downloadFile">
|
|
|
|
<span>{{ $t('word.download') }}</span>
|
2020-08-12 10:48:18 +02:00
|
|
|
<i class="mdi mdi-24px mdi-download ml-1" />
|
2020-08-04 17:54:19 +02:00
|
|
|
</button>
|
|
|
|
<button class="btn btn-link btn-sm" @click="prepareToDelete">
|
|
|
|
<span>{{ $t('word.delete') }}</span>
|
2020-08-12 10:48:18 +02:00
|
|
|
<i class="mdi mdi-24px mdi-delete-forever ml-1" />
|
2020-08-04 17:54:19 +02:00
|
|
|
</button>
|
|
|
|
</div>
|
2020-08-03 18:07:08 +02:00
|
|
|
</div>
|
2020-08-04 17:54:19 +02:00
|
|
|
</transition>
|
2020-08-03 18:07:08 +02:00
|
|
|
<div class="editor-field-info">
|
|
|
|
<div>
|
2020-08-07 17:26:02 +02:00
|
|
|
<b>{{ $t('word.size') }}</b>: {{ editingContent.length | formatBytes }}<br>
|
2020-08-03 18:07:08 +02:00
|
|
|
<b>{{ $t('word.mimeType') }}</b>: {{ contentInfo.mime }}
|
|
|
|
</div>
|
2020-08-07 17:26:02 +02:00
|
|
|
<div><b>{{ $t('word.type') }}</b>: {{ editingType.toUpperCase() }}</div>
|
2020-08-03 18:07:08 +02:00
|
|
|
</div>
|
|
|
|
<div class="mt-3">
|
|
|
|
<label>{{ $t('message.uploadFile') }}</label>
|
|
|
|
<input
|
|
|
|
class="form-input"
|
|
|
|
type="file"
|
|
|
|
@change="filesChange($event)"
|
|
|
|
>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</ConfirmModal>
|
2020-06-26 18:14:16 +02:00
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
import moment from 'moment';
|
2020-08-04 17:54:19 +02:00
|
|
|
import { mimeFromHex } from 'common/libs/mimeFromHex';
|
|
|
|
import { formatBytes } from 'common/libs/formatBytes';
|
|
|
|
import { bufferToBase64 } from 'common/libs/bufferToBase64';
|
2020-06-26 18:14:16 +02:00
|
|
|
import hexToBinary from 'common/libs/hexToBinary';
|
2021-02-10 18:24:28 +01:00
|
|
|
import { TEXT, LONG_TEXT, NUMBER, FLOAT, DATE, TIME, DATETIME, BLOB, BIT } from 'common/fieldTypes';
|
2020-07-02 19:17:25 +02:00
|
|
|
import { mask } from 'vue-the-mask';
|
2020-07-30 19:12:29 +02:00
|
|
|
import ConfirmModal from '@/components/BaseConfirmModal';
|
2020-08-17 15:10:19 +02:00
|
|
|
import ForeignKeySelect from '@/components/ForeignKeySelect';
|
2020-06-26 18:14:16 +02:00
|
|
|
|
|
|
|
export default {
|
2020-08-07 17:26:02 +02:00
|
|
|
name: 'WorkspaceQueryTableRow',
|
2020-07-30 19:12:29 +02:00
|
|
|
components: {
|
2020-08-17 15:10:19 +02:00
|
|
|
ConfirmModal,
|
|
|
|
ForeignKeySelect
|
2020-07-30 19:12:29 +02:00
|
|
|
},
|
2020-08-07 17:26:02 +02:00
|
|
|
directives: {
|
|
|
|
mask
|
|
|
|
},
|
2020-06-26 18:14:16 +02:00
|
|
|
filters: {
|
2020-08-03 18:07:08 +02:00
|
|
|
formatBytes,
|
2020-07-22 18:30:52 +02:00
|
|
|
cutText (val) {
|
|
|
|
if (typeof val !== 'string') return val;
|
2020-07-24 13:26:56 +02:00
|
|
|
return val.length > 128 ? `${val.substring(0, 128)}[...]` : val;
|
2020-07-22 18:30:52 +02:00
|
|
|
},
|
2020-07-05 16:06:56 +02:00
|
|
|
typeFormat (val, type, precision) {
|
2020-06-26 18:14:16 +02:00
|
|
|
if (!val) return val;
|
|
|
|
|
2020-12-09 18:22:46 +01:00
|
|
|
type = type.toUpperCase();
|
|
|
|
|
2020-08-04 17:54:19 +02:00
|
|
|
if (DATE.includes(type))
|
|
|
|
return moment(val).isValid() ? moment(val).format('YYYY-MM-DD') : val;
|
2020-07-05 16:06:56 +02:00
|
|
|
|
2020-08-04 17:54:19 +02:00
|
|
|
if (DATETIME.includes(type)) {
|
|
|
|
let datePrecision = '';
|
|
|
|
for (let i = 0; i < precision; i++)
|
|
|
|
datePrecision += i === 0 ? '.S' : 'S';
|
2020-06-26 18:14:16 +02:00
|
|
|
|
2020-08-04 17:54:19 +02:00
|
|
|
return moment(val).isValid() ? moment(val).format(`YYYY-MM-DD HH:mm:ss${datePrecision}`) : val;
|
2020-06-26 18:14:16 +02:00
|
|
|
}
|
2020-08-04 17:54:19 +02:00
|
|
|
|
|
|
|
if (BLOB.includes(type)) {
|
|
|
|
const buff = Buffer.from(val);
|
|
|
|
if (!buff.length) return '';
|
|
|
|
|
|
|
|
const hex = buff.toString('hex').substring(0, 8).toUpperCase();
|
|
|
|
return `${mimeFromHex(hex).mime} (${formatBytes(buff.length)})`;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (BIT.includes(type)) {
|
2020-10-20 13:12:12 +02:00
|
|
|
if (typeof val === 'number') val = [val];
|
2020-08-04 17:54:19 +02:00
|
|
|
const hex = Buffer.from(val).toString('hex');
|
|
|
|
return hexToBinary(hex);
|
|
|
|
}
|
|
|
|
|
|
|
|
return val;
|
2020-06-26 18:14:16 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
props: {
|
2020-08-07 17:26:02 +02:00
|
|
|
row: Object,
|
2020-09-06 08:41:57 +02:00
|
|
|
fields: {
|
|
|
|
type: Array,
|
|
|
|
default: () => []
|
|
|
|
},
|
2020-08-14 18:07:29 +02:00
|
|
|
keyUsage: Array
|
2020-06-26 18:14:16 +02:00
|
|
|
},
|
|
|
|
data () {
|
|
|
|
return {
|
2020-08-07 17:26:02 +02:00
|
|
|
isInlineEditor: {},
|
2020-07-30 19:12:29 +02:00
|
|
|
isTextareaEditor: false,
|
2020-08-03 18:07:08 +02:00
|
|
|
isBlobEditor: false,
|
2020-08-04 17:54:19 +02:00
|
|
|
willBeDeleted: false,
|
2020-08-07 17:26:02 +02:00
|
|
|
originalContent: null,
|
|
|
|
editingContent: null,
|
|
|
|
editingType: null,
|
|
|
|
editingField: null,
|
2020-08-03 18:07:08 +02:00
|
|
|
contentInfo: {
|
|
|
|
ext: '',
|
|
|
|
mime: '',
|
|
|
|
size: null
|
|
|
|
},
|
|
|
|
fileToUpload: null
|
2020-06-26 18:14:16 +02:00
|
|
|
};
|
|
|
|
},
|
|
|
|
computed: {
|
2020-07-02 19:17:25 +02:00
|
|
|
inputProps () {
|
2020-08-10 18:07:16 +02:00
|
|
|
if ([...TEXT, ...LONG_TEXT].includes(this.editingType))
|
2020-08-04 17:54:19 +02:00
|
|
|
return { type: 'text', mask: false };
|
|
|
|
|
2021-02-10 18:24:28 +01:00
|
|
|
if ([...NUMBER, ...FLOAT].includes(this.editingType))
|
2020-08-04 17:54:19 +02:00
|
|
|
return { type: 'number', mask: false };
|
|
|
|
|
2020-08-10 18:07:16 +02:00
|
|
|
if (TIME.includes(this.editingType)) {
|
|
|
|
let timeMask = '##:##:##';
|
2020-09-01 19:23:13 +02:00
|
|
|
const precision = this.getFieldPrecision(this.editingField);
|
2020-08-10 18:07:16 +02:00
|
|
|
|
|
|
|
for (let i = 0; i < precision; i++)
|
|
|
|
timeMask += i === 0 ? '.#' : '#';
|
|
|
|
|
|
|
|
return { type: 'text', mask: timeMask };
|
|
|
|
}
|
2020-08-04 17:54:19 +02:00
|
|
|
|
2020-08-10 18:07:16 +02:00
|
|
|
if (DATE.includes(this.editingType))
|
2020-08-04 17:54:19 +02:00
|
|
|
return { type: 'text', mask: '####-##-##' };
|
|
|
|
|
2020-08-10 18:07:16 +02:00
|
|
|
if (DATETIME.includes(this.editingType)) {
|
2020-08-04 17:54:19 +02:00
|
|
|
let datetimeMask = '####-##-## ##:##:##';
|
2020-09-01 19:23:13 +02:00
|
|
|
const precision = this.getFieldPrecision(this.editingField);
|
2020-08-10 18:07:16 +02:00
|
|
|
|
|
|
|
for (let i = 0; i < precision; i++)
|
2020-08-04 17:54:19 +02:00
|
|
|
datetimeMask += i === 0 ? '.#' : '#';
|
2020-08-10 18:07:16 +02:00
|
|
|
|
2020-08-04 17:54:19 +02:00
|
|
|
return { type: 'text', mask: datetimeMask };
|
2020-06-26 18:14:16 +02:00
|
|
|
}
|
2020-08-04 17:54:19 +02:00
|
|
|
|
2020-08-10 18:07:16 +02:00
|
|
|
if (BLOB.includes(this.editingType))
|
2020-08-04 17:54:19 +02:00
|
|
|
return { type: 'file', mask: false };
|
|
|
|
|
2020-08-10 18:07:16 +02:00
|
|
|
if (BIT.includes(this.editingType))
|
2020-08-04 17:54:19 +02:00
|
|
|
return { type: 'text', mask: false };
|
|
|
|
|
|
|
|
return { type: 'text', mask: false };
|
2020-08-03 18:07:08 +02:00
|
|
|
},
|
|
|
|
isImage () {
|
2020-08-04 17:54:19 +02:00
|
|
|
return ['gif', 'jpg', 'png', 'bmp', 'ico', 'tif'].includes(this.contentInfo.ext);
|
2020-08-17 15:10:19 +02:00
|
|
|
},
|
|
|
|
foreignKeys () {
|
2020-12-15 17:08:36 +01:00
|
|
|
return this.keyUsage.map(key => key.field);
|
2020-10-10 16:54:00 +02:00
|
|
|
},
|
|
|
|
isEditable () {
|
2021-02-17 14:17:50 +01:00
|
|
|
if (this.fields) {
|
|
|
|
const nElements = this.fields.reduce((acc, curr) => {
|
|
|
|
acc.add(curr.table);
|
|
|
|
acc.add(curr.schema);
|
|
|
|
return acc;
|
|
|
|
}, new Set([]));
|
|
|
|
|
|
|
|
if (nElements.size > 2) return false;
|
|
|
|
|
|
|
|
return !!(this.fields[0].schema && this.fields[0].table);
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2020-06-26 18:14:16 +02:00
|
|
|
}
|
|
|
|
},
|
2020-09-06 08:41:57 +02:00
|
|
|
watch: {
|
|
|
|
fields () {
|
|
|
|
this.fields.forEach(field => {
|
|
|
|
this.isInlineEditor[field.name] = false;
|
|
|
|
});
|
|
|
|
}
|
2020-08-07 17:26:02 +02:00
|
|
|
},
|
2020-06-26 18:14:16 +02:00
|
|
|
methods: {
|
2021-02-17 14:17:50 +01:00
|
|
|
isForeignKey (key) {
|
|
|
|
if (key.includes('.'))
|
|
|
|
key = key.split('.').pop();
|
|
|
|
|
|
|
|
return this.foreignKeys.includes(key);
|
|
|
|
},
|
2020-09-01 19:23:13 +02:00
|
|
|
getFieldType (cKey) {
|
2020-08-07 17:26:02 +02:00
|
|
|
let type = 'unknown';
|
2020-09-01 19:23:13 +02:00
|
|
|
const field = this.getFieldObj(cKey);
|
2020-08-07 17:26:02 +02:00
|
|
|
if (field)
|
|
|
|
type = field.type;
|
|
|
|
|
2020-12-07 19:11:29 +01:00
|
|
|
return type.toLowerCase();
|
2020-08-07 17:26:02 +02:00
|
|
|
},
|
2020-09-01 19:23:13 +02:00
|
|
|
getFieldPrecision (cKey) {
|
2020-08-07 17:26:02 +02:00
|
|
|
let length = 0;
|
2020-09-01 19:23:13 +02:00
|
|
|
const field = this.getFieldObj(cKey);
|
2020-08-07 17:26:02 +02:00
|
|
|
if (field)
|
2020-08-12 10:48:18 +02:00
|
|
|
length = field.datePrecision;
|
2020-08-07 17:26:02 +02:00
|
|
|
|
|
|
|
return length;
|
|
|
|
},
|
2020-09-01 19:23:13 +02:00
|
|
|
getFieldObj (cKey) {
|
2020-10-21 14:58:22 +02:00
|
|
|
return this.fields.filter(field => {
|
|
|
|
let fieldNames = [
|
|
|
|
field.name,
|
|
|
|
field.alias,
|
|
|
|
`${field.table}.${field.name}`,
|
|
|
|
`${field.table}.${field.alias}`,
|
|
|
|
`${field.tableAlias}.${field.name}`,
|
|
|
|
`${field.tableAlias}.${field.alias}`
|
|
|
|
];
|
2020-10-20 13:30:36 +02:00
|
|
|
|
2020-10-21 14:58:22 +02:00
|
|
|
if (field.table)
|
|
|
|
fieldNames = [...fieldNames, `${field.table.toLowerCase()}.${field.name}`, `${field.table.toLowerCase()}.${field.alias}`];
|
2020-10-20 13:30:36 +02:00
|
|
|
|
2020-10-21 14:58:22 +02:00
|
|
|
if (field.tableAlias)
|
|
|
|
fieldNames = [...fieldNames, `${field.tableAlias.toLowerCase()}.${field.name}`, `${field.tableAlias.toLowerCase()}.${field.alias}`];
|
2020-10-20 13:30:36 +02:00
|
|
|
|
2020-10-21 14:58:22 +02:00
|
|
|
return fieldNames.includes(cKey);
|
|
|
|
})[0];
|
2020-09-01 19:23:13 +02:00
|
|
|
},
|
2020-06-26 18:14:16 +02:00
|
|
|
isNull (value) {
|
|
|
|
return value === null ? ' is-null' : '';
|
|
|
|
},
|
2020-08-03 18:07:08 +02:00
|
|
|
bufferToBase64 (val) {
|
|
|
|
return bufferToBase64(val);
|
|
|
|
},
|
2020-08-07 17:26:02 +02:00
|
|
|
editON (event, content, field) {
|
2020-10-10 16:54:00 +02:00
|
|
|
if (!this.isEditable) return;
|
|
|
|
|
2020-12-10 15:15:32 +01:00
|
|
|
const type = this.getFieldType(field).toUpperCase(); ;
|
2020-08-07 17:26:02 +02:00
|
|
|
this.originalContent = content;
|
|
|
|
this.editingType = type;
|
|
|
|
this.editingField = field;
|
|
|
|
|
|
|
|
if (LONG_TEXT.includes(type)) {
|
2020-08-04 17:54:19 +02:00
|
|
|
this.isTextareaEditor = true;
|
2020-08-07 17:26:02 +02:00
|
|
|
this.editingContent = this.$options.filters.typeFormat(this.originalContent, type);
|
2020-08-04 17:54:19 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-08-07 17:26:02 +02:00
|
|
|
if (BLOB.includes(type)) {
|
2020-08-04 17:54:19 +02:00
|
|
|
this.isBlobEditor = true;
|
2020-08-07 17:26:02 +02:00
|
|
|
this.editingContent = this.originalContent || '';
|
2020-08-04 17:54:19 +02:00
|
|
|
this.fileToUpload = null;
|
|
|
|
this.willBeDeleted = false;
|
2020-06-26 18:14:16 +02:00
|
|
|
|
2020-08-07 17:26:02 +02:00
|
|
|
if (this.originalContent !== null) {
|
|
|
|
const buff = Buffer.from(this.editingContent);
|
2020-08-04 17:54:19 +02:00
|
|
|
if (buff.length) {
|
|
|
|
const hex = buff.toString('hex').substring(0, 8).toUpperCase();
|
|
|
|
const { ext, mime } = mimeFromHex(hex);
|
|
|
|
this.contentInfo = {
|
|
|
|
ext,
|
|
|
|
mime,
|
2020-08-07 17:26:02 +02:00
|
|
|
size: this.editingContent.length
|
2020-08-04 17:54:19 +02:00
|
|
|
};
|
2020-08-03 18:07:08 +02:00
|
|
|
}
|
2020-08-04 17:54:19 +02:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2020-08-03 18:07:08 +02:00
|
|
|
|
2020-08-04 17:54:19 +02:00
|
|
|
// Inline editable fields
|
2020-09-01 19:23:13 +02:00
|
|
|
this.editingContent = this.$options.filters.typeFormat(this.originalContent, type, this.getFieldPrecision(field));
|
2020-08-04 17:54:19 +02:00
|
|
|
this.$nextTick(() => { // Focus on input
|
2020-08-07 17:26:02 +02:00
|
|
|
event.target.blur();
|
2020-07-30 19:12:29 +02:00
|
|
|
|
2020-08-07 17:26:02 +02:00
|
|
|
this.$nextTick(() => document.querySelector('.editable-field').focus());
|
2020-08-04 17:54:19 +02:00
|
|
|
});
|
2020-08-07 17:26:02 +02:00
|
|
|
|
2020-11-13 12:39:40 +01:00
|
|
|
const obj = { [field]: true };
|
2020-08-07 17:26:02 +02:00
|
|
|
this.isInlineEditor = { ...this.isInlineEditor, ...obj };
|
2020-06-26 18:14:16 +02:00
|
|
|
},
|
|
|
|
editOFF () {
|
2020-08-07 17:26:02 +02:00
|
|
|
this.isInlineEditor[this.editingField] = false;
|
2020-08-03 18:07:08 +02:00
|
|
|
let content;
|
2020-08-14 18:07:29 +02:00
|
|
|
if (!BLOB.includes(this.editingType)) {
|
2020-08-07 17:26:02 +02:00
|
|
|
if (this.editingContent === this.$options.filters.typeFormat(this.originalContent, this.editingType)) return;// If not changed
|
|
|
|
content = this.editingContent;
|
2020-08-03 18:07:08 +02:00
|
|
|
}
|
|
|
|
else { // Handle file upload
|
2020-08-04 17:54:19 +02:00
|
|
|
if (this.willBeDeleted) {
|
|
|
|
content = '';
|
|
|
|
this.willBeDeleted = false;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (!this.fileToUpload) return;
|
|
|
|
content = this.fileToUpload.file.path;
|
|
|
|
}
|
2020-08-03 18:07:08 +02:00
|
|
|
}
|
2020-06-26 18:14:16 +02:00
|
|
|
|
2020-08-18 18:03:59 +02:00
|
|
|
this.$emit('update-field', {
|
2020-09-01 19:23:13 +02:00
|
|
|
field: this.getFieldObj(this.editingField).name,
|
2020-08-07 17:26:02 +02:00
|
|
|
type: this.editingType,
|
2020-08-03 18:07:08 +02:00
|
|
|
content
|
|
|
|
});
|
2020-08-07 17:26:02 +02:00
|
|
|
|
|
|
|
this.editingType = null;
|
|
|
|
this.editingField = null;
|
2020-07-30 19:12:29 +02:00
|
|
|
},
|
|
|
|
hideEditorModal () {
|
|
|
|
this.isTextareaEditor = false;
|
2020-08-03 18:07:08 +02:00
|
|
|
this.isBlobEditor = false;
|
|
|
|
},
|
|
|
|
downloadFile () {
|
|
|
|
const downloadLink = document.createElement('a');
|
|
|
|
|
2020-08-07 17:26:02 +02:00
|
|
|
downloadLink.href = `data:${this.contentInfo.mime};base64, ${bufferToBase64(this.editingContent)}`;
|
2020-08-12 10:48:18 +02:00
|
|
|
downloadLink.setAttribute('download', `${this.editingField}.${this.contentInfo.ext}`);
|
2020-08-03 18:07:08 +02:00
|
|
|
document.body.appendChild(downloadLink);
|
|
|
|
|
|
|
|
downloadLink.click();
|
|
|
|
downloadLink.remove();
|
|
|
|
},
|
|
|
|
filesChange (event) {
|
|
|
|
const { files } = event.target;
|
|
|
|
if (!files.length) return;
|
|
|
|
|
|
|
|
this.fileToUpload = { name: files[0].name, file: files[0] };
|
2020-08-04 17:54:19 +02:00
|
|
|
this.willBeDeleted = false;
|
|
|
|
},
|
|
|
|
prepareToDelete () {
|
2020-08-07 17:26:02 +02:00
|
|
|
this.editingContent = '';
|
2020-08-04 17:54:19 +02:00
|
|
|
this.contentInfo = {
|
|
|
|
ext: '',
|
|
|
|
mime: '',
|
|
|
|
size: null
|
|
|
|
};
|
|
|
|
this.willBeDeleted = true;
|
2020-08-07 17:26:02 +02:00
|
|
|
},
|
|
|
|
contextMenu (event, cell) {
|
2020-08-18 18:03:59 +02:00
|
|
|
this.$emit('update-field', event, cell);
|
2020-08-07 17:26:02 +02:00
|
|
|
},
|
|
|
|
selectRow (event, row) {
|
2020-08-18 18:03:59 +02:00
|
|
|
this.$emit('select-row', event, row);
|
2020-08-17 15:10:19 +02:00
|
|
|
},
|
|
|
|
getKeyUsage (keyName) {
|
2021-02-17 14:17:50 +01:00
|
|
|
if (keyName.includes('.'))
|
|
|
|
return this.keyUsage.find(key => key.field === keyName.split('.').pop());
|
2020-12-15 17:08:36 +01:00
|
|
|
return this.keyUsage.find(key => key.field === keyName);
|
2020-06-26 18:14:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss">
|
2020-07-31 18:16:28 +02:00
|
|
|
.editable-field {
|
|
|
|
margin: 0;
|
|
|
|
border: none;
|
|
|
|
line-height: 1;
|
|
|
|
width: 100%;
|
2020-08-10 16:06:11 +02:00
|
|
|
position: absolute;
|
|
|
|
left: 0;
|
|
|
|
right: 0;
|
2020-06-26 18:14:16 +02:00
|
|
|
}
|
|
|
|
|
2020-07-31 18:16:28 +02:00
|
|
|
.cell-content {
|
|
|
|
display: block;
|
|
|
|
min-height: 0.8rem;
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
white-space: nowrap;
|
|
|
|
overflow: hidden;
|
2020-06-26 18:14:16 +02:00
|
|
|
}
|
2020-07-30 19:12:29 +02:00
|
|
|
|
2020-07-31 18:16:28 +02:00
|
|
|
.textarea-editor {
|
|
|
|
height: 50vh !important;
|
2020-07-30 19:12:29 +02:00
|
|
|
}
|
2020-07-31 15:45:32 +02:00
|
|
|
|
2020-07-31 18:16:28 +02:00
|
|
|
.editor-field-info {
|
|
|
|
margin-top: 0.6rem;
|
|
|
|
display: flex;
|
|
|
|
justify-content: space-between;
|
2020-08-03 18:07:08 +02:00
|
|
|
white-space: normal;
|
|
|
|
}
|
|
|
|
|
|
|
|
.editor-buttons {
|
|
|
|
display: flex;
|
2020-08-04 17:54:19 +02:00
|
|
|
justify-content: space-evenly;
|
2020-08-03 18:07:08 +02:00
|
|
|
|
|
|
|
.btn {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
}
|
2020-07-31 15:45:32 +02:00
|
|
|
}
|
2020-06-26 18:14:16 +02:00
|
|
|
</style>
|