feat: context menu option to duplicate a table row

This commit is contained in:
Fabio Di Stasio 2022-07-19 17:48:51 +02:00
parent 78902639eb
commit 985e5d3527
5 changed files with 100 additions and 38 deletions

View File

@ -13,7 +13,7 @@
</template>
<script setup lang="ts">
import { computed, Ref, ref } from 'vue';
import { computed, Ref, ref, watch } from 'vue';
import { storeToRefs } from 'pinia';
import Tables from '@/ipc-api/Tables';
import { useNotificationsStore } from '@/stores/notifications';
@ -40,7 +40,7 @@ const { getSelected: selectedWorkspace } = storeToRefs(workspacesStore);
const editField: Ref<HTMLSelectElement> = ref(null);
const foreignList = ref([]);
const currentValue = ref(props.modelValue);
const currentValue = ref(null);
const isValidDefault = computed(() => {
if (!foreignList.value.length) return true;
@ -66,6 +66,10 @@ const cutText = (val: string) => {
return val.length > 15 ? `${val.substring(0, 15)}...` : val;
};
watch(() => props.modelValue, () => {
currentValue.value = props.modelValue;
});
let foreignDesc: string | false;
const params = {
uid: selectedWorkspace.value,

View File

@ -113,6 +113,8 @@ import BaseSelect from '@/components/BaseSelect.vue';
const props = defineProps({
tabUid: [String, Number],
fields: Array as Prop<TableField[]>,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
rowToDuplicate: Object as Prop<any>,
keyUsage: Array as Prop<TableForeign[]>
});
@ -284,44 +286,57 @@ onMounted(() => {
const rowObj: {[key: string]: unknown} = {};
for (const field of props.fields) {
let fieldDefault;
if (!props.rowToDuplicate) {
// Set default values
for (const field of props.fields) {
let fieldDefault;
if (field.default === 'NULL') fieldDefault = null;
else {
if ([...NUMBER, ...FLOAT].includes(field.type))
fieldDefault = !field.default || Number.isNaN(+field.default.replaceAll('\'', '')) ? null : +field.default.replaceAll('\'', '');
else if ([...TEXT, ...LONG_TEXT].includes(field.type)) {
fieldDefault = field.default
? field.default.includes('\'')
? field.default.split('\'')[1]
: field.default
: '';
}
else if ([...TIME, ...DATE].includes(field.type))
fieldDefault = field.default;
else if (BIT.includes(field.type))
fieldDefault = field.default?.replaceAll('\'', '').replaceAll('b', '');
else if (DATETIME.includes(field.type)) {
if (field.default && ['current_timestamp', 'now()'].some(term => field.default.toLowerCase().includes(term))) {
let datePrecision = '';
for (let i = 0; i < field.datePrecision; i++)
datePrecision += i === 0 ? '.S' : 'S';
fieldDefault = moment().format(`YYYY-MM-DD HH:mm:ss${datePrecision}`);
if (field.default === 'NULL') fieldDefault = null;
else {
if ([...NUMBER, ...FLOAT].includes(field.type))
fieldDefault = !field.default || Number.isNaN(+field.default.replaceAll('\'', '')) ? null : +field.default.replaceAll('\'', '');
else if ([...TEXT, ...LONG_TEXT].includes(field.type)) {
fieldDefault = field.default
? field.default.includes('\'')
? field.default.split('\'')[1]
: field.default
: '';
}
else if ([...TIME, ...DATE].includes(field.type))
fieldDefault = field.default;
else if (BIT.includes(field.type))
fieldDefault = field.default?.replaceAll('\'', '').replaceAll('b', '');
else if (DATETIME.includes(field.type)) {
if (field.default && ['current_timestamp', 'now()'].some(term => field.default.toLowerCase().includes(term))) {
let datePrecision = '';
for (let i = 0; i < field.datePrecision; i++)
datePrecision += i === 0 ? '.S' : 'S';
fieldDefault = moment().format(`YYYY-MM-DD HH:mm:ss${datePrecision}`);
}
else
fieldDefault = field.default;
}
else if (field.enumValues)
fieldDefault = field.enumValues.replaceAll('\'', '').split(',');
else
fieldDefault = field.default;
}
else if (field.enumValues)
fieldDefault = field.enumValues.replaceAll('\'', '').split(',');
else
fieldDefault = field.default;
rowObj[field.name] = { value: fieldDefault };
if (field.autoIncrement || !!field.onUpdate)// Disable by default auto increment or "on update" fields
fieldsToExclude.value = [...fieldsToExclude.value, field.name];
}
}
else {
// Set values to duplicate
for (const field of props.fields) {
if (typeof props.rowToDuplicate[field.name] !== 'object')
rowObj[field.name] = { value: props.rowToDuplicate[field.name] };
rowObj[field.name] = { value: fieldDefault };
if (field.autoIncrement || !!field.onUpdate)// Disable by default auto increment or "on update" fields
fieldsToExclude.value = [...fieldsToExclude.value, field.name];
if (field.autoIncrement || !!field.onUpdate)// Disable by default auto increment or "on update" fields
fieldsToExclude.value = [...fieldsToExclude.value, field.name];
}
}
localRow.value = { ...rowObj };

View File

@ -14,10 +14,12 @@
:context-event="contextEvent"
:selected-rows="selectedRows"
:selected-cell="selectedCell"
:mode="mode"
@show-delete-modal="showDeleteConfirmModal"
@set-null="setNull"
@copy-cell="copyCell"
@copy-row="copyRow"
@duplicate-row="duplicateRow"
@close-context="closeContext"
/>
<ul v-if="resultsWithRows.length > 1" class="tab tab-block result-tabs">
@ -143,12 +145,17 @@ const { consoleHeight } = storeToRefs(consoleStore);
const props = defineProps({
results: Array as Prop<QueryResult[]>,
connUid: String,
mode: String,
mode: String as Prop<'table' | 'query'>,
isSelected: Boolean,
elementType: { type: String, default: 'table' }
});
const emit = defineEmits(['update-field', 'delete-selected', 'hard-sort']);
const emit = defineEmits([
'update-field',
'delete-selected',
'hard-sort',
'duplicate-row'
]);
const resultTable: Ref<Component & {updateWindow: () => void}> = ref(null);
const tableWrapper: Ref<HTMLDivElement> = ref(null);
@ -412,6 +419,13 @@ const copyRow = () => {
navigator.clipboard.writeText(JSON.stringify(rowToCopy));
};
const duplicateRow = () => {
const row = localResults.value.find((row: any) => selectedRows.value.includes(row._antares_id));
const rowToDuplicate = JSON.parse(JSON.stringify(row));
delete rowToDuplicate._antares_id;
emit('duplicate-row', rowToDuplicate);
};
const applyUpdate = (params: TableUpdateParams) => {
const { primary, id, field, table, content } = params;

View File

@ -27,6 +27,15 @@
</div>
</div>
</div>
<div
v-if="selectedRows.length === 1 && selectedCell.isEditable && mode === 'table'"
class="context-element"
@click="duplicateRow"
>
<span class="d-flex">
<i class="mdi mdi-18px mdi-content-duplicate text-light pr-1" /> {{ t('word.duplicate') }}
</span>
</div>
<div
v-if="selectedRows.length === 1 && selectedCell.isEditable"
class="context-element"
@ -49,6 +58,7 @@
</template>
<script setup lang="ts">
import { Prop } from 'vue';
import BaseContextMenu from '@/components/BaseContextMenu.vue';
import { useI18n } from 'vue-i18n';
@ -57,10 +67,18 @@ const { t } = useI18n();
defineProps({
contextEvent: MouseEvent,
selectedRows: Array,
selectedCell: Object
selectedCell: Object,
mode: String as Prop<'table' | 'query'>
});
const emit = defineEmits(['show-delete-modal', 'close-context', 'set-null', 'copy-cell', 'copy-row']);
const emit = defineEmits([
'show-delete-modal',
'close-context',
'set-null',
'copy-cell',
'copy-row',
'duplicate-row'
]);
const showConfirmModal = () => {
emit('show-delete-modal');
@ -84,4 +102,9 @@ const copyRow = () => {
emit('copy-row');
closeContext();
};
const duplicateRow = () => {
emit('duplicate-row');
closeContext();
};
</script>

View File

@ -153,12 +153,14 @@
:element-type="elementType"
@update-field="updateField"
@delete-selected="deleteSelected"
@duplicate-row="showFakerModal"
@hard-sort="hardSort"
/>
</div>
<ModalFakerRows
v-if="isFakerModal"
:fields="fields"
:row-to-duplicate="rowToDuplicate"
:key-usage="keyUsage"
:tab-uid="tabUid"
@hide="hideFakerModal"
@ -224,6 +226,7 @@ const filters = ref([]);
const page = ref(1);
const pageProxy = ref(1);
const approximateCount = ref(0);
const rowToDuplicate = ref(null);
const workspace = computed(() => {
return getWorkspace(props.connection.uid);
@ -329,13 +332,16 @@ const pageChange = (direction: 'prev' | 'next') => {
page.value--;
};
const showFakerModal = () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const showFakerModal = (row?: any) => {
if (isQuering.value) return;
isFakerModal.value = true;
rowToDuplicate.value = row;
};
const hideFakerModal = () => {
isFakerModal.value = false;
rowToDuplicate.value = null;
};
const onKey = (e: KeyboardEvent) => {