2020-06-10 19:29:10 +02:00
|
|
|
<template>
|
2020-08-10 16:06:11 +02:00
|
|
|
<div
|
|
|
|
ref="tableWrapper"
|
2021-04-20 16:30:10 +02:00
|
|
|
class="vscroll no-outline"
|
|
|
|
tabindex="0"
|
2020-08-10 16:06:11 +02:00
|
|
|
:style="{'height': resultsSize+'px'}"
|
2021-04-20 16:30:10 +02:00
|
|
|
@keyup.46="showDeleteConfirmModal"
|
2022-02-16 09:14:46 +01:00
|
|
|
@keydown.ctrl.65="selectAllRows($event)"
|
2021-10-16 09:58:32 +02:00
|
|
|
@keydown.esc="deselectRows"
|
2020-08-10 16:06:11 +02:00
|
|
|
>
|
2020-07-10 19:51:36 +02:00
|
|
|
<TableContext
|
|
|
|
v-if="isContext"
|
|
|
|
:context-event="contextEvent"
|
2020-07-22 18:30:52 +02:00
|
|
|
:selected-rows="selectedRows"
|
2021-07-16 17:09:02 +02:00
|
|
|
:selected-cell="selectedCell"
|
2021-04-20 16:30:10 +02:00
|
|
|
@show-delete-modal="showDeleteConfirmModal"
|
2021-02-28 21:45:38 +01:00
|
|
|
@set-null="setNull"
|
2021-06-30 19:27:24 +02:00
|
|
|
@copy-cell="copyCell"
|
|
|
|
@copy-row="copyRow"
|
2021-04-20 16:30:10 +02:00
|
|
|
@close-context="closeContext"
|
2020-07-10 19:51:36 +02:00
|
|
|
/>
|
2020-09-08 11:47:01 +02:00
|
|
|
<ul v-if="resultsWithRows.length > 1" class="tab tab-block result-tabs">
|
2020-09-06 08:41:57 +02:00
|
|
|
<li
|
2020-09-08 11:47:01 +02:00
|
|
|
v-for="(result, index) in resultsWithRows"
|
2020-09-06 08:41:57 +02:00
|
|
|
:key="index"
|
|
|
|
class="tab-item"
|
|
|
|
:class="{'active': resultsetIndex === index}"
|
|
|
|
@click="selectResultset(index)"
|
|
|
|
>
|
2020-10-09 22:44:05 +02:00
|
|
|
<a>{{ result.fields ? result.fields[0].table : '' }} ({{ result.rows.length }})</a>
|
2020-09-06 08:41:57 +02:00
|
|
|
</li>
|
|
|
|
</ul>
|
2020-08-10 16:06:11 +02:00
|
|
|
<div ref="table" class="table table-hover">
|
|
|
|
<div class="thead">
|
|
|
|
<div class="tr">
|
|
|
|
<div
|
2020-09-11 18:01:07 +02:00
|
|
|
v-for="(field, index) in fields"
|
|
|
|
:key="index"
|
2020-08-10 16:06:11 +02:00
|
|
|
class="th c-hand"
|
2020-10-18 10:27:02 +02:00
|
|
|
:title="`${field.type} ${fieldLength(field) ? `(${fieldLength(field)})` : ''}`"
|
2020-08-10 16:06:11 +02:00
|
|
|
>
|
|
|
|
<div ref="columnResize" class="column-resizable">
|
|
|
|
<div class="table-column-title" @click="sort(field.name)">
|
|
|
|
<i
|
|
|
|
v-if="field.key"
|
2020-08-12 10:48:18 +02:00
|
|
|
class="mdi mdi-key column-key c-help"
|
2020-08-10 16:06:11 +02:00
|
|
|
:class="`key-${field.key}`"
|
|
|
|
:title="keyName(field.key)"
|
2020-08-12 10:48:18 +02:00
|
|
|
/>
|
2020-10-18 10:27:02 +02:00
|
|
|
<span>{{ field.alias || field.name }}</span>
|
2020-08-12 10:48:18 +02:00
|
|
|
<i
|
2021-03-03 19:31:05 +01:00
|
|
|
v-if="isSortable && currentSort === field.name || currentSort === `${field.table}.${field.name}`"
|
2020-08-12 10:48:18 +02:00
|
|
|
class="mdi sort-icon"
|
|
|
|
:class="currentSortDir === 'asc' ? 'mdi-sort-ascending':'mdi-sort-descending'"
|
|
|
|
/>
|
2022-02-16 09:14:46 +01:00
|
|
|
<i v-else class="mdi sort-icon mdi-minus d-invisible" />
|
2020-06-16 18:01:22 +02:00
|
|
|
</div>
|
2020-06-11 23:34:38 +02:00
|
|
|
</div>
|
|
|
|
</div>
|
2020-06-10 19:29:10 +02:00
|
|
|
</div>
|
2020-08-10 16:06:11 +02:00
|
|
|
</div>
|
|
|
|
<BaseVirtualScroll
|
2020-09-08 11:47:01 +02:00
|
|
|
v-if="resultsWithRows[resultsetIndex] && resultsWithRows[resultsetIndex].rows"
|
2020-08-10 16:06:11 +02:00
|
|
|
ref="resultTable"
|
|
|
|
:items="sortedResults"
|
2022-02-16 09:14:46 +01:00
|
|
|
:item-height="rowHeight"
|
2020-08-10 16:06:11 +02:00
|
|
|
class="tbody"
|
|
|
|
:visible-height="resultsSize"
|
|
|
|
:scroll-element="scrollElement"
|
|
|
|
>
|
|
|
|
<template slot-scope="{ items }">
|
2021-08-12 09:54:13 +02:00
|
|
|
<WorkspaceTabQueryTableRow
|
2020-08-10 16:06:11 +02:00
|
|
|
v-for="row in items"
|
2022-02-16 09:14:46 +01:00
|
|
|
:key="row._antares_id"
|
|
|
|
:item-height="rowHeight"
|
2020-08-10 16:06:11 +02:00
|
|
|
:row="row"
|
2021-02-26 22:31:05 +01:00
|
|
|
:fields="fieldsObj"
|
2020-08-14 18:07:29 +02:00
|
|
|
:key-usage="keyUsage"
|
2021-07-14 16:10:34 +02:00
|
|
|
:element-type="elementType"
|
2022-02-16 09:14:46 +01:00
|
|
|
:class="{'selected': selectedRows.includes(row._antares_id)}"
|
|
|
|
@select-row="selectRow($event, row._antares_id)"
|
2021-01-30 14:58:12 +01:00
|
|
|
@update-field="updateField($event, row)"
|
2020-08-10 16:06:11 +02:00
|
|
|
@contextmenu="contextMenu"
|
|
|
|
/>
|
|
|
|
</template>
|
2020-10-20 13:12:12 +02:00
|
|
|
</BaseVirtualScroll>
|
2020-08-10 16:06:11 +02:00
|
|
|
</div>
|
2021-04-20 16:30:10 +02:00
|
|
|
|
|
|
|
<ConfirmModal
|
|
|
|
v-if="isDeleteConfirmModal"
|
|
|
|
@confirm="deleteSelected"
|
|
|
|
@hide="hideDeleteConfirmModal"
|
|
|
|
>
|
2022-02-16 09:14:46 +01:00
|
|
|
<template #header>
|
2021-04-20 16:30:10 +02:00
|
|
|
<div class="d-flex">
|
2021-06-13 11:16:21 +02:00
|
|
|
<i class="mdi mdi-24px mdi-delete mr-1" />
|
|
|
|
<span class="cut-text">{{ $tc('message.deleteRows', selectedRows.length) }}</span>
|
2021-04-20 16:30:10 +02:00
|
|
|
</div>
|
|
|
|
</template>
|
2022-02-16 09:14:46 +01:00
|
|
|
<template #body>
|
2021-04-20 16:30:10 +02:00
|
|
|
<div class="mb-2">
|
|
|
|
{{ $tc('message.confirmToDeleteRows', selectedRows.length) }}
|
|
|
|
</div>
|
2022-02-16 09:14:46 +01:00
|
|
|
</template>
|
2021-04-20 16:30:10 +02:00
|
|
|
</ConfirmModal>
|
2020-07-10 19:51:36 +02:00
|
|
|
</div>
|
2020-06-10 19:29:10 +02:00
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2020-08-04 17:54:19 +02:00
|
|
|
import { uidGen } from 'common/libs/uidGen';
|
2021-01-08 21:55:03 +01:00
|
|
|
import arrayToFile from '../libs/arrayToFile';
|
2021-02-12 18:02:18 +01:00
|
|
|
import { TEXT, LONG_TEXT, BLOB } from 'common/fieldTypes';
|
2020-06-11 23:34:38 +02:00
|
|
|
import BaseVirtualScroll from '@/components/BaseVirtualScroll';
|
2021-08-12 09:54:13 +02:00
|
|
|
import WorkspaceTabQueryTableRow from '@/components/WorkspaceTabQueryTableRow';
|
|
|
|
import TableContext from '@/components/WorkspaceTabQueryTableContext';
|
2021-04-20 16:30:10 +02:00
|
|
|
import ConfirmModal from '@/components/BaseConfirmModal';
|
2020-08-14 18:07:29 +02:00
|
|
|
import { mapActions, mapGetters } from 'vuex';
|
2021-04-07 15:05:11 +02:00
|
|
|
import moment from 'moment';
|
2020-06-11 23:34:38 +02:00
|
|
|
|
2020-06-10 19:29:10 +02:00
|
|
|
export default {
|
2021-08-12 09:54:13 +02:00
|
|
|
name: 'WorkspaceTabQueryTable',
|
2020-06-11 23:34:38 +02:00
|
|
|
components: {
|
2020-06-26 18:14:16 +02:00
|
|
|
BaseVirtualScroll,
|
2021-08-12 09:54:13 +02:00
|
|
|
WorkspaceTabQueryTableRow,
|
2021-04-20 16:30:10 +02:00
|
|
|
TableContext,
|
|
|
|
ConfirmModal
|
2020-06-18 19:01:09 +02:00
|
|
|
},
|
2020-06-10 19:29:10 +02:00
|
|
|
props: {
|
2020-09-06 08:41:57 +02:00
|
|
|
results: Array,
|
2020-09-18 12:54:02 +02:00
|
|
|
connUid: String,
|
2021-03-05 17:10:52 +01:00
|
|
|
mode: String,
|
2021-07-14 16:10:34 +02:00
|
|
|
isSelected: Boolean,
|
|
|
|
elementType: { type: String, default: 'table' }
|
2020-06-10 19:29:10 +02:00
|
|
|
},
|
2020-06-11 23:34:38 +02:00
|
|
|
data () {
|
|
|
|
return {
|
2021-08-03 17:59:15 +02:00
|
|
|
resultsSize: 0,
|
2020-07-10 19:51:36 +02:00
|
|
|
localResults: [],
|
|
|
|
isContext: false,
|
2021-04-20 16:30:10 +02:00
|
|
|
isDeleteConfirmModal: false,
|
2020-07-22 18:30:52 +02:00
|
|
|
contextEvent: null,
|
|
|
|
selectedCell: null,
|
2020-07-24 13:26:56 +02:00
|
|
|
selectedRows: [],
|
|
|
|
currentSort: '',
|
2020-09-06 08:41:57 +02:00
|
|
|
currentSortDir: 'asc',
|
|
|
|
resultsetIndex: 0,
|
2022-02-16 09:14:46 +01:00
|
|
|
scrollElement: null,
|
|
|
|
rowHeight: 23
|
2020-06-11 23:34:38 +02:00
|
|
|
};
|
|
|
|
},
|
2020-06-26 18:14:16 +02:00
|
|
|
computed: {
|
2020-08-14 18:07:29 +02:00
|
|
|
...mapGetters({
|
2021-05-29 11:04:02 +02:00
|
|
|
getWorkspace: 'workspaces/getWorkspace',
|
|
|
|
pageSize: 'settings/getDataTabLimit'
|
2020-08-14 18:07:29 +02:00
|
|
|
}),
|
2020-09-18 12:54:02 +02:00
|
|
|
workspaceSchema () {
|
|
|
|
return this.getWorkspace(this.connUid).breadcrumbs.schema;
|
|
|
|
},
|
2020-06-26 18:14:16 +02:00
|
|
|
primaryField () {
|
2021-04-08 17:47:10 +02:00
|
|
|
const primaryFields = this.fields.filter(field => field.key === 'pri');
|
|
|
|
const uniqueFields = this.fields.filter(field => field.key === 'uni');
|
2021-03-21 13:00:27 +01:00
|
|
|
|
2021-04-08 17:47:10 +02:00
|
|
|
if ((primaryFields.length > 1 || !primaryFields.length) && (uniqueFields.length > 1 || !uniqueFields.length))
|
2021-03-21 13:00:27 +01:00
|
|
|
return false;
|
|
|
|
|
2021-04-08 17:47:10 +02:00
|
|
|
return primaryFields[0] || uniqueFields[0];
|
2020-07-24 13:26:56 +02:00
|
|
|
},
|
2021-03-03 19:31:05 +01:00
|
|
|
isSortable () {
|
2021-02-18 18:12:36 +01:00
|
|
|
return this.fields.every(field => field.name);
|
|
|
|
},
|
2020-12-07 17:51:48 +01:00
|
|
|
isHardSort () {
|
2021-05-29 11:04:02 +02:00
|
|
|
return this.mode === 'table' && this.localResults.length === this.pageSize;
|
2020-12-07 17:51:48 +01:00
|
|
|
},
|
2020-07-24 13:26:56 +02:00
|
|
|
sortedResults () {
|
2020-12-07 17:51:48 +01:00
|
|
|
if (this.currentSort && !this.isHardSort) {
|
2020-07-24 13:26:56 +02:00
|
|
|
return [...this.localResults].sort((a, b) => {
|
|
|
|
let modifier = 1;
|
|
|
|
const valA = typeof a[this.currentSort] === 'string' ? a[this.currentSort].toLowerCase() : a[this.currentSort];
|
|
|
|
const valB = typeof b[this.currentSort] === 'string' ? b[this.currentSort].toLowerCase() : b[this.currentSort];
|
|
|
|
if (this.currentSortDir === 'desc') modifier = -1;
|
|
|
|
if (valA < valB) return -1 * modifier;
|
|
|
|
if (valA > valB) return 1 * modifier;
|
|
|
|
return 0;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return this.localResults;
|
2020-08-10 16:06:11 +02:00
|
|
|
},
|
2020-09-08 11:47:01 +02:00
|
|
|
resultsWithRows () {
|
|
|
|
return this.results.filter(result => result.rows);
|
|
|
|
},
|
2020-08-14 18:07:29 +02:00
|
|
|
fields () {
|
2020-10-27 16:41:00 +01:00
|
|
|
return this.resultsWithRows.length ? this.resultsWithRows[this.resultsetIndex].fields : [];
|
2020-08-14 18:07:29 +02:00
|
|
|
},
|
|
|
|
keyUsage () {
|
2020-10-27 16:41:00 +01:00
|
|
|
return this.resultsWithRows.length ? this.resultsWithRows[this.resultsetIndex].keys : [];
|
2021-02-26 22:31:05 +01:00
|
|
|
},
|
|
|
|
fieldsObj () {
|
|
|
|
if (this.sortedResults.length) {
|
|
|
|
const fieldsObj = {};
|
|
|
|
for (const key in this.sortedResults[0]) {
|
2022-02-16 09:14:46 +01:00
|
|
|
if (key === '_antares_id') continue;
|
2021-02-26 22:31:05 +01:00
|
|
|
|
|
|
|
const fieldObj = this.fields.find(field => {
|
|
|
|
let fieldNames = [
|
|
|
|
field.name,
|
|
|
|
field.alias,
|
|
|
|
`${field.table}.${field.name}`,
|
|
|
|
`${field.table}.${field.alias}`,
|
|
|
|
`${field.tableAlias}.${field.name}`,
|
|
|
|
`${field.tableAlias}.${field.alias}`
|
|
|
|
];
|
|
|
|
|
|
|
|
if (field.table)
|
|
|
|
fieldNames = [...fieldNames, `${field.table.toLowerCase()}.${field.name}`, `${field.table.toLowerCase()}.${field.alias}`];
|
|
|
|
|
|
|
|
if (field.tableAlias)
|
|
|
|
fieldNames = [...fieldNames, `${field.tableAlias.toLowerCase()}.${field.name}`, `${field.tableAlias.toLowerCase()}.${field.alias}`];
|
|
|
|
|
|
|
|
return fieldNames.includes(key);
|
|
|
|
});
|
|
|
|
|
|
|
|
fieldsObj[key] = fieldObj;
|
|
|
|
}
|
|
|
|
return fieldsObj;
|
|
|
|
}
|
|
|
|
return {};
|
2020-06-26 18:14:16 +02:00
|
|
|
}
|
|
|
|
},
|
2020-06-16 18:01:22 +02:00
|
|
|
watch: {
|
|
|
|
results () {
|
2020-09-06 08:41:57 +02:00
|
|
|
this.setLocalResults();
|
|
|
|
this.resultsetIndex = 0;
|
|
|
|
},
|
|
|
|
resultsetIndex () {
|
|
|
|
this.setLocalResults();
|
2021-07-15 19:51:18 +02:00
|
|
|
},
|
|
|
|
isSelected (val) {
|
|
|
|
if (val) this.refreshScroller();
|
2020-06-11 23:34:38 +02:00
|
|
|
}
|
|
|
|
},
|
2020-06-12 18:10:45 +02:00
|
|
|
updated () {
|
2020-08-10 16:06:11 +02:00
|
|
|
if (this.$refs.table)
|
2020-07-24 13:26:56 +02:00
|
|
|
this.refreshScroller();
|
2020-09-06 08:41:57 +02:00
|
|
|
|
|
|
|
if (this.$refs.tableWrapper)
|
|
|
|
this.scrollElement = this.$refs.tableWrapper;
|
2022-02-16 09:14:46 +01:00
|
|
|
|
|
|
|
document.querySelectorAll('.column-resizable').forEach(element => {
|
|
|
|
if (element.clientWidth !== 0)
|
|
|
|
element.style.width = element.clientWidth + 'px';
|
|
|
|
});
|
2020-06-11 23:34:38 +02:00
|
|
|
},
|
|
|
|
mounted () {
|
|
|
|
window.addEventListener('resize', this.resizeResults);
|
|
|
|
},
|
|
|
|
destroyed () {
|
|
|
|
window.removeEventListener('resize', this.resizeResults);
|
|
|
|
},
|
2020-06-10 19:29:10 +02:00
|
|
|
methods: {
|
2020-06-26 18:14:16 +02:00
|
|
|
...mapActions({
|
|
|
|
addNotification: 'notifications/addNotification'
|
|
|
|
}),
|
2020-06-18 19:01:09 +02:00
|
|
|
fieldType (cKey) {
|
|
|
|
let type = 'unknown';
|
|
|
|
const field = this.fields.filter(field => field.name === cKey)[0];
|
|
|
|
if (field)
|
|
|
|
type = field.type;
|
2020-06-10 19:29:10 +02:00
|
|
|
|
2020-06-18 19:01:09 +02:00
|
|
|
return type;
|
|
|
|
},
|
2020-07-05 16:06:56 +02:00
|
|
|
fieldPrecision (cKey) {
|
|
|
|
let length = 0;
|
|
|
|
const field = this.fields.filter(field => field.name === cKey)[0];
|
|
|
|
if (field)
|
2020-08-12 10:48:18 +02:00
|
|
|
length = field.datePrecision;
|
2020-07-05 16:06:56 +02:00
|
|
|
|
|
|
|
return length;
|
|
|
|
},
|
2020-10-17 10:12:40 +02:00
|
|
|
fieldLength (field) {
|
|
|
|
if ([...BLOB, ...LONG_TEXT].includes(field.type)) return null;
|
2021-02-12 18:02:18 +01:00
|
|
|
else if (TEXT.includes(field.type)) return field.charLength;
|
2022-02-16 09:14:46 +01:00
|
|
|
else if (field.numScale) return `${field.numPrecision}, ${field.numScale}`;
|
2021-01-21 18:14:37 +01:00
|
|
|
return field.length;
|
2020-10-17 10:12:40 +02:00
|
|
|
},
|
2020-06-16 18:01:22 +02:00
|
|
|
keyName (key) {
|
|
|
|
switch (key) {
|
|
|
|
case 'pri':
|
|
|
|
return 'PRIMARY';
|
|
|
|
case 'uni':
|
|
|
|
return 'UNIQUE';
|
|
|
|
case 'mul':
|
|
|
|
return 'INDEX';
|
|
|
|
default:
|
|
|
|
return 'UNKNOWN ' + key;
|
|
|
|
}
|
|
|
|
},
|
2020-09-08 11:47:01 +02:00
|
|
|
getTable (index) {
|
|
|
|
if (this.resultsWithRows[index] && this.resultsWithRows[index].fields && this.resultsWithRows[index].fields.length)
|
2020-10-27 16:41:00 +01:00
|
|
|
return this.resultsWithRows[index].fields[0].table;
|
2020-09-08 11:47:01 +02:00
|
|
|
return '';
|
|
|
|
},
|
2020-09-18 12:54:02 +02:00
|
|
|
getSchema (index) {
|
|
|
|
if (this.resultsWithRows[index] && this.resultsWithRows[index].fields && this.resultsWithRows[index].fields.length)
|
2020-10-10 16:54:00 +02:00
|
|
|
return this.resultsWithRows[index].fields[0].schema;
|
2020-09-18 12:54:02 +02:00
|
|
|
return this.workspaceSchema;
|
|
|
|
},
|
2020-09-13 18:25:28 +02:00
|
|
|
getPrimaryValue (row) {
|
|
|
|
const primaryFieldName = Object.keys(row).find(prop => [
|
|
|
|
this.primaryField.alias,
|
|
|
|
this.primaryField.name,
|
|
|
|
`${this.primaryField.table}.${this.primaryField.alias}`,
|
2020-10-21 14:58:22 +02:00
|
|
|
`${this.primaryField.table}.${this.primaryField.name}`,
|
|
|
|
`${this.primaryField.tableAlias}.${this.primaryField.alias}`,
|
|
|
|
`${this.primaryField.tableAlias}.${this.primaryField.name}`
|
2020-09-13 18:25:28 +02:00
|
|
|
].includes(prop));
|
|
|
|
return row[primaryFieldName];
|
|
|
|
},
|
2020-09-06 08:41:57 +02:00
|
|
|
setLocalResults () {
|
2020-11-13 12:39:40 +01:00
|
|
|
this.localResults = this.resultsWithRows[this.resultsetIndex] && this.resultsWithRows[this.resultsetIndex].rows
|
|
|
|
? this.resultsWithRows[this.resultsetIndex].rows.map(item => {
|
2022-02-16 09:14:46 +01:00
|
|
|
return { ...item, _antares_id: uidGen() };
|
2020-11-13 12:39:40 +01:00
|
|
|
})
|
|
|
|
: [];
|
2020-09-06 08:41:57 +02:00
|
|
|
},
|
2020-07-23 19:10:14 +02:00
|
|
|
resizeResults () {
|
2021-03-05 17:10:52 +01:00
|
|
|
if (this.$refs.resultTable && this.isSelected) {
|
2020-08-19 16:25:42 +02:00
|
|
|
const el = this.$refs.tableWrapper;
|
2020-06-11 23:34:38 +02:00
|
|
|
|
2020-06-12 18:10:45 +02:00
|
|
|
if (el) {
|
2020-08-10 16:06:11 +02:00
|
|
|
const footer = document.getElementById('footer');
|
2020-06-12 18:10:45 +02:00
|
|
|
const size = window.innerHeight - el.getBoundingClientRect().top - footer.offsetHeight;
|
|
|
|
this.resultsSize = size;
|
|
|
|
}
|
2020-07-23 19:10:14 +02:00
|
|
|
this.$refs.resultTable.updateWindow();
|
2020-06-11 23:34:38 +02:00
|
|
|
}
|
2020-06-26 18:14:16 +02:00
|
|
|
},
|
2020-07-23 19:10:14 +02:00
|
|
|
refreshScroller () {
|
|
|
|
this.resizeResults();
|
|
|
|
},
|
2021-01-30 14:58:12 +01:00
|
|
|
updateField (payload, row) {
|
2022-02-16 09:14:46 +01:00
|
|
|
const orgRow = this.localResults.find(lr => lr._antares_id === row._antares_id);
|
2021-01-30 14:58:12 +01:00
|
|
|
|
2021-04-07 15:05:11 +02:00
|
|
|
Object.keys(orgRow).forEach(key => { // remap the row
|
|
|
|
if (orgRow[key] instanceof Date && moment(orgRow[key]).isValid()) { // if datetime
|
|
|
|
let datePrecision = '';
|
|
|
|
const precision = this.fields.find(field => field.name === key).datePrecision;
|
|
|
|
for (let i = 0; i < precision; i++)
|
|
|
|
datePrecision += i === 0 ? '.S' : 'S';
|
|
|
|
|
|
|
|
orgRow[key] = moment(orgRow[key]).format(`YYYY-MM-DD HH:mm:ss${datePrecision}`);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-01-30 14:58:12 +01:00
|
|
|
const params = {
|
|
|
|
primary: this.primaryField.name,
|
|
|
|
schema: this.getSchema(this.resultsetIndex),
|
|
|
|
table: this.getTable(this.resultsetIndex),
|
2021-03-21 13:00:27 +01:00
|
|
|
id: this.getPrimaryValue(orgRow),
|
|
|
|
row,
|
|
|
|
orgRow,
|
2021-01-30 14:58:12 +01:00
|
|
|
...payload
|
|
|
|
};
|
|
|
|
this.$emit('update-field', params);
|
2020-06-28 15:31:16 +02:00
|
|
|
},
|
2021-04-20 16:30:10 +02:00
|
|
|
closeContext () {
|
|
|
|
this.isContext = false;
|
|
|
|
},
|
2021-06-02 12:32:12 +02:00
|
|
|
showDeleteConfirmModal (e) {
|
|
|
|
if (e && e.path && ['INPUT', 'TEXTAREA', 'SELECT'].includes(e.path[0].tagName))
|
|
|
|
return;
|
2021-04-20 16:30:10 +02:00
|
|
|
this.isDeleteConfirmModal = true;
|
|
|
|
},
|
|
|
|
hideDeleteConfirmModal () {
|
|
|
|
this.isDeleteConfirmModal = false;
|
|
|
|
},
|
2020-07-23 19:10:14 +02:00
|
|
|
deleteSelected () {
|
2021-04-20 16:30:10 +02:00
|
|
|
this.closeContext();
|
2022-02-16 09:14:46 +01:00
|
|
|
const rows = JSON.parse(JSON.stringify(this.localResults)).filter(row => this.selectedRows.includes(row._antares_id)).map(row => {
|
|
|
|
delete row._antares_id;
|
2021-01-28 18:33:29 +01:00
|
|
|
return row;
|
|
|
|
});
|
|
|
|
|
|
|
|
const params = {
|
|
|
|
primary: this.primaryField.name,
|
|
|
|
schema: this.getSchema(this.resultsetIndex),
|
|
|
|
table: this.getTable(this.resultsetIndex),
|
|
|
|
rows
|
|
|
|
};
|
|
|
|
this.$emit('delete-selected', params);
|
2020-07-23 19:10:14 +02:00
|
|
|
},
|
2021-02-28 21:45:38 +01:00
|
|
|
setNull () {
|
2022-02-16 09:14:46 +01:00
|
|
|
const row = this.localResults.find(row => this.selectedRows.includes(row._antares_id));
|
2021-02-28 21:45:38 +01:00
|
|
|
|
|
|
|
const params = {
|
|
|
|
primary: this.primaryField.name,
|
|
|
|
schema: this.getSchema(this.resultsetIndex),
|
|
|
|
table: this.getTable(this.resultsetIndex),
|
|
|
|
id: this.getPrimaryValue(row),
|
|
|
|
row,
|
2021-03-21 13:00:27 +01:00
|
|
|
orgRow: row,
|
2021-02-28 21:45:38 +01:00
|
|
|
field: this.selectedCell.field,
|
|
|
|
content: null
|
|
|
|
};
|
|
|
|
this.$emit('update-field', params);
|
|
|
|
},
|
2021-06-30 19:27:24 +02:00
|
|
|
copyCell () {
|
2022-02-16 09:14:46 +01:00
|
|
|
const row = this.localResults.find(row => this.selectedRows.includes(row._antares_id));
|
2021-06-30 19:27:24 +02:00
|
|
|
const cellName = Object.keys(row).find(prop => [
|
|
|
|
this.selectedCell.field,
|
2022-02-16 09:14:46 +01:00
|
|
|
this.selectedCell.orgField,
|
2021-06-30 19:27:24 +02:00
|
|
|
`${this.fields[0].table}.${this.selectedCell.field}`,
|
|
|
|
`${this.fields[0].tableAlias}.${this.selectedCell.field}`
|
|
|
|
].includes(prop));
|
2022-02-16 09:14:46 +01:00
|
|
|
let valueToCopy = row[cellName];
|
|
|
|
if (typeof valueToCopy === 'object')
|
|
|
|
valueToCopy = JSON.stringify(valueToCopy);
|
2021-06-30 19:27:24 +02:00
|
|
|
navigator.clipboard.writeText(valueToCopy);
|
|
|
|
},
|
|
|
|
copyRow () {
|
2022-02-16 09:14:46 +01:00
|
|
|
const row = this.localResults.find(row => this.selectedRows.includes(row._antares_id));
|
2021-06-30 19:27:24 +02:00
|
|
|
const rowToCopy = JSON.parse(JSON.stringify(row));
|
2022-02-16 09:14:46 +01:00
|
|
|
delete rowToCopy._antares_id;
|
2021-06-30 19:27:24 +02:00
|
|
|
navigator.clipboard.writeText(JSON.stringify(rowToCopy));
|
|
|
|
},
|
2020-06-28 15:31:16 +02:00
|
|
|
applyUpdate (params) {
|
2020-09-14 11:08:11 +02:00
|
|
|
const { primary, id, field, table, content } = params;
|
|
|
|
|
2020-06-28 15:31:16 +02:00
|
|
|
this.localResults = this.localResults.map(row => {
|
2020-09-14 11:08:11 +02:00
|
|
|
if (row[primary] === id)// only fieldName
|
2020-06-28 15:31:16 +02:00
|
|
|
row[field] = content;
|
2020-09-14 11:08:11 +02:00
|
|
|
else if (row[`${table}.${primary}`] === id)// table.fieldName
|
|
|
|
row[`${table}.${field}`] = content;
|
2020-06-28 15:31:16 +02:00
|
|
|
|
|
|
|
return row;
|
|
|
|
});
|
2020-07-10 19:51:36 +02:00
|
|
|
},
|
2020-07-22 18:30:52 +02:00
|
|
|
selectRow (event, row) {
|
|
|
|
if (event.ctrlKey) {
|
|
|
|
if (this.selectedRows.includes(row))
|
|
|
|
this.selectedRows = this.selectedRows.filter(el => el !== row);
|
|
|
|
else
|
|
|
|
this.selectedRows.push(row);
|
|
|
|
}
|
|
|
|
else if (event.shiftKey) {
|
|
|
|
if (!this.selectedRows.length)
|
|
|
|
this.selectedRows.push(row);
|
|
|
|
else {
|
|
|
|
const lastID = this.selectedRows.slice(-1)[0];
|
2022-02-16 09:14:46 +01:00
|
|
|
const lastIndex = this.sortedResults.findIndex(el => el._antares_id === lastID);
|
|
|
|
const clickedIndex = this.sortedResults.findIndex(el => el._antares_id === row);
|
2020-07-22 18:30:52 +02:00
|
|
|
if (lastIndex > clickedIndex) {
|
|
|
|
for (let i = clickedIndex; i < lastIndex; i++)
|
2022-02-16 09:14:46 +01:00
|
|
|
this.selectedRows.push(this.sortedResults[i]._antares_id);
|
2020-07-22 18:30:52 +02:00
|
|
|
}
|
|
|
|
else if (lastIndex < clickedIndex) {
|
|
|
|
for (let i = clickedIndex; i > lastIndex; i--)
|
2022-02-16 09:14:46 +01:00
|
|
|
this.selectedRows.push(this.sortedResults[i]._antares_id);
|
2020-07-22 18:30:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
this.selectedRows = [row];
|
|
|
|
},
|
2022-02-16 09:14:46 +01:00
|
|
|
selectAllRows (e) {
|
|
|
|
if (e.target.classList.contains('editable-field')) return;
|
|
|
|
|
2021-10-16 09:58:32 +02:00
|
|
|
this.selectedRows = this.localResults.reduce((acc, curr) => {
|
2022-02-16 09:14:46 +01:00
|
|
|
acc.push(curr._antares_id);
|
2021-10-16 09:58:32 +02:00
|
|
|
return acc;
|
|
|
|
}, []);
|
|
|
|
},
|
|
|
|
deselectRows () {
|
|
|
|
this.selectedRows = [];
|
|
|
|
},
|
2020-07-22 18:30:52 +02:00
|
|
|
contextMenu (event, cell) {
|
2021-02-21 21:24:25 +01:00
|
|
|
if (event.target.localName === 'input') return;
|
|
|
|
|
2020-07-22 18:30:52 +02:00
|
|
|
this.selectedCell = cell;
|
|
|
|
if (!this.selectedRows.includes(cell.id))
|
|
|
|
this.selectedRows = [cell.id];
|
2020-07-10 19:51:36 +02:00
|
|
|
this.contextEvent = event;
|
|
|
|
this.isContext = true;
|
2020-07-24 13:26:56 +02:00
|
|
|
},
|
|
|
|
sort (field) {
|
2021-03-03 19:31:05 +01:00
|
|
|
if (!this.isSortable) return;
|
2021-02-18 18:12:36 +01:00
|
|
|
|
2021-05-11 18:32:11 +02:00
|
|
|
this.selectedRows = [];
|
|
|
|
|
2020-09-18 12:54:02 +02:00
|
|
|
if (this.mode === 'query')
|
|
|
|
field = `${this.getTable(this.resultsetIndex)}.${field}`;
|
|
|
|
|
2020-07-24 13:26:56 +02:00
|
|
|
if (field === this.currentSort) {
|
|
|
|
if (this.currentSortDir === 'asc')
|
|
|
|
this.currentSortDir = 'desc';
|
|
|
|
else
|
|
|
|
this.resetSort();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this.currentSortDir = 'asc';
|
|
|
|
this.currentSort = field;
|
|
|
|
}
|
2020-12-07 17:51:48 +01:00
|
|
|
|
|
|
|
if (this.isHardSort)
|
|
|
|
this.$emit('hard-sort', { field: this.currentSort, dir: this.currentSortDir });
|
2020-07-24 13:26:56 +02:00
|
|
|
},
|
|
|
|
resetSort () {
|
|
|
|
this.currentSort = '';
|
|
|
|
this.currentSortDir = 'asc';
|
2020-09-06 08:41:57 +02:00
|
|
|
},
|
|
|
|
selectResultset (index) {
|
|
|
|
this.resultsetIndex = index;
|
2021-01-08 21:55:03 +01:00
|
|
|
},
|
|
|
|
downloadTable (format, filename) {
|
|
|
|
if (!this.sortedResults) return;
|
|
|
|
|
2021-06-29 23:23:11 +02:00
|
|
|
const rows = JSON.parse(JSON.stringify(this.sortedResults)).map(row => {
|
2022-02-16 09:14:46 +01:00
|
|
|
delete row._antares_id;
|
2021-01-13 11:57:26 +01:00
|
|
|
return row;
|
|
|
|
});
|
|
|
|
|
2021-01-08 21:55:03 +01:00
|
|
|
arrayToFile({
|
|
|
|
type: format,
|
2021-01-13 11:57:26 +01:00
|
|
|
content: rows,
|
2021-01-08 21:55:03 +01:00
|
|
|
filename
|
|
|
|
});
|
2020-06-10 19:29:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
|
2020-09-06 08:41:57 +02:00
|
|
|
<style lang="scss" scoped>
|
2020-06-11 23:34:38 +02:00
|
|
|
.vscroll {
|
2020-07-31 18:16:28 +02:00
|
|
|
height: 1000px;
|
|
|
|
overflow: auto;
|
|
|
|
overflow-anchor: none;
|
2020-06-11 23:34:38 +02:00
|
|
|
}
|
2020-06-16 18:01:22 +02:00
|
|
|
|
2020-07-31 18:16:28 +02:00
|
|
|
.column-resizable {
|
|
|
|
&:hover,
|
|
|
|
&:active {
|
|
|
|
resize: horizontal;
|
|
|
|
overflow: hidden;
|
|
|
|
}
|
2020-07-24 13:26:56 +02:00
|
|
|
}
|
|
|
|
|
2020-07-31 18:16:28 +02:00
|
|
|
.table-column-title {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
2020-06-16 18:01:22 +02:00
|
|
|
}
|
|
|
|
|
2020-07-31 18:16:28 +02:00
|
|
|
.sort-icon {
|
|
|
|
font-size: 0.7rem;
|
|
|
|
line-height: 1;
|
|
|
|
margin-left: 0.2rem;
|
2020-07-24 13:26:56 +02:00
|
|
|
}
|
2020-09-06 08:41:57 +02:00
|
|
|
|
|
|
|
.result-tabs {
|
|
|
|
background: transparent !important;
|
|
|
|
margin: 0;
|
|
|
|
}
|
2020-06-10 19:29:10 +02:00
|
|
|
</style>
|