Browse Source

Merge pull request #3370 from nocodb/feat/3261-tab-level-state

fix: tab level state
pull/4043/head
աɨռɢӄաօռɢ 2 years ago committed by GitHub
parent
commit
a0de3dc6bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      packages/nc-gui/components/cell/MultiSelect.vue
  2. 7
      packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue
  3. 2
      packages/nc-gui/components/smartsheet/toolbar/ColumnFilterMenu.vue
  4. 8
      packages/nc-gui/components/tabs/Smartsheet.vue
  5. 4
      packages/nc-gui/composables/useTabs.ts
  6. 28
      packages/nc-gui/composables/useViewFilters.ts
  7. 15
      packages/nc-gui/composables/useViewSorts.ts
  8. 2
      packages/nc-gui/lib/types.ts

3
packages/nc-gui/components/cell/MultiSelect.vue

@ -1,8 +1,7 @@
<script lang="ts" setup>
import tinycolor from 'tinycolor2'
import type { Select as AntSelect } from 'ant-design-vue'
import { SelectOptionType } from 'nocodb-sdk'
import type { SelectOptionsType } from 'nocodb-sdk'
import type { SelectOptionType, SelectOptionsType } from 'nocodb-sdk'
import {
ActiveCellInj,
ColumnInj,

7
packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue

@ -86,11 +86,13 @@ const types = computed(() => {
watch(
() => activeView.value?.id,
(n, o) => {
if (n !== o && (hookId || !webHook)) loadFilters(hookId as string)
// if nested no need to reload since it will get reloaded from parent
if (!nested && n !== o && (hookId || !webHook)) loadFilters(hookId as string)
},
{ immediate: true },
)
loadFilters(hookId as string)
watch(
() => nonDeletedFilters.value.length,
(length) => {
@ -153,6 +155,7 @@ defineExpose({
<div class="col-span-5">
<LazySmartsheetToolbarColumnFilter
v-if="filter.id || filter.children"
:key="filter.id ?? i"
ref="localNestedFilters"
v-model="filter.children"
:parent-id="filter.id"

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

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

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

@ -35,13 +35,13 @@ const fields = ref<ColumnType[]>([])
const meta = computed<TableType | undefined>(() => activeTab.value && metas.value[activeTab.value.id!])
const reloadEventHook = createEventHook()
const { isGallery, isGrid, isForm, isKanban, isLocked } = useProvideSmartsheetStore(activeView, meta)
const openNewRecordFormHook = createEventHook()
const reloadEventHook = createEventHook<void | boolean>()
const reloadViewMetaEventHook = createEventHook<void | boolean>()
const reloadViewMetaEventHook = createEventHook()
const openNewRecordFormHook = createEventHook<void>()
useProvideKanbanViewStore(meta, activeView)

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

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

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

@ -13,16 +13,19 @@ import {
useUIPermission,
watch,
} from '#imports'
import type { Filter } from '~/lib'
import { TabMetaInj } from '~/context'
import type { Filter, TabItem } from '~/lib'
export function useViewFilters(
view: Ref<ViewType | undefined>,
parentId?: string,
autoApply?: ComputedRef<boolean>,
reloadData?: () => void,
currentFilters?: Filter[],
_currentFilters?: Filter[],
isNestedRoot?: boolean,
) {
let currentFilters = $ref(_currentFilters)
const reloadHook = inject(ReloadViewDataHookInj)
const { nestedFilters } = useSmartsheetStoreOrThrow()
@ -37,16 +40,23 @@ export function useViewFilters(
const _filters = ref<Filter[]>([])
const nestedMode = computed(() => isPublic.value || !isUIAllowed('filterSync' || !isUIAllowed('filterChildrenRead')))
const nestedMode = computed(() => isPublic.value || !isUIAllowed('filte rSync') || !isUIAllowed('filterChildrenRead'))
const tabMeta = inject(TabMetaInj, ref({ filterState: new Map(), sortsState: new Map() } as TabItem))
const filters = computed<Filter[]>({
get: () => (nestedMode.value ? currentFilters! : _filters.value),
get: () => {
return nestedMode.value ? currentFilters! : _filters.value
},
set: (value: Filter[]) => {
if (nestedMode.value) {
currentFilters = value
if (isNestedRoot) nestedFilters.value = value
if (isNestedRoot) {
nestedFilters.value = value
tabMeta.value.filterState!.set(view.value!.id!, nestedFilters.value)
}
nestedFilters.value = [...nestedFilters.value]
reloadHook?.trigger()
return
}
@ -66,7 +76,11 @@ export function useViewFilters(
}
const loadFilters = async (hookId?: string) => {
if (nestedMode.value) return
if (nestedMode.value) {
// ignore restoring if not root filter group
if (isNestedRoot) filters.value = tabMeta.value.filterState!.get(view.value!.id!) || []
return
}
try {
if (hookId) {

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

@ -13,6 +13,7 @@ import {
useSmartsheetStoreOrThrow,
useUIPermission,
} from '#imports'
import type { TabItem } from '~/lib'
export function useViewSorts(view: Ref<ViewType | undefined>, reloadData?: () => void) {
const { sharedView } = useSharedView()
@ -29,6 +30,8 @@ export function useViewSorts(view: Ref<ViewType | undefined>, reloadData?: () =>
const isPublic = inject(IsPublicInj, ref(false))
const tabMeta = inject(TabMetaInj, ref({ sortsState: new Map() } as TabItem))
const loadSorts = async () => {
if (isPublic.value) {
// todo: sorts missing on `ViewType`
@ -38,6 +41,13 @@ export function useViewSorts(view: Ref<ViewType | undefined>, reloadData?: () =>
}
try {
if (!isUIAllowed('sortSync')) {
const sortsBackup = tabMeta.value.sortsState!.get(view.value!.id!)
if (sortsBackup) {
sorts.value = sortsBackup
return
}
}
if (!view?.value) return
sorts.value = (await $api.dbTableSort.list(view.value!.id!)).sorts?.list || []
} catch (e: any) {
@ -51,6 +61,7 @@ export function useViewSorts(view: Ref<ViewType | undefined>, reloadData?: () =>
sorts.value[i] = sort
sorts.value = [...sorts.value]
reloadHook?.trigger()
tabMeta.value.sortsState!.set(view.value!.id!, sorts.value)
return
}
@ -79,6 +90,8 @@ export function useViewSorts(view: Ref<ViewType | undefined>, reloadData?: () =>
]
$e('a:sort:add', { length: sorts?.value?.length })
tabMeta.value.sortsState!.set(view.value!.id!, sorts.value)
}
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 = [...sorts.value]
tabMeta.value.sortsState!.set(view.value!.id!, sorts.value)
reloadHook?.trigger()
$e('a:sort:delete')
} catch (e: any) {

2
packages/nc-gui/lib/types.ts

@ -69,6 +69,8 @@ export interface TabItem {
id?: string
viewTitle?: string
viewId?: string
sortsState?: Map<string, any>
filterState?: Map<string, any>
}
export interface SharedViewMeta extends Record<string, any> {

Loading…
Cancel
Save