diff --git a/packages/nc-gui/components/cell/ClampedText.vue b/packages/nc-gui/components/cell/ClampedText.vue index e6b4fa3eb0..515a95bed3 100644 --- a/packages/nc-gui/components/cell/ClampedText.vue +++ b/packages/nc-gui/components/cell/ClampedText.vue @@ -31,7 +31,7 @@ onMounted(() => { :key="`clamp-${key}-${props.value?.toString().length || 0}`" class="w-full h-full break-word" :text="`${props.value || ' '}`" - :max-lines="props.lines" + :max-lines="props.lines || 1" /> diff --git a/packages/nc-gui/components/cell/MultiSelect.vue b/packages/nc-gui/components/cell/MultiSelect.vue index d77f29ba47..ebef31bd75 100644 --- a/packages/nc-gui/components/cell/MultiSelect.vue +++ b/packages/nc-gui/components/cell/MultiSelect.vue @@ -283,7 +283,7 @@ const onTagClick = (e: Event, onClose: Function) => { } } -const cellClickHook = inject(CellClickHookInj) +const cellClickHook = inject(CellClickHookInj, null) const toggleMenu = () => { if (cellClickHook) return diff --git a/packages/nc-gui/components/cell/SingleSelect.vue b/packages/nc-gui/components/cell/SingleSelect.vue index 51c1554bb2..a06abbaa9b 100644 --- a/packages/nc-gui/components/cell/SingleSelect.vue +++ b/packages/nc-gui/components/cell/SingleSelect.vue @@ -209,7 +209,7 @@ const onSelect = () => { isOpen.value = false } -const cellClickHook = inject(CellClickHookInj) +const cellClickHook = inject(CellClickHookInj, null) const toggleMenu = (e: Event) => { // todo: refactor diff --git a/packages/nc-gui/components/cell/Text.vue b/packages/nc-gui/components/cell/Text.vue index 1f744070f3..05fcbc4856 100644 --- a/packages/nc-gui/components/cell/Text.vue +++ b/packages/nc-gui/components/cell/Text.vue @@ -14,7 +14,10 @@ const { showNull } = useGlobal() const editEnabled = inject(EditModeInj) -const rowHeight = inject(RowHeightInj) +const rowHeight = inject( + RowHeightInj, + computed(() => undefined), +) const readonly = inject(ReadonlyInj, ref(false)) diff --git a/packages/nc-gui/components/cell/TextArea.vue b/packages/nc-gui/components/cell/TextArea.vue index 21ebfd8e0b..859b495bbd 100644 --- a/packages/nc-gui/components/cell/TextArea.vue +++ b/packages/nc-gui/components/cell/TextArea.vue @@ -10,7 +10,10 @@ const emits = defineEmits(['update:modelValue']) const editEnabled = inject(EditModeInj) -const rowHeight = inject(RowHeightInj) +const rowHeight = inject( + RowHeightInj, + computed(() => undefined), +) const { showNull } = useGlobal() diff --git a/packages/nc-gui/components/dashboard/TreeView.vue b/packages/nc-gui/components/dashboard/TreeView.vue index dd1a6f129c..cdcbacb674 100644 --- a/packages/nc-gui/components/dashboard/TreeView.vue +++ b/packages/nc-gui/components/dashboard/TreeView.vue @@ -29,6 +29,7 @@ import { useTabs, useToggle, useUIPermission, + useUndoRedo, watchEffect, } from '#imports' @@ -55,6 +56,8 @@ const [searchActive, toggleSearchActive] = useToggle() const { appInfo } = useGlobal() +const { addUndo, defineProjectScope } = useUndoRedo() + const toggleDialog = inject(ToggleDialogInj, () => {}) const keys = $ref>({}) @@ -90,13 +93,14 @@ const initSortable = (el: Element) => { if (sortables[base_id]) sortables[base_id].destroy() Sortable.create(el as HTMLLIElement, { onEnd: async (evt) => { - const offset = tables.value.findIndex((table) => table.base_id === base_id) - const { newIndex = 0, oldIndex = 0 } = evt const itemEl = evt.item as HTMLLIElement const item = tablesById[itemEl.dataset.id as string] + // store the old order for undo + const oldOrder = item.order + // get the html collection of all list items const children: HTMLCollection = evt.to.children @@ -120,8 +124,19 @@ const initSortable = (el: Element) => { item.order = ((itemBefore.order as number) + (itemAfter.order as number)) / 2 } - // update the order of the moved item - tables.value?.splice(newIndex + offset, 0, ...tables.value?.splice(oldIndex + offset, 1)) + // find the index of the moved item + const itemIndex = tables.value?.findIndex((table) => table.id === item.id) + + // move the item to the new position + if (itemBefore) { + // find the index of the item before the moved item + const itemBeforeIndex = tables.value?.findIndex((table) => table.id === itemBefore.id) + tables.value?.splice(itemBeforeIndex + (newIndex > oldIndex ? 0 : 1), 0, ...tables.value?.splice(itemIndex, 1)) + } else { + // if the item before is undefined (moving item to first slot), then find the index of the item after the moved item + const itemAfterIndex = tables.value?.findIndex((table) => table.id === itemAfter.id) + tables.value?.splice(itemAfterIndex, 0, ...tables.value?.splice(itemIndex, 1)) + } // force re-render the list if (keys[base_id]) { @@ -134,6 +149,38 @@ const initSortable = (el: Element) => { await $api.dbTable.reorder(item.id as string, { order: item.order, }) + + const nextIndex = tables.value?.findIndex((table) => table.id === item.id) + + addUndo({ + undo: { + fn: async (id: string, order: number, index: number) => { + const itemIndex = tables.value.findIndex((table) => table.id === id) + if (itemIndex < 0) return + const item = tables.value[itemIndex] + item.order = order + tables.value?.splice(index, 0, ...tables.value?.splice(itemIndex, 1)) + await $api.dbTable.reorder(item.id as string, { + order: item.order, + }) + }, + args: [item.id, oldOrder, itemIndex], + }, + redo: { + fn: async (id: string, order: number, index: number) => { + const itemIndex = tables.value.findIndex((table) => table.id === id) + if (itemIndex < 0) return + const item = tables.value[itemIndex] + item.order = order + tables.value?.splice(index, 0, ...tables.value?.splice(itemIndex, 1)) + await $api.dbTable.reorder(item.id as string, { + order: item.order, + }) + }, + args: [item.id, item.order, nextIndex], + }, + scope: defineProjectScope({ project: project.value }), + }) }, animation: 150, }) @@ -1085,6 +1132,7 @@ const setIcon = async (icon: string, table: TableType) => {