Start implementing fields edit

This commit is contained in:
Fabio 2020-06-26 18:14:16 +02:00
parent 85ac1bc85f
commit cc8dbb8df7
8 changed files with 176 additions and 53 deletions

View File

@ -45,7 +45,7 @@ export default {
computed: {
...mapGetters({
updateStatus: 'application/getUpdateStatus',
downloadPercentage: 'application/getDownloadProgress'// TODO: remove float
downloadPercentage: 'application/getDownloadProgress'
}),
updateMessage () {
switch (this.updateStatus) {

View File

@ -82,7 +82,6 @@ export default {
},
methods: {
...mapActions({
addNotification: 'notifications/addNotification',
addWorkspace: 'workspaces/addWorkspace',
connectWorkspace: 'workspaces/connectWorkspace',
removeConnected: 'workspaces/removeConnected',

View File

@ -45,7 +45,6 @@ export default {
},
methods: {
...mapActions({
addNotification: 'notifications/addNotification',
connectWorkspace: 'workspaces/connectWorkspace'
}),
async startConnection () {

View File

@ -34,16 +34,14 @@
:key="row._id"
class="tr"
>
<div
<WorkspaceQueryTableCell
v-for="(col, cKey) in row"
:key="cKey"
class="td"
:class="`type-${fieldType(cKey)}${isNull(col)}`"
:style="{'display': cKey === '_id' ? 'none' : ''}"
tabindex="0"
>
{{ col | typeFormat(fieldType(cKey)) }}
</div>
:content="col"
:field="cKey"
:type="fieldType(cKey)"
@updateField="updateField"
/>
</div>
</div>
</div>
@ -52,48 +50,16 @@
</template>
<script>
import { uidGen, mimeFromHex, formatBytes } from 'common/libs/utilities';
import hexToBinary from 'common/libs/hexToBinary';
import moment from 'moment';
import { uidGen } from 'common/libs/utilities';
import BaseVirtualScroll from '@/components/BaseVirtualScroll';
import WorkspaceQueryTableCell from '@/components/WorkspaceQueryTableCell';
import { mapActions } from 'vuex';
export default {
name: 'WorkspaceQueryTable',
components: {
BaseVirtualScroll
},
filters: {
typeFormat (val, type) {
if (!val) return val;
switch (type) {
case 'char':
case 'varchar':
case 'text':
case 'mediumtext':
return val.substring(0, 128);
case 'date':
return moment(val).format('YYYY-MM-DD');
case 'datetime':
case 'timestamp':
return moment(val).format('YYYY-MM-DD HH:mm:ss.SSS');
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;
}
}
BaseVirtualScroll,
WorkspaceQueryTableCell
},
props: {
results: Object,
@ -105,6 +71,11 @@ export default {
localResults: []
};
},
computed: {
primaryField () {
return this.fields.filter(field => field.key === 'pri')[0] || false;
}
},
watch: {
results () {
this.localResults = this.results.rows ? this.results.rows.map(item => {
@ -123,6 +94,9 @@ export default {
window.removeEventListener('resize', this.resizeResults);
},
methods: {
...mapActions({
addNotification: 'notifications/addNotification'
}),
fieldType (cKey) {
let type = 'unknown';
const field = this.fields.filter(field => field.name === cKey)[0];
@ -131,9 +105,6 @@ export default {
return type;
},
isNull (col) {
return col === null ? ' is-null' : '';
},
keyName (key) {
switch (key) {
case 'pri':
@ -156,6 +127,11 @@ export default {
this.resultsSize = size;
}
}
},
updateField (payload) {
if (!this.primaryField)
this.addNotification({ status: 'warning', message: this.$t('message.unableEditFieldWithoutPrimary') });
console.log(payload);
}
}
};

View File

@ -0,0 +1,147 @@
<template>
<div
v-if="field !== '_id'"
ref="cell"
class="td"
:class="`type-${type} p-0`"
tabindex="0"
>
<span
v-if="!isEditing"
class="cell-content px-2"
:class="isNull(content)"
@dblclick="editON"
>{{ content | typeFormat(type) }}</span>
<input
v-else
ref="editField"
v-model="localContent"
:type="inputType"
autofocus
class="editable-field px-2"
@blur="editOFF"
>
</div>
</template>
<script>
import moment from 'moment';
import { mimeFromHex, formatBytes } from 'common/libs/utilities';
import hexToBinary from 'common/libs/hexToBinary';
export default {
name: 'WorkspaceQueryTableCell',
filters: {
typeFormat (val, type) {
if (!val) return val;
switch (type) {
case 'char':
case 'varchar':
case 'text':
case 'mediumtext':
return val.substring(0, 128);
case 'date':
return moment(val).format('YYYY-MM-DD');
case 'datetime':
case 'timestamp':
return moment(val).format('YYYY-MM-DD HH:mm:ss.SSS');
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;
}
}
},
props: {
type: String,
field: String,
content: [String, Number, Object, Date, Uint8Array]
},
data () {
return {
isEditing: false,
localContent: ''
};
},
computed: {
inputType () {
switch (this.type) {
case 'char':
case 'varchar':
case 'text':
case 'mediumtext':
return 'text';
case 'int':
case 'tinyint':
case 'smallint':
case 'mediumint':
return 'number';
case 'date':
return 'date';
case 'datetime':
case 'timestamp':
return 'datetime-local';
// TODO: file uploader/viewer or bit field
case 'blob':
case 'mediumblob':
case 'longblob':
case 'bit':
default:
return 'text';
}
}
},
methods: {
isNull (value) {
return value === null ? ' is-null' : '';
},
editON () {
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;
const { field, localContent: content } = this;
this.$emit('updateField', { field, content });
}
}
};
</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>

View File

@ -51,7 +51,8 @@ module.exports = {
updateAvailable: 'Update available',
downloadingUpdate: 'Downloading update',
updateDownloaded: 'Update downloaded',
restartToInstall: 'Restart Antares to install'
restartToInstall: 'Restart Antares to install',
unableEditFieldWithoutPrimary: 'Unable to edit a field without a primary key in resultset'
},
// Date and Time
short: {

View File

@ -7,6 +7,7 @@ $bg-color-gray: #272727;
$primary-color: #e36929;
$success-color: #32b643;
$error-color: #de3b28;
$warning-color: #e0a40c;
/*Sizes*/
$titlebar-height: 1.5rem;

View File

@ -24,7 +24,7 @@ export default {
isSettingModal: state => state.is_setting_modal,
selectedSettingTab: state => state.selected_setting_tab,
getUpdateStatus: state => state.update_status,
getDownloadProgress: state => state.download_progress
getDownloadProgress: state => Number(state.download_progress.toFixed(1))
},
mutations: {
SET_LOADING_STATUS (state, payload) {