Browse Source

refactor(gui-v2): tab level sort state

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/3370/head
Pranav C 2 years ago
parent
commit
be70b540a5
  1. 4
      packages/nc-gui/components/smartsheet/toolbar/ColumnFilterMenu.vue
  2. 45
      packages/nc-gui/components/tabs/Smartsheet.vue
  3. 5
      packages/nc-gui/composables/useTabs.ts
  4. 12
      packages/nc-gui/composables/useViewFilters.ts
  5. 17
      packages/nc-gui/composables/useViewSorts.ts

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

@ -29,8 +29,8 @@ const { $e } = useNuxtApp()
const { nestedFilters } = useSmartsheetStoreOrThrow() const { nestedFilters } = useSmartsheetStoreOrThrow()
// todo: avoid duplicate api call by keeping a filter store // todo: avoid duplicate api call by keeping a filter store
const { nonDeletedFilters, loadFilters } = useViewFilters( const { activeView, nonDeletedFilters, loadFilters } = useViewFilters(
activeView, activeView!,
undefined, undefined,
computed(() => true), computed(() => true),
() => false, () => false,

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

@ -1,7 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { ColumnType, TableType, ViewType } from 'nocodb-sdk' import type { ColumnType, TableType } from 'nocodb-sdk'
import type { Ref } from 'vue'
import { useUIPermission } from '#imports'
import SmartsheetGrid from '../smartsheet/Grid.vue' import SmartsheetGrid from '../smartsheet/Grid.vue'
import { import {
ActiveViewInj, ActiveViewInj,
@ -21,6 +19,8 @@ import {
useMetas, useMetas,
useProvideKanbanViewStore, useProvideKanbanViewStore,
useProvideSmartsheetStore, useProvideSmartsheetStore,
useUIPermission,
watch,
} from '#imports' } from '#imports'
import type { TabItem } from '~/lib' import type { TabItem } from '~/lib'
@ -44,43 +44,10 @@ const { isGallery, isGrid, isForm, isKanban, isLocked, nestedFilters, sorts } =
const openNewRecordFormHook = createEventHook() const openNewRecordFormHook = createEventHook()
const reloadViewMetaEventHook = createEventHook() const reloadEventHook = createEventHook<void | boolean>()
const openNewRecordFormHook = createEventHook<void>()
useProvideKanbanViewStore(meta, activeView) const { isGallery, isGrid, isForm, isLocked } = useProvideSmartsheetStore(activeView, meta)
const { isUIAllowed } = useUIPermission()
/** keep view level state in tabMeta and restore on view change */
watch(nestedFilters, (newFilters) => {
activeTab.value.state = activeTab.value.state || new Map()
if (!activeTab.value.state.has(activeView.value.id)) {
activeTab.value.state.set(activeView.value.id, new Map())
}
activeTab.value.state.get(activeView.value.id)!.set('filters', newFilters)
})
watch(sorts, (newSorts) => {
activeTab.value.state = activeTab.value.state || new Map()
if (!activeTab.value.state.has(activeView.value.id)) {
activeTab.value.state.set(activeView.value.id, new Map())
}
activeTab.value.state.get(activeView.value.id)!.set('sorts', newSorts)
})
watch(activeView, (newView: ViewType) => {
if(!newView || !activeTab.value?.state?.get(newView.id as string)) return
if (
activeTab.value?.state?.get(newView.id as string)?.has('filters') &&
!isUIAllowed('filterSync') &&
!isUIAllowed('filterChildrenRead')
) {
nestedFilters.value = activeTab.value?.state?.get(newView.id as string)?.get('filters') || []
}
if (activeTab.value?.state?.get(newView.id as string)?.has('sorts') && !isUIAllowed('sortSync')) {
nestedFilters.value = activeTab.value?.state?.get(newView.id as string)?.get('sorts') || []
}
})
// todo: move to store // todo: move to store
provide(MetaInj, meta) provide(MetaInj, meta)

5
packages/nc-gui/composables/useTabs.ts

@ -38,7 +38,8 @@ const [setup, use] = useInjectionState(() => {
let index = tabs.value.findIndex((t) => t.id === tab.id) let index = tabs.value.findIndex((t) => t.id === tab.id)
if (index === -1) { if (index === -1) {
tab.state = tab.state || new Map() tab.sortsState = tab.sortsState || new Map()
tab.filterState = tab.filterState || new Map()
tabs.value.push(tab) tabs.value.push(tab)
index = tabs.value.length - 1 index = tabs.value.length - 1
} }
@ -71,6 +72,8 @@ const [setup, use] = useInjectionState(() => {
const activeTab = computed(() => tabs.value?.[activeTabIndex.value]) const activeTab = computed(() => tabs.value?.[activeTabIndex.value])
const addTab = (tabMeta: TabItem) => { const addTab = (tabMeta: TabItem) => {
tabMeta.sortsState = tabMeta.sortsState || new Map()
tabMeta.filterState = tabMeta.filterState || new Map()
const tabIndex = tabs.value.findIndex((tab) => tab.id === tabMeta.id) const tabIndex = tabs.value.findIndex((tab) => tab.id === tabMeta.id)
// if tab already found make it active // if tab already found make it active
if (tabIndex > -1) { if (tabIndex > -1) {

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

@ -13,6 +13,8 @@ import {
useUIPermission, useUIPermission,
watch, watch,
} from '#imports' } from '#imports'
import type { TabItem } from '~/composables/useTabs'
import { TabMetaInj } from '~/context'
import type { Filter } from '~/lib' import type { Filter } from '~/lib'
export function useViewFilters( export function useViewFilters(
@ -39,6 +41,8 @@ export function useViewFilters(
const nestedMode = computed(() => isPublic.value || !isUIAllowed('filte rSync') || !isUIAllowed('filterChildrenRead')) const nestedMode = computed(() => isPublic.value || !isUIAllowed('filte rSync') || !isUIAllowed('filterChildrenRead'))
const tabMeta = inject(TabMetaInj, ref({ filterState: new Map() } as TabItem))
const filters = computed<Filter[]>({ const filters = computed<Filter[]>({
get: () => (nestedMode.value ? currentFilters! : _filters.value), get: () => (nestedMode.value ? currentFilters! : _filters.value),
set: (value: Filter[]) => { set: (value: Filter[]) => {
@ -47,6 +51,9 @@ export function useViewFilters(
if (isNestedRoot) nestedFilters.value = value if (isNestedRoot) nestedFilters.value = value
nestedFilters.value = [...nestedFilters.value] nestedFilters.value = [...nestedFilters.value]
tabMeta.value.filterState!.set(view!.value.id!, nestedFilters.value)
reloadHook?.trigger()
return return
} }
@ -66,7 +73,10 @@ export function useViewFilters(
} }
const loadFilters = async (hookId?: string) => { const loadFilters = async (hookId?: string) => {
if (nestedMode.value) return if (nestedMode.value) {
filters.value = tabMeta.value.filterState!.get(view.value.id!) || []
return
}
try { try {
if (hookId) { if (hookId) {

17
packages/nc-gui/composables/useViewSorts.ts

@ -1,4 +1,5 @@
import type { SortType, ViewType } from 'nocodb-sdk' import { ViewType } from 'nocodb-sdk'
import type { GalleryType, GridType, KanbanType, SortType } from 'nocodb-sdk'
import type { Ref } from 'vue' import type { Ref } from 'vue'
import { import {
IsPublicInj, IsPublicInj,
@ -29,6 +30,8 @@ export function useViewSorts(view: Ref<ViewType | undefined>, reloadData?: () =>
const isPublic = inject(IsPublicInj, ref(false)) const isPublic = inject(IsPublicInj, ref(false))
const tabMeta = inject(TabMetaInj, ref({ sortsState: new Map() } as TabItem))
const loadSorts = async () => { const loadSorts = async () => {
if (isPublic.value) { if (isPublic.value) {
// todo: sorts missing on `ViewType` // todo: sorts missing on `ViewType`
@ -38,6 +41,13 @@ export function useViewSorts(view: Ref<ViewType | undefined>, reloadData?: () =>
} }
try { try {
if (!isUIAllowed('sortSync')) {
const sortsBackup = tabMeta.value.sortsState.get(view.value.id!)
if (sortsBackup) {
sorts.value = sortsBackup
return
}
}
if (!view?.value) return if (!view?.value) return
sorts.value = (await $api.dbTableSort.list(view.value!.id!)).sorts?.list || [] sorts.value = (await $api.dbTableSort.list(view.value!.id!)).sorts?.list || []
} catch (e: any) { } catch (e: any) {
@ -51,6 +61,7 @@ export function useViewSorts(view: Ref<ViewType | undefined>, reloadData?: () =>
sorts.value[i] = sort sorts.value[i] = sort
sorts.value = [...sorts.value] sorts.value = [...sorts.value]
reloadHook?.trigger() reloadHook?.trigger()
tabMeta.value.sortsState.set(view.value.id!, sorts.value)
return return
} }
@ -79,6 +90,8 @@ export function useViewSorts(view: Ref<ViewType | undefined>, reloadData?: () =>
] ]
$e('a:sort:add', { length: sorts?.value?.length }) $e('a:sort:add', { length: sorts?.value?.length })
tabMeta.value.sortsState.set(view.value.id!, sorts.value)
} }
const deleteSort = async (sort: SortType, i: number) => { const deleteSort = async (sort: SortType, i: number) => {
@ -89,6 +102,8 @@ export function useViewSorts(view: Ref<ViewType | undefined>, reloadData?: () =>
sorts.value.splice(i, 1) sorts.value.splice(i, 1)
sorts.value = [...sorts.value] sorts.value = [...sorts.value]
tabMeta.value.sortsState.set(view.value.id!, sorts.value)
reloadHook?.trigger() reloadHook?.trigger()
$e('a:sort:delete') $e('a:sort:delete')
} catch (e: any) { } catch (e: any) {

Loading…
Cancel
Save