Browse Source

feat: add scope to undo/redo

Signed-off-by: mertmit <mertmit99@gmail.com>
pull/5332/head
mertmit 2 years ago
parent
commit
4d6e3c0c94
  1. 18
      packages/nc-gui/composables/useLTARStore.ts
  2. 63
      packages/nc-gui/composables/useUndoRedo.ts
  3. 69
      packages/nc-gui/composables/useViewData.ts
  4. 1
      packages/nc-gui/lib/types.ts

18
packages/nc-gui/composables/useLTARStore.ts

@ -276,14 +276,15 @@ const [useProvideLTARStore, useLTARStore] = useInjectionState(
if (!undo) { if (!undo) {
addUndo({ addUndo({
redo: { redo: {
fn: (row: Record<string, any>, { metaValue }: { metaValue?: TableType } = {}) => unlink(row, { metaValue }, true), fn: (row: Record<string, any>) => unlink(row, {}, true),
args: [clone(row), clone({ metaValue })], args: [clone(row)],
}, },
undo: { undo: {
// eslint-disable-next-line @typescript-eslint/no-use-before-define // eslint-disable-next-line @typescript-eslint/no-use-before-define
fn: (row: Record<string, any>, { metaValue }: { metaValue?: TableType } = {}) => link(row, { metaValue }, true), fn: (row: Record<string, any>) => link(row, {}, true),
args: [clone(row), clone({ metaValue })], args: [clone(row)],
}, },
scope: metaValue.id,
}) })
} }
} catch (e: any) { } catch (e: any) {
@ -322,13 +323,14 @@ const [useProvideLTARStore, useLTARStore] = useInjectionState(
if (!undo) { if (!undo) {
addUndo({ addUndo({
redo: { redo: {
fn: (row: Record<string, any>, { metaValue }: { metaValue?: TableType } = {}) => link(row, { metaValue }, true), fn: (row: Record<string, any>) => link(row, {}, true),
args: [clone(row), clone({ metaValue })], args: [clone(row)],
}, },
undo: { undo: {
fn: (row: Record<string, any>, { metaValue }: { metaValue?: TableType } = {}) => unlink(row, { metaValue }, true), fn: (row: Record<string, any>) => unlink(row, {}, true),
args: [clone(row), clone({ metaValue })], args: [clone(row)],
}, },
scope: metaValue.id,
}) })
} }
} catch (e: any) { } catch (e: any) {

63
packages/nc-gui/composables/useUndoRedo.ts

@ -1,11 +1,34 @@
import type { Ref } from 'vue' import type { Ref } from 'vue'
import rfdc from 'rfdc' import rfdc from 'rfdc'
import { createSharedComposable, ref } from '#imports' import { createSharedComposable, ref, useRouter } from '#imports'
import type { UndoRedoAction } from '~/lib' import type { UndoRedoAction } from '~/lib'
export const useUndoRedo = createSharedComposable(() => { export const useUndoRedo = createSharedComposable(() => {
const clone = rfdc() const clone = rfdc()
const router = useRouter()
const route = $(router.currentRoute)
const scope = computed<string[]>(() => {
let tempScope = ['root']
for (const param of Object.values(route.params)) {
if (Array.isArray(param)) {
tempScope = tempScope.concat(param)
} else {
tempScope.push(param)
}
}
if (
Object.keys(route.params).includes('viewTitle') &&
Object.keys(route.params).includes('title') &&
route.params.viewTitle.length
) {
tempScope.splice(tempScope.indexOf(route.params.title as string), 1)
}
return tempScope
})
const undoQueue: Ref<UndoRedoAction[]> = ref([]) const undoQueue: Ref<UndoRedoAction[]> = ref([])
const redoQueue: Ref<UndoRedoAction[]> = ref([]) const redoQueue: Ref<UndoRedoAction[]> = ref([])
@ -19,7 +42,24 @@ export const useUndoRedo = createSharedComposable(() => {
} }
const undo = () => { const undo = () => {
const action = undoQueue.value.pop() let actionIndex = -1
for (let i = undoQueue.value.length - 1; i >= 0; i--) {
if (Array.isArray(undoQueue.value[i].scope)) {
if (scope.value.some((s) => undoQueue.value[i].scope?.includes(s))) {
actionIndex = i
break
}
} else {
if (scope.value.includes((undoQueue.value[i].scope as string) || 'root')) {
actionIndex = i
break
}
}
}
if (actionIndex === -1) return
const action = undoQueue.value.splice(actionIndex, 1)[0]
if (action) { if (action) {
action.undo.fn.apply(action, action.undo.args) action.undo.fn.apply(action, action.undo.args)
addRedo(action) addRedo(action)
@ -27,7 +67,24 @@ export const useUndoRedo = createSharedComposable(() => {
} }
const redo = () => { const redo = () => {
const action = redoQueue.value.pop() let actionIndex = -1
for (let i = redoQueue.value.length - 1; i >= 0; i--) {
if (Array.isArray(redoQueue.value[i].scope)) {
if (scope.value.some((s) => redoQueue.value[i].scope?.includes(s))) {
actionIndex = i
break
}
} else {
if (scope.value.includes((redoQueue.value[i].scope as string) || 'root')) {
actionIndex = i
break
}
}
}
if (actionIndex === -1) return
const action = redoQueue.value.splice(actionIndex, 1)[0]
if (action) { if (action) {
action.redo.fn.apply(action, action.redo.args) action.redo.fn.apply(action, action.redo.args)
addUndo(action) addUndo(action)

69
packages/nc-gui/composables/useViewData.ts

@ -256,30 +256,22 @@ export function useViewData(
addUndo({ addUndo({
redo: { redo: {
fn: async function redo( fn: async function redo(this: UndoRedoAction, row: Row, ltarState: Record<string, any>) {
this: UndoRedoAction,
row: Row,
ltarState: Record<string, any>,
{ metaValue, viewMetaValue }: { metaValue?: TableType; viewMetaValue?: ViewType },
) {
const pkData = rowPkData(row.row, metaValue?.columns as ColumnType[]) const pkData = rowPkData(row.row, metaValue?.columns as ColumnType[])
row.row = { ...pkData, ...row.row } row.row = { ...pkData, ...row.row }
await insertRow(row, ltarState, { metaValue, viewMetaValue }, true) await insertRow(row, ltarState, undefined, true)
loadData() loadData()
}, },
args: [clone(currentRow), clone(ltarState), clone({ metaValue, viewMetaValue })], args: [clone(currentRow), clone(ltarState)],
}, },
undo: { undo: {
fn: async function undo( fn: async function undo(this: UndoRedoAction, id: string) {
this: UndoRedoAction, await deleteRowById(id)
id: string,
{ metaValue, viewMetaValue }: { metaValue?: TableType; viewMetaValue?: ViewType } = {},
) {
await deleteRowById(id, { metaValue, viewMetaValue })
loadData() loadData()
}, },
args: [id, clone({ metaValue, viewMetaValue })], args: [id],
}, },
scope: viewMeta.value?.is_default ? [viewMeta.value.fk_model_id, viewMeta.value.title] : viewMeta.value?.title,
}) })
} }
@ -338,30 +330,23 @@ export function useViewData(
if (!undo) { if (!undo) {
addUndo({ addUndo({
redo: { redo: {
fn: async function redo( fn: async function redo(toUpdate: Row, property: string) {
toUpdate: Row, await updateRowProperty(toUpdate, property, undefined, true)
property: string,
{ metaValue, viewMetaValue }: { metaValue?: TableType; viewMetaValue?: ViewType } = {},
) {
await updateRowProperty(toUpdate, property, { metaValue, viewMetaValue }, true)
}, },
args: [clone(toUpdate), property, clone({ metaValue, viewMetaValue })], args: [clone(toUpdate), property],
}, },
undo: { undo: {
fn: async function undo( fn: async function undo(toUpdate: Row, property: string) {
toUpdate: Row,
property: string,
{ metaValue, viewMetaValue }: { metaValue?: TableType; viewMetaValue?: ViewType } = {},
) {
await updateRowProperty( await updateRowProperty(
{ row: toUpdate.oldRow, oldRow: toUpdate.row, rowMeta: toUpdate.rowMeta }, { row: toUpdate.oldRow, oldRow: toUpdate.row, rowMeta: toUpdate.rowMeta },
property, property,
{ metaValue, viewMetaValue }, undefined,
true, true,
) )
}, },
args: [clone(toUpdate), property, clone({ metaValue, viewMetaValue })], args: [clone(toUpdate), property],
}, },
scope: viewMeta.value?.is_default ? [viewMeta.value.fk_model_id, viewMeta.value.title] : viewMeta.value?.title,
}) })
/** update row data(to sync formula and other related columns) /** update row data(to sync formula and other related columns)
@ -461,34 +446,24 @@ export function useViewData(
.join('___') .join('___')
if (!undo) { if (!undo) {
const metaValue = meta.value
const viewMetaValue = viewMeta.value
addUndo({ addUndo({
redo: { redo: {
fn: async function undo( fn: async function undo(this: UndoRedoAction, id: string) {
this: UndoRedoAction, await deleteRowById(id)
id: string,
{ metaValue, viewMetaValue }: { metaValue?: TableType; viewMetaValue?: ViewType } = {},
) {
await deleteRowById(id, { metaValue, viewMetaValue })
loadData() loadData()
}, },
args: [id, clone({ metaValue, viewMetaValue })], args: [id],
}, },
undo: { undo: {
fn: async function redo( fn: async function redo(this: UndoRedoAction, row: Row, ltarState: Record<string, any>) {
this: UndoRedoAction, const pkData = rowPkData(row.row, meta.value?.columns as ColumnType[])
row: Row,
ltarState: Record<string, any>,
{ metaValue, viewMetaValue }: { metaValue?: TableType; viewMetaValue?: ViewType },
) {
const pkData = rowPkData(row.row, metaValue?.columns as ColumnType[])
row.row = { ...pkData, ...row.row } row.row = { ...pkData, ...row.row }
await insertRow(row, ltarState, { metaValue, viewMetaValue }, true) await insertRow(row, ltarState, {}, true)
loadData() loadData()
}, },
args: [clone(row), {}, clone({ metaValue, viewMetaValue })], args: [clone(row), {}],
}, },
scope: viewMeta.value?.is_default ? [viewMeta.value.fk_model_id, viewMeta.value.title] : viewMeta.value?.title,
}) })
} }

1
packages/nc-gui/lib/types.ts

@ -108,4 +108,5 @@ export type Nullable<T> = { [K in keyof T]: T[K] | null }
export interface UndoRedoAction { export interface UndoRedoAction {
undo: { fn: Function; args: any[] } undo: { fn: Function; args: any[] }
redo: { fn: Function; args: any[] } redo: { fn: Function; args: any[] }
scope?: string | string[]
} }

Loading…
Cancel
Save