From 6c8825bed91682fba7dc25d2d3bbf7c081bcef1f Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Tue, 27 Feb 2024 12:39:20 +0000 Subject: [PATCH] feat(nc-gui): add limit options for single & multi select field --- .../nc-gui/components/cell/MultiSelect.vue | 39 +++++++++++++++++- .../nc-gui/components/cell/SingleSelect.vue | 40 ++++++++++++++++++- packages/nc-gui/components/cell/User.vue | 28 ++++++------- .../smartsheet/form/LimitOptions.vue | 17 +++----- packages/nc-gui/lib/types.ts | 7 ++++ 5 files changed, 103 insertions(+), 28 deletions(-) diff --git a/packages/nc-gui/components/cell/MultiSelect.vue b/packages/nc-gui/components/cell/MultiSelect.vue index eec679eb95..9559bcb48c 100644 --- a/packages/nc-gui/components/cell/MultiSelect.vue +++ b/packages/nc-gui/components/cell/MultiSelect.vue @@ -3,6 +3,7 @@ import { message } from 'ant-design-vue' import tinycolor from 'tinycolor2' import type { Select as AntSelect } from 'ant-design-vue' import type { SelectOptionType, SelectOptionsType } from 'nocodb-sdk' +import type { FormFieldsLimitOptionsType } from '~/lib' import { ActiveCellInj, ColumnInj, @@ -95,7 +96,43 @@ const options = computed<(SelectOptionType & { value?: string })[]>(() => { for (const op of opts.filter((el: SelectOptionType) => el.order === null)) { op.title = op.title?.replace(/^'/, '').replace(/'$/, '') } - return opts.map((o: SelectOptionType) => ({ ...o, value: o.title })) + let order = 1 + const limitOptionsById = + ((parseProp(column.value.meta)?.limitOptions || []).reduce( + (o: Record, f: FormFieldsLimitOptionsType) => { + if (f?.order !== undefined && order < f.order) { + order = f.order + } + return { + ...o, + [f.id]: f, + } + }, + {}, + ) as Record) ?? {} + + if ( + !isEditColumn.value && + isForm.value && + parseProp(column.value.meta)?.isLimitOption && + (parseProp(column.value.meta)?.limitOptions || []).length + ) { + return opts + ?.filter((o: SelectOptionType) => { + if (limitOptionsById[o.id!]?.show !== undefined) { + return limitOptionsById[o.id!]?.show + } + return false + }) + ?.map((o) => ({ + ...o, + value: o.title, + order: o.id && limitOptionsById[o.id] ? limitOptionsById[o.id]?.order : order++, + })) + ?.sort((a, b) => a.order - b.order) + } else { + return opts.map((o: SelectOptionType) => ({ ...o, value: o.title })) + } } return [] }) diff --git a/packages/nc-gui/components/cell/SingleSelect.vue b/packages/nc-gui/components/cell/SingleSelect.vue index fa37963d1f..def1196ca3 100644 --- a/packages/nc-gui/components/cell/SingleSelect.vue +++ b/packages/nc-gui/components/cell/SingleSelect.vue @@ -3,6 +3,7 @@ import { message } from 'ant-design-vue' import tinycolor from 'tinycolor2' import type { Select as AntSelect } from 'ant-design-vue' import type { SelectOptionType } from 'nocodb-sdk' +import type { FormFieldsLimitOptionsType } from '~/lib' import { ActiveCellInj, ColumnInj, @@ -88,7 +89,44 @@ const options = computed<(SelectOptionType & { value: string })[]>(() => { for (const op of opts.filter((el: any) => el.order === null)) { op.title = op.title.replace(/^'/, '').replace(/'$/, '') } - return opts.map((o: any) => ({ ...o, value: o.title })) + + let order = 1 + const limitOptionsById = + ((parseProp(column.value.meta)?.limitOptions || []).reduce( + (o: Record, f: FormFieldsLimitOptionsType) => { + if (f?.order !== undefined && order < f.order) { + order = f.order + } + return { + ...o, + [f.id]: f, + } + }, + {}, + ) as Record) ?? {} + + if ( + !isEditColumn.value && + isForm.value && + parseProp(column.value.meta)?.isLimitOption && + (parseProp(column.value.meta)?.limitOptions || []).length + ) { + return opts + ?.filter((o: any) => { + if (limitOptionsById[o.id]?.show !== undefined) { + return limitOptionsById[o.id]?.show + } + return false + }) + ?.map((o: any) => ({ + ...o, + value: o.title, + order: o.id && limitOptionsById[o.id] ? limitOptionsById[o.id]?.order : order++, + })) + ?.sort((a, b) => a.order - b.order) + } else { + return opts.map((o: any) => ({ ...o, value: o.title })) + } } return [] }) diff --git a/packages/nc-gui/components/cell/User.vue b/packages/nc-gui/components/cell/User.vue index effaa9228c..aeb6e6acea 100644 --- a/packages/nc-gui/components/cell/User.vue +++ b/packages/nc-gui/components/cell/User.vue @@ -4,6 +4,7 @@ import tinycolor from 'tinycolor2' import { CheckboxGroup, Checkbox, RadioGroup, Radio } from 'ant-design-vue' import type { Select as AntSelect } from 'ant-design-vue' import type { UserFieldRecordType } from 'nocodb-sdk' +import type { FormFieldsLimitOptionsType } from '~/lib' import { ActiveCellInj, CellClickHookInj, @@ -26,12 +27,6 @@ import { } from '#imports' import MdiCloseCircle from '~icons/mdi/close-circle' -interface LimitOptionsType { - id: string - order: number - show: boolean -} - interface Props { modelValue?: UserFieldRecordType[] | UserFieldRecordType | string | null rowIndex?: number @@ -86,15 +81,18 @@ const { isUIAllowed } = useRoles() const options = computed(() => { let order = 1 const limitOptionsById = - ((parseProp(column.value.meta)?.limitOptions || []).reduce((o: Record, f: LimitOptionsType) => { - if (f?.order !== undefined && order < f.order) { - order = f.order - } - return { - ...o, - [f.id]: f, - } - }, {}) as Record) ?? {} + ((parseProp(column.value.meta)?.limitOptions || []).reduce( + (o: Record, f: FormFieldsLimitOptionsType) => { + if (f?.order !== undefined && order < f.order) { + order = f.order + } + return { + ...o, + [f.id]: f, + } + }, + {}, + ) as Record) ?? {} const collaborators: UserFieldRecordType[] = [] diff --git a/packages/nc-gui/components/smartsheet/form/LimitOptions.vue b/packages/nc-gui/components/smartsheet/form/LimitOptions.vue index a4dca81ebd..3893c69db2 100644 --- a/packages/nc-gui/components/smartsheet/form/LimitOptions.vue +++ b/packages/nc-gui/components/smartsheet/form/LimitOptions.vue @@ -1,18 +1,13 @@