Browse Source

fix: Added auto scrolling/auto hiding of create view btn in sidebar

pull/6802/head
Muhammed Mustafa 10 months ago
parent
commit
a1e06f1074
  1. 10
      packages/nc-gui/components/dashboard/Sidebar.vue
  2. 12
      packages/nc-gui/components/dashboard/TreeView/ProjectNode.vue
  3. 9
      packages/nc-gui/components/dashboard/TreeView/TableList.vue
  4. 21
      packages/nc-gui/components/dashboard/TreeView/TableNode.vue
  5. 71
      packages/nc-gui/components/dashboard/TreeView/ViewsList.vue
  6. 10
      packages/nc-gui/components/dashboard/TreeView/index.vue

10
packages/nc-gui/components/dashboard/Sidebar.vue

@ -31,6 +31,14 @@ onMounted(() => {
onUnmounted(() => {
treeViewDom.value?.removeEventListener('scroll', checkScrollTopMoreThanZero)
})
const onOpenTable = (scrollDown: boolean) => {
if (scrollDown && treeViewDom.value && !isMobileMode.value) {
nextTick(() => {
treeViewDom.value!.scrollTop = treeViewDom.value!.scrollTop - 8
})
}
}
</script>
<template>
@ -54,7 +62,7 @@ onUnmounted(() => {
'pt-0.25': isSharedBase,
}"
>
<DashboardTreeView v-if="!isWorkspaceLoading" />
<DashboardTreeView v-if="!isWorkspaceLoading" @open-table="onOpenTable" />
</div>
<div v-if="!isSharedBase">
<DashboardSidebarUserInfo />

12
packages/nc-gui/components/dashboard/TreeView/ProjectNode.vue

@ -35,6 +35,10 @@ import {
import type { NcProject } from '#imports'
import { useNuxtApp } from '#app'
const emit = defineEmits<{
(event: 'openTable', scrollDown: boolean): void
}>()
const indicator = h(LoadingOutlined, {
class: '!text-gray-400',
style: {
@ -361,6 +365,10 @@ const projectDelete = () => {
isProjectDeleteDialogVisible.value = true
$e('c:project:delete')
}
const onOpenTable = (scrollDown: boolean) => {
emit('openTable', scrollDown)
}
</script>
<template>
@ -580,7 +588,7 @@ const projectDelete = () => {
<div class="flex-1 overflow-y-auto overflow-x-hidden flex flex-col" :class="{ 'mb-[20px]': isSharedBase }">
<div v-if="base?.sources?.[0]?.enabled" class="flex-1">
<div class="transition-height duration-200">
<DashboardTreeViewTableList :base="base" :source-index="0" />
<DashboardTreeViewTableList :base="base" :source-index="0" @open-table="onOpenTable" />
</div>
</div>
@ -694,7 +702,7 @@ const projectDelete = () => {
:key="`sortable-${source.id}-${source.id && source.id in keys ? keys[source.id] : '0'}`"
:nc-source="source.id"
>
<DashboardTreeViewTableList :base="base" :source-index="sourceIndex" />
<DashboardTreeViewTableList :base="base" :source-index="sourceIndex" @open-table="onOpenTable" />
</div>
</a-collapse-panel>
</a-collapse>

9
packages/nc-gui/components/dashboard/TreeView/TableList.vue

@ -16,6 +16,10 @@ const props = withDefaults(
},
)
const emit = defineEmits<{
(event: 'openTable', scrollDown: boolean): void
}>()
const base = toRef(props, 'base')
const sourceIndex = toRef(props, 'sourceIndex')
@ -127,6 +131,10 @@ watchEffect(() => {
const availableTables = computed(() => {
return tables.value.filter((table) => table.source_id === base.value?.sources?.[sourceIndex.value].id)
})
const onOpenTable = (scrollDown: boolean) => {
emit('openTable', scrollDown)
}
</script>
<template>
@ -160,6 +168,7 @@ const availableTables = computed(() => {
:data-title="table.title"
:data-source-id="source?.id"
:data-type="table.type"
@open-table="onOpenTable"
>
</TableNode>
</div>

21
packages/nc-gui/components/dashboard/TreeView/TableNode.vue

@ -16,6 +16,10 @@ const props = withDefaults(
{ sourceIndex: 0 },
)
const emit = defineEmits<{
(event: 'openTable', scrollDown: boolean): void
}>()
const base = toRef(props, 'base')
const table = toRef(props, 'table')
const sourceIndex = toRef(props, 'sourceIndex')
@ -48,8 +52,12 @@ const { loadViews: _loadViews } = useViewsStore()
const { activeView } = storeToRefs(useViewsStore())
const { isLeftSidebarOpen } = storeToRefs(useSidebarStore())
const { viewsByTable } = storeToRefs(useViewsStore())
const views = computed(() => viewsByTable.value.get(table.value.id!)?.filter((v) => !v.is_default) ?? [])
// todo: temp
const { baseTables } = storeToRefs(useTablesStore())
const { baseTables, activeTableId } = storeToRefs(useTablesStore())
const tables = computed(() => baseTables.value.get(base.value.id!) ?? [])
const openedTableId = computed(() => route.params.viewId)
@ -113,6 +121,8 @@ const onOpenTable = async () => {
if (isMobileMode.value) {
isLeftSidebarOpen.value = false
}
emit('openTable', true)
} catch (e) {
message.error(await extractSdkResponseErrorMsg(e))
} finally {
@ -138,6 +148,12 @@ watch(
const isTableOpened = computed(() => {
return openedTableId.value === table.value?.id && activeView.value?.is_default
})
watch(activeTableId, () => {
if (activeTableId.value !== table.value.id && views.value.length === 0) {
isExpanded.value = false
}
})
</script>
<template>
@ -169,7 +185,6 @@ const isTableOpened = computed(() => {
>
<div class="flex flex-row h-full items-center">
<NcButton
v-if="(table.meta as any)?.hasNonDefaultViews"
v-e="['c:table:toggle-expand']"
type="text"
size="xxsmall"
@ -182,7 +197,7 @@ const isTableOpened = computed(() => {
:class="{ '!rotate-180': isExpanded }"
/>
</NcButton>
<div v-else class="sm:min-w-5.75 xs:min-w-7.5 h-2"></div>
<!-- <div v-else class="sm:min-w-5.75 xs:min-w-7.5 h-2"></div> -->
<div class="flex w-auto" :data-testid="`tree-view-table-draggable-handle-${table.title}`">
<div
class="flex items-center nc-table-icon"

71
packages/nc-gui/components/dashboard/TreeView/ViewsList.vue

@ -5,6 +5,7 @@ import type { SortableEvent } from 'sortablejs'
import Sortable from 'sortablejs'
import type { Menu as AntMenu } from 'ant-design-vue'
import {
isDefaultBase as _isDefaultBase,
extractSdkResponseErrorMsg,
message,
onMounted,
@ -32,6 +33,10 @@ const table = inject(SidebarTableInj)!
const { isLeftSidebarOpen } = storeToRefs(useSidebarStore())
const { activeTableId } = storeToRefs(useTablesStore())
const { isUIAllowed } = useRoles()
const { isMobileMode } = useGlobal()
const { $e } = useNuxtApp()
@ -77,6 +82,13 @@ function markItem(id: string) {
}, 300)
}
const isDefaultSource = computed(() => {
const source = base.value?.sources?.find((b) => b.id === table.value.source_id)
if (!source) return false
return _isDefaultBase(source)
})
/** validate view title */
function validate(view: ViewType) {
if (!view.title || view.title.trim().length < 0) {
@ -367,31 +379,54 @@ function onOpenModal({
<template>
<a-menu
v-if="views.length"
ref="menuRef"
:class="{ dragging }"
class="nc-views-menu flex flex-col w-full !border-r-0 !bg-inherit"
:selected-keys="selected"
>
<DashboardTreeViewViewsNode
v-for="view of views"
:id="view.id"
:key="view.id"
:view="view"
:on-validate="validate"
class="nc-view-item !rounded-md !px-0.75 !py-0.5 w-full transition-all ease-in duration-100"
<DashboardTreeViewCreateViewBtn
v-if="isUIAllowed('viewCreateOrEdit')"
:class="{
'bg-gray-200': isMarked === view.id,
'active': activeView?.id === view.id,
[`nc-${view.type ? viewTypeAlias[view.type] : undefined || view.type}-view-item`]: true,
'hidden': activeTableId !== table.id && views.length,
'!ml-18 !xs:(ml-19.75)': isDefaultSource,
'!ml-23.5 !xs:(ml-27)': !isDefaultSource,
}"
:data-view-id="view.id"
@change-view="changeView"
@open-modal="onOpenModal"
@delete="openDeleteDialog"
@rename="onRename"
@select-icon="setIcon($event, view)"
/>
>
<div class="flex flex-row items-center hover:text-brand-500 text-gray-500 cursor-pointer rounded-md">
<div class="flex flex-row items-center pl-1.25 !py-1.5 text-inherit">
<GeneralIcon icon="plus" />
<div class="pl-1.75">
{{
$t('general.createEntity', {
entity: $t('objects.view'),
})
}}
</div>
</div>
</div>
</DashboardTreeViewCreateViewBtn>
<template v-if="views.length">
<DashboardTreeViewViewsNode
v-for="view of views"
:id="view.id"
:key="view.id"
:view="view"
:on-validate="validate"
class="nc-view-item !rounded-md !px-0.75 !py-0.5 w-full transition-all ease-in duration-100"
:class="{
'bg-gray-200': isMarked === view.id,
'active': activeView?.id === view.id,
[`nc-${view.type ? viewTypeAlias[view.type] : undefined || view.type}-view-item`]: true,
}"
:data-view-id="view.id"
@change-view="changeView"
@open-modal="onOpenModal"
@delete="openDeleteDialog"
@rename="onRename"
@select-icon="setIcon($event, view)"
/>
</template>
</a-menu>
</template>

10
packages/nc-gui/components/dashboard/TreeView/index.vue

@ -23,6 +23,10 @@ import {
import { useRouter } from '#app'
const emit = defineEmits<{
(event: 'openTable', scrollDown: boolean): void
}>()
const { isUIAllowed } = useRoles()
const { $e } = useNuxtApp()
@ -219,6 +223,10 @@ watch(
immediate: true,
},
)
const onOpenTable = (scrollDown: boolean) => {
emit('openTable', scrollDown)
}
</script>
<template>
@ -227,7 +235,7 @@ watch(
<div mode="inline" class="nc-treeview pb-0.5 flex-grow min-h-50 overflow-x-hidden">
<template v-if="basesList?.length">
<ProjectWrapper v-for="base of basesList" :key="base.id" :base-role="base.project_role" :base="base">
<DashboardTreeViewProjectNode />
<DashboardTreeViewProjectNode @open-table="onOpenTable" />
</ProjectWrapper>
</template>

Loading…
Cancel
Save