From 31248ba5dd496385e563309a475489aa950b1683 Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Tue, 27 Feb 2024 12:39:19 +0000 Subject: [PATCH 01/18] fix(nc-gui): splitpanes typeerror: Cannot read properties of null (reading 'children') --- packages/nc-gui/components/smartsheet/Form.vue | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/nc-gui/components/smartsheet/Form.vue b/packages/nc-gui/components/smartsheet/Form.vue index 3eda8c15d1..285dd9a81d 100644 --- a/packages/nc-gui/components/smartsheet/Form.vue +++ b/packages/nc-gui/components/smartsheet/Form.vue @@ -1145,7 +1145,7 @@ useEventListener(
- +
@@ -1298,12 +1298,7 @@ useEventListener(
- +
{{ $t('labels.appearanceSettings') }}
From 5a4a6eb7d9568e5d596ccfe2bbb14bde78c39448 Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Tue, 27 Feb 2024 12:39:19 +0000 Subject: [PATCH 02/18] feat(nc-gui): add single select list options layout --- .../nc-gui/components/cell/SingleSelect.vue | 190 ++++++++++++------ .../nc-gui/components/smartsheet/Form.vue | 60 +++++- packages/nc-gui/lang/en.json | 5 +- 3 files changed, 179 insertions(+), 76 deletions(-) diff --git a/packages/nc-gui/components/cell/SingleSelect.vue b/packages/nc-gui/components/cell/SingleSelect.vue index 1ca601c92f..fac921b5c7 100644 --- a/packages/nc-gui/components/cell/SingleSelect.vue +++ b/packages/nc-gui/components/cell/SingleSelect.vue @@ -272,82 +272,66 @@ const onFocus = () => { @@ -412,6 +455,19 @@ const onFocus = () => { :deep(.ant-select-clear > span) { @apply block; } +.nc-field-layout-list { + @apply !flex !flex-col !items-start w-full !space-y-0.5 !max-w-full; + + :deep(.ant-radio-wrapper) { + @apply !m-0 !h-9 !mr-0 !flex !items-center w-full !max-w-full pl-2 rounded-lg hover:bg-gray-100; + .ant-radio { + @apply !top-0; + } + .ant-radio + span { + @apply !flex !pl-4 max-w-[calc(100%_-_16px)]; + } + } +} diff --git a/packages/nc-gui/lang/en.json b/packages/nc-gui/lang/en.json index 8d8dacb99b..3598e1f691 100644 --- a/packages/nc-gui/lang/en.json +++ b/packages/nc-gui/lang/en.json @@ -692,7 +692,10 @@ "backgroundColor":"Background Color", "hideNocodbBranding":"Hide NocoDB Branding", "showOnConditions": "Show on condtions", - "showFieldOnConditionsMet":"Shows field only when conditions are met" + "showFieldOnConditionsMet":"Shows field only when conditions are met", + "limitOptions": "Limit ptions", + "limitOptionsSubtext": "Limit options visible to users by selecting available options", + "clearSelection": "Clear selection" }, "activity": { "noRange": "Calendar view requires a date range", From bfc13045d2585a81bdf0ff50d9ba82e3a635f5b7 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 03/18] feat(nc-gui): list option for single & multiselect field --- .../nc-gui/components/cell/MultiSelect.vue | 347 +++++++++++------- .../nc-gui/components/cell/SingleSelect.vue | 2 +- .../nc-gui/components/smartsheet/Form.vue | 2 +- 3 files changed, 208 insertions(+), 143 deletions(-) diff --git a/packages/nc-gui/components/cell/MultiSelect.vue b/packages/nc-gui/components/cell/MultiSelect.vue index 34080cd190..eec679eb95 100644 --- a/packages/nc-gui/components/cell/MultiSelect.vue +++ b/packages/nc-gui/components/cell/MultiSelect.vue @@ -353,154 +353,194 @@ const onFocus = () => { +
+ + -
- -
- {{ $t('msg.selectOption.createNewOptionNamed') }} {{ searchVal }} -
-
- - - + - + + + + + {{ op.title }} + + + + + + + +
+ +
+ {{ $t('msg.selectOption.createNewOptionNamed') }} {{ searchVal }} +
+
+
+ + -
+ + {{ val }} + + + + +
@@ -570,6 +610,31 @@ const onFocus = () => { :deep(.ant-select-selection-search-input) { @apply !text-xs; } + +.nc-field-layout-list { + @apply !flex !flex-col !items-start w-full !space-y-0.5 !max-w-full; + + :deep(.ant-checkbox-wrapper) { + @apply !m-0 !h-9 !mr-0 !flex !items-center w-full !max-w-full pl-2 rounded-lg hover:bg-gray-100; + + &:hover { + .ant-checkbox-checked:after { + @apply !rounded; + } + } + .ant-checkbox { + @apply !top-0; + + & + span { + @apply !flex !pl-4 max-w-[calc(100%_-_16px)]; + } + .ant-checkbox-checked:after, + .ant-checkbox-inner { + @apply !rounded; + } + } + } +} From 51a8f4a4d73bc3bd17e0c3d6442a4f68864f950c 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 05/18] fix(nc-gui): shared form select type list options --- .../nc-gui/components/smartsheet/Form.vue | 25 ++++++++++++++----- .../composables/useSharedFormViewStore.ts | 1 + packages/nocodb-sdk/src/lib/UITypes.ts | 7 ++++++ packages/nocodb-sdk/src/lib/index.ts | 1 + 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/packages/nc-gui/components/smartsheet/Form.vue b/packages/nc-gui/components/smartsheet/Form.vue index ea84ba026a..63f8ad8d94 100644 --- a/packages/nc-gui/components/smartsheet/Form.vue +++ b/packages/nc-gui/components/smartsheet/Form.vue @@ -4,7 +4,16 @@ import Draggable from 'vuedraggable' import tinycolor from 'tinycolor2' import { Pane, Splitpanes } from 'splitpanes' import 'splitpanes/dist/splitpanes.css' -import { ProjectRoles, RelationTypes, UITypes, ViewTypes, getSystemColumns, isLinksOrLTAR, isVirtualCol } from 'nocodb-sdk' +import { + ProjectRoles, + RelationTypes, + UITypes, + ViewTypes, + getSystemColumns, + isLinksOrLTAR, + isVirtualCol, + isSelectTypeCol, +} from 'nocodb-sdk' import type { Permission } from '#imports' import { ActiveViewInj, @@ -157,8 +166,6 @@ const focusLabel: VNodeRef = (el) => { const searchQuery = ref('') -const selectTypeFields = [UITypes.SingleSelect, UITypes.MultiSelect, UITypes.User] - const { t } = useI18n() const { betaFeatureToggleState } = useBetaFeatureToggle() @@ -1090,7 +1097,7 @@ useEventListener( class="nc-form-field-settings border-t border-gray-200 p-4 lg:p-6 flex flex-col gap-3" > -
+
Layout
- +
{{ $t('labels.limitOptions') }}
{{ $t('labels.limitOptionsSubtext') }}.
+
diff --git a/packages/nc-gui/composables/useSharedFormViewStore.ts b/packages/nc-gui/composables/useSharedFormViewStore.ts index e60f089657..4be41faebc 100644 --- a/packages/nc-gui/composables/useSharedFormViewStore.ts +++ b/packages/nc-gui/composables/useSharedFormViewStore.ts @@ -109,6 +109,7 @@ const [useProvideSharedFormStore, useSharedFormStore] = useInjectionState((share columns.value = viewMeta.model?.columns?.map((c) => ({ ...c, + meta: { ...parseProp(fieldById[c.id].meta), ...parseProp(c.meta) }, description: fieldById[c.id].description, })) diff --git a/packages/nocodb-sdk/src/lib/UITypes.ts b/packages/nocodb-sdk/src/lib/UITypes.ts index d5fa23214c..f7895f0cac 100644 --- a/packages/nocodb-sdk/src/lib/UITypes.ts +++ b/packages/nocodb-sdk/src/lib/UITypes.ts @@ -202,4 +202,11 @@ export const getEquivalentUIType = ({ } }; +export const isSelectTypeCol = ( + colOrUidt: ColumnType | { uidt: UITypes | string } | UITypes | string +) => { + return [UITypes.SingleSelect, UITypes.MultiSelect, UITypes.User].includes( + (typeof colOrUidt === 'object' ? colOrUidt?.uidt : colOrUidt) + ); +}; export default UITypes; diff --git a/packages/nocodb-sdk/src/lib/index.ts b/packages/nocodb-sdk/src/lib/index.ts index e06f405e5d..2a38f678de 100644 --- a/packages/nocodb-sdk/src/lib/index.ts +++ b/packages/nocodb-sdk/src/lib/index.ts @@ -18,6 +18,7 @@ export { isCreatedOrLastModifiedByCol, isHiddenCol, getEquivalentUIType, + isSelectTypeCol, } from '~/lib/UITypes'; export { default as CustomAPI, FileType } from '~/lib/CustomAPI'; export { default as TemplateGenerator } from '~/lib/TemplateGenerator'; From 081e57370b1993df5217498bfa06a9ca239e269b 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 06/18] feat(nc-gui): add form select type field option limit --- packages/nc-gui/assets/nc-icons/eye-off.svg | 14 + packages/nc-gui/assets/nc-icons/eye.svg | 10 +- packages/nc-gui/components/cell/User.vue | 63 ++++- .../nc-gui/components/smartsheet/Form.vue | 51 ++-- .../smartsheet/form/LimitOptions.vue | 267 ++++++++++++++++++ packages/nc-gui/utils/iconUtils.ts | 3 +- 6 files changed, 379 insertions(+), 29 deletions(-) create mode 100644 packages/nc-gui/assets/nc-icons/eye-off.svg create mode 100644 packages/nc-gui/components/smartsheet/form/LimitOptions.vue diff --git a/packages/nc-gui/assets/nc-icons/eye-off.svg b/packages/nc-gui/assets/nc-icons/eye-off.svg new file mode 100644 index 0000000000..196a4ed3a0 --- /dev/null +++ b/packages/nc-gui/assets/nc-icons/eye-off.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/packages/nc-gui/assets/nc-icons/eye.svg b/packages/nc-gui/assets/nc-icons/eye.svg index 3e19595fa4..597b5e291f 100644 --- a/packages/nc-gui/assets/nc-icons/eye.svg +++ b/packages/nc-gui/assets/nc-icons/eye.svg @@ -1,4 +1,8 @@ - - - + + + \ No newline at end of file diff --git a/packages/nc-gui/components/cell/User.vue b/packages/nc-gui/components/cell/User.vue index 244a5f21e6..effaa9228c 100644 --- a/packages/nc-gui/components/cell/User.vue +++ b/packages/nc-gui/components/cell/User.vue @@ -26,6 +26,12 @@ 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 @@ -78,16 +84,57 @@ const searchVal = ref() 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) ?? {} + const collaborators: UserFieldRecordType[] = [] - collaborators.push( - ...(baseUsers.value?.map((user: any) => ({ - id: user.id, - email: user.email, - display_name: user.display_name, - deleted: user.deleted, - })) || []), - ) + if ( + !isEditColumn.value && + isForm.value && + parseProp(column.value.meta)?.isLimitOption && + (parseProp(column.value.meta)?.limitOptions || []).length + ) { + collaborators.push( + ...( + baseUsers.value + .filter((user) => { + if (limitOptionsById[user.id]?.show !== undefined) { + return limitOptionsById[user.id]?.show + } + return false + }) + ?.map((user: any) => ({ + id: user.id, + email: user.email, + display_name: user.display_name, + deleted: user.deleted, + order: user.id && limitOptionsById[user.id] ? limitOptionsById[user.id]?.order ?? user.order : order++, + })) || [] + ).sort((a, b) => a.order - b.order), + ) + } else { + collaborators.push( + ...( + baseUsers.value?.map((user: any) => ({ + id: user.id, + email: user.email, + display_name: user.display_name, + deleted: user.deleted, + order: order++, + })) || [] + ).sort((a, b) => a.order - b.order), + ) + } return collaborators }) diff --git a/packages/nc-gui/components/smartsheet/Form.vue b/packages/nc-gui/components/smartsheet/Form.vue index 63f8ad8d94..5870f16d3c 100644 --- a/packages/nc-gui/components/smartsheet/Form.vue +++ b/packages/nc-gui/components/smartsheet/Form.vue @@ -160,9 +160,7 @@ const imageCropperData = ref<{ cropFor: 'banner', }) -const focusLabel: VNodeRef = (el) => { - return (el as HTMLInputElement)?.focus() -} +const focusLabel = ref() const searchQuery = ref('') @@ -514,7 +512,15 @@ const handleOnUploadImage = (data: Record = {}) => { updateView() } -onClickOutside(draggableRef, () => { +onClickOutside(draggableRef, (e) => { + if ( + (e.target as HTMLElement)?.closest( + '.nc-dropdown-single-select-cell, .nc-dropdown-multi-select-cell, .nc-dropdown-user-select-cell', + ) + ) { + return + } + activeRow.value = '' isTabPressed.value = false }) @@ -570,6 +576,12 @@ watch(activeRow, (newValue) => { } }) +watch([focusLabel, activeRow], () => { + if (activeRow && focusLabel.value) { + focusLabel.value?.focus() + } +}) + useEventListener( formRef, 'focusout', @@ -991,7 +1003,7 @@ useEventListener( +
+ {{ $t('labels.clearSelection') }} +
- +
- From 1adbfd5477f034eba627ba6d39609eadbbdc524d Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Tue, 27 Feb 2024 12:39:22 +0000 Subject: [PATCH 17/18] fix(nc-gui): form search limit option issue --- packages/nc-gui/components/cell/SingleSelect.vue | 2 +- packages/nc-gui/components/cell/User.vue | 6 +++++- packages/nc-gui/components/smartsheet/Form.vue | 4 ++-- .../nc-gui/components/smartsheet/form/LimitOptions.vue | 10 +++++++--- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/nc-gui/components/cell/SingleSelect.vue b/packages/nc-gui/components/cell/SingleSelect.vue index 4d91f1dd9a..414134298e 100644 --- a/packages/nc-gui/components/cell/SingleSelect.vue +++ b/packages/nc-gui/components/cell/SingleSelect.vue @@ -351,7 +351,7 @@ const onFocus = () => { -
+
{{ $t('labels.clearSelection') }}
diff --git a/packages/nc-gui/components/cell/User.vue b/packages/nc-gui/components/cell/User.vue index 62fef82ce3..3331110136 100644 --- a/packages/nc-gui/components/cell/User.vue +++ b/packages/nc-gui/components/cell/User.vue @@ -377,7 +377,11 @@ const filterOption = (input: string, option: any) => { -
+
{{ $t('labels.clearSelection') }}
diff --git a/packages/nc-gui/components/smartsheet/Form.vue b/packages/nc-gui/components/smartsheet/Form.vue index 8234c0b7d5..716e3c1f42 100644 --- a/packages/nc-gui/components/smartsheet/Form.vue +++ b/packages/nc-gui/components/smartsheet/Form.vue @@ -1139,7 +1139,7 @@ useEventListener(
-
+
{{ $t('labels.limitOptions') }}
-
+
{{ $t('labels.limitOptionsSubtext') }}.