Browse Source

refactor(gui-v2): fix right sidebar layout

# What's changed?

* teleport right sidebar and pull it up to header border bottom
* Show icons when toggling right sidebar
* Replace toggle icon
pull/2892/head
braks 2 years ago
parent
commit
d01c96a4d9
  1. 149
      packages/nc-gui-v2/components/dashboard/TabView.vue
  2. 9
      packages/nc-gui-v2/components/smartsheet-toolbar/ToggleDrawer.vue
  3. 23
      packages/nc-gui-v2/components/smartsheet/Toolbar.vue
  4. 2
      packages/nc-gui-v2/components/smartsheet/sidebar/MenuBottom.vue
  5. 2
      packages/nc-gui-v2/components/smartsheet/sidebar/MenuTop.vue
  6. 31
      packages/nc-gui-v2/components/smartsheet/sidebar/Toolbar.vue
  7. 18
      packages/nc-gui-v2/components/smartsheet/sidebar/index.vue
  8. 12
      packages/nc-gui-v2/components/tabs/Smartsheet.vue
  9. 193
      packages/nc-gui-v2/pages/nc/[projectId]/index/index.vue

149
packages/nc-gui-v2/components/dashboard/TabView.vue

@ -1,149 +0,0 @@
<script setup lang="ts">
import useTabs from '~/composables/useTabs'
import MdiPlusIcon from '~icons/mdi/plus'
import MdiTableIcon from '~icons/mdi/table'
import MdiCsvIcon from '~icons/mdi/file-document-outline'
import MdiExcelIcon from '~icons/mdi/file-excel'
import MdiJSONIcon from '~icons/mdi/code-json'
import MdiAirTableIcon from '~icons/mdi/table-large'
import MdiRequestDataSourceIcon from '~icons/mdi/open-in-new'
import MdiAccountGroupIcon from '~icons/mdi/account-group'
const { tabs, activeTab, closeTab } = useTabs()
const { isUIAllowed } = useUIPermission()
const tableCreateDialog = ref(false)
const airtableImportDialog = ref(false)
const quickImportDialog = ref(false)
const importType = ref('')
const currentMenu = ref<string[]>(['addORImport'])
function onEdit(targetKey: number, action: string) {
if (action !== 'add') {
closeTab(targetKey)
}
}
function openQuickImportDialog(type: string) {
quickImportDialog.value = true
importType.value = type
}
</script>
<template>
<div>
<a-tabs v-model:activeKey="activeTab" hide-add type="editable-card" :tab-position="top" @edit="onEdit">
<a-tab-pane v-for="(tab, i) in tabs" :key="i" :value="i" class="text-capitalize" :closable="true">
<template #tab>
<span class="flex items-center gap-2">
<MdiAccountGroupIcon v-if="tab.type === 'auth'" class="text-primary" />
<MdiTableIcon v-else class="text-primary" />
{{ tab.title }}
</span>
</template>
</a-tab-pane>
<template #leftExtra>
<a-menu v-model:selectedKeys="currentMenu" mode="horizontal">
<a-sub-menu key="addORImport">
<template #title>
<span class="flex items-center gap-2">
<MdiPlusIcon />
Add / Import
</span>
</template>
<a-menu-item-group v-if="isUIAllowed('addTable')">
<a-menu-item key="add-new-table" v-t="['a:actions:create-table']" @click="tableCreateDialog = true">
<span class="flex items-center gap-2">
<MdiTableIcon class="text-primary" />
<!-- Add new table -->
{{ $t('tooltip.addTable') }}
</span>
</a-menu-item>
</a-menu-item-group>
<a-menu-item-group title="QUICK IMPORT FROM">
<a-menu-item
v-if="isUIAllowed('airtableImport')"
key="quick-import-airtable"
v-t="['a:actions:import-airtable']"
@click="airtableImportDialog = true"
>
<span class="flex items-center gap-2">
<MdiAirTableIcon class="text-primary" />
<!-- TODO: i18n -->
Airtable
</span>
</a-menu-item>
<a-menu-item
v-if="isUIAllowed('csvImport')"
key="quick-import-csv"
v-t="['a:actions:import-csv']"
@click="openQuickImportDialog('csv')"
>
<span class="flex items-center gap-2">
<MdiCsvIcon class="text-primary" />
<!-- TODO: i18n -->
CSV file
</span>
</a-menu-item>
<a-menu-item
v-if="isUIAllowed('jsonImport')"
key="quick-import-json"
v-t="['a:actions:import-json']"
@click="openQuickImportDialog('json')"
>
<span class="flex items-center gap-2">
<MdiJSONIcon class="text-primary" />
<!-- TODO: i18n -->
JSON file
</span>
</a-menu-item>
<a-menu-item
v-if="isUIAllowed('excelImport')"
key="quick-import-excel"
v-t="['a:actions:import-excel']"
@click="openQuickImportDialog('excel')"
>
<span class="flex items-center gap-2">
<MdiExcelIcon class="text-primary" />
<!-- TODO: i18n -->
Microsoft Excel
</span>
</a-menu-item>
</a-menu-item-group>
<a-divider class="ma-0 mb-2" />
<a-menu-item
v-if="isUIAllowed('importRequest')"
key="add-new-table"
v-t="['e:datasource:import-request']"
class="ma-0 mt-3"
>
<a href="https://github.com/nocodb/nocodb/issues/2052" target="_blank" class="prose-sm pa-0">
<span class="flex items-center gap-2">
<MdiRequestDataSourceIcon class="text-primary" />
<!-- TODO: i18n -->
Request a data source you need?
</span>
</a>
</a-menu-item>
</a-sub-menu>
</a-menu>
</template>
</a-tabs>
<DlgTableCreate v-if="tableCreateDialog" v-model="tableCreateDialog" />
<DlgQuickImport v-if="quickImportDialog" v-model="quickImportDialog" :import-type="importType" />
<DlgAirtableImport v-if="airtableImportDialog" v-model="airtableImportDialog" />
<v-window v-model="activeTab">
<v-window-item v-for="(tab, i) in tabs" :key="i" :value="i">
<TabsAuth v-if="tab.type === 'auth'" :tab-meta="tab" />
<TabsSmartsheet v-else :tab-meta="tab" />
</v-window-item>
</v-window>
</div>
</template>
<style scoped lang="scss">
:deep(.ant-menu-item-group-list) .ant-menu-item {
@apply m-0 pa-0 pl-4 pr-16;
}
</style>

9
packages/nc-gui-v2/components/smartsheet-toolbar/ToggleDrawer.vue

@ -1,14 +1,15 @@
<script setup lang="ts">
import MdiDoorOpenIcon from '~icons/mdi/door-open'
import MdiDoorClosedIcon from '~icons/mdi/door-closed'
import MdiMenuClose from '~icons/mdi/menu-close'
const drawerOpen = inject('navDrawerOpen', ref(false))
const Icon = computed(() => (drawerOpen.value ? MdiDoorOpenIcon : MdiDoorClosedIcon))
</script>
<template>
<a-tooltip placement="left">
<template #title> {{ $t('tooltip.toggleNavDraw') }} </template>
<Icon class="rounded text-xl p-1 text-gray-500 hover:(text-white bg-pink-500 shadow)" @click="drawerOpen = !drawerOpen" />
<MdiMenuClose
class="rounded text-xl p-1 text-gray-500 hover:(text-white bg-pink-500 shadow)"
@click="drawerOpen = !drawerOpen"
/>
</a-tooltip>
</template>

23
packages/nc-gui-v2/components/smartsheet/Toolbar.vue

@ -15,26 +15,6 @@
<SmartsheetToolbarMoreActions />
<div class="flex-1" />
<SmartsheetToolbarLockMenu />
<div class="dot" />
<SmartsheetToolbarReload />
<div class="dot" />
<SmartsheetToolbarAddRow />
<div class="dot" />
<SmartsheetToolbarDeleteTable />
<div class="dot" />
<SmartsheetToolbarToggleDrawer class="mr-2" />
<div class="dot" />
</div>
</template>
@ -42,7 +22,4 @@
:deep(.nc-toolbar-btn) {
@apply border-0 !text-xs font-semibold px-2;
}
.dot {
@apply w-[3px] h-[3px] bg-gray-300 mx-1 rounded-full;
}
</style>

2
packages/nc-gui-v2/components/smartsheet/sidebar/MenuBottom.vue

@ -30,8 +30,6 @@ function onOpenModal(type: ViewTypes, title = '') {
<template>
<a-menu :selected-keys="[]" class="flex-1 flex flex-col">
<a-divider class="my-2" />
<h3 class="px-3 text-xs font-semibold flex items-center gap-4">
{{ $t('activity.createView') }}
<a-tooltip>

2
packages/nc-gui-v2/components/smartsheet/sidebar/MenuTop.vue

@ -194,7 +194,7 @@ function onDeleted() {
</script>
<template>
<h3 class="nc-headline pt-3 px-3 text-xs font-semibold">{{ $t('objects.views') }}</h3>
<h3 class="pt-2 px-3 text-xs font-semibold">{{ $t('objects.views') }}</h3>
<a-menu ref="menuRef" :class="{ dragging }" class="nc-views-menu" :selected-keys="selected">
<RenameableMenuItem

31
packages/nc-gui-v2/components/smartsheet/sidebar/Toolbar.vue

@ -0,0 +1,31 @@
<template>
<div class="flex gap-2">
<SmartsheetToolbarLockMenu />
<div class="dot" />
<SmartsheetToolbarReload />
<div class="dot" />
<SmartsheetToolbarAddRow />
<div class="dot" />
<SmartsheetToolbarDeleteTable />
<div class="dot" />
<SmartsheetToolbarToggleDrawer />
</div>
</template>
<style scoped>
:deep(.nc-toolbar-btn) {
@apply border-0 !text-xs font-semibold px-2;
}
.dot {
@apply w-[3px] h-[3px] bg-gray-300 rounded-full;
}
</style>

18
packages/nc-gui-v2/components/smartsheet/sidebar/index.vue

@ -2,6 +2,7 @@
import type { FormType, GalleryType, GridType, KanbanType, ViewTypes } from 'nocodb-sdk'
import MenuTop from './MenuTop.vue'
import MenuBottom from './MenuBottom.vue'
import Toolbar from './Toolbar.vue'
import { inject, provide, ref, useApi, useViews, watch } from '#imports'
import { ActiveViewInj, MetaInj, ViewListInj } from '~/context'
@ -16,7 +17,7 @@ const { api } = useApi()
provide(ViewListInj, views)
/** Sidebar visible */
const drawerOpen = inject('navDrawerOpen', ref(false))
const drawerOpen = inject('navDrawerOpen', ref(true))
/** View type to create from modal */
let viewCreateType = $ref<ViewTypes>()
@ -54,9 +55,16 @@ function onCreate(view: GridType | FormType | KanbanType | GalleryType) {
</script>
<template>
<a-layout-sider theme="light" class="shadow" :width="drawerOpen ? 0 : 250">
<div class="flex flex-col h-full">
<a-layout-sider class="shadow !mt-[-9px]" style="height: calc(100% + 9px)" theme="light" :width="drawerOpen ? 250 : 50">
<Toolbar v-if="drawerOpen" class="flex items-center py-3 px-3 justify-between border-b-1" />
<Toolbar v-else class="py-3 px-2 max-w-[50px] flex !flex-col-reverse gap-4 items-center mt-[-1px]" />
<div v-if="drawerOpen" class="flex-1 flex flex-col">
<MenuTop @open-modal="openModal" @deleted="loadViews" @sorted="loadViews" />
<a-divider class="my-2" />
<MenuBottom @open-modal="openModal" />
</div>
@ -68,4 +76,8 @@ function onCreate(view: GridType | FormType | KanbanType | GalleryType) {
:deep(.ant-menu-title-content) {
@apply w-full;
}
:deep(.ant-layout-sider-children) {
@apply flex flex-col;
}
</style>

12
packages/nc-gui-v2/components/tabs/Smartsheet.vue

@ -1,7 +1,7 @@
<script setup lang="ts">
import type { ColumnType, ViewType } from 'nocodb-sdk'
import { ViewTypes } from 'nocodb-sdk'
import { computed, inject, onMounted, provide, watch, watchEffect } from '#imports'
import { computed, inject, provide, watch, watchEffect } from '#imports'
import { ActiveViewInj, FieldsInj, IsLockedInj, MetaInj, ReloadViewDataHookInj, TabMetaInj } from '~/context'
import useMetas from '~/composables/useMetas'
@ -27,7 +27,7 @@ provide(ActiveViewInj, activeView)
provide(IsLockedInj, false)
provide(ReloadViewDataHookInj, reloadEventHook)
provide(FieldsInj, fields)
provide('navDrawerOpen', ref(false))
provide('navDrawerOpen', ref(true))
watch(
() => tabMeta && tabMeta?.id,
@ -41,15 +41,21 @@ watch(
<div class="nc-container flex h-full">
<div class="flex flex-col h-full flex-1 min-w-0">
<SmartsheetToolbar />
<template v-if="meta">
<div class="flex flex-1 min-h-0">
<div v-if="activeView" class="h-full flex-grow min-w-0 min-h-0">
<SmartsheetGrid v-if="activeView.type === ViewTypes.GRID" :ref="el" />
<SmartsheetGallery v-else-if="activeView.type === ViewTypes.GALLERY" />
<SmartsheetForm v-else-if="activeView.type === ViewTypes.FORM" />
</div>
<SmartsheetSidebar />
</div>
<teleport to="#sidebar-right">
<SmartsheetSidebar />
</teleport>
</template>
</div>
</div>

193
packages/nc-gui-v2/pages/nc/[projectId]/index/index.vue

@ -36,107 +36,111 @@ function openQuickImportDialog(type: string) {
</script>
<template>
<div class="nc-container flex flex-col">
<div>
<a-tabs v-model:activeKey="activeTabIndex" type="editable-card" @edit="closeTab">
<a-tab-pane v-for="(tab, i) in tabs" :key="i" :tab="tab.title" />
<div class="flex w-full h-full">
<div class="nc-container flex flex-col">
<div>
<a-tabs v-model:activeKey="activeTabIndex" type="editable-card" @edit="closeTab">
<a-tab-pane v-for="(tab, i) in tabs" :key="i" :tab="tab.title" />
<template #leftExtra>
<a-menu v-model:selectedKeys="currentMenu" class="border-0" mode="horizontal">
<a-sub-menu key="addORImport">
<template #title>
<div class="text-sm flex items-center gap-2">
<MdiPlusIcon />
Add / Import
</div>
</template>
<a-menu-item-group v-if="isUIAllowed('addTable')">
<a-menu-item key="add-new-table" v-t="['a:actions:create-table']" @click="tableCreateDialog = true">
<span class="flex items-center gap-2">
<MdiTableIcon class="text-primary" />
<!-- Add new table -->
{{ $t('tooltip.addTable') }}
</span>
</a-menu-item>
</a-menu-item-group>
<a-menu-item-group title="QUICK IMPORT FROM">
<a-menu-item
v-if="isUIAllowed('airtableImport')"
key="quick-import-airtable"
v-t="['a:actions:import-airtable']"
@click="airtableImportDialog = true"
>
<span class="flex items-center gap-2">
<MdiAirTableIcon class="text-primary" />
<!-- TODO: i18n -->
Airtable
</span>
</a-menu-item>
<a-menu-item
v-if="isUIAllowed('csvImport')"
key="quick-import-csv"
v-t="['a:actions:import-csv']"
@click="openQuickImportDialog('csv')"
>
<span class="flex items-center gap-2">
<MdiCsvIcon class="text-primary" />
<!-- TODO: i18n -->
CSV file
</span>
</a-menu-item>
<a-menu-item
v-if="isUIAllowed('jsonImport')"
key="quick-import-json"
v-t="['a:actions:import-json']"
@click="openQuickImportDialog('json')"
>
<span class="flex items-center gap-2">
<MdiJSONIcon class="text-primary" />
<!-- TODO: i18n -->
JSON file
</span>
</a-menu-item>
<template #leftExtra>
<a-menu v-model:selectedKeys="currentMenu" class="border-0" mode="horizontal">
<a-sub-menu key="addORImport">
<template #title>
<div class="text-sm flex items-center gap-2">
<MdiPlusIcon />
Add / Import
</div>
</template>
<a-menu-item-group v-if="isUIAllowed('addTable')">
<a-menu-item key="add-new-table" v-t="['a:actions:create-table']" @click="tableCreateDialog = true">
<span class="flex items-center gap-2">
<MdiTableIcon class="text-primary" />
<!-- Add new table -->
{{ $t('tooltip.addTable') }}
</span>
</a-menu-item>
</a-menu-item-group>
<a-menu-item-group title="QUICK IMPORT FROM">
<a-menu-item
v-if="isUIAllowed('airtableImport')"
key="quick-import-airtable"
v-t="['a:actions:import-airtable']"
@click="airtableImportDialog = true"
>
<span class="flex items-center gap-2">
<MdiAirTableIcon class="text-primary" />
<!-- TODO: i18n -->
Airtable
</span>
</a-menu-item>
<a-menu-item
v-if="isUIAllowed('csvImport')"
key="quick-import-csv"
v-t="['a:actions:import-csv']"
@click="openQuickImportDialog('csv')"
>
<span class="flex items-center gap-2">
<MdiCsvIcon class="text-primary" />
<!-- TODO: i18n -->
CSV file
</span>
</a-menu-item>
<a-menu-item
v-if="isUIAllowed('jsonImport')"
key="quick-import-json"
v-t="['a:actions:import-json']"
@click="openQuickImportDialog('json')"
>
<span class="flex items-center gap-2">
<MdiJSONIcon class="text-primary" />
<!-- TODO: i18n -->
JSON file
</span>
</a-menu-item>
<a-menu-item
v-if="isUIAllowed('excelImport')"
key="quick-import-excel"
v-t="['a:actions:import-excel']"
@click="openQuickImportDialog('excel')"
>
<span class="flex items-center gap-2">
<MdiExcelIcon class="text-primary" />
<!-- TODO: i18n -->
Microsoft Excel
</span>
</a-menu-item>
</a-menu-item-group>
<a-divider class="ma-0 mb-2" />
<a-menu-item
v-if="isUIAllowed('excelImport')"
key="quick-import-excel"
v-t="['a:actions:import-excel']"
@click="openQuickImportDialog('excel')"
v-if="isUIAllowed('importRequest')"
key="add-new-table"
v-t="['e:datasource:import-request']"
class="ma-0 mt-3"
>
<span class="flex items-center gap-2">
<MdiExcelIcon class="text-primary" />
<!-- TODO: i18n -->
Microsoft Excel
</span>
<a href="https://github.com/nocodb/nocodb/issues/2052" target="_blank" class="prose-sm pa-0">
<span class="flex items-center gap-2">
<MdiRequestDataSourceIcon class="text-primary" />
<!-- TODO: i18n -->
Request a data source you need?
</span>
</a>
</a-menu-item>
</a-menu-item-group>
<a-divider class="ma-0 mb-2" />
<a-menu-item
v-if="isUIAllowed('importRequest')"
key="add-new-table"
v-t="['e:datasource:import-request']"
class="ma-0 mt-3"
>
<a href="https://github.com/nocodb/nocodb/issues/2052" target="_blank" class="prose-sm pa-0">
<span class="flex items-center gap-2">
<MdiRequestDataSourceIcon class="text-primary" />
<!-- TODO: i18n -->
Request a data source you need?
</span>
</a>
</a-menu-item>
</a-sub-menu>
</a-menu>
</template>
</a-tabs>
</div>
</a-sub-menu>
</a-menu>
</template>
</a-tabs>
</div>
<div class="flex-1 min-h-0">
<NuxtPage />
</div>
<div class="flex-1 min-h-0">
<NuxtPage />
<DlgTableCreate v-if="tableCreateDialog" v-model="tableCreateDialog" />
<DlgQuickImport v-if="quickImportDialog" v-model="quickImportDialog" :import-type="importType" />
<DlgAirtableImport v-if="airtableImportDialog" v-model="airtableImportDialog" />
</div>
<DlgTableCreate v-if="tableCreateDialog" v-model="tableCreateDialog" />
<DlgQuickImport v-if="quickImportDialog" v-model="quickImportDialog" :import-type="importType" />
<DlgAirtableImport v-if="airtableImportDialog" v-model="airtableImportDialog" />
<div id="sidebar-right" class="h-full" />
</div>
</template>
@ -144,6 +148,7 @@ function openQuickImportDialog(type: string) {
.nc-container {
height: calc(100vh - var(--header-height) - 8px);
@apply overflow-hidden;
flex: 1 1 100%;
}
:deep(.ant-tabs-nav) {

Loading…
Cancel
Save