Skip to content

Commit

Permalink
feat: context menu option to duplicate a table row
Browse files Browse the repository at this point in the history
  • Loading branch information
Fabio286 committed Jul 19, 2022
1 parent 7890263 commit 985e5d3
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 39 deletions.
8 changes: 6 additions & 2 deletions src/renderer/components/ForeignKeySelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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;
Expand All @@ -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,
Expand Down
79 changes: 47 additions & 32 deletions src/renderer/components/ModalFakerRows.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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[]>
});
Expand Down Expand Up @@ -284,44 +286,57 @@ onMounted(() => {
const rowObj: {[key: string]: unknown} = {};
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 (!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}`);
}
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 };
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];
}
}
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] };
if (field.autoIncrement || !!field.onUpdate)// Disable by default auto increment or "on update" fields
fieldsToExclude.value = [...fieldsToExclude.value, field.name];
}
}
localRow.value = { ...rowObj };
Expand Down
18 changes: 16 additions & 2 deletions src/renderer/components/WorkspaceTabQueryTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
27 changes: 25 additions & 2 deletions src/renderer/components/WorkspaceTabQueryTableContext.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -49,6 +58,7 @@
</template>

<script setup lang="ts">
import { Prop } from 'vue';
import BaseContextMenu from '@/components/BaseContextMenu.vue';
import { useI18n } from 'vue-i18n';
Expand All @@ -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');
Expand All @@ -84,4 +102,9 @@ const copyRow = () => {
emit('copy-row');
closeContext();
};
const duplicateRow = () => {
emit('duplicate-row');
closeContext();
};
</script>
8 changes: 7 additions & 1 deletion src/renderer/components/WorkspaceTabTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) => {
Expand Down

0 comments on commit 985e5d3

Please sign in to comment.