Browse Source

Merge pull request #3157 from nocodb/feat/gui-v2-misc

feat(gui-v2): misc issues (con't)
pull/3170/head
աɨռɢӄաօռɢ 2 years ago committed by GitHub
parent
commit
2e80f6e6fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      packages/nc-gui-v2/components.d.ts
  2. 16
      packages/nc-gui-v2/components/dashboard/settings/Misc.vue
  3. 5
      packages/nc-gui-v2/components/dashboard/settings/Modal.vue
  4. 7
      packages/nc-gui-v2/components/dashboard/settings/UIAcl.vue
  5. 69
      packages/nc-gui-v2/components/general/ReleaseInfo.vue
  6. 33
      packages/nc-gui-v2/components/general/ShareBaseButton.vue
  7. 28
      packages/nc-gui-v2/components/smartsheet/sidebar/toolbar/DebugMeta.vue
  8. 4
      packages/nc-gui-v2/components/smartsheet/sidebar/toolbar/DeleteCache.vue
  9. 2
      packages/nc-gui-v2/components/smartsheet/sidebar/toolbar/DeleteTable.vue
  10. 5
      packages/nc-gui-v2/components/smartsheet/sidebar/toolbar/ExportCache.vue
  11. 6
      packages/nc-gui-v2/components/smartsheet/sidebar/toolbar/index.vue
  12. 4
      packages/nc-gui-v2/composables/useGlobal/state.ts
  13. 4
      packages/nc-gui-v2/composables/useGlobal/types.ts
  14. 6
      packages/nc-gui-v2/composables/useProject.ts
  15. 22
      packages/nc-gui-v2/layouts/base.vue

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

@ -93,6 +93,7 @@ declare module '@vue/runtime-core' {
MdiArrowExpand: typeof import('~icons/mdi/arrow-expand')['default'] MdiArrowExpand: typeof import('~icons/mdi/arrow-expand')['default']
MdiArrowLeftBold: typeof import('~icons/mdi/arrow-left-bold')['default'] MdiArrowLeftBold: typeof import('~icons/mdi/arrow-left-bold')['default']
MdiAt: typeof import('~icons/mdi/at')['default'] MdiAt: typeof import('~icons/mdi/at')['default']
MdiBugOutline: typeof import('~icons/mdi/bug-outline')['default']
MdiCalculator: typeof import('~icons/mdi/calculator')['default'] MdiCalculator: typeof import('~icons/mdi/calculator')['default']
MdiCalendarMonth: typeof import('~icons/mdi/calendar-month')['default'] MdiCalendarMonth: typeof import('~icons/mdi/calendar-month')['default']
MdiCardsHeart: typeof import('~icons/mdi/cards-heart')['default'] MdiCardsHeart: typeof import('~icons/mdi/cards-heart')['default']
@ -151,6 +152,8 @@ declare module '@vue/runtime-core' {
MdiPlusOutline: typeof import('~icons/mdi/plus-outline')['default'] MdiPlusOutline: typeof import('~icons/mdi/plus-outline')['default']
MdiRefresh: typeof import('~icons/mdi/refresh')['default'] MdiRefresh: typeof import('~icons/mdi/refresh')['default']
MdiReload: typeof import('~icons/mdi/reload')['default'] MdiReload: typeof import('~icons/mdi/reload')['default']
MdiRocketLaunchOutline: typeof import('~icons/mdi/rocket-launch-outline')['default']
MdiScriptTextOutline: typeof import('~icons/mdi/script-text-outline')['default']
MdiSearch: typeof import('~icons/mdi/search')['default'] MdiSearch: typeof import('~icons/mdi/search')['default']
MdiSlack: typeof import('~icons/mdi/slack')['default'] MdiSlack: typeof import('~icons/mdi/slack')['default']
MdiStar: typeof import('~icons/mdi/star')['default'] MdiStar: typeof import('~icons/mdi/star')['default']

16
packages/nc-gui-v2/components/dashboard/settings/Misc.vue

@ -0,0 +1,16 @@
<script setup lang="ts">
const { includeM2M } = useGlobal()
const { loadTables } = useProject()
watch(includeM2M, async () => await loadTables())
</script>
<template>
<div class="flex flex-row w-full">
<div class="flex flex-column w-full">
<div class="flex flex-row items-center w-full mb-4 gap-2">
<a-checkbox v-model:checked="includeM2M">Show M2M Tables</a-checkbox>
</div>
</div>
</div>
</template>

5
packages/nc-gui-v2/components/dashboard/settings/Modal.vue

@ -5,6 +5,7 @@ import AuditTab from './AuditTab.vue'
import AppStore from './AppStore.vue' import AppStore from './AppStore.vue'
import Metadata from './Metadata.vue' import Metadata from './Metadata.vue'
import UIAcl from './UIAcl.vue' import UIAcl from './UIAcl.vue'
import Misc from './Misc.vue'
import ApiTokenManagement from '~/components/tabs/auth/ApiTokenManagement.vue' import ApiTokenManagement from '~/components/tabs/auth/ApiTokenManagement.vue'
import UserManagement from '~/components/tabs/auth/UserManagement.vue' import UserManagement from '~/components/tabs/auth/UserManagement.vue'
import StoreFrontOutline from '~icons/mdi/storefront-outline' import StoreFrontOutline from '~icons/mdi/storefront-outline'
@ -86,6 +87,10 @@ const tabsInfo: TabGroup = {
title: 'UI Access Control', title: 'UI Access Control',
body: UIAcl, body: UIAcl,
}, },
misc: {
title: 'Misc',
body: Misc,
},
}, },
}, },
audit: { audit: {

7
packages/nc-gui-v2/components/dashboard/settings/UIAcl.vue

@ -7,6 +7,8 @@ const { $api, $e } = useNuxtApp()
const { project } = useProject() const { project } = useProject()
const { includeM2M } = useGlobal()
const roles = $ref<string[]>(['editor', 'commenter', 'viewer']) const roles = $ref<string[]>(['editor', 'commenter', 'viewer'])
let isLoading = $ref(false) let isLoading = $ref(false)
@ -28,9 +30,10 @@ async function loadTableList() {
if (!project.value?.id) return if (!project.value?.id) return
isLoading = true isLoading = true
// TODO includeM2M
tables = await $api.project.modelVisibilityList(project.value?.id, { tables = await $api.project.modelVisibilityList(project.value?.id, {
includeM2M: false, // FIXME: type
includeM2M: includeM2M.value || '',
}) })
} catch (e) { } catch (e) {
console.error(e) console.error(e)

69
packages/nc-gui-v2/components/general/ReleaseInfo.vue

@ -0,0 +1,69 @@
<script setup lang="ts">
import { message } from 'ant-design-vue'
import { extractSdkResponseErrorMsg, onMounted } from '#imports'
const { $api } = useNuxtApp()
const { currentVersion, latestRelease, hiddenRelease } = useGlobal()
const releaseAlert = computed(
() =>
currentVersion.value &&
latestRelease.value &&
currentVersion.value !== latestRelease.value &&
latestRelease.value !== hiddenRelease.value,
)
async function fetchReleaseInfo() {
try {
const versionInfo = await $api.utils.appVersion()
if (versionInfo && versionInfo.releaseVersion && versionInfo.currentVersion && !/[^0-9.]/.test(versionInfo.currentVersion)) {
currentVersion.value = versionInfo.currentVersion
latestRelease.value = versionInfo.releaseVersion
} else {
currentVersion.value = null
latestRelease.value = null
}
} catch (e: any) {
message.error(await extractSdkResponseErrorMsg(e))
}
}
onMounted(async () => await fetchReleaseInfo())
</script>
<template>
<div v-if="releaseAlert" class="flex items-center">
<a-dropdown :trigger="['click']" placement="bottom">
<a-button class="bg-primary border-none">
<div class="flex gap-1 align-center text-white">
<span class="text-sm font-weight-medium">{{ $t('activity.upgrade.available') }}</span>
<mdi-menu-down />
</div>
</a-button>
<template #overlay>
<div class="mt-1 bg-white shadow-lg !border">
<nuxt-link class="text-primary" to="https://github.com/nocodb/nocodb/releases" target="_blank">
<div class="nc-menu-item">
<mdi-script-text-outline />
{{ latestRelease }} {{ $t('activity.upgrade.releaseNote') }}
</div>
</nuxt-link>
<nuxt-link class="text-primary" to="https://docs.nocodb.com/getting-started/upgrading" target="_blank">
<div class="nc-menu-item">
<mdi-rocket-launch-outline />
<!-- How to upgrade? -->
{{ $t('activity.upgrade.howTo') }}
</div>
</nuxt-link>
<a-divider class="ma-0" />
<div class="nc-menu-item" @click="latestRelease = null">
<mdi-close />
<!-- Hide menu -->
{{ $t('general.hideMenu') }}
</div>
</div>
</template>
</a-dropdown>
</div>
</template>

33
packages/nc-gui-v2/components/general/ShareBaseButton.vue

@ -0,0 +1,33 @@
<script setup lang="ts">
import { useRoute } from '#imports'
const route = useRoute()
const showUserModal = $ref(false)
const { isUIAllowed } = useUIPermission()
</script>
<template>
<div class="flex items-center mr-4">
<a-button
v-if="
isUIAllowed('newUser') &&
route.name !== 'index' &&
route.name !== 'project-index-create' &&
route.name !== 'project-index-create-external' &&
route.name !== 'index-user-index'
"
size="middle"
type="primary"
class="!bg-white !text-primary rounded"
@click="showUserModal = true"
>
<div class="flex items-center space-x-1">
<mdi-account-supervisor-outline class="mr-1" />
<div>{{ $t('activity.share') }}</div>
</div>
</a-button>
<TabsAuthUserManagementUsersModal :key="showUserModal" :show="showUserModal" @closed="showUserModal = false" />
</div>
</template>

28
packages/nc-gui-v2/components/smartsheet/sidebar/toolbar/DebugMeta.vue

@ -0,0 +1,28 @@
<script setup lang="ts">
const editorOpen = ref(false)
const tabKey = ref()
const { metas } = $(useMetas())
const { tables } = useTable()
const localTables = tables.value.filter((t) => metas[t.id as string])
</script>
<template>
<a-tooltip placement="bottom">
<template #title>
<span> Debug Meta </span>
</template>
<mdi-bug-outline class="cursor-pointer" @click="editorOpen = true" />
</a-tooltip>
<a-modal v-model:visible="editorOpen" :footer="null" width="80%">
<a-tabs v-model:activeKey="tabKey" type="card" closeable="false" class="shadow-sm">
<a-tab-pane v-for="table in localTables" :key="table.id" :tab="table.title">
<MonacoEditor v-model="metas[table.id]" class="h-max-[70vh]" :read-only="true" />
</a-tab-pane>
</a-tabs>
</a-modal>
</template>

4
packages/nc-gui-v2/components/smartsheet/sidebar/toolbar/DeleteCache.vue

@ -13,10 +13,10 @@ async function deleteCache() {
</script> </script>
<template> <template>
<a-tooltip> <a-tooltip placement="bottom">
<template #title> <template #title>
<span> Delete Cache </span> <span> Delete Cache </span>
</template> </template>
<mdi-delete class="cursor-pointer mx-3" @click="deleteCache" /> <mdi-delete class="cursor-pointer" @click="deleteCache" />
</a-tooltip> </a-tooltip>
</template> </template>

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

@ -14,7 +14,7 @@ const sidebarOpen = inject(RightSidebarInj, ref(true))
<template #title> {{ $t('activity.deleteTable') }} </template> <template #title> {{ $t('activity.deleteTable') }} </template>
<div class="nc-sidebar-right-item hover:after:bg-red-500 group"> <div class="nc-sidebar-right-item hover:after:bg-red-500 group">
<MdiDeleteOutline class="cursor-pointer group-hover:(!text-white)" @click="deleteTable(meta)" /> <MdiDeleteOutline class="cursor-pointer" @click="deleteTable(meta)" />
</div> </div>
</a-tooltip> </a-tooltip>
</template> </template>

5
packages/nc-gui-v2/components/smartsheet/sidebar/toolbar/ExportCache.vue

@ -23,11 +23,10 @@ async function exportCache() {
</script> </script>
<template> <template>
<!-- Export Cache --> <a-tooltip placement="bottom">
<a-tooltip>
<template #title> <template #title>
<span> Export Cache </span> <span> Export Cache </span>
</template> </template>
<mdi-export class="cursor-pointer mx-3" @click="exportCache" /> <mdi-export class="cursor-pointer" @click="exportCache" />
</a-tooltip> </a-tooltip>
</template> </template>

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

@ -4,6 +4,7 @@ import LockMenu from './LockMenu.vue'
import Reload from './Reload.vue' import Reload from './Reload.vue'
import ExportCache from './ExportCache.vue' import ExportCache from './ExportCache.vue'
import DeleteCache from './DeleteCache.vue' import DeleteCache from './DeleteCache.vue'
import DebugMeta from './DebugMeta.vue'
const { isUIAllowed } = useUIPermission() const { isUIAllowed } = useUIPermission()
@ -33,8 +34,9 @@ const clickCount = $ref(0)
<div class="dot" /> <div class="dot" />
<!-- TODO: --> <DebugMeta />
<!-- <debug-metas v-if="debug" class="mr-3" /> -->
<div class="dot" />
</template> </template>
<LockMenu v-if="isUIAllowed('view-type')" /> <LockMenu v-if="isUIAllowed('view-type')" />

4
packages/nc-gui-v2/composables/useGlobal/state.ts

@ -58,6 +58,10 @@ export function useGlobalState(storageKey = 'nocodb-gui-v2'): State {
}, },
filterAutoSave: true, filterAutoSave: true,
previewAs: null, previewAs: null,
includeM2M: false,
currentVersion: null,
latestRelease: null,
hiddenRelease: null,
} }
/** saves a reactive state, any change to these values will write/delete to localStorage */ /** saves a reactive state, any change to these values will write/delete to localStorage */

4
packages/nc-gui-v2/composables/useGlobal/types.ts

@ -35,6 +35,10 @@ export interface StoredState {
feedbackForm: FeedbackForm feedbackForm: FeedbackForm
filterAutoSave: boolean filterAutoSave: boolean
previewAs: string | null previewAs: string | null
includeM2M: boolean
currentVersion: string | null
latestRelease: string | null
hiddenRelease: string | null
} }
export type State = ToRefs<Omit<StoredState, 'token'>> & { export type State = ToRefs<Omit<StoredState, 'token'>> & {

6
packages/nc-gui-v2/composables/useProject.ts

@ -12,6 +12,7 @@ export function useProject(projectId?: MaybeRef<string>) {
const project = useState<ProjectType>('project') const project = useState<ProjectType>('project')
const tables = useState<TableType[]>('tables', () => [] as TableType[]) const tables = useState<TableType[]>('tables', () => [] as TableType[])
const route = useRoute() const route = useRoute()
const { includeM2M } = useGlobal()
// todo: refactor path param name and variable name // todo: refactor path param name and variable name
const projectType = $computed(() => route.params.projectType as string) const projectType = $computed(() => route.params.projectType as string)
@ -27,7 +28,10 @@ export function useProject(projectId?: MaybeRef<string>) {
async function loadTables() { async function loadTables() {
if (project.value.id) { if (project.value.id) {
const tablesResponse = await $api.dbTable.list(project.value.id) const tablesResponse = await $api.dbTable.list(project.value.id, {
// FIXME: type
includeM2M: includeM2M.value || '',
})
if (tablesResponse.list) tables.value = tablesResponse.list if (tablesResponse.list) tables.value = tablesResponse.list
} }
} }

22
packages/nc-gui-v2/layouts/base.vue

@ -10,10 +10,6 @@ const route = useRoute()
const email = computed(() => user.value?.email ?? '---') const email = computed(() => user.value?.email ?? '---')
const { isUIAllowed } = useUIPermission()
const showUserModal = $ref(false)
const logout = () => { const logout = () => {
signOut() signOut()
navigateTo('/signin') navigateTo('/signin')
@ -47,21 +43,9 @@ const logout = () => {
<div class="flex-1" /> <div class="flex-1" />
<div class="flex items-center mr-4"> <GeneralReleaseInfo />
<a-button
v-if="isUIAllowed('newUser')" <GeneralShareBaseButton />
size="middle"
type="primary"
class="!bg-white !text-primary rounded"
@click="showUserModal = true"
>
<div class="flex items-center space-x-1">
<mdi-account-supervisor-outline class="mr-1" />
<div>{{ $t('activity.share') }}</div>
</div>
</a-button>
<TabsAuthUserManagementUsersModal :key="showUserModal" :show="showUserModal" @closed="showUserModal = false" />
</div>
<a-tooltip placement="bottom"> <a-tooltip placement="bottom">
<template #title> Switch language </template> <template #title> Switch language </template>

Loading…
Cancel
Save