Browse Source

feat: merge view columns and grid view columns state

pull/6645/head
mertmit 1 year ago
parent
commit
f05cb7da73
  1. 6
      packages/nc-gui/components/shared-view/Grid.vue
  2. 6
      packages/nc-gui/components/smartsheet/Form.vue
  3. 11
      packages/nc-gui/components/smartsheet/column/BarcodeOptions.vue
  4. 9
      packages/nc-gui/components/smartsheet/column/QrCodeOptions.vue
  5. 7
      packages/nc-gui/components/smartsheet/details/Fields.vue
  6. 8
      packages/nc-gui/components/smartsheet/grid/Table.vue
  7. 2
      packages/nc-gui/components/smartsheet/toolbar/FieldListAutoCompleteDropdown.vue
  8. 6
      packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue
  9. 3
      packages/nc-gui/components/smartsheet/toolbar/GroupByMenu.vue
  10. 4
      packages/nc-gui/components/smartsheet/toolbar/MappedBy.vue
  11. 2
      packages/nc-gui/components/smartsheet/toolbar/SortListMenu.vue
  12. 1
      packages/nc-gui/components/tabs/Smartsheet.vue
  13. 99
      packages/nc-gui/composables/useGridViewColumn.ts
  14. 59
      packages/nc-gui/composables/useViewColumns.ts
  15. 2
      packages/nc-gui/composables/useViewFilters.ts
  16. 4
      packages/nc-gui/composables/useViewGroupBy.ts

6
packages/nc-gui/components/shared-view/Grid.vue

@ -39,8 +39,6 @@ provide(IsLockedInj, isLocked)
useProvideViewColumns(sharedView, meta, () => reloadEventHook?.trigger(), true) useProvideViewColumns(sharedView, meta, () => reloadEventHook?.trigger(), true)
const { loadGridViewColumns } = useProvideGridViewColumn(sharedView, true)
if (signedIn.value) { if (signedIn.value) {
try { try {
await loadProject() await loadProject()
@ -57,10 +55,6 @@ watch(
immediate: true, immediate: true,
}, },
) )
onMounted(async () => {
await loadGridViewColumns()
})
</script> </script>
<template> <template>

6
packages/nc-gui/components/smartsheet/Form.vue

@ -58,16 +58,14 @@ const isPublic = inject(IsPublicInj, ref(false))
const { loadFormView, insertRow, formColumnData, formViewData, updateFormView } = useViewData(meta, view) const { loadFormView, insertRow, formColumnData, formViewData, updateFormView } = useViewData(meta, view)
const reloadEventHook = createEventHook<boolean | void>() const reloadEventHook = inject(ReloadViewDataHookInj, createEventHook<boolean | void>())
provide(ReloadViewDataHookInj, reloadEventHook)
reloadEventHook.on(async () => { reloadEventHook.on(async () => {
await loadFormView() await loadFormView()
setFormData() setFormData()
}) })
const { showAll, hideAll, saveOrUpdate } = useViewColumnsOrThrow(view, meta) const { showAll, hideAll, saveOrUpdate } = useViewColumnsOrThrow()
const { syncLTARRefs, row } = useProvideSmartsheetRowStore( const { syncLTARRefs, row } = useProvideSmartsheetRowStore(
meta, meta,

11
packages/nc-gui/components/smartsheet/column/BarcodeOptions.vue

@ -10,11 +10,7 @@ const props = defineProps<{
const emit = defineEmits(['update:modelValue']) const emit = defineEmits(['update:modelValue'])
const meta = inject(MetaInj, ref()) const { fields, metaColumnById } = useViewColumnsOrThrow()
const activeView = inject(ActiveViewInj, ref())
const { fields, metaColumnById } = useViewColumnsOrThrow(activeView, meta)
const vModel = useVModel(props, 'modelValue', emit) const vModel = useVModel(props, 'modelValue', emit)
@ -57,11 +53,12 @@ onMounted(() => {
...vModel.value.meta, ...vModel.value.meta,
} }
vModel.value.fk_barcode_value_column_id = vModel.value.fk_barcode_value_column_id =
(column?.value?.colOptions as Record<string, any>)?.fk_barcode_value_column_id || columnsAllowedAsBarcodeValue.value?.[0] (column?.value?.colOptions as Record<string, any>)?.fk_barcode_value_column_id ||
columnsAllowedAsBarcodeValue.value?.[0]?.value
}) })
watch(columnsAllowedAsBarcodeValue, (newColumnsAllowedAsBarcodeValue) => { watch(columnsAllowedAsBarcodeValue, (newColumnsAllowedAsBarcodeValue) => {
if (vModel.value.fk_barcode_value_column_id == null) { if (vModel.value.fk_barcode_value_column_id === null) {
vModel.value.fk_barcode_value_column_id = newColumnsAllowedAsBarcodeValue?.[0]?.value vModel.value.fk_barcode_value_column_id = newColumnsAllowedAsBarcodeValue?.[0]?.value
} }
}) })

9
packages/nc-gui/components/smartsheet/column/QrCodeOptions.vue

@ -10,13 +10,9 @@ const props = defineProps<{
const emit = defineEmits(['update:modelValue']) const emit = defineEmits(['update:modelValue'])
const meta = inject(MetaInj, ref())
const activeView = inject(ActiveViewInj, ref())
const { t } = useI18n() const { t } = useI18n()
const { fields, metaColumnById } = useViewColumnsOrThrow(activeView, meta) const { fields, metaColumnById } = useViewColumnsOrThrow()
const vModel = useVModel(props, 'modelValue', emit) const vModel = useVModel(props, 'modelValue', emit)
@ -38,7 +34,8 @@ const columnsAllowedAsQrValue = computed<SelectProps['options']>(() => {
onMounted(() => { onMounted(() => {
// set default value // set default value
vModel.value.fk_qr_value_column_id = (column?.value?.colOptions as Record<string, any>)?.fk_qr_value_column_id || '' vModel.value.fk_qr_value_column_id =
(column?.value?.colOptions as Record<string, any>)?.fk_qr_value_column_id || columnsAllowedAsQrValue.value?.[0]?.value
}) })
setAdditionalValidations({ setAdditionalValidations({

7
packages/nc-gui/components/smartsheet/details/Fields.vue

@ -45,12 +45,7 @@ const visibilityOps = ref<fieldsVisibilityOps[]>([])
const fieldsListWrapperDomRef = ref<HTMLElement>() const fieldsListWrapperDomRef = ref<HTMLElement>()
const { const { fields: viewFields, toggleFieldVisibility, loadViewColumns, isViewColumnsLoading } = useViewColumnsOrThrow()
fields: viewFields,
toggleFieldVisibility,
loadViewColumns,
isViewColumnsLoading,
} = useViewColumnsOrThrow(view, meta as Ref<TableType | undefined>)
const loading = ref(false) const loading = ref(false)

8
packages/nc-gui/components/smartsheet/grid/Table.vue

@ -28,7 +28,6 @@ import {
provide, provide,
ref, ref,
useEventListener, useEventListener,
useGridViewColumnOrThrow,
useI18n, useI18n,
useMultiSelect, useMultiSelect,
useNuxtApp, useNuxtApp,
@ -36,6 +35,7 @@ import {
useRoute, useRoute,
useSmartsheetStoreOrThrow, useSmartsheetStoreOrThrow,
useUndoRedo, useUndoRedo,
useViewColumnsOrThrow,
useViewsStore, useViewsStore,
watch, watch,
} from '#imports' } from '#imports'
@ -123,8 +123,6 @@ const reloadViewDataHook = inject(ReloadViewDataHookInj, createEventHook())
const openNewRecordFormHook = inject(OpenNewRecordFormHookInj, createEventHook()) const openNewRecordFormHook = inject(OpenNewRecordFormHookInj, createEventHook())
const { isViewColumnsLoading } = useViewColumnsOrThrow(view, meta)
const { isMobileMode } = useGlobal() const { isMobileMode } = useGlobal()
const scrollParent = inject(ScrollParentInj, ref<undefined>()) const scrollParent = inject(ScrollParentInj, ref<undefined>())
@ -141,6 +139,8 @@ const { getMeta } = useMetas()
const { addUndo, clone, defineViewScope } = useUndoRedo() const { addUndo, clone, defineViewScope } = useUndoRedo()
const { isViewColumnsLoading, updateGridViewColumn, gridViewCols, resizingColOldWith } = useViewColumnsOrThrow()
const { const {
predictingNextColumn, predictingNextColumn,
predictedNextColumn, predictedNextColumn,
@ -894,8 +894,6 @@ const saveOrUpdateRecords = async (args: { metaValue?: TableType; viewMetaValue?
} }
// #Grid Resize // #Grid Resize
const { updateGridViewColumn, gridViewCols, resizingColOldWith } = useGridViewColumnOrThrow()
const onresize = (colID: string | undefined, event: any) => { const onresize = (colID: string | undefined, event: any) => {
if (!colID) return if (!colID) return
updateGridViewColumn(colID, { width: event.detail }) updateGridViewColumn(colID, { width: event.detail })

2
packages/nc-gui/components/smartsheet/toolbar/FieldListAutoCompleteDropdown.vue

@ -24,7 +24,7 @@ const localValue = computed({
const activeView = inject(ActiveViewInj, ref()) const activeView = inject(ActiveViewInj, ref())
const { showSystemFields, metaColumnById } = useViewColumnsOrThrow(activeView, meta) const { showSystemFields, metaColumnById } = useViewColumnsOrThrow()
const options = computed<SelectProps['options']>(() => const options = computed<SelectProps['options']>(() =>
( (

6
packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue

@ -25,12 +25,8 @@ import {
watch, watch,
} from '#imports' } from '#imports'
const meta = inject(MetaInj, ref())
const activeView = inject(ActiveViewInj, ref()) const activeView = inject(ActiveViewInj, ref())
const reloadDataHook = inject(ReloadViewDataHookInj)!
const reloadViewMetaHook = inject(ReloadViewMetaHookInj, undefined)! const reloadViewMetaHook = inject(ReloadViewMetaHookInj, undefined)!
const rootFields = inject(FieldsInj) const rootFields = inject(FieldsInj)
@ -55,7 +51,7 @@ const {
metaColumnById, metaColumnById,
loadViewColumns, loadViewColumns,
toggleFieldVisibility, toggleFieldVisibility,
} = useViewColumnsOrThrow(activeView, meta) } = useViewColumnsOrThrow()
const { eventBus } = useSmartsheetStoreOrThrow() const { eventBus } = useSmartsheetStoreOrThrow()

3
packages/nc-gui/components/smartsheet/toolbar/GroupByMenu.vue

@ -14,6 +14,7 @@ import {
useMetas, useMetas,
useNuxtApp, useNuxtApp,
useSmartsheetStoreOrThrow, useSmartsheetStoreOrThrow,
useViewColumnsOrThrow,
} from '#imports' } from '#imports'
const groupingUidt = [ const groupingUidt = [
@ -33,7 +34,7 @@ const meta = inject(MetaInj, ref())
const view = inject(ActiveViewInj, ref()) const view = inject(ActiveViewInj, ref())
const isLocked = inject(IsLockedInj, ref(false)) const isLocked = inject(IsLockedInj, ref(false))
const { gridViewCols, updateGridViewColumn } = useGridViewColumnOrThrow() const { gridViewCols, updateGridViewColumn } = useViewColumnsOrThrow()
const { $e } = useNuxtApp() const { $e } = useNuxtApp()

4
packages/nc-gui/components/smartsheet/toolbar/MappedBy.vue

@ -22,13 +22,11 @@ const meta = inject(MetaInj, ref())
const activeView = inject(ActiveViewInj, ref()) const activeView = inject(ActiveViewInj, ref())
const reloadDataHook = inject(ReloadViewDataHookInj)!
const isLocked = inject(IsLockedInj, ref(false)) const isLocked = inject(IsLockedInj, ref(false))
const IsPublic = inject(IsPublicInj, ref(false)) const IsPublic = inject(IsPublicInj, ref(false))
const { fields, loadViewColumns, metaColumnById } = useViewColumnsOrThrow(activeView, meta) const { fields, loadViewColumns, metaColumnById } = useViewColumnsOrThrow()
const { loadMapData, loadMapMeta, updateMapMeta, mapMetaData, geoDataFieldColumn } = useMapViewStoreOrThrow() const { loadMapData, loadMapMeta, updateMapMeta, mapMetaData, geoDataFieldColumn } = useMapViewStoreOrThrow()

2
packages/nc-gui/components/smartsheet/toolbar/SortListMenu.vue

@ -28,7 +28,7 @@ const { eventBus } = useSmartsheetStoreOrThrow()
const { sorts, saveOrUpdate, loadSorts, addSort: _addSort, deleteSort } = useViewSorts(view, () => reloadDataHook?.trigger()) const { sorts, saveOrUpdate, loadSorts, addSort: _addSort, deleteSort } = useViewSorts(view, () => reloadDataHook?.trigger())
const { showSystemFields, metaColumnById } = useViewColumnsOrThrow(view, meta) const { showSystemFields, metaColumnById } = useViewColumnsOrThrow()
const showCreateSort = ref(false) const showCreateSort = ref(false)

1
packages/nc-gui/components/tabs/Smartsheet.vue

@ -63,7 +63,6 @@ const openNewRecordFormHook = createEventHook<void>()
useProvideKanbanViewStore(meta, activeView) useProvideKanbanViewStore(meta, activeView)
useProvideMapViewStore(meta, activeView) useProvideMapViewStore(meta, activeView)
useProvideGridViewColumn(activeView)
// todo: move to store // todo: move to store
provide(MetaInj, meta) provide(MetaInj, meta)

99
packages/nc-gui/composables/useGridViewColumn.ts

@ -1,99 +0,0 @@
import type { ColumnType, GridColumnReqType, GridColumnType, ViewType } from 'nocodb-sdk'
import type { Ref } from 'vue'
import { IsPublicInj, computed, inject, ref, useMetas, useNuxtApp, useRoles, useUndoRedo, watch } from '#imports'
const [useProvideGridViewColumn, useGridViewColumn] = useInjectionState(
(view: Ref<(ViewType & { columns?: GridColumnType[] }) | undefined>, statePublic = false) => {
const { isUIAllowed } = useRoles()
const { $api } = useNuxtApp()
const { metas } = useMetas()
const { addUndo, defineViewScope } = useUndoRedo()
const gridViewCols = ref<Record<string, GridColumnType>>({})
const resizingColOldWith = ref('200px')
const isPublic = inject(IsPublicInj, ref(statePublic))
const columns = computed<ColumnType[]>(() => metas.value?.[view.value?.fk_model_id as string]?.columns || [])
const loadGridViewColumns = async () => {
if (!view.value?.id && !isPublic.value) return
const colsData: GridColumnType[] =
(isPublic.value ? view.value?.columns : await $api.dbView.gridColumnsList(view.value!.id!)) ?? []
gridViewCols.value = colsData.reduce<Record<string, GridColumnType>>(
(o, col) => ({
...o,
[col.fk_column_id as string]: col,
}),
{},
)
}
/** when columns changes(create/delete) reload grid columns
* or when view changes reload columns width */
watch(
[() => columns.value?.length, () => view.value?.id],
async (n) => {
if (n[0] && n[1]) await loadGridViewColumns()
},
{
immediate: true,
},
)
const updateGridViewColumn = async (id: string, props: Partial<GridColumnReqType>, undo = false) => {
if (!undo) {
const oldProps = Object.keys(props).reduce<Partial<GridColumnReqType>>((o: any, k) => {
if (gridViewCols.value[id][k as keyof GridColumnType]) {
if (k === 'width') o[k] = `${resizingColOldWith.value}px`
else o[k] = gridViewCols.value[id][k as keyof GridColumnType]
}
return o
}, {})
addUndo({
redo: {
fn: (w: Partial<GridColumnReqType>) => updateGridViewColumn(id, w, true),
args: [props],
},
undo: {
fn: (w: Partial<GridColumnReqType>) => updateGridViewColumn(id, w, true),
args: [oldProps],
},
scope: defineViewScope({ view: view.value }),
})
}
// sync with server if allowed
if (!isPublic.value && isUIAllowed('viewFieldEdit') && gridViewCols.value[id]?.id) {
await $api.dbView.gridColumnUpdate(gridViewCols.value[id].id as string, {
...props,
})
}
if (gridViewCols.value?.[id]) {
Object.assign(gridViewCols.value[id], {
...gridViewCols.value[id],
...props,
})
} else {
// fallback to reload
await loadGridViewColumns()
}
}
return { loadGridViewColumns, updateGridViewColumn, gridViewCols, resizingColOldWith }
},
'useGridViewColumn',
)
export { useProvideGridViewColumn }
export function useGridViewColumnOrThrow() {
const gridViewColumn = useGridViewColumn()
if (gridViewColumn == null) throw new Error('Please call `useProvideGridViewColumn` on the appropriate parent component')
return gridViewColumn
}

59
packages/nc-gui/composables/useViewColumns.ts

@ -1,5 +1,5 @@
import { ViewTypes, isSystemColumn } from 'nocodb-sdk' import { ViewTypes, isSystemColumn } from 'nocodb-sdk'
import type { ColumnType, MapType, TableType, ViewType } from 'nocodb-sdk' import type { ColumnType, GridColumnReqType, GridColumnType, MapType, TableType, ViewType } from 'nocodb-sdk'
import type { ComputedRef, Ref } from 'vue' import type { ComputedRef, Ref } from 'vue'
import { computed, ref, storeToRefs, useBase, useNuxtApp, useRoles, useUndoRedo, watch } from '#imports' import { computed, ref, storeToRefs, useBase, useNuxtApp, useRoles, useUndoRedo, watch } from '#imports'
import type { Field } from '#imports' import type { Field } from '#imports'
@ -50,6 +50,8 @@ const [useProvideViewColumns, useViewColumns] = useInjectionState(
) as Record<string, ColumnType> ) as Record<string, ColumnType>
}) })
const gridViewCols = ref<Record<string, GridColumnType>>({})
const loadViewColumns = async () => { const loadViewColumns = async () => {
if (!meta || !view) return if (!meta || !view) return
@ -92,6 +94,16 @@ const [useProvideViewColumns, useViewColumns] = useInjectionState(
} }
} }
} }
const colsData: GridColumnType[] = (isPublic.value ? view.value?.columns : fields.value) ?? []
gridViewCols.value = colsData.reduce<Record<string, GridColumnType>>(
(o, col) => ({
...o,
[col.fk_column_id as string]: col,
}),
{},
)
} }
} }
@ -279,6 +291,48 @@ const [useProvideViewColumns, useViewColumns] = useInjectionState(
{ immediate: true }, { immediate: true },
) )
const resizingColOldWith = ref('200px')
const updateGridViewColumn = async (id: string, props: Partial<GridColumnReqType>, undo = false) => {
if (!undo) {
const oldProps = Object.keys(props).reduce<Partial<GridColumnReqType>>((o: any, k) => {
if (gridViewCols.value[id][k as keyof GridColumnType]) {
if (k === 'width') o[k] = `${resizingColOldWith.value}px`
else o[k] = gridViewCols.value[id][k as keyof GridColumnType]
}
return o
}, {})
addUndo({
redo: {
fn: (w: Partial<GridColumnReqType>) => updateGridViewColumn(id, w, true),
args: [props],
},
undo: {
fn: (w: Partial<GridColumnReqType>) => updateGridViewColumn(id, w, true),
args: [oldProps],
},
scope: defineViewScope({ view: view.value }),
})
}
// sync with server if allowed
if (!isPublic.value && isUIAllowed('viewFieldEdit') && gridViewCols.value[id]?.id) {
await $api.dbView.gridColumnUpdate(gridViewCols.value[id].id as string, {
...props,
})
}
if (gridViewCols.value?.[id]) {
Object.assign(gridViewCols.value[id], {
...gridViewCols.value[id],
...props,
})
} else {
// fallback to reload
await loadViewColumns()
}
}
return { return {
fields, fields,
loadViewColumns, loadViewColumns,
@ -292,6 +346,9 @@ const [useProvideViewColumns, useViewColumns] = useInjectionState(
metaColumnById, metaColumnById,
toggleFieldVisibility, toggleFieldVisibility,
isViewColumnsLoading, isViewColumnsLoading,
updateGridViewColumn,
gridViewCols,
resizingColOldWith,
} }
}, },
'useViewColumnsOrThrow', 'useViewColumnsOrThrow',

2
packages/nc-gui/composables/useViewFilters.ts

@ -81,7 +81,7 @@ export function useViewFilters(
const activeView = inject(ActiveViewInj, ref()) const activeView = inject(ActiveViewInj, ref())
const { showSystemFields, metaColumnById } = useViewColumnsOrThrow(activeView, meta) const { showSystemFields, metaColumnById } = useViewColumnsOrThrow()
const options = computed<SelectProps['options']>(() => const options = computed<SelectProps['options']>(() =>
meta.value?.columns?.filter((c: ColumnType) => { meta.value?.columns?.filter((c: ColumnType) => {

4
packages/nc-gui/composables/useViewGroupBy.ts

@ -1,6 +1,6 @@
import { type ColumnType, type SelectOptionsType, UITypes, type ViewType } from 'nocodb-sdk' import { type ColumnType, type SelectOptionsType, UITypes, type ViewType } from 'nocodb-sdk'
import type { Ref } from 'vue' import type { Ref } from 'vue'
import { GROUP_BY_VARS, ref, storeToRefs, useApi, useBase } from '#imports' import { GROUP_BY_VARS, ref, storeToRefs, useApi, useBase, useViewColumnsOrThrow } from '#imports'
import type { Group, GroupNestedIn, Row } from '#imports' import type { Group, GroupNestedIn, Row } from '#imports'
export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: ComputedRef<string | undefined>) => { export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: ComputedRef<string | undefined>) => {
@ -12,7 +12,7 @@ export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: Computed
const meta = inject(MetaInj) const meta = inject(MetaInj)
const { gridViewCols } = useGridViewColumnOrThrow() const { gridViewCols } = useViewColumnsOrThrow()
const groupBy = computed<{ column: ColumnType; sort: string; order?: number }[]>(() => { const groupBy = computed<{ column: ColumnType; sort: string; order?: number }[]>(() => {
const tempGroupBy: { column: ColumnType; sort: string; order?: number }[] = [] const tempGroupBy: { column: ColumnType; sort: string; order?: number }[] = []

Loading…
Cancel
Save