Browse Source

Merge pull request #3703 from nocodb/chore/cleanup

pull/3783/head
Braks 2 years ago committed by GitHub
parent
commit
5050f00882
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      packages/nc-gui/.eslintrc.js
  2. 4
      packages/nc-gui/app.vue
  3. 28
      packages/nc-gui/components/general/PreviewAs.vue
  4. 2
      packages/nc-gui/components/smartsheet/sidebar/MenuTop.vue
  5. 4
      packages/nc-gui/components/smartsheet/sidebar/RenameableMenuItem.vue
  6. 3
      packages/nc-gui/components/smartsheet/sidebar/index.vue
  7. 6
      packages/nc-gui/components/tabs/Smartsheet.vue
  8. 2
      packages/nc-gui/composables/index.ts
  9. 9
      packages/nc-gui/composables/useAttachment.ts
  10. 11
      packages/nc-gui/composables/useGlobal/index.ts
  11. 4
      packages/nc-gui/composables/useGlobal/types.ts
  12. 35
      packages/nc-gui/composables/useProject.ts
  13. 65
      packages/nc-gui/composables/useRoles/index.ts
  14. 2
      packages/nc-gui/composables/useSharedFormViewStore.ts
  15. 51
      packages/nc-gui/composables/useSidebar/index.ts
  16. 20
      packages/nc-gui/composables/useTheme/index.ts
  17. 48
      packages/nc-gui/composables/useUIPermission/index.ts
  18. 42
      packages/nc-gui/composables/useUIPermission/rolePermissions.ts
  19. 4
      packages/nc-gui/layouts/default.vue
  20. 1
      packages/nc-gui/lib/enums.ts
  21. 6
      packages/nc-gui/lib/types.ts
  22. 9
      packages/nc-gui/plugins/tele.ts
  23. 1
      packages/nc-gui/utils/index.ts

2
packages/nc-gui/.eslintrc.js

@ -14,5 +14,5 @@ module.exports = {
extends: ['@antfu', 'plugin:prettier/recommended'],
plugins: ['prettier'],
rules: baseRules,
ignorePatterns: ['!*.d.ts'],
ignorePatterns: ['!*.d.ts', 'components.d.ts'],
}

4
packages/nc-gui/app.vue

@ -1,11 +1,9 @@
<script setup lang="ts">
import { computed, provideTheme, useRoute } from '#imports'
import { computed, useRoute } from '#imports'
const route = useRoute()
const disableBaseLayout = computed(() => route.path.startsWith('/nc/view') || route.path.startsWith('/nc/form'))
provideTheme()
</script>
<template>

28
packages/nc-gui/components/general/PreviewAs.vue

@ -1,29 +1,26 @@
<script lang="ts" setup>
import { onUnmounted, useEventListener, useGlobal, useState, watch } from '#imports'
import { onUnmounted, ref, useEventListener, useGlobal, useI18n, useNuxtApp, watch } from '#imports'
import MdiAccountStar from '~icons/mdi/account-star'
import MdiAccountHardHat from '~icons/mdi/account-hard-hat'
import MdiAccountEdit from '~icons/mdi/account-edit'
import MdiEyeOutline from '~icons/mdi/eye-outline'
import MdiCommentAccountOutline from '~icons/mdi/comment-account-outline'
import { ProjectRole } from '~/lib'
const { float } = defineProps<{ float?: boolean }>()
const position = useState('preview-as-position', () => ({
y: `${window.innerHeight - 100}px`,
x: `${window.innerWidth / 2 - 250}px`,
}))
const { $e } = useNuxtApp()
const { t } = useI18n()
const { previewAs } = useGlobal()
const roleList = [
{ value: 'editor', label: t('objects.roleType.editor') },
{ value: 'commenter', label: t('objects.roleType.commenter') },
{ value: 'viewer', label: t('objects.roleType.viewer') },
{ value: ProjectRole.Editor, label: t('objects.roleType.editor') },
{ value: ProjectRole.Commenter, label: t('objects.roleType.commenter') },
{ value: ProjectRole.Viewer, label: t('objects.roleType.viewer') },
]
const { previewAs } = useGlobal()
const roleIcon = {
owner: MdiAccountStar,
creator: MdiAccountHardHat,
@ -32,6 +29,11 @@ const roleIcon = {
commenter: MdiCommentAccountOutline,
}
const position = ref({
y: `${window.innerHeight - 100}px`,
x: `${window.innerWidth / 2 - 250}px`,
})
const divMove = (e: MouseEvent) => {
position.value = { y: `${e.clientY - 10}px`, x: `${e.clientX - 18}px` }
}
@ -49,7 +51,7 @@ onUnmounted(() => {
window.removeEventListener('mousemove', divMove, true)
})
/** reload page on previewas change */
/** reload page on preview-as change */
watch(previewAs, (newRole) => {
$e('a:navdraw:preview', { role: newRole })
window.location.reload()
@ -63,7 +65,7 @@ watch(previewAs, (newRole) => {
class="floating-reset-btn nc-floating-preview-btn p-4"
:style="{ top: position.y, left: position.x }"
>
<MdiDrag style="cursor: move" class="text-white" @mousedown="mouseDown" />
<MdiDrag class="cursor-move text-white" @mousedown="mouseDown" />
<div class="divider" />

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

@ -32,8 +32,6 @@ interface Emits {
(event: 'openModal', data: { type: ViewTypes; title?: string; copyViewId?: string }): void
(event: 'deleted'): void
(event: 'sorted'): void
}
const { $e } = useNuxtApp()

4
packages/nc-gui/components/smartsheet/sidebar/RenameableMenuItem.vue

@ -2,7 +2,7 @@
import type { ViewType, ViewTypes } from 'nocodb-sdk'
import { message } from 'ant-design-vue'
import type { WritableComputedRef } from '@vue/reactivity'
import { IsLockedInj, onKeyStroke, useDebounceFn, useNuxtApp, useUIPermission, useVModel, viewIcons } from '#imports'
import { IsLockedInj, inject, onKeyStroke, useDebounceFn, useNuxtApp, useUIPermission, useVModel, viewIcons } from '#imports'
interface Props {
view: ViewType
@ -21,7 +21,7 @@ const props = defineProps<Props>()
const emits = defineEmits<Emits>()
const vModel = useVModel(props, 'view', emits) as WritableComputedRef<any>
const vModel = useVModel(props, 'view', emits) as WritableComputedRef<ViewType & { is_default: boolean }>
const { $e } = useNuxtApp()

3
packages/nc-gui/components/smartsheet/sidebar/index.vue

@ -14,6 +14,7 @@ import {
useRoute,
useRouter,
useSidebar,
useUIPermission,
useViews,
watch,
} from '#imports'
@ -114,7 +115,7 @@ function onCreate(view: ViewType) {
class="min-h-[var(--toolbar-height)] max-h-[var(--toolbar-height)] flex items-center py-3 px-3 justify-between border-b-1"
/>
<div v-if="isOpen" class="flex-1 flex flex-col min-h-0">
<MenuTop @open-modal="openModal" @deleted="loadViews" @sorted="loadViews" />
<MenuTop @open-modal="openModal" @deleted="loadViews" />
<div v-if="isUIAllowed('virtualViewsCreateOrEdit')" class="!my-3 w-full border-b-1" />

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

@ -11,9 +11,9 @@ import {
ReloadViewDataHookInj,
ReloadViewMetaHookInj,
computed,
createEventHook,
inject,
provide,
provideSidebar,
useMetas,
useProvideSmartsheetStore,
watch,
@ -35,14 +35,14 @@ const fields = ref<ColumnType[]>([])
provide(TabMetaInj, ref(activeTab))
const meta = computed<TableType>(() => metas.value?.[activeTab?.id as string])
const reloadEventHook = createEventHook<void>()
const reloadEventHook = createEventHook()
const reloadViewMetaEventHook = createEventHook<void>()
const openNewRecordFormHook = createEventHook<void>()
const { isGallery, isGrid, isForm, isLocked } = useProvideSmartsheetStore(activeView, meta)
// provide the sidebar injection state
provideSidebar('nc-right-sidebar', { useStorage: true, isOpen: true })
useSidebar('nc-right-sidebar', { useStorage: true, isOpen: true })
// todo: move to store
provide(MetaInj, meta)

2
packages/nc-gui/composables/index.ts

@ -2,10 +2,10 @@ export * from './useApi'
export * from './useDialog'
export * from './useGlobal'
export * from './useInjectionState'
export * from './useRoles'
export * from './useSidebar'
export * from './useTheme'
export * from './useUIPermission'
export * from './useAttachment'
export * from './useColors'
export * from './useColumn'
export * from './useGridViewColumnWidth'

9
packages/nc-gui/composables/useAttachment.ts

@ -1,9 +0,0 @@
// todo: implement useAttachment
export function useAttachment() {
const localFilesState = reactive([])
const attachments = ref([])
const uploadFile = () => {}
return { uploadFile, localFilesState, attachments }
}

11
packages/nc-gui/composables/useGlobal/index.ts

@ -2,7 +2,7 @@ import { useGlobalState } from './state'
import { useGlobalActions } from './actions'
import type { UseGlobalReturn } from './types'
import { useGlobalGetters } from './getters'
import { useNuxtApp, watch } from '#imports'
import { createGlobalState, useNuxtApp, watch } from '#imports'
/**
* Global state is injected by {@link import('~/plugins/state') state} plugin into our nuxt app (available as `$state`).
@ -34,11 +34,8 @@ import { useNuxtApp, watch } from '#imports'
* console.log(state.isLoading.value) // isLoading = true if any api request is still running
* ```
*/
export const useGlobal = (): UseGlobalReturn => {
const { $state, provide } = useNuxtApp()
/** If state already exists, return it */
if (typeof $state !== 'undefined') return $state
export const useGlobal = createGlobalState((): UseGlobalReturn => {
const { provide } = useNuxtApp()
const state = useGlobalState()
@ -84,4 +81,4 @@ export const useGlobal = (): UseGlobalReturn => {
provide('state', globalState)
return globalState
}
})

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

@ -1,7 +1,7 @@
import type { ComputedRef, Ref, ToRefs } from 'vue'
import type { WritableComputedRef } from '@vue/reactivity'
import type { JwtPayload } from 'jwt-decode'
import type { Language, User } from '~/lib'
import type { Language, ProjectRole, User } from '~/lib'
import type { useCounter } from '#imports'
export interface FeedbackForm {
@ -33,7 +33,7 @@ export interface StoredState {
darkMode: boolean
feedbackForm: FeedbackForm
filterAutoSave: boolean
previewAs: string | null
previewAs: ProjectRole | null
includeM2M: boolean
currentVersion: string | null
latestRelease: string | null

35
packages/nc-gui/composables/useProject.ts

@ -3,7 +3,6 @@ import type { OracleUi, ProjectType, TableType } from 'nocodb-sdk'
import { SqlUiFactory } from 'nocodb-sdk'
import { isString } from '@vueuse/core'
import {
USER_PROJECT_ROLES,
computed,
createEventHook,
ref,
@ -11,12 +10,12 @@ import {
useGlobal,
useInjectionState,
useNuxtApp,
useRoles,
useRoute,
useState,
useTheme,
watch,
} from '#imports'
import type { ProjectMetaInfo, Roles } from '~/lib'
import type { ProjectMetaInfo } from '~/lib'
import type { ThemeConfig } from '@/composables/useTheme'
const [setup, use] = useInjectionState((_projectId?: MaybeRef<string>) => {
@ -30,14 +29,14 @@ const [setup, use] = useInjectionState((_projectId?: MaybeRef<string>) => {
const { setTheme, theme } = useTheme()
const { projectRoles, loadProjectRoles } = useRoles()
const projectLoadedHook = createEventHook<ProjectType>()
const project = ref<ProjectType>({})
const tables = ref<TableType[]>([])
const projectRoles = useState<Roles>(USER_PROJECT_ROLES, () => ({}))
const projectMetaInfo = ref<ProjectMetaInfo | undefined>()
const projectId = computed(() => (_projectId ? unref(_projectId) : (route.params.projectId as string)))
@ -72,26 +71,6 @@ const [setup, use] = useInjectionState((_projectId?: MaybeRef<string>) => {
}
}
async function loadProjectRoles() {
projectRoles.value = {}
if (isSharedBase.value) {
const user = await api.auth.me(
{},
{
headers: {
'xc-shared-base-id': route.params.projectId,
},
},
)
projectRoles.value = user.roles
} else if (project.value.id) {
const user = await api.auth.me({ project_id: project.value.id })
projectRoles.value = user.roles
}
}
async function loadTables() {
if (project.value.id) {
const tablesResponse = await api.dbTable.list(project.value.id, {
@ -121,7 +100,11 @@ const [setup, use] = useInjectionState((_projectId?: MaybeRef<string>) => {
return
}
await loadProjectRoles()
await loadProjectRoles(
project.value.id || (route.params.projectId as string),
isSharedBase.value,
route.params.projectId as string,
)
await loadTables()

65
packages/nc-gui/composables/useRoles/index.ts

@ -0,0 +1,65 @@
import { isString } from '@vueuse/core'
import { computed, createSharedComposable, ref, useApi, useGlobal } from '#imports'
import type { ProjectRole, Role, Roles } from '~/lib'
/**
* Provides the roles a user currently has
*
* * `userRoles` - the roles a user has outside of projects
* * `projectRoles` - the roles a user has in the current project (if one was loaded)
* * `allRoles` - all roles a user has (userRoles + projectRoles)
* * `hasRole` - a function to check if a user has a specific role
* * `loadProjectRoles` - a function to load the project roles for a specific project (by id)
*/
export const useRoles = createSharedComposable(() => {
const { user } = useGlobal()
const { api } = useApi()
const projectRoles = ref<Roles<ProjectRole>>({})
const userRoles = computed<Roles<Role>>(() => {
let roles = user.value?.roles ?? {}
// if string populate key-value paired object
if (isString(roles)) {
roles = roles.split(',').reduce<Roles>((acc, role) => {
acc[role] = true
return acc
}, {})
}
return roles
})
const allRoles = computed<Roles>(() => ({
...userRoles.value,
...projectRoles.value,
}))
async function loadProjectRoles(projectId: string, isSharedBase?: boolean, sharedBaseId?: string) {
projectRoles.value = {}
if (isSharedBase) {
const user = await api.auth.me(
{},
{
headers: {
'xc-shared-base-id': sharedBaseId,
},
},
)
projectRoles.value = user.roles
} else if (projectId) {
const user = await api.auth.me({ project_id: projectId })
projectRoles.value = user.roles
}
}
function hasRole(role: Role | ProjectRole | string) {
return allRoles.value[role]
}
return { allRoles, userRoles, projectRoles, loadProjectRoles, hasRole }
})

2
packages/nc-gui/composables/useSharedFormViewStore.ts

@ -30,7 +30,7 @@ const [useProvideSharedFormStore, useSharedFormStore] = useInjectionState((share
const sharedView = ref<ViewType>()
const sharedFormView = ref<FormType>()
const meta = ref<TableType>()
const columns = ref<(ColumnType & { required?: boolean; show?: boolean })[]>()
const columns = ref<(ColumnType & { required?: boolean; show?: boolean; label?: string })[]>()
const { api, isLoading } = useApi()

51
packages/nc-gui/composables/useSidebar/index.ts

@ -1,5 +1,5 @@
import { useStorage } from '@vueuse/core'
import { MemStorage, onScopeDispose, useInjectionState, watch } from '#imports'
import { MemStorage, onScopeDispose, ref, syncRef, toRefs, watch } from '#imports'
interface UseSidebarProps {
hasSidebar?: boolean
@ -8,14 +8,12 @@ interface UseSidebarProps {
}
/**
* Injection state for sidebars
* States for sidebars
*
* Use `provideSidebar` to provide the injection state on current component level (will affect all children injections)
* Use `useSidebar` to use the injection state on current component level
*
* If `provideSidebar` is not called explicitly, `useSidebar` will trigger the provider if no injection state can be found
* Requires an id to work, id should correspond to the sidebar state you want to create or fetch
* If `useSidebar` was not called before it will create a new state if no state can be found for the specified id
*/
const [setupSidebarStore, useSidebarStore] = useInjectionState(() => new MemStorage(), 'SidebarStore')
const sidebarStorage = new MemStorage()
const createSidebar = (id: string, props: UseSidebarProps = {}) => {
const isOpen = ref(props.isOpen ?? false)
@ -59,52 +57,25 @@ const createSidebar = (id: string, props: UseSidebarProps = {}) => {
}
}
const useSidebarStorage = () => {
let sidebarStorage = useSidebarStore()
if (!sidebarStorage) {
sidebarStorage = setupSidebarStore()
}
return sidebarStorage
}
export const provideSidebar = (id: string, props: UseSidebarProps = {}) => {
const sidebarStorage = useSidebarStorage()
onScopeDispose(() => {
sidebarStorage.remove(id)
})
export function useSidebar(id: string, props: UseSidebarProps = {}) {
if (!id) throw new Error('useSidebar requires an id')
if (!sidebarStorage.has(id)) {
const sidebar = createSidebar(id, props)
sidebarStorage.set(id, sidebar)
return sidebar
} else {
const sidebar = sidebarStorage.get(id)
if (props.isOpen !== undefined) sidebar.isOpen.value = props.isOpen
if (props.hasSidebar !== undefined) sidebar.hasSidebar.value = props.hasSidebar
onScopeDispose(() => {
sidebarStorage.remove(id)
})
return sidebar
}
}
export function useSidebar(id: string, props: UseSidebarProps = {}) {
if (!id) throw new Error('useSidebar requires an id')
const sidebarStorage = useSidebarStorage()
if (sidebarStorage.has(id)) {
} else {
const sidebar = sidebarStorage.get(id)
if (props.isOpen !== undefined) sidebar.isOpen.value = props.isOpen
if (props.hasSidebar !== undefined) sidebar.hasSidebar.value = props.hasSidebar
return sidebar
} else {
return provideSidebar(id, props)
}
}

20
packages/nc-gui/composables/useTheme/index.ts

@ -1,14 +1,14 @@
import { ConfigProvider } from 'ant-design-vue'
import type { Theme as AntTheme } from 'ant-design-vue/es/config-provider'
import tinycolor from 'tinycolor2'
import { hexToRGB, themeV2Colors, useCssVar, useInjectionState } from '#imports'
import { createGlobalState, hexToRGB, ref, themeV2Colors, useCssVar } from '#imports'
export interface ThemeConfig extends AntTheme {
primaryColor: string
accentColor: string
}
const [setup, use] = useInjectionState((config?: Partial<ThemeConfig>) => {
export const useTheme = createGlobalState((config?: Partial<ThemeConfig>) => {
const primaryColor = useCssVar('--color-primary', typeof document !== 'undefined' ? document.documentElement : null)
const accentColor = useCssVar('--color-accent', typeof document !== 'undefined' ? document.documentElement : null)
@ -46,18 +46,4 @@ const [setup, use] = useInjectionState((config?: Partial<ThemeConfig>) => {
theme: currentTheme,
setTheme,
}
}, 'theme')
export const provideTheme = setup
export function useTheme(config?: Partial<ThemeConfig>) {
const theme = use()
if (!theme) {
return setup(config)
} else {
if (config) theme.setTheme(config)
}
return theme
}
})

48
packages/nc-gui/composables/useUIPermission/index.ts

@ -1,46 +1,34 @@
import { isString } from '@vueuse/core'
import type { Permission } from './rolePermissions'
import rolePermissions from './rolePermissions'
import { USER_PROJECT_ROLES, computed, useGlobal, useState } from '#imports'
import type { Role, Roles } from '~/lib'
import { createSharedComposable, useGlobal, useRoles } from '#imports'
import type { ProjectRole, Role } from '~/lib'
export function useUIPermission() {
const { user, previewAs } = useGlobal()
const hasPermission = (role: Role | ProjectRole, hasRole: boolean, permission: Permission | string) => {
const rolePermission = rolePermissions[role]
const projectRoles = useState<Record<string, boolean>>(USER_PROJECT_ROLES, () => ({}))
if (!hasRole || !rolePermission) return false
const baseRoles = computed(() => {
let userRoles = isString(user.value?.roles) ? user.value?.roles : ({ ...(user.value?.roles || {}) } as Roles)
if (isString(rolePermission) && rolePermission === '*') return true
// if string populate key-value paired object
if (typeof userRoles === 'string') {
userRoles = userRoles.split(',').reduce<Record<string, boolean>>((acc, role) => {
acc[role] = true
return acc
}, {})
}
return rolePermission[permission as keyof typeof rolePermission]
}
// merge user role and project specific user roles
return {
...userRoles,
...projectRoles.value,
}
})
export const useUIPermission = createSharedComposable(() => {
const { previewAs } = useGlobal()
const { allRoles } = useRoles()
const isUIAllowed = (permission: Permission | string, skipPreviewAs = false) => {
let roles = baseRoles.value as Record<string, any>
if (previewAs.value && !skipPreviewAs) {
roles = {
[previewAs.value as Role]: true,
}
const hasPreviewPermission = hasPermission(previewAs.value, true, permission)
if (hasPreviewPermission) return true
}
return Object.entries<boolean>(roles).some(([role, hasRole]) => {
const rolePermission = rolePermissions[role as keyof typeof rolePermissions] as '*' | Record<Permission, true>
return hasRole && (rolePermission === '*' || rolePermission?.[permission as Permission])
})
return Object.entries(allRoles.value).some(([role, hasRole]) =>
hasPermission(role as Role | ProjectRole, hasRole, permission),
)
}
return { isUIAllowed }
}
})

42
packages/nc-gui/composables/useUIPermission/rolePermissions.ts

@ -1,13 +1,24 @@
import { ProjectRole, Role } from '~/lib'
const rolePermissions = {
// general role permissions
/** todo: enable wildcard permission
* limited permission due to unexpected behaviour in shared base if opened in same window */
super: {
[Role.Super]: {
projectTheme: true,
},
creator: '*',
owner: '*',
guest: {},
editor: {
[Role.Admin]: {},
[Role.Guest]: {},
[Role.User]: {
projectCreate: true,
projectActions: true,
projectSettings: true,
},
// Project role permissions
[ProjectRole.Creator]: '*',
[ProjectRole.Owner]: '*',
[ProjectRole.Editor]: {
smartSheet: true,
xcDatatableEditable: true,
column: true,
@ -25,32 +36,25 @@ const rolePermissions = {
projectSettings: true,
newUser: false,
},
commenter: {
[ProjectRole.Commenter]: {
smartSheet: true,
column: true,
rowComments: true,
projectSettings: true,
},
viewer: {
[ProjectRole.Viewer]: {
smartSheet: true,
column: true,
projectSettings: true,
},
user: {
projectCreate: true,
projectActions: true,
projectSettings: true,
},
} as const
export default rolePermissions
type RolePermissions = Omit<typeof rolePermissions, 'creator' | 'owner' | 'guest' | 'admin'>
type GetKeys<T> = T extends Record<string, any> ? keyof T : never
export type Permission<T extends typeof rolePermissions = typeof rolePermissions, K extends keyof T = keyof T> = K extends
| 'creator'
| 'owner'
? T[K]
: never | T[K] extends Record<string, any>
? GetKeys<T[K]>
export type Permission<K extends keyof RolePermissions = keyof RolePermissions> = RolePermissions[K] extends Record<string, any>
? GetKeys<RolePermissions[K]>
: never
export default rolePermissions

4
packages/nc-gui/layouts/default.vue

@ -1,12 +1,12 @@
<script lang="ts" setup>
import { useTitle } from '@vueuse/core'
import { provideSidebar, useI18n, useRoute } from '#imports'
import { useI18n, useRoute, useSidebar } from '#imports'
const route = useRoute()
const { te, t } = useI18n()
const { hasSidebar } = provideSidebar('nc-left-sidebar')
const { hasSidebar } = useSidebar('nc-left-sidebar')
useTitle(route.meta?.title && te(route.meta.title) ? `${t(route.meta.title)} | NocoDB` : 'NocoDB')
</script>

1
packages/nc-gui/lib/enums.ts

@ -2,6 +2,7 @@ export enum Role {
Super = 'super',
Admin = 'admin',
User = 'user',
Guest = 'guest',
}
export enum ProjectRole {

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

@ -1,13 +1,13 @@
import type { FilterType } from 'nocodb-sdk'
import type { I18n } from 'vue-i18n'
import type { Role } from './enums'
import type { ProjectRole, Role } from './enums'
export interface User {
id: string
email: string
firstname: string | null
lastname: string | null
roles: Roles
roles: Roles | string
invite_token?: string
project_id?: string
}
@ -31,7 +31,7 @@ export interface Field {
system?: boolean
}
export type Roles = Record<Role | string, boolean> | string
export type Roles<T extends Role | ProjectRole = Role | ProjectRole> = Record<T | string, boolean>
export type Filter = FilterType & { status?: 'update' | 'delete' | 'create'; parentId?: string; readOnly?: boolean }

9
packages/nc-gui/plugins/tele.ts

@ -41,15 +41,6 @@ export default defineNuxtPlugin(async (nuxtApp) => {
})
})
/**
* unreachable code?
if (socket) {
socket.emit('page', {
path: route.matched[0].path + (route.query && route.query.type ? `?type=${route.query.type}` : ''),
})
}
*/
const tele = {
emit(evt: string, data: Record<string, any>) {
// debugger

1
packages/nc-gui/utils/index.ts

@ -18,3 +18,4 @@ export * from './currencyUtils'
export * from './dataUtils'
export * from './userUtils'
export * from './stringUtils'
export * from './memStorage'

Loading…
Cancel
Save