Browse Source

refactor(gui-v2): show sidebar toggle on hover

# What's changed?

* delay toggle tooltips and view create tooltips by 1s
* cleanup imports
* fix some minor padding issues
pull/3159/head
braks 2 years ago
parent
commit
a0fa1c169d
  1. 9
      packages/nc-gui-v2/components.d.ts
  2. 2
      packages/nc-gui-v2/components/dashboard/TreeView.vue
  3. 2
      packages/nc-gui-v2/components/smartsheet/Pagination.vue
  4. 8
      packages/nc-gui-v2/components/smartsheet/sidebar/MenuBottom.vue
  5. 43
      packages/nc-gui-v2/components/smartsheet/sidebar/index.vue
  6. 2
      packages/nc-gui-v2/components/smartsheet/sidebar/menu/ApiSnippet.vue
  7. 3
      packages/nc-gui-v2/nuxt.config.ts
  8. 59
      packages/nc-gui-v2/pages/[projectType]/[projectId]/index.vue

9
packages/nc-gui-v2/components.d.ts vendored

@ -12,6 +12,7 @@ declare module '@vue/runtime-core' {
ABadgeRibbon: typeof import('ant-design-vue/es')['BadgeRibbon']
AButton: typeof import('ant-design-vue/es')['Button']
ACard: typeof import('ant-design-vue/es')['Card']
ACardMeta: typeof import('ant-design-vue/es')['CardMeta']
ACarousel: typeof import('ant-design-vue/es')['Carousel']
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
ACol: typeof import('ant-design-vue/es')['Col']
@ -84,12 +85,14 @@ declare module '@vue/runtime-core' {
MdiAccountGroup: typeof import('~icons/mdi/account-group')['default']
MdiAccountOutline: typeof import('~icons/mdi/account-outline')['default']
MdiAccountPlusOutline: typeof import('~icons/mdi/account-plus-outline')['default']
MdiAccountSupervisorOutline: typeof import('~icons/mdi/account-supervisor-outline')['default']
MdiAlphaA: typeof import('~icons/mdi/alpha-a')['default']
MdiApi: typeof import('~icons/mdi/api')['default']
MdiArrowExpand: typeof import('~icons/mdi/arrow-expand')['default']
MdiArrowLeftBold: typeof import('~icons/mdi/arrow-left-bold')['default']
MdiAt: typeof import('~icons/mdi/at')['default']
MdiCalculator: typeof import('~icons/mdi/calculator')['default']
MdiCalendarMonth: typeof import('~icons/mdi/calendar-month')['default']
MdiCardsHeart: typeof import('~icons/mdi/cards-heart')['default']
MdiCellphoneMessage: typeof import('~icons/mdi/cellphone-message')['default']
MdiChat: typeof import('~icons/mdi/chat')['default']
@ -102,6 +105,7 @@ declare module '@vue/runtime-core' {
MdiContentCopy: typeof import('~icons/mdi/content-copy')['default']
MdiContentSave: typeof import('~icons/mdi/content-save')['default']
MdiDatabaseOutline: typeof import('~icons/mdi/database-outline')['default']
MdiDelete: typeof import('~icons/mdi/delete')['default']
MdiDeleteOutline: typeof import('~icons/mdi/delete-outline')['default']
MdiDiscord: typeof import('~icons/mdi/discord')['default']
MdiDotsVertical: typeof import('~icons/mdi/dots-vertical')['default']
@ -114,6 +118,7 @@ declare module '@vue/runtime-core' {
MdiEmail: typeof import('~icons/mdi/email')['default']
MdiEmailArrowRightOutline: typeof import('~icons/mdi/email-arrow-right-outline')['default']
MdiExitToApp: typeof import('~icons/mdi/exit-to-app')['default']
MdiExport: typeof import('~icons/mdi/export')['default']
MdiEyeOffOutline: typeof import('~icons/mdi/eye-off-outline')['default']
MdiFileDocumentOutline: typeof import('~icons/mdi/file-document-outline')['default']
MdiFileExcel: typeof import('~icons/mdi/file-excel')['default']
@ -122,6 +127,7 @@ declare module '@vue/runtime-core' {
MdiFolder: typeof import('~icons/mdi/folder')['default']
MdiFunction: typeof import('~icons/mdi/function')['default']
MdiGestureDoubleTap: typeof import('~icons/mdi/gesture-double-tap')['default']
MdiGithub: typeof import('~icons/mdi/github')['default']
MdiHeart: typeof import('~icons/mdi/heart')['default']
MdiHook: typeof import('~icons/mdi/hook')['default']
MdiInformation: typeof import('~icons/mdi/information')['default']
@ -139,12 +145,14 @@ declare module '@vue/runtime-core' {
MdiNumeric: typeof import('~icons/mdi/numeric')['default']
MdiOpenInNew: typeof import('~icons/mdi/open-in-new')['default']
MdiPlus: typeof import('~icons/mdi/plus')['default']
MdiPlusBoxOutline: typeof import('~icons/mdi/plus-box-outline')['default']
MdiPlusOutline: typeof import('~icons/mdi/plus-outline')['default']
MdiRefresh: typeof import('~icons/mdi/refresh')['default']
MdiReload: typeof import('~icons/mdi/reload')['default']
MdiSearch: typeof import('~icons/mdi/search')['default']
MdiSlack: typeof import('~icons/mdi/slack')['default']
MdiStar: typeof import('~icons/mdi/star')['default']
MdiStarOutline: typeof import('~icons/mdi/star-outline')['default']
MdiStore: typeof import('~icons/mdi/store')['default']
MdiTable: typeof import('~icons/mdi/table')['default']
MdiTableArrowRight: typeof import('~icons/mdi/table-arrow-right')['default']
@ -153,6 +161,7 @@ declare module '@vue/runtime-core' {
MdiText: typeof import('~icons/mdi/text')['default']
MdiThumbUp: typeof import('~icons/mdi/thumb-up')['default']
MdiTrashCan: typeof import('~icons/mdi/trash-can')['default']
MdiTwitter: typeof import('~icons/mdi/twitter')['default']
MdiUploadOutline: typeof import('~icons/mdi/upload-outline')['default']
MdiViewListOutline: typeof import('~icons/mdi/view-list-outline')['default']
MdiWhatsapp: typeof import('~icons/mdi/whatsapp')['default']

2
packages/nc-gui-v2/components/dashboard/TreeView.vue

@ -137,7 +137,7 @@ const activeTable = computed(() => {
<template>
<div class="nc-treeview-container flex flex-col">
<div class="px-6 py-[8.75px] border-b-1 nc-filter-input">
<div class="px-6 py-[9px] border-b-1 nc-filter-input">
<div class="flex items-center bg-gray-50 rounded relative">
<a-input
v-model:value="filterQuery"

2
packages/nc-gui-v2/components/smartsheet/Pagination.vue

@ -17,7 +17,7 @@ const page = computed({
</script>
<template>
<div class="flex items-center">
<div class="flex items-center mb-1">
<span v-if="count !== null && count !== Infinity" class="caption ml-5 text-gray-500">
{{ count }} record{{ count !== 1 ? 's' : '' }}
</span>

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

@ -46,7 +46,7 @@ function onOpenModal(type: ViewTypes, title = '') {
class="group !flex !items-center !my-0 !h-[30px] nc-create-3-view"
@click="onOpenModal(ViewTypes.GRID)"
>
<a-tooltip placement="left">
<a-tooltip mouse-enter-delay="1000" placement="left">
<template #title>
{{ $t('msg.info.addView.grid') }}
</template>
@ -68,7 +68,7 @@ function onOpenModal(type: ViewTypes, title = '') {
class="group !flex !items-center !-my0 !h-[30px] nc-create-2-view"
@click="onOpenModal(ViewTypes.GALLERY)"
>
<a-tooltip placement="left">
<a-tooltip mouse-enter-delay="1000" placement="left">
<template #title>
{{ $t('msg.info.addView.gallery') }}
</template>
@ -91,7 +91,7 @@ function onOpenModal(type: ViewTypes, title = '') {
class="group !flex !items-center !my-0 !h-[30px] nc-create-1-view"
@click="onOpenModal(ViewTypes.FORM)"
>
<a-tooltip placement="left">
<a-tooltip mouse-enter-delay="1000" placement="left">
<template #title>
{{ $t('msg.info.addView.form') }}
</template>
@ -111,7 +111,7 @@ function onOpenModal(type: ViewTypes, title = '') {
<SmartsheetSidebarMenuApiSnippet v-model="showApiSnippet" />
<div class="flex-auto justify-end flex flex-col gap-4 mt-4">
<div class="flex-auto justify-end flex flex-col gap-3 mt-3">
<button
v-if="isUIAllowed('virtualViewsCreateOrEdit')"
class="flex items-center gap-2 w-full mx-3 px-4 py-3 rounded border transform translate-x-4 hover:(translate-x-0 shadow-lg) transition duration-150 ease !text-xs"

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

@ -3,7 +3,7 @@ import type { FormType, GalleryType, GridType, KanbanType, ViewTypes } from 'noc
import MenuTop from './MenuTop.vue'
import MenuBottom from './MenuBottom.vue'
import Toolbar from './toolbar/index.vue'
import { computed, inject, provide, ref, useRoute, useRouter, useViews, watch } from '#imports'
import { computed, inject, provide, ref, useElementHover, useRoute, useRouter, useViews, watch } from '#imports'
import { ActiveViewInj, MetaInj, RightSidebarInj, ViewListInj } from '~/context'
const meta = inject(MetaInj, ref())
@ -25,6 +25,9 @@ const sidebarOpen = inject(RightSidebarInj, ref(true))
const sidebarCollapsed = computed(() => !sidebarOpen.value)
/** Sidebar ref */
const sidebar = ref()
/** View type to create from modal */
let viewCreateType = $ref<ViewTypes>()
@ -37,6 +40,8 @@ let selectedViewId = $ref('')
/** is view creation modal open */
let modalOpen = $ref(false)
const isHovered = useElementHover(sidebar)
/** Watch route param and change active view based on `viewTitle` */
watch(
[views, () => route.params.viewTitle],
@ -74,6 +79,7 @@ function onCreate(view: GridType | FormType | KanbanType | GalleryType) {
<template>
<a-layout-sider
ref="sidebar"
:collapsed="sidebarCollapsed"
collapsiple
collapsed-width="50"
@ -81,24 +87,27 @@ function onCreate(view: GridType | FormType | KanbanType | GalleryType) {
class="relative shadow-md h-full"
theme="light"
>
<a-tooltip placement="left">
<a-tooltip mouse-enter-delay="1000" placement="left">
<template #title> Toggle sidebar </template>
<div
class="group color-transition cursor-pointer hover:ring active:ring-pink-500 z-1 flex items-center p-[1px] absolute top-1/2 left-[-1rem] shadow bg-gray-100 rounded-full"
>
<MaterialSymbolsChevronRightRounded
v-if="sidebarOpen"
class="transform group-hover:(scale-115 text-pink-500) text-xl text-gray-400"
@click="sidebarOpen = false"
/>
<MaterialSymbolsChevronLeftRounded
v-else
class="transform group-hover:(scale-115 text-pink-500) text-xl text-gray-400"
@click="sidebarOpen = true"
/>
</div>
<Transition name="layout">
<div
v-show="isHovered"
class="group color-transition cursor-pointer hover:ring active:ring-pink-500 z-1 flex items-center p-[1px] absolute top-1/2 left-[-1rem] shadow bg-gray-100 rounded-full"
>
<MaterialSymbolsChevronRightRounded
v-if="sidebarOpen"
class="transform group-hover:(scale-115 text-pink-500) text-xl text-gray-400"
@click="sidebarOpen = false"
/>
<MaterialSymbolsChevronLeftRounded
v-else
class="transform group-hover:(scale-115 text-pink-500) text-xl text-gray-400"
@click="sidebarOpen = true"
/>
</div>
</Transition>
</a-tooltip>
<Toolbar v-if="sidebarOpen" class="flex items-center py-3 px-3 justify-between border-b-1" />

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

@ -172,5 +172,3 @@ const afterVisibleChange = (visible: boolean) => {
</div>
</a-drawer>
</template>
<style scoped></style>

3
packages/nc-gui-v2/nuxt.config.ts

@ -51,6 +51,9 @@ export default defineNuxtConfig({
// todo: minifiy again
build: {
minify: false,
rollupOptions: {
external: 'httpsnippet',
},
},
css: {
preprocessorOptions: {

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

@ -1,7 +1,17 @@
<script setup lang="ts">
import { navigateTo, onKeyStroke, provideSidebar, ref, useProject, useRoute, useTabs, useUIPermission } from '#imports'
import {
navigateTo,
onKeyStroke,
openLink,
provideSidebar,
ref,
useElementHover,
useProject,
useRoute,
useTabs,
useUIPermission,
} from '#imports'
import { TabType } from '~/composables'
import { openLink } from '~/utils'
const route = useRoute()
@ -20,6 +30,9 @@ const openDialogKey = ref<string>()
const dropdownOpen = ref(false)
/** Sidebar ref */
const sidebar = ref()
onKeyStroke(
'Escape',
() => {
@ -42,12 +55,15 @@ function toggleDialog(value?: boolean, key?: string) {
await loadProject()
await loadTables()
const isHovered = useElementHover(sidebar)
</script>
<template>
<NuxtLayout id="content" class="flex">
<template #sidebar>
<a-layout-sider
ref="sidebar"
:collapsed="!isOpen"
width="250"
collapsed-width="50"
@ -68,6 +84,7 @@ await loadTables()
>
<img alt="NocoDB" src="~/assets/img/icons/512x512-trans.png" />
</div>
<a
v-if="isOpen && isSharedBase"
class="w-[40px] min-w-[40px] transition-all duration-200 p-1 cursor-pointer transform hover:scale-105"
@ -81,6 +98,7 @@ await loadTables()
<template v-if="isOpen">
<div class="text-xl font-semibold truncate">{{ project.title }}</div>
</template>
<template v-else>
<MdiFolder class="text-primary cursor-pointer transform hover:scale-105 text-2xl" />
</template>
@ -115,6 +133,7 @@ await loadTables()
<div class="flex items-center gap-1">
<div class="group-hover:(!text-primary)">ID:</div>
<div class="text-xs group-hover:text-pink-500 truncate font-italic">{{ project.id }}</div>
</div>
</div>
@ -216,24 +235,27 @@ await loadTables()
</a-dropdown>
</div>
<a-tooltip placement="right">
<a-tooltip mouse-enter-delay="1000" placement="right">
<template #title> Toggle table list </template>
<div
class="group color-transition cursor-pointer hover:ring active:ring-pink-500 z-1 flex items-center absolute top-1/2 right-[-0.75rem] shadow bg-gray-100 rounded-full"
>
<MaterialSymbolsChevronLeftRounded
v-if="isOpen"
class="transform group-hover:(scale-115 text-pink-500) text-xl text-gray-400"
@click="toggle(false)"
/>
<MaterialSymbolsChevronRightRounded
v-else
class="transform group-hover:(scale-115 text-pink-500) text-xl text-gray-400"
@click="toggle(true)"
/>
</div>
<Transition name="layout">
<div
v-show="isHovered"
class="group color-transition cursor-pointer hover:ring active:ring-pink-500 z-1 flex items-center absolute top-1/2 right-[-0.75rem] shadow bg-gray-100 rounded-full"
>
<MaterialSymbolsChevronLeftRounded
v-if="isOpen"
class="transform group-hover:(scale-115 text-pink-500) text-xl text-gray-400"
@click="toggle(false)"
/>
<MaterialSymbolsChevronRightRounded
v-else
class="transform group-hover:(scale-115 text-pink-500) text-xl text-gray-400"
@click="toggle(true)"
/>
</div>
</Transition>
</a-tooltip>
<DashboardTreeView v-show="isOpen" />
@ -241,6 +263,7 @@ await loadTables()
</template>
<dashboard-settings-modal v-model="dialogOpen" :open-key="openDialogKey" />
<NuxtPage />
<GeneralPreviewAs float />

Loading…
Cancel
Save