From 287725923fe30b9bfa575d5863be1f85aa1c2965 Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Mon, 22 Apr 2024 05:37:59 +0000 Subject: [PATCH] feat(nc-gui): add & remove group by this field --- .../components/smartsheet/header/Menu.vue | 20 ++++- .../smartsheet/toolbar/GroupByMenu.vue | 78 +++--------------- packages/nc-gui/composables/useViewGroupBy.ts | 82 ++++++++++++++++++- packages/nc-gui/lib/enums.ts | 3 +- 4 files changed, 110 insertions(+), 73 deletions(-) diff --git a/packages/nc-gui/components/smartsheet/header/Menu.vue b/packages/nc-gui/components/smartsheet/header/Menu.vue index 3328ff7fe0..aa0b9fee26 100644 --- a/packages/nc-gui/components/smartsheet/header/Menu.vue +++ b/packages/nc-gui/components/smartsheet/header/Menu.vue @@ -52,6 +52,8 @@ const { addUndo, defineModelScope, defineViewScope } = useUndoRedo() const showDeleteColumnModal = ref(false) +const { gridViewCols } = useViewColumnsOrThrow() + const setAsDisplayValue = async () => { try { const currentDisplayValue = meta?.value?.columns?.find((f) => f.pv) @@ -296,8 +298,14 @@ const isDuplicateAllowed = computed(() => { return column?.value && !column.value.system }) +const isGroupedByThisField = computed(() => { + return !!gridViewCols.value[column?.value?.id]?.group_by +}) + const filterOrGroupByThisField = (event: SmartsheetStoreEvents) => { - eventBus.emit(event) + if (column?.value) { + eventBus.emit(event, column.value) + } isOpen.value = false } @@ -378,11 +386,17 @@ const filterOrGroupByThisField = (event: SmartsheetStoreEvents) => { - +
- Group by this field + {{ isGroupedByThisField ? "Don't group by this field" : 'Group by this field' }}
diff --git a/packages/nc-gui/components/smartsheet/toolbar/GroupByMenu.vue b/packages/nc-gui/components/smartsheet/toolbar/GroupByMenu.vue index b7a46f1871..2aeea561ae 100644 --- a/packages/nc-gui/components/smartsheet/toolbar/GroupByMenu.vue +++ b/packages/nc-gui/components/smartsheet/toolbar/GroupByMenu.vue @@ -8,30 +8,26 @@ import { computed, getSortDirectionOptions, inject, - onMounted, ref, useMenuCloseOnEsc, - useMetas, useNuxtApp, useSmartsheetStoreOrThrow, useViewColumnsOrThrow, watch, } from '#imports' -const excludedGroupingUidt = [UITypes.Attachment] - const meta = inject(MetaInj, ref()) const view = inject(ActiveViewInj, ref()) const isLocked = inject(IsLockedInj, ref(false)) const { gridViewCols, updateGridViewColumn, metaColumnById, showSystemFields } = useViewColumnsOrThrow() +const { fieldsToGroupBy } = useViewGroupBy(view) + const { $e } = useNuxtApp() const _groupBy = ref<{ fk_column_id?: string; sort: string; order: number }[]>([]) -const { getMeta } = useMetas() - const groupBy = computed<{ fk_column_id?: string; sort: string; order: number }[]>(() => { const tempGroupBy: { fk_column_id?: string; sort: string; order: number }[] = [] Object.values(gridViewCols.value).forEach((col) => { @@ -53,24 +49,8 @@ const { eventBus } = useSmartsheetStoreOrThrow() const { isMobileMode } = useGlobal() -const supportedLookups = ref([]) - const showCreateGroupBy = ref(false) -const fieldsToGroupBy = computed(() => { - const fields = meta.value?.columns || [] - - return fields.filter((field) => { - if (excludedGroupingUidt.includes(field.uidt as UITypes)) return false - - if (field.uidt === UITypes.Lookup) { - return field.id && supportedLookups.value.includes(field.id) - } - - return true - }) -}) - const columns = computed(() => meta.value?.columns || []) const columnByID = computed(() => @@ -152,6 +132,7 @@ const saveGroupBy = async () => { } const addFieldToGroupBy = (column: ColumnType) => { + console.log('groupByField', column) _groupBy.value.push({ fk_column_id: column.id, sort: 'asc', order: _groupBy.value.length + 1 }) saveGroupBy() showCreateGroupBy.value = false @@ -174,54 +155,19 @@ watch(open, () => { } }) -const loadAllowedLookups = async () => { - const filteredLookupCols = [] - try { - for (const col of meta.value?.columns || []) { - if (col.uidt !== UITypes.Lookup) continue - - let nextCol: ColumnType = col - // check the lookup column is supported type or not - while (nextCol && nextCol.uidt === UITypes.Lookup) { - const lookupRelation = (await getMeta(nextCol.fk_model_id as string))?.columns?.find( - (c) => c.id === (nextCol?.colOptions as LookupType).fk_relation_column_id, - ) - - const relatedTableMeta = await getMeta( - (lookupRelation?.colOptions as LinkToAnotherRecordType).fk_related_model_id as string, - ) - - nextCol = relatedTableMeta?.columns?.find( - (c) => c.id === ((nextCol?.colOptions as LookupType).fk_lookup_column_id as string), - ) as ColumnType +eventBus.on(async (event, column) => { + if (!column?.id) return - // if next column is same as root lookup column then break the loop - // since it's going to be a circular loop, and ignore the column - if (nextCol?.id === col.id) { - break - } - } + console.log('_groupBy', column, _groupBy.value) - if (nextCol?.uidt !== UITypes.Attachment && col.id) filteredLookupCols.push(col.id) - } - - supportedLookups.value = filteredLookupCols - } catch (e) { - console.error(e) - } -} - -onMounted(async () => { - await loadAllowedLookups() -}) + if (event === SmartsheetStoreEvents.GROUP_BY_ADD) { + addFieldToGroupBy(column) + } else if (event === SmartsheetStoreEvents.GROUP_BY_REMOVE) { + if (groupedByColumnIds.value.length === 0) return -watch(meta, async () => { - await loadAllowedLookups() -}) + _groupBy.value = _groupBy.value.filter((g) => g.fk_column_id !== column.id) -eventBus.on(async (event, payload) => { - if (event === SmartsheetStoreEvents.GROUP_BY_ADD) { - open.value = true + await saveGroupBy() } }) diff --git a/packages/nc-gui/composables/useViewGroupBy.ts b/packages/nc-gui/composables/useViewGroupBy.ts index 37c38e6763..91038689c1 100644 --- a/packages/nc-gui/composables/useViewGroupBy.ts +++ b/packages/nc-gui/composables/useViewGroupBy.ts @@ -1,10 +1,13 @@ -import { type ColumnType, type SelectOptionsType, UITypes, type ViewType } from 'nocodb-sdk' +import { UITypes } from 'nocodb-sdk' +import type { ColumnType, SelectOptionsType, ViewType, LookupType, LinkToAnotherRecordType } from 'nocodb-sdk' import type { Ref } from 'vue' import { message } from 'ant-design-vue' import { extractSdkResponseErrorMsg } from '../utils' -import { GROUP_BY_VARS, ref, storeToRefs, useApi, useBase, useViewColumnsOrThrow } from '#imports' +import { GROUP_BY_VARS, ref, storeToRefs, useApi, useBase, useViewColumnsOrThrow, useMetas } from '#imports' import type { Group, GroupNestedIn, Row } from '#imports' +const excludedGroupingUidt = [UITypes.Attachment, UITypes.QrCode, UITypes.Barcode] + export const useViewGroupBy = (view: Ref, where?: ComputedRef) => { const { api } = useApi() @@ -18,6 +21,8 @@ export const useViewGroupBy = (view: Ref, where?: Computed const { gridViewCols } = useViewColumnsOrThrow() + const { getMeta } = useMetas() + const groupBy = computed<{ column: ColumnType; sort: string; order?: number }[]>(() => { const tempGroupBy: { column: ColumnType; sort: string; order?: number }[] = [] Object.values(gridViewCols.value).forEach((col) => { @@ -54,6 +59,22 @@ export const useViewGroupBy = (view: Ref, where?: Computed return appInfo.value.defaultGroupByLimit?.limitRecord || 10 }) + const supportedLookups = ref([]) + + const fieldsToGroupBy = computed(() => { + const fields = meta?.value?.columns || [] + + return fields.filter((field) => { + if (excludedGroupingUidt.includes(field.uidt as UITypes)) return false + + if (field.uidt === UITypes.Lookup) { + return field.id && supportedLookups.value.includes(field.id) + } + + return true + }) + }) + const rootGroup = ref({ key: 'root', color: 'root', @@ -464,5 +485,60 @@ export const useViewGroupBy = (view: Ref, where?: Computed } } - return { rootGroup, groupBy, isGroupBy, loadGroups, loadGroupData, loadGroupPage, groupWrapperChangePage, redistributeRows } + const loadAllowedLookups = async () => { + const filteredLookupCols = [] + try { + for (const col of meta?.value?.columns || []) { + if (col.uidt !== UITypes.Lookup) continue + + let nextCol: ColumnType = col + // check the lookup column is supported type or not + while (nextCol && nextCol.uidt === UITypes.Lookup) { + const lookupRelation = (await getMeta(nextCol.fk_model_id as string))?.columns?.find( + (c) => c.id === (nextCol?.colOptions as LookupType).fk_relation_column_id, + ) + + const relatedTableMeta = await getMeta( + (lookupRelation?.colOptions as LinkToAnotherRecordType).fk_related_model_id as string, + ) + + nextCol = relatedTableMeta?.columns?.find( + (c) => c.id === ((nextCol?.colOptions as LookupType).fk_lookup_column_id as string), + ) as ColumnType + + // if next column is same as root lookup column then break the loop + // since it's going to be a circular loop, and ignore the column + if (nextCol?.id === col.id) { + break + } + } + + if (nextCol?.uidt !== UITypes.Attachment && col.id) filteredLookupCols.push(col.id) + } + + supportedLookups.value = filteredLookupCols + } catch (e) { + console.error(e) + } + } + + onMounted(async () => { + await loadAllowedLookups() + }) + + watch(meta, async () => { + await loadAllowedLookups() + }) + + return { + rootGroup, + groupBy, + isGroupBy, + fieldsToGroupBy, + loadGroups, + loadGroupData, + loadGroupPage, + groupWrapperChangePage, + redistributeRows, + } } diff --git a/packages/nc-gui/lib/enums.ts b/packages/nc-gui/lib/enums.ts index bb7ab6e3dc..38be605039 100644 --- a/packages/nc-gui/lib/enums.ts +++ b/packages/nc-gui/lib/enums.ts @@ -82,7 +82,8 @@ export enum SmartsheetStoreEvents { MAPPED_BY_COLUMN_CHANGE = 'mapped-by-column-change', CLEAR_NEW_ROW = 'clear-new-row', GROUP_BY_ADD = 'group-by-add', - FILTER_ADD = 'filter-add' + GROUP_BY_REMOVE = 'group-by-remove', + FILTER_ADD = 'filter-add', } export enum DataSourcesSubTab {