@ -1,31 +1,53 @@
import type { MaybeRef } from '@vueuse/core'
import type { MaybeRef } from '@vueuse/core'
import { SqlUiFactory } from 'nocodb-sdk'
import type { OracleUi , ProjectType , TableType } from 'nocodb-sdk'
import type { OracleUi , ProjectType , TableType } from 'nocodb-sdk'
import { useNuxtApp , useRoute } from '#app'
import { SqlUiFactory } from 'nocodb-sdk'
import type { ProjectMetaInfo } from '~/lib'
import { isString } from '@vueuse/core'
import {
USER_PROJECT_ROLES ,
computed ,
createEventHook ,
ref ,
useApi ,
useGlobal ,
useInjectionState ,
useNuxtApp ,
useRoute ,
useState ,
useTheme ,
watch ,
} from '#imports'
import type { ProjectMetaInfo , Roles } from '~/lib'
import type { ThemeConfig } from '@/composables/useTheme'
import type { ThemeConfig } from '@/composables/useTheme'
import { createEventHook , useInjectionState } from '#imports'
const [ setup , use ] = useInjectionState ( ( _projectId? : MaybeRef < string > ) = > {
const [ setup , use ] = useInjectionState ( ( _projectId? : MaybeRef < string > ) = > {
const { $api , $e } = useNuxtApp ( )
const { $e } = useNuxtApp ( )
const { api , isLoading } = useApi ( )
const route = useRoute ( )
const route = useRoute ( )
const { includeM2M } = useGlobal ( )
const { includeM2M } = useGlobal ( )
const { setTheme , theme } = useTheme ( )
const { setTheme , theme } = useTheme ( )
const projectLoadedHook = createEventHook < ProjectType > ( )
const projectLoadedHook = createEventHook < ProjectType > ( )
const projectId = computed ( ( ) = > ( _projectId ? unref ( _projectId ) : ( route . params . projectId as string ) ) )
const project = ref < ProjectType > ( { } )
const project = ref < ProjectType > ( { } )
const tables = ref < TableType [ ] > ( [ ] )
const tables = ref < TableType [ ] > ( [ ] )
const projectRoles = useState < Record < string , boolean > > ( USER_PROJECT_ROLES , ( ) = > ( { } ) )
const projectRoles = useState < Roles > ( USER_PROJECT_ROLES , ( ) = > ( { } ) )
const projectMetaInfo = ref < ProjectMetaInfo | undefined > ( )
const projectMetaInfo = ref < ProjectMetaInfo | undefined > ( )
const projectId = computed ( ( ) = > ( _projectId ? unref ( _projectId ) : ( route . params . projectId as string ) ) )
// 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 )
const projectMeta = computed ( ( ) = > {
const projectMeta = computed < Record < string , any > > ( ( ) = > {
try {
try {
return typeof project . value . meta === 'string' ? JSON . parse ( project . value . meta ) : project . value . meta
return project . value . meta && isString ( project . value . meta ) ? JSON . parse ( project . value . meta ) : project . value . meta
} catch ( e ) {
} catch ( e ) {
return { }
return { }
}
}
@ -44,15 +66,15 @@ const [setup, use] = useInjectionState((_projectId?: MaybeRef<string>) => {
async function loadProjectMetaInfo ( force? : boolean ) {
async function loadProjectMetaInfo ( force? : boolean ) {
if ( ! projectMetaInfo . value || force ) {
if ( ! projectMetaInfo . value || force ) {
const data = await $api . project . metaGet ( project . value . id ! , { } , { } )
projectMetaInfo . value = await api . project . metaGet ( project . value . id ! , { } , { } )
projectMetaInfo . value = data
}
}
}
}
async function loadProjectRoles() {
async function loadProjectRoles() {
projectRoles . value = { }
projectRoles . value = { }
if ( isSharedBase . value ) {
if ( isSharedBase . value ) {
const user = await $ api. auth . me (
const user = await api . auth . me (
{ } ,
{ } ,
{
{
headers : {
headers : {
@ -60,33 +82,40 @@ const [setup, use] = useInjectionState((_projectId?: MaybeRef<string>) => {
} ,
} ,
} ,
} ,
)
)
projectRoles . value = user . roles
projectRoles . value = user . roles
} else if ( project . value . id ) {
} else if ( project . value . id ) {
const user = await $ api. auth . me ( { project_id : project.value.id } )
const user = await api . auth . me ( { project_id : project.value.id } )
projectRoles . value = user . roles
projectRoles . value = user . roles
}
}
}
}
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 , {
includeM2M : includeM2M.value ,
includeM2M : includeM2M.value ,
} )
} )
if ( tablesResponse . list ) tables . value = tablesResponse . list
if ( tablesResponse . list ) tables . value = tablesResponse . list
}
}
}
}
async function loadProject() {
async function loadProject ( id? : string ) {
if ( projectType === 'base' ) {
if ( id ) {
const baseData = await $api . public . sharedBaseGet ( route . params . projectId as string )
project . value = await api . project . read ( projectId . value )
project . value = await $api . project . read ( baseData . project_id ! )
} else if ( projectType === 'base' ) {
const baseData = await api . public . sharedBaseGet ( route . params . projectId as string )
project . value = await api . project . read ( baseData . project_id ! )
} else if ( projectId . value ) {
} else if ( projectId . value ) {
project . value = await $api . project . read ( projectId . value )
project . value = await api . project . read ( projectId . value )
} else {
} else {
return
return
}
}
await loadProjectRoles ( )
await loadProjectRoles ( )
await loadTables ( )
await loadTables ( )
setTheme ( projectMeta . value ? . theme )
setTheme ( projectMeta . value ? . theme )
projectLoadedHook . trigger ( project . value )
projectLoadedHook . trigger ( project . value )
@ -97,15 +126,13 @@ const [setup, use] = useInjectionState((_projectId?: MaybeRef<string>) => {
return
return
}
}
if ( data . meta && typeof data . meta === 'string' ) {
if ( data . meta && typeof data . meta === 'string' ) {
await $ api. project . update ( projectId . value , data )
await api . project . update ( projectId . value , data )
} else {
} else {
await $ api. project . update ( projectId . value , { . . . data , meta : JSON.stringify ( data . meta ) } )
await api . project . update ( projectId . value , { . . . data , meta : JSON.stringify ( data . meta ) } )
}
}
}
}
async function saveTheme ( _theme : Partial < ThemeConfig > ) {
async function saveTheme ( _theme : Partial < ThemeConfig > ) {
$e ( 'c:themes:change' )
const fullTheme = {
const fullTheme = {
primaryColor : theme.value.primaryColor ,
primaryColor : theme.value.primaryColor ,
accentColor : theme.value.accentColor ,
accentColor : theme.value.accentColor ,
@ -119,25 +146,30 @@ const [setup, use] = useInjectionState((_projectId?: MaybeRef<string>) => {
theme : fullTheme ,
theme : fullTheme ,
} ,
} ,
} )
} )
setTheme ( fullTheme )
setTheme ( fullTheme )
$e ( 'c:themes:change' )
}
}
watch (
watch (
( ) = > route . params ,
( ) = > route . params ,
( v ) = > {
( next ) = > {
if ( ! v ? . projectId ) {
if ( ! next . projectId ) {
setTheme ( )
setTheme ( )
}
}
} ,
} ,
)
)
// TODO useProject should only called inside a project for now this doesn't work
const reset = ( ) = > {
onScopeDispose ( ( ) = > {
project . value = { }
project . value = { }
tables . value = [ ]
tables . value = [ ]
projectMetaInfo . value = undefined
projectMetaInfo . value = undefined
projectRoles . value = { }
projectRoles . value = { }
} )
}
// TODO useProject should only called inside a project for now this doesn't work
// onScopeDispose(reset)
return {
return {
project ,
project ,
@ -156,6 +188,8 @@ const [setup, use] = useInjectionState((_projectId?: MaybeRef<string>) => {
projectMeta ,
projectMeta ,
saveTheme ,
saveTheme ,
projectLoadedHook : projectLoadedHook.on ,
projectLoadedHook : projectLoadedHook.on ,
reset ,
isLoading ,
}
}
} , 'useProject' )
} , 'useProject' )