From 04f49c13d89d304228ff29f126b00650c0559ffd Mon Sep 17 00:00:00 2001 From: Anbarasu Date: Fri, 8 Nov 2024 11:38:47 +0530 Subject: [PATCH] feat: infinite scroll (#9403) * feat: infinite scroll wip * feat: implement column create * feat: improve scroll performance and minor bugs * fix: optimize cache clear fix: preserver selected items from cache clear * feat: add keyboard support * fix: get rid of unwanted data * feat: infinite scroll * fix: reload visible data * fix: rowIndex Sync * fix: row height fix * fix: performance issues * fix: small issues * fix: stablize scrolling * fix: scroll fails to load new data * fix: best part is no part remove bunch of manual handling and move to computedProperty * fix: load data as chunks instead of offset * fix: deboucne 500 ms * feat: safe chunk clearing * feat: working infinite table(wip) * fix: handle delete selected range of rows * fix: update types * fix: nuxt warnings * fix: table fixes * feat: undo-redo support for infiniteTable * fix: fix addEmptyRow * fix: groupby fixes * fix: refactor visibleDtaa computed * fix: cache clear * fix: invalid offset error * fix: add empty row elem * fix: rows not loading at end * fix: refactor * fix: more tests passing * fix: perf optimizations * fix: couple tests * fix: row height tests * fix: row height tests * fix: row height tests * fix: sync row comment count * fix: fixes * fix: lot of tests * fix: update the row placeholder columns size calculation * fix: update the totalRows on loadData * fix: tests when count is 0 * fix: hide placeholder if rowHeight is small * fix: not required imo as infinite scroll is implemented * fix: links tests * fix: filter tests * fix: insert after test fix: Row: Create, Update, Delete fix: Row height fix: Create column tests * fix: error, timezone bug fix: shared view data not loading after 100 * fix: ignore shifting. this fixes errors in rows, which has some mandatory required cells * fix: keyboardShortcuts test * fix: project collaboration test * fix: increase local cache fix: records empty on switching to full screen mode fix: links issue on new records * fix: row and col margin for improved data rendering * fix: addEmptyRow to table bottom * fix: update gridShare test fix: shared view grid feat: new count endpoint public * fix: undo-redo test failing * fix: bulkUpdate chore: disabled bulkUpdate tests for now * fix: slow searchBtn * fix: limit max selection * fix: limit selection to 100 * fix: initial chunk load to 100 * fix: couple fixes * fix: couple fixes * fix: row expand * fix: scrollto Top and scrollTo Bottom on Shift Cmd Down/Up * fix: drop support for cmd A * fix: failing tests * fix: error on clicking resize col * fix: premature fetching * fix: deleteSelected not working properly * fix: test build * fix: test build * fix: throttled 500 * fix: scroll related issues fix: added transitions * fix: scroll related issues * fix: decrease col margin * fix: increase local cache and update Buffer * fix: decrease throttle * fix: improve scroll performance * fix: improve scroll performance * fix: improve scroll performance * fix: fixes * feat: beta toggle show * feat: beta toggle show * fix: hold scroll action * fix: sync visible data reloadVisibleDataHook * fix: refactor useBetaFeatureToggle fix: useMultiSelect in table * fix: dynamically reduce margin while loading records * fix: some bugs * fix: data loading in infinitescroll * fix: shared view and search issues * feat: betaToggles menu * fix: scroll showing up in aggregation * fix: text * fix: implement shifting in addEmptyRow * fix: calculate slices on rowHeight modified * fix: keep invalid cells until another row selected * fix: remove row if filter gets failed * fix: update styles * fix: move filter handling to nocodb-sdk * fix: user field filter * fix: sort order * fix:user field sorting * fix: update virtual cols * fix: updated sort handling * fix: updated sort handling * fix: updated sort handling for bulkUpdate and undo-redo * fix: unit tests * fix: deleteSelectedRecords fails * fix: chunkstates errors * fix: sort bugs * fix: scroll position * fix: delete selectedrange of records * fix: improved chunk management * fix: sync toggle states across tabs * fix: sync between tabs * fix: limit issues * fix: update issues * fix: zIndex * fix: minor fixes * fix: cmd arrow issue * fix: bulkdelete index issues * fix: empty rows at top * fix: queue add new record behaviour * fix: resolve rowObj addEmptyRow * fix: typo * fix: clear indexes * fix: reload if width is zero * fix: manual handling * fix: remove console * fix: prefetch when scroll from below * fix: refactor fixes * fix:undo-redo with sort --------- Co-authored-by: mertmit --- packages/nc-gui/assets/nc-icons/bulb.svg | 8 + .../dashboard/FeatureExperimentation.vue | 110 + .../components/dashboard/Sidebar/UserInfo.vue | 12 + .../nc-gui/components/smartsheet/Topbar.vue | 5 +- .../smartsheet/column/EditOrAdd.vue | 6 +- .../smartsheet/form/field-settings.vue | 4 +- .../smartsheet/grid/InfiniteTable.vue | 2848 +++++++++++++++++ .../smartsheet/grid/PaginationV2.vue | 60 +- .../components/smartsheet/grid/Table.vue | 39 +- .../components/smartsheet/grid/index.vue | 128 +- .../composables/useBetaFeatureToggle.ts | 129 +- packages/nc-gui/composables/useExtensions.ts | 18 +- .../nc-gui/composables/useGridViewData.ts | 303 ++ .../nc-gui/composables/useInfiniteData.ts | 1371 ++++++++ .../composables/useMultiSelect/index.ts | 497 ++- packages/nc-gui/composables/useSharedView.ts | 28 +- packages/nc-gui/composables/useViewData.ts | 1 + packages/nc-gui/context/index.ts | 1 + packages/nc-gui/lang/en.json | 2 + packages/nc-gui/lib/types.ts | 7 +- packages/nc-gui/utils/dataUtils.ts | 286 +- packages/nc-gui/utils/iconUtils.ts | 2 + packages/nc-gui/utils/sortUtils.ts | 185 +- packages/nocodb-sdk/src/lib/errorUtils.ts | 7 + packages/nocodb-sdk/src/lib/filterHelpers.ts | 320 ++ packages/nocodb-sdk/src/lib/index.ts | 2 + .../controllers/public-datas.controller.ts | 14 + packages/nocodb/src/db/BaseModelSqlv2.ts | 202 +- packages/nocodb/src/db/conditionV2.ts | 5 +- .../global-exception.filter.ts | 14 +- packages/nocodb/src/models/Filter.ts | 8 +- packages/nocodb/src/schema/swagger.json | 75 + .../src/services/public-datas.service.ts | 49 + packages/nocodb/src/utils/globals.ts | 62 - .../pages/Dashboard/Grid/Column/index.ts | 8 +- .../playwright/pages/Dashboard/Grid/index.ts | 34 +- .../Dashboard/common/Toolbar/SearchData.ts | 2 +- tests/playwright/quickTests/commonTest.ts | 7 - .../db/columns/columnMenuOperations.spec.ts | 7 +- .../db/features/keyboardShortcuts.spec.ts | 89 +- .../tests/db/features/undo-redo.spec.ts | 5 +- .../db/general/tableColumnOperation.spec.ts | 8 +- .../tests/db/views/viewGridShare.spec.ts | 9 +- 43 files changed, 6317 insertions(+), 660 deletions(-) create mode 100644 packages/nc-gui/assets/nc-icons/bulb.svg create mode 100644 packages/nc-gui/components/dashboard/FeatureExperimentation.vue create mode 100644 packages/nc-gui/components/smartsheet/grid/InfiniteTable.vue create mode 100644 packages/nc-gui/composables/useGridViewData.ts create mode 100644 packages/nc-gui/composables/useInfiniteData.ts create mode 100644 packages/nocodb-sdk/src/lib/errorUtils.ts create mode 100644 packages/nocodb-sdk/src/lib/filterHelpers.ts diff --git a/packages/nc-gui/assets/nc-icons/bulb.svg b/packages/nc-gui/assets/nc-icons/bulb.svg new file mode 100644 index 0000000000..47ed29da94 --- /dev/null +++ b/packages/nc-gui/assets/nc-icons/bulb.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/nc-gui/components/dashboard/FeatureExperimentation.vue b/packages/nc-gui/components/dashboard/FeatureExperimentation.vue new file mode 100644 index 0000000000..0e01c1c794 --- /dev/null +++ b/packages/nc-gui/components/dashboard/FeatureExperimentation.vue @@ -0,0 +1,110 @@ + + + diff --git a/packages/nc-gui/components/dashboard/Sidebar/UserInfo.vue b/packages/nc-gui/components/dashboard/Sidebar/UserInfo.vue index b910689230..1e628e1c13 100644 --- a/packages/nc-gui/components/dashboard/Sidebar/UserInfo.vue +++ b/packages/nc-gui/components/dashboard/Sidebar/UserInfo.vue @@ -52,6 +52,13 @@ onMounted(() => { isMounted.value = true }) +const isExperimentalFeatureModalOpen = ref(false) + +const openExperimentationMenu = () => { + isMenuOpen.value = false + isExperimentalFeatureModalOpen.value = true +} + const accountUrl = computed(() => { return isUIAllowed('superAdminSetup') && !isEeUI ? '/account/setup' : '/account/profile' }) @@ -183,6 +190,10 @@ const accountUrl = computed(() => { + + + {{ $t('general.featurePreview') }} + {{ $t('title.accountSettings') }} @@ -191,6 +202,7 @@ const accountUrl = computed(() => { + diff --git a/packages/nc-gui/components/smartsheet/Topbar.vue b/packages/nc-gui/components/smartsheet/Topbar.vue index ff03528d40..9d8ccc739a 100644 --- a/packages/nc-gui/components/smartsheet/Topbar.vue +++ b/packages/nc-gui/components/smartsheet/Topbar.vue @@ -14,6 +14,8 @@ const { appInfo } = useGlobal() const { toggleExtensionPanel, isPanelExpanded, extensionsEgg, onEggClick } = useExtensions() +const { isFeatureEnabled } = useBetaFeatureToggle() + const isSharedBase = computed(() => route.value.params.typeOrId === 'base') const topbarBreadcrumbItemWidth = computed(() => { @@ -54,7 +56,7 @@ const topbarBreadcrumbItemWidth = computed(() => { { -
diff --git a/packages/nc-gui/components/smartsheet/column/EditOrAdd.vue b/packages/nc-gui/components/smartsheet/column/EditOrAdd.vue index ea08d77c20..2910a1ba0a 100644 --- a/packages/nc-gui/components/smartsheet/column/EditOrAdd.vue +++ b/packages/nc-gui/components/smartsheet/column/EditOrAdd.vue @@ -59,7 +59,7 @@ const { $e } = useNuxtApp() const { appInfo } = useGlobal() -const { betaFeatureToggleState } = useBetaFeatureToggle() +const { isFeatureEnabled } = useBetaFeatureToggle() const { openedViewsTab } = storeToRefs(useViewsStore()) @@ -122,7 +122,9 @@ const isColumnTypeOpen = ref(false) const geoDataToggleCondition = (t: { name: UITypes }) => { if (!appInfo.value.ee) return true - return betaFeatureToggleState.show ? betaFeatureToggleState.show : !t.name.includes(UITypes.GeoData) + const isColEnabled = isFeatureEnabled(FEATURE_FLAG.GEODATA_COLUMN) + + return isColEnabled || !t.name.includes(UITypes.GeoData) } const showDeprecated = ref(false) diff --git a/packages/nc-gui/components/smartsheet/form/field-settings.vue b/packages/nc-gui/components/smartsheet/form/field-settings.vue index de8441e703..285a36a583 100644 --- a/packages/nc-gui/components/smartsheet/form/field-settings.vue +++ b/packages/nc-gui/components/smartsheet/form/field-settings.vue @@ -3,7 +3,7 @@ import { UITypes, isSelectTypeCol } from 'nocodb-sdk' const { formState, activeField, updateColMeta, isRequired } = useFormViewStoreOrThrow() -const { betaFeatureToggleState } = useBetaFeatureToggle() +const { isFeatureEnabled } = useBetaFeatureToggle() const updateSelectFieldLayout = (value: boolean) => { if (!activeField.value) return @@ -13,7 +13,7 @@ const updateSelectFieldLayout = (value: boolean) => { } const columnSupportsScanning = (elementType: UITypes) => - betaFeatureToggleState.show && + isFeatureEnabled(FEATURE_FLAG.FORM_SUPPORT_COLUMN_SCANNING) && [UITypes.SingleLineText, UITypes.Number, UITypes.Email, UITypes.URL, UITypes.LongText].includes(elementType) diff --git a/packages/nc-gui/components/smartsheet/grid/InfiniteTable.vue b/packages/nc-gui/components/smartsheet/grid/InfiniteTable.vue new file mode 100644 index 0000000000..a17fa04c20 --- /dev/null +++ b/packages/nc-gui/components/smartsheet/grid/InfiniteTable.vue @@ -0,0 +1,2848 @@ + + + + + diff --git a/packages/nc-gui/components/smartsheet/grid/PaginationV2.vue b/packages/nc-gui/components/smartsheet/grid/PaginationV2.vue index f4cab5c0ac..0e5dc34685 100644 --- a/packages/nc-gui/components/smartsheet/grid/PaginationV2.vue +++ b/packages/nc-gui/components/smartsheet/grid/PaginationV2.vue @@ -4,11 +4,13 @@ import { type PaginatedType, UITypes } from 'nocodb-sdk' const props = defineProps<{ scrollLeft?: number - paginationData: PaginatedType - changePage: (page: number) => void + paginationData?: PaginatedType + changePage?: (page: number) => void showSizeChanger?: boolean customLabel?: string + totalRows?: number depth?: number + disablePagination?: boolean }>() const emits = defineEmits(['update:paginationData']) @@ -23,6 +25,8 @@ const showSizeChanger = toRef(props, 'showSizeChanger') const vPaginationData = useVModel(props, 'paginationData', emits) +const disablePagination = toRef(props, 'disablePagination') + const { updateAggregate, getAggregations, visibleFieldsComputed, displayFieldComputed } = useViewAggregateOrThrow() const scrollLeft = toRef(props, 'scrollLeft') @@ -46,6 +50,9 @@ const count = computed(() => vPaginationData.value?.totalRows ?? Infinity) const page = computed({ get: () => vPaginationData?.value?.page ?? 1, set: async (p) => { + if (disablePagination.value) { + return + } isPaginationLoading.value = true try { await changePage?.(p) @@ -118,21 +125,36 @@ const renderAltOrOptlKey = () => { }" >
-
- -
- - - - {{ Intl.NumberFormat('en', { notation: 'compact' }).format(count) }} - {{ customLabel ? customLabel : count !== 1 ? $t('objects.records') : $t('objects.record') }} - - + + +