antares/src/renderer/components/WorkspaceQueryTableCell.vue

178 lines
4.7 KiB
Vue
Raw Normal View History

2020-06-26 18:14:16 +02:00
<template>
<div
v-if="field !== '_id'"
ref="cell"
class="td"
:class="`type-${type} p-0`"
tabindex="0"
@contextmenu.prevent="$emit('cellContext', $event)"
2020-06-26 18:14:16 +02:00
>
<span
v-if="!isEditing"
class="cell-content px-2"
:class="isNull(content)"
@dblclick="editON"
2020-07-05 16:06:56 +02:00
>{{ content | typeFormat(type, precision) }}</span>
<template v-else>
<input
v-if="inputProps.mask"
ref="editField"
v-model="localContent"
v-mask="inputProps.mask"
:type="inputProps.type"
autofocus
class="editable-field px-2"
@blur="editOFF"
>
<input
v-else
ref="editField"
v-model="localContent"
:type="inputProps.type"
autofocus
class="editable-field px-2"
@blur="editOFF"
>
</template>
2020-06-26 18:14:16 +02:00
</div>
</template>
<script>
import moment from 'moment';
import { mimeFromHex, formatBytes } from 'common/libs/utilities';
import hexToBinary from 'common/libs/hexToBinary';
2020-07-02 19:17:25 +02:00
import { mask } from 'vue-the-mask';
2020-06-26 18:14:16 +02:00
export default {
name: 'WorkspaceQueryTableCell',
filters: {
2020-07-05 16:06:56 +02:00
typeFormat (val, type, precision) {
2020-06-26 18:14:16 +02:00
if (!val) return val;
switch (type) {
case 'char':
case 'varchar':
case 'text':
case 'mediumtext':
return val.substring(0, 128);
2020-07-02 19:17:25 +02:00
case 'date': {
return moment(val).isValid() ? moment(val).format('YYYY-MM-DD') : val;
}
2020-06-26 18:14:16 +02:00
case 'datetime':
2020-07-02 19:17:25 +02:00
case 'timestamp': {
2020-07-05 16:06:56 +02:00
let datePrecision = '';
for (let i = 0; i < precision; i++)
datePrecision += i === 0 ? '.S' : 'S';
return moment(val).isValid() ? moment(val).format(`YYYY-MM-DD HH:mm:ss${datePrecision}`) : val;
2020-07-02 19:17:25 +02:00
}
2020-06-26 18:14:16 +02:00
case 'blob':
case 'mediumblob':
case 'longblob': {
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)})`;
}
case 'bit': {
const hex = Buffer.from(val).toString('hex');
return hexToBinary(hex);
}
default:
return val;
}
}
},
2020-07-02 19:17:25 +02:00
directives: {
mask
},
2020-06-26 18:14:16 +02:00
props: {
type: String,
field: String,
2020-07-05 16:06:56 +02:00
precision: [Number, null],
2020-06-26 18:14:16 +02:00
content: [String, Number, Object, Date, Uint8Array]
},
data () {
return {
isEditing: false,
localContent: ''
};
},
computed: {
2020-07-02 19:17:25 +02:00
inputProps () {
2020-06-26 18:14:16 +02:00
switch (this.type) {
case 'char':
case 'varchar':
case 'text':
case 'mediumtext':
2020-07-02 19:17:25 +02:00
return { type: 'text', mask: false };
2020-06-26 18:14:16 +02:00
case 'int':
case 'tinyint':
case 'smallint':
case 'mediumint':
2020-07-02 19:17:25 +02:00
return { type: 'number', mask: false };
2020-06-26 18:14:16 +02:00
case 'date':
2020-07-02 19:17:25 +02:00
return { type: 'text', mask: '####-##-##' };
2020-06-26 18:14:16 +02:00
case 'datetime':
2020-07-05 16:06:56 +02:00
case 'timestamp': {
let datetimeMask = '####-##-## ##:##:##';
for (let i = 0; i < this.precision; i++)
datetimeMask += i === 0 ? '.#' : '#';
return { type: 'text', mask: datetimeMask };
}
2020-06-26 18:14:16 +02:00
case 'blob':
case 'mediumblob':
case 'longblob':
case 'bit':
2020-07-05 16:06:56 +02:00
return { type: 'file', mask: false };
2020-06-26 18:14:16 +02:00
default:
2020-06-28 15:31:16 +02:00
return 'hidden';
2020-06-26 18:14:16 +02:00
}
}
},
methods: {
isNull (value) {
return value === null ? ' is-null' : '';
},
editON () {
2020-07-05 16:06:56 +02:00
if (['file'].includes(this.inputProps.type)) return;// TODO: remove temporary file block
2020-06-26 18:14:16 +02:00
this.$nextTick(() => {
this.$refs.cell.blur();
this.$nextTick(() => this.$refs.editField.focus());
});
this.localContent = this.$options.filters.typeFormat(this.content, this.type);
this.isEditing = true;
},
editOFF () {
this.isEditing = false;
if (this.localContent === this.content) return;
2020-06-27 15:14:08 +02:00
const { field, type, localContent: content } = this;
this.$emit('updateField', { field, type, content });
2020-06-26 18:14:16 +02:00
}
}
};
</script>
<style lang="scss">
.editable-field{
margin: 0;
border: none;
line-height: 1;
width: 100%;
max-width: 200px;
}
.cell-content{
display: block;
min-height: .8rem;
text-overflow: ellipsis;
max-width: 200px;
white-space: nowrap;
overflow: hidden;
}
</style>