From c9346f728001ca8692e74fe13d1b3101763b6740 Mon Sep 17 00:00:00 2001 From: mertmit Date: Sat, 25 Mar 2023 00:01:37 +0300 Subject: [PATCH] feat: undo/redo expanded row insert and update Signed-off-by: mertmit --- .../composables/useExpandedFormStore.ts | 68 ++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/packages/nc-gui/composables/useExpandedFormStore.ts b/packages/nc-gui/composables/useExpandedFormStore.ts index a3f02c0f9b..3937bd5b5d 100644 --- a/packages/nc-gui/composables/useExpandedFormStore.ts +++ b/packages/nc-gui/composables/useExpandedFormStore.ts @@ -21,8 +21,9 @@ import { useProject, useProvideSmartsheetRowStore, useSharedView, + useUndoRedo, } from '#imports' -import type { Row } from '~/lib' +import type { Row, UndoRedoAction } from '~/lib' const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((meta: Ref, row: Ref) => { const { $e, $state, $api } = useNuxtApp() @@ -51,6 +52,10 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m const { sharedView } = useSharedView() + const { addUndo, clone } = useUndoRedo() + + const reloadTrigger = inject(ReloadRowDataHookInj, createEventHook()) + // getters const displayValue = computed(() => { if (row?.value?.row) { @@ -135,7 +140,7 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m $e('a:row-expand:comment') } - const save = async (ltarState: Record = {}) => { + const save = async (ltarState: Record = {}, undo = false) => { let data try { const isNewRow = row.value.rowMeta?.new ?? false @@ -155,6 +160,40 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m data = await $api.dbTableRow.create('noco', project.value.title as string, meta.value.title, insertObj) + if (!undo) { + const id = extractPkFromRow(data, meta.value?.columns as ColumnType[]) + + // TODO remove linked record + addUndo({ + redo: { + fn: async function redo(this: UndoRedoAction, row: Row) { + const pkData = rowPkData(row.row, meta.value?.columns as ColumnType[]) + row.row = { ...pkData, ...row.row } + await $api.dbTableRow.create('noco', project.value.title as string, meta.value.title, row.row) + reloadTrigger?.trigger() + }, + args: [clone(row.value)], + }, + undo: { + fn: async function undo(this: UndoRedoAction, id: string) { + const res: any = await $api.dbViewRow.delete( + 'noco', + project.value.id as string, + meta.value?.id as string, + activeView.value?.id as string, + id, + ) + if (res.message) { + throw new Error(res.message) + } + reloadTrigger?.trigger() + }, + args: [id], + }, + scope: activeView.value?.title, + }) + } + Object.assign(row.value, { row: data, rowMeta: {}, @@ -174,6 +213,31 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m await $api.dbTableRow.update(NOCO, project.value.title as string, meta.value.title, id, updateOrInsertObj) + if (!undo) { + const undoObject = [...changedColumns.value].reduce((obj, col) => { + obj[col] = row.value.oldRow[col] + return obj + }, {} as Record) + + addUndo({ + redo: { + fn: async (id: string, data: Record) => { + await $api.dbTableRow.update(NOCO, project.value.title as string, meta.value.title, id, data) + reloadTrigger?.trigger() + }, + args: [id, clone(updateOrInsertObj)], + }, + undo: { + fn: async (id: string, data: Record) => { + await $api.dbTableRow.update(NOCO, project.value.title as string, meta.value.title, id, data) + reloadTrigger?.trigger() + }, + args: [id, clone(undoObject)], + }, + scope: activeView.value?.title, + }) + } + for (const key of Object.keys(updateOrInsertObj)) { // audit $api.utils