Browse Source

feat: undo/redo sorts menu

Signed-off-by: mertmit <mertmit99@gmail.com>
pull/5332/head
mertmit 2 years ago
parent
commit
450bf7dc8e
  1. 8
      packages/nc-gui/composables/useUndoRedo.ts
  2. 114
      packages/nc-gui/composables/useViewSorts.ts

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

@ -41,7 +41,7 @@ export const useUndoRedo = createSharedComposable(() => {
redoQueue.value.push(action)
}
const undo = () => {
const undo = async () => {
let actionIndex = -1
for (let i = undoQueue.value.length - 1; i >= 0; i--) {
if (Array.isArray(undoQueue.value[i].scope)) {
@ -61,12 +61,12 @@ export const useUndoRedo = createSharedComposable(() => {
const action = undoQueue.value.splice(actionIndex, 1)[0]
if (action) {
action.undo.fn.apply(action, action.undo.args)
await action.undo.fn.apply(action, action.undo.args)
addRedo(action)
}
}
const redo = () => {
const redo = async () => {
let actionIndex = -1
for (let i = redoQueue.value.length - 1; i >= 0; i--) {
if (Array.isArray(redoQueue.value[i].scope)) {
@ -86,7 +86,7 @@ export const useUndoRedo = createSharedComposable(() => {
const action = redoQueue.value.splice(actionIndex, 1)[0]
if (action) {
action.redo.fn.apply(action, action.redo.args)
await action.redo.fn.apply(action, action.redo.args)
addUndo(action)
}
}

114
packages/nc-gui/composables/useViewSorts.ts

@ -27,12 +27,20 @@ export function useViewSorts(view: Ref<ViewType | undefined>, reloadData?: () =>
const { isSharedBase } = storeToRefs(useProject())
const { addUndo, clone } = useUndoRedo()
const reloadHook = inject(ReloadViewDataHookInj)
const isPublic = inject(IsPublicInj, ref(false))
const tabMeta = inject(TabMetaInj, ref({ sortsState: new Map() } as TabItem))
const lastSorts = ref<SortType[]>([])
watchOnce(sorts, (sorts: SortType[]) => {
lastSorts.value = clone(sorts)
})
const loadSorts = async () => {
if (isPublic.value) {
// todo: sorts missing on `ViewType`
@ -57,7 +65,45 @@ export function useViewSorts(view: Ref<ViewType | undefined>, reloadData?: () =>
}
}
const saveOrUpdate = async (sort: SortType, i: number) => {
// get delta between two objects and return the changed fields (value is from b)
const getDelta = (a: any, b: any) => {
return Object.entries(b)
.filter(([key, val]) => a[key] !== val && key in a)
.reduce((a, [key, v]) => ({ ...a, [key]: v }), {})
}
const saveOrUpdate = async (sort: SortType, i: number, undo = false) => {
if (!undo) {
const lastSort = lastSorts.value[i]
if (lastSort) {
const delta = clone(getDelta(sort, lastSort))
if (Object.keys(delta).length > 0) {
addUndo({
undo: {
fn: (prop: string, data: any) => {
const f = sorts.value[i]
if (f) {
f[prop] = data
saveOrUpdate(f, i, true)
}
},
args: [Object.keys(delta)[0], Object.values(delta)[0]],
},
redo: {
fn: (prop: string, data: any) => {
const f = sorts.value[i]
if (f) {
f[prop] = data
saveOrUpdate(f, i, true)
}
},
args: [Object.keys(delta)[0], sort[Object.keys(delta)[0]]],
},
})
}
}
}
if (isPublic.value || isSharedBase.value) {
sorts.value[i] = sort
sorts.value = [...sorts.value]
@ -81,21 +127,11 @@ export function useViewSorts(view: Ref<ViewType | undefined>, reloadData?: () =>
console.error(e)
message.error(await extractSdkResponseErrorMsg(e))
}
}
const addSort = () => {
sorts.value = [
...sorts.value,
{
direction: 'asc',
},
]
$e('a:sort:add', { length: sorts?.value?.length })
tabMeta.value.sortsState!.set(view.value!.id!, sorts.value)
lastSorts.value = clone(sorts.value)
}
const deleteSort = async (sort: SortType, i: number) => {
const deleteSort = async (sort: SortType, i: number, undo = false) => {
try {
if (isUIAllowed('sortSync') && sort.id && !isPublic.value && !isSharedBase.value) {
await $api.dbTableSort.delete(sort.id)
@ -103,6 +139,26 @@ export function useViewSorts(view: Ref<ViewType | undefined>, reloadData?: () =>
sorts.value.splice(i, 1)
sorts.value = [...sorts.value]
if (!undo) {
addUndo({
redo: {
fn: async () => {
await deleteSort(sort, i, true)
},
args: [],
},
undo: {
fn: () => {
sorts.value.splice(i, 0, sort)
saveOrUpdate(sort, i, true)
},
args: [clone(sort), i],
},
})
}
lastSorts.value = clone(sorts.value)
tabMeta.value.sortsState!.set(view.value!.id!, sorts.value)
reloadHook?.trigger()
@ -113,5 +169,37 @@ export function useViewSorts(view: Ref<ViewType | undefined>, reloadData?: () =>
}
}
const addSort = (undo = false) => {
sorts.value = [
...sorts.value,
{
direction: 'asc',
},
]
$e('a:sort:add', { length: sorts?.value?.length })
if (!undo) {
addUndo({
undo: {
fn: async () => {
await deleteSort(sorts.value[sorts.value.length - 1], sorts.value.length - 1, true)
},
args: [],
},
redo: {
fn: () => {
addSort(true)
},
args: [],
},
})
}
lastSorts.value = clone(sorts.value)
tabMeta.value.sortsState!.set(view.value!.id!, sorts.value)
}
return { sorts, loadSorts, addSort, deleteSort, saveOrUpdate }
}

Loading…
Cancel
Save