Browse Source

feat(gui-v2): add eslint config and lint files

pull/2716/head
bcakmakoglu 2 years ago committed by Pranav C
parent
commit
fbc1ad38fd
  1. 10
      packages/nc-gui-v2/.eslintrc.js
  2. 8
      packages/nc-gui-v2/app.vue
  3. 37
      packages/nc-gui-v2/components/dashboard/TabView.vue
  4. 27
      packages/nc-gui-v2/components/dashboard/TreeView.vue
  5. 95
      packages/nc-gui-v2/components/smartsheet/Grid.vue
  6. 31
      packages/nc-gui-v2/components/tabs/Smartsheet.vue
  7. 26
      packages/nc-gui-v2/composables/metas.ts
  8. 14
      packages/nc-gui-v2/composables/project.ts
  9. 12
      packages/nc-gui-v2/composables/tabs.ts
  10. 49
      packages/nc-gui-v2/composables/user.ts
  11. 10
      packages/nc-gui-v2/helpers/errorUtils.ts
  12. 29
      packages/nc-gui-v2/layouts/default.vue
  13. 28
      packages/nc-gui-v2/nuxt.config.ts
  14. 8338
      packages/nc-gui-v2/package-lock.json
  15. 1
      packages/nc-gui-v2/package.json
  16. 74
      packages/nc-gui-v2/pages/dashboard/[projectId].vue
  17. 27
      packages/nc-gui-v2/pages/form.vue
  18. 16
      packages/nc-gui-v2/pages/index.vue
  19. 79
      packages/nc-gui-v2/pages/projects/create.vue
  20. 118
      packages/nc-gui-v2/pages/projects/createExternal.vue
  21. 121
      packages/nc-gui-v2/pages/projects/index.vue
  22. 19
      packages/nc-gui-v2/pages/sample.vue
  23. 73
      packages/nc-gui-v2/pages/signin.vue
  24. 63
      packages/nc-gui-v2/pages/signup.vue
  25. 34
      packages/nc-gui-v2/plugins/api.ts
  26. 4
      packages/nc-gui-v2/plugins/primevue.ts
  27. 13
      packages/nc-gui-v2/plugins/vuetify.ts
  28. 3
      packages/nc-gui-v2/tsconfig.json

10
packages/nc-gui-v2/.eslintrc.js

@ -0,0 +1,10 @@
const baseRules = {
'vue/no-setup-props-destructure': 0,
'no-console': 0,
'antfu/if-newline': 0,
}
module.exports = {
extends: ['@antfu'],
rules: baseRules,
}

8
packages/nc-gui-v2/app.vue

@ -1,6 +1,6 @@
<template> <template>
<!-- <NuxtLayout>--> <!-- <NuxtLayout> -->
<!-- <NuxtPage />--> <!-- <NuxtPage /> -->
<!-- </NuxtLayout>--> <!-- </NuxtLayout> -->
<NuxtPage/> <NuxtPage />
</template> </template>

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

@ -1,44 +1,29 @@
<template> <script setup lang="ts">
<div> import { useTabs } from '~/composables/tabs'
<v-tabs density="compact" v-model="activeTab">
<v-tab v-for="(tab,i) in tabs" :key="i" :value="i" >{{tab.title}} </v-tab> const { tabs, activeTab } = useTabs()
</script>
<template>
<div>
<v-tabs v-model="activeTab" density="compact">
<v-tab v-for="(tab, i) of tabs" :key="i" :value="i">
{{ tab.title }}
</v-tab>
</v-tabs> </v-tabs>
<v-window v-model="activeTab"> <v-window v-model="activeTab">
<v-window-item <v-window-item
v-for="(tab,i) in tabs" v-for="(tab, i) of tabs"
:key="i" :key="i"
:value="i" :value="i"
> >
<TabsSmartsheet :tab-meta="tab" /> <TabsSmartsheet :tab-meta="tab" />
</v-window-item> </v-window-item>
</v-window> </v-window>
</div> </div>
</template> </template>
<script setup lang="ts">
import { useTabs } from "~/composables/tabs";
const { tabs, activeTab } = useTabs();
// const tabItems = computed(() => {
// return tabs.value.map(tab => {
// return {
// label: tab.title,
// // icon: tab.icon,
// closable: true
// }
// })
// })
</script>
<style scoped> <style scoped>
</style> </style>

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

@ -1,23 +1,24 @@
<script setup lang="ts">
import { useProject } from '~/composables/project'
import { useTabs } from '~/composables/tabs'
const { tables } = useProject()
const { addTab } = useTabs()
</script>
<template> <template>
<div> <div>
<v-list density="medium"> <v-list density="medium">
<v-list-item v-for="table in tables" class="p-2 text-sm pointer" <v-list-item
@click="addTab({type:'table',title:table.title, id:table.id})"> v-for="table in tables" class="p-2 text-sm pointer"
{{ table.title }} @click="addTab({ type: 'table', title: table.title, id: table.id })"
</v-list-item> >
{{ table.title }}
</v-list-item>
</v-list> </v-list>
</div> </div>
</template> </template>
<script setup lang="ts">
import {useProject} from "~/composables/project";
import {useTabs} from "~/composables/tabs";
const {tables} = useProject()
const {addTab} = useTabs()
</script>
<style scoped> <style scoped>
.pointer{ .pointer{
cursor: pointer; cursor: pointer;

95
packages/nc-gui-v2/components/smartsheet/Grid.vue

@ -1,71 +1,64 @@
<script lang="ts" setup>
import { Api } from 'nocodb-sdk'
import { useNuxtApp } from '#app'
import { useUser } from '~/composables/user'
const { tabMeta, meta } = defineProps({
tabMeta: Object,
meta: Object,
})
const { project } = useProject()
const { user } = useUser()
const rows = ref()
const { $api } = useNuxtApp()
const loadData = async () => {
const response = await $api.dbTableRow.list('noco',
project.value.id,
meta.id, {}, {
headers: {
'xc-auth': user.token,
},
})
rows.value = response.list
}
onMounted(async () => {
await loadData()
})
</script>
<template> <template>
<div> <div>
<div class="card"> <div class="card">
<v-table> <v-table>
<thead> <thead>
<tr> <tr>
<th v-for="col in meta.columns"> <th v-for="col in meta.columns">
{{ col.title }} {{ col.title }}
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="(row, i) in rows" :key="i">
<tr v-for="(row,i) in rows" :key="i"> <th v-for="col in meta.columns" :key="col.title">
<th v-for="col in meta.columns" :key="col.title"> {{ row[col.title] }}
{{ row[col.title] }} </th>
</th> </tr>
</tr>
</tbody> </tbody>
<!-- <Column v-for="col in meta.columns" :key="col.id" :field="col.title" :header="col.title"> <!-- <Column v-for="col in meta.columns" :key="col.id" :field="col.title" :header="col.title">
<template v-if="col.uidt === 'LinkToAnotherRecord'" #body="{data:{[col.title]:d}}"> <template v-if="col.uidt === 'LinkToAnotherRecord'" #body="{data:{[col.title]:d}}">
{{ d && (Array.isArray(d) ? d : [d]).map(c1 => c1[Object.keys(c1)[1]]).join(', ') }} {{ d && (Array.isArray(d) ? d : [d]).map(c1 => c1[Object.keys(c1)[1]]).join(', ') }}
</template> </template>
</Column>--> </Column> -->
</v-table> </v-table>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts" setup>
import { useNuxtApp } from "#app";
import { Api } from "nocodb-sdk";
import { useUser } from "~/composables/user";
const { tabMeta, meta } = defineProps({
tabMeta: Object,
meta: Object
});
const { project } = useProject();
const { user } = useUser();
const rows = ref();
const { $api } = useNuxtApp();
const loadData = async () => {
const response = await $api.dbTableRow.list("noco",
project.value.id,
meta.id, {}, {
headers: {
"xc-auth": user.token
}
});
rows.value = response.list;
};
onMounted(async () => {
await loadData();
});
</script>
<style scoped> <style scoped>
</style> </style>

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

@ -1,36 +1,35 @@
<template>
<div>
<template v-if="meta && tabMeta">
<SmartsheetGrid :meta="meta" :tabMeta="tabMeta"></SmartsheetGrid>
</template>
</div>
</template>
<script setup lang="ts"> <script setup lang="ts">
import {useMetas} from "~/composables/metas"; import { computed, onMounted, watch } from 'vue'
import {computed, onMounted, watch} from 'vue' import { useMetas } from '~/composables/metas'
const {tabMeta} = defineProps({ const { tabMeta } = defineProps({
tabMeta: Object tabMeta: Object,
}) })
const {getMeta, metas} = useMetas() const { getMeta, metas } = useMetas()
const meta = computed(() => { const meta = computed(() => {
return metas.value?.[tabMeta?.id] return metas.value?.[tabMeta?.id]
}) })
onMounted(async () => { onMounted(async () => {
await getMeta(tabMeta?.id) await getMeta(tabMeta?.id)
}) })
watch(() => tabMeta && tabMeta?.id, async (newVal, oldVal) => { watch(() => tabMeta && tabMeta?.id, async (newVal, oldVal) => {
if (newVal !== oldVal) { if (newVal !== oldVal)
await getMeta(newVal) await getMeta(newVal)
}
}) })
</script> </script>
<template>
<div>
<template v-if="meta && tabMeta">
<SmartsheetGrid :meta="meta" :tab-meta="tabMeta" />
</template>
</div>
</template>
<style scoped> <style scoped>
</style> </style>

26
packages/nc-gui-v2/composables/metas.ts

@ -1,20 +1,18 @@
import {useNuxtApp, useState} from "#app"; import type { Api, TableType } from 'nocodb-sdk'
import {Api, TableType} from "nocodb-sdk"; import { useNuxtApp, useState } from '#app'
import {useUser} from "~/composables/user"; import { useUser } from '~/composables/user'
import {useProject} from "~/composables/project"; import { useProject } from '~/composables/project'
export const useMetas = () => { export const useMetas = () => {
const {$api} = useNuxtApp() const { $api } = useNuxtApp()
const {user} = useUser() const { user } = useUser()
const {tables} = useProject() const { tables } = useProject()
const metas = useState<{ [idOrTitle: string]: TableType | any }>('metas', () => ({})) const metas = useState<{ [idOrTitle: string]: TableType | any }>('metas', () => ({}))
const getMeta = async (tableIdOrTitle: string, force = false) => { const getMeta = async (tableIdOrTitle: string, force = false) => {
if (!force && metas[tableIdOrTitle]) { if (!force && metas[tableIdOrTitle])
return metas[tableIdOrTitle] return metas[tableIdOrTitle]
}
const modelId = (tables.value.find(t => t.title === tableIdOrTitle || t.id === tableIdOrTitle) || {}).id const modelId = (tables.value.find(t => t.title === tableIdOrTitle || t.id === tableIdOrTitle) || {}).id
if (!modelId) { if (!modelId) {
@ -24,18 +22,18 @@ export const useMetas = () => {
const model = await $api.dbTable.read(modelId, { const model = await $api.dbTable.read(modelId, {
headers: { headers: {
'xc-auth': user.token 'xc-auth': user.token,
} },
}) })
metas.value = { metas.value = {
...metas.value, ...metas.value,
[model.id]: model, [model.id]: model,
[model.title]: model [model.title]: model,
} }
return model return model
} }
return {getMeta, metas} return { getMeta, metas }
} }

14
packages/nc-gui-v2/composables/project.ts

@ -1,11 +1,10 @@
import {useNuxtApp} from "#app"; import type { TableType } from 'nocodb-sdk'
import {Api, TableType} from "nocodb-sdk"; import { useNuxtApp } from '#app'
import {useUser} from "~/composables/user";
export const useProject = () => { export const useProject = () => {
const {$api} = useNuxtApp() const { $api } = useNuxtApp()
const project = useState<{ id?: string, title?: string }>('project', null) const project = useState<{ id?: string; title?: string }>('project', null)
const tables = useState<Array<TableType>>('tables', null) const tables = useState<Array<TableType>>('tables', null)
const loadTables = async () => { const loadTables = async () => {
@ -15,13 +14,12 @@ export const useProject = () => {
tables.value = tablesResponse.list tables.value = tablesResponse.list
} }
const loadProject = async (projectId:string) => { const loadProject = async (projectId: string) => {
const projectResponse = await $api.project.read(projectId) const projectResponse = await $api.project.read(projectId)
console.log(projectResponse) console.log(projectResponse)
project.value = projectResponse project.value = projectResponse
} }
return { project, tables, loadProject, loadTables }
return {project, tables, loadProject, loadTables}
} }

12
packages/nc-gui-v2/composables/tabs.ts

@ -1,14 +1,14 @@
import {useState} from "#app"; import { useState } from '#app'
interface TabItem { interface TabItem {
type: 'table' | 'view', type: 'table' | 'view'
title: string, title: string
id:string id: string
} }
export const useTabs = () => { export const useTabs = () => {
const tabs = useState<Array<TabItem>>('tabs', () => []) const tabs = useState<Array<TabItem>>('tabs', () => [])
const activeTab = useState<number>('activeTab', ()=>0) const activeTab = useState<number>('activeTab', () => 0)
const addTab = (tabMeta: TabItem) => { const addTab = (tabMeta: TabItem) => {
tabs.value = [...(tabs.value || []), tabMeta] tabs.value = [...(tabs.value || []), tabMeta]
@ -18,5 +18,5 @@ export const useTabs = () => {
tabs.value = [] tabs.value = []
} }
return {tabs, addTab, activeTab, clearTabs} return { tabs, addTab, activeTab, clearTabs }
} }

49
packages/nc-gui-v2/composables/user.ts

@ -1,51 +1,46 @@
import {store} from 'nuxt3-store' import { store } from 'nuxt3-store'
import {Api} from "nocodb-sdk"; import { useNuxtApp } from '#app'
import {useNuxtApp} from "#app";
export const useUser = () =>{ export const useUser = () => {
const user = store({ const user = store({
name: 'user', name: 'user',
type: 'localstorage', type: 'localstorage',
value: {token: null, user : null}, value: { token: null, user: null },
reactiveType: 'reactive', reactiveType: 'reactive',
version: '1.0.0' version: '1.0.0',
}) })
const {$api} = useNuxtApp() const { $api } = useNuxtApp()
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const getUser = async (args = {}) => {
const getUser =async (args = {}) => {
const userInfo = await $api.auth.me(args, { const userInfo = await $api.auth.me(args, {
headers: { headers: {
'xc-auth': user.value.token 'xc-auth': user.value.token,
} },
}) })
user.user = userInfo user.user = userInfo
} }
const setToken = (token) => { const setToken = (token) => {
user.token = token user.token = token
} }
$api?.instance?.interceptors.request.use((config) => { $api?.instance?.interceptors.request.use((config) => {
config.headers['xc-gui'] = 'true' config.headers['xc-gui'] = 'true'
if (user?.token) { if (user?.token)
config.headers['xc-auth'] = user?.token config.headers['xc-auth'] = user?.token
}
if (!config.url.endsWith('/user/me') && !config.url.endsWith('/admin/roles')) { if (!config.url.endsWith('/user/me') && !config.url.endsWith('/admin/roles')) {
// config.headers['xc-preview'] = store.state.users.previewAs // config.headers['xc-preview'] = store.state.users.previewAs
} }
if (!config.url.endsWith('/user/me') && !config.url.endsWith('/admin/roles')) { if (!config.url.endsWith('/user/me') && !config.url.endsWith('/admin/roles')) {
if (route && route.params && route.params.shared_base_id) { if (route && route.params && route.params.shared_base_id)
config.headers['xc-shared-base-id'] = route.params.shared_base_id config.headers['xc-shared-base-id'] = route.params.shared_base_id
}
} }
return config return config
@ -82,13 +77,13 @@ export const useUser = () =>{
// Try request again with new token // Try request again with new token
return $api.instance.post('/auth/refresh-token', null, { return $api.instance.post('/auth/refresh-token', null, {
withCredentials: true withCredentials: true,
}) })
.then((token) => { .then((token) => {
// New request with new token // New request with new token
const config = error.config const config = error.config
config.headers['xc-auth'] = token.data.token config.headers['xc-auth'] = token.data.token
user.token = token.data.token user.token = token.data.token
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
$api.instance.request(config).then((response) => { $api.instance.request(config).then((response) => {
@ -99,12 +94,13 @@ export const useUser = () =>{
}) })
}) })
.catch(async (error) => { .catch(async (error) => {
//todo: clear token // todo: clear token
// await store.dispatch('users/ActSignOut') // await store.dispatch('users/ActSignOut')
setToken(null) setToken(null)
if (store.state.project.appInfo.firstUser) { if (store.state.project.appInfo.firstUser) {
router.replace('/') router.replace('/')
} else { }
else {
// $toast.clear() // $toast.clear()
// $toast.info('Token Expired. Please login again.', { // $toast.info('Token Expired. Please login again.', {
// position: 'bottom-center' // position: 'bottom-center'
@ -115,10 +111,5 @@ export const useUser = () =>{
}) })
}) })
return { user, setToken, getUser }
return {user,setToken, getUser}
} }

10
packages/nc-gui-v2/helpers/errorUtils.ts

@ -1,13 +1,15 @@
export async function extractSdkResponseErrorMsg(e:Error & {response:any}) { export async function extractSdkResponseErrorMsg(e: Error & { response: any }) {
if (!e || !e.response) { return e.message } if (!e || !e.response) return e.message
let msg let msg
if (e.response.data instanceof Blob) { if (e.response.data instanceof Blob) {
try { try {
msg = JSON.parse(await e.response.data.text()).msg msg = JSON.parse(await e.response.data.text()).msg
} catch { }
catch {
msg = 'Some internal error occurred' msg = 'Some internal error occurred'
} }
} else { }
else {
msg = e.response.data.msg || e.response.data.message || 'Some internal error occurred' msg = e.response.data.msg || e.response.data.message || 'Some internal error occurred'
} }
return msg || 'Some error occurred' return msg || 'Some error occurred'

29
packages/nc-gui-v2/layouts/default.vue

@ -1,27 +1,26 @@
<script>
export default {
name: 'Default',
}
</script>
<template> <template>
<div class=""> <div class="">
<!-- <div class="topbar">--> <!-- <div class="topbar"> -->
<!-- </div>--> <!-- </div> -->
<!-- <div class="sidebar">--> <!-- <div class="sidebar"> -->
<!-- </div>--> <!-- </div> -->
<!-- <div class="content">--> <!-- <div class="content"> -->
<v-layout> <v-layout>
<v-app-bar color=""></v-app-bar> <v-app-bar color="" />
<slot></slot> <slot />
</v-layout> </v-layout>
<!-- </div>--> <!-- </div> -->
</div> </div>
</template> </template>
<script>
export default {
name: "default"
}
</script>
<style scoped> <style scoped>
</style> </style>

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

@ -1,35 +1,17 @@
import {defineNuxtConfig} from 'nuxt' import { defineNuxtConfig } from 'nuxt'
// https://v3.nuxtjs.org/api/configuration/nuxt.config // https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({ export default defineNuxtConfig({
// modules: ['@nuxtjs/tailwindcss'],
// buildModules: [
// 'nuxt-vite'
// ],
modules: ['nuxt3-store'], modules: ['nuxt3-store'],
ssr:false, ssr: false,
plugins: [
// '~/plugins/vuetify.ts',
// '~/plugins/api.ts',
],
css: ['vuetify/lib/styles/main.sass'], css: ['vuetify/lib/styles/main.sass'],
build: { build: {
transpile: ['vuetify'] transpile: ['vuetify'],
}, },
// css: [
// 'primevue/resources/themes/saga-blue/theme.css',
// 'primevue/resources/primevue.css',
// 'primeicons/primeicons.css',
// 'primeflex/primeflex.css',
// ],
// build: {
// transpile: ['primevue']
// },
vite: { vite: {
define: { define: {
'process.env.DEBUG': 'false', 'process.env.DEBUG': 'false',
} },
} },
}) })

8338
packages/nc-gui-v2/package-lock.json generated

File diff suppressed because it is too large Load Diff

1
packages/nc-gui-v2/package.json

@ -7,6 +7,7 @@
"preview": "nuxt preview" "preview": "nuxt preview"
}, },
"devDependencies": { "devDependencies": {
"@antfu/eslint-config": "^0.25.2",
"@nuxtjs/tailwindcss": "^5.1.2", "@nuxtjs/tailwindcss": "^5.1.2",
"fibers": "^5.0.1", "fibers": "^5.0.1",
"nuxt": "3.0.0-rc.3", "nuxt": "3.0.0-rc.3",

74
packages/nc-gui-v2/pages/dashboard/[projectId].vue

@ -1,62 +1,40 @@
<template> <script setup lang="ts">
import { watch } from 'vue'
import { useProject } from '~/composables/project'
import { useTabs } from '~/composables/tabs'
const route = useRoute()
const { user } = useUser()
const { loadProject, loadTables } = useProject()
const { clearTabs } = useTabs()
onMounted(async () => {
await loadProject(route.params.projectId as string)
await loadTables()
})
watch(() => route.params.projectId, async (newVal, oldVal) => {
if (newVal && newVal !== oldVal) {
clearTabs()
await loadProject(newVal as string)
await loadTables()
}
})
</script>
<template>
<NuxtLayout> <NuxtLayout>
<v-navigation-drawer color="" permanent> <v-navigation-drawer color="" permanent>
<DashboardTreeView />
<DashboardTreeView></DashboardTreeView>
</v-navigation-drawer> </v-navigation-drawer>
<v-main> <v-main>
<v-container> <v-container>
<DashboardTabView></DashboardTabView> <DashboardTabView />
</v-container> </v-container>
</v-main> </v-main>
</NuxtLayout> </NuxtLayout>
<!-- <NuxtLayout>
&lt;!&ndash; todo: move to layout or create a reusable component &ndash;&gt;
<div class="nc-container">
<div class="nc-topbar shadow-2">
</div>
<div class="nc-sidebar shadow-2 p-4 overflow-y-auto">
<DashboardTreeView></DashboardTreeView>
</div>
<div class="nc-content p-4 overflow-auto">
<DashboardTabView></DashboardTabView>
</div>
</div>
</NuxtLayout>-->
</template> </template>
<script setup lang="ts">
import { useProject } from "~/composables/project";
import { watch } from "vue";
import { useTabs } from "~/composables/tabs";
const route = useRoute();
const { loadProject, loadTables } = useProject();
const { clearTabs } = useTabs();
const {user} = useUser()
onMounted(async () => {
await loadProject(route.params.projectId as string);
await loadTables();
});
watch(() => route.params.projectId, async (newVal, oldVal) => {
if (newVal && newVal !== oldVal) {
clearTabs();
await loadProject(newVal as string);
await loadTables();
}
});
</script>
<style scoped lang="scss"> <style scoped lang="scss">
.nc-container { .nc-container {
.nc-topbar { .nc-topbar {

27
packages/nc-gui-v2/pages/form.vue

@ -1,30 +1,29 @@
<script setup lang="ts">
import { ref } from 'vue'
import { useToast } from 'primevue/usetoast'
const text = ref()
const toast = useToast()
const greet = () => {
toast.add({ severity: 'info', summary: `Hello ${text.value}` })
}
</script>
<template> <template>
<div class="container"> <div class="container">
<Card style="width:500px"> <Card style="width:500px">
<template #title> <template #title>
Signup Signup
</template> </template>
<template #content> <template #content>
<InputText type="text" v-model="value" label="Email"/> <InputText v-model="value" type="text" label="Email" />
</template> </template>
<template #footer> <template #footer>
<Button label="Small" icon="pi pi-check" class="p-button-sm" /> <Button label="Small" icon="pi pi-check" class="p-button-sm" />
</template> </template>
</Card> </Card>
</div> </div>
</template> </template>
<script setup lang="ts">
import { ref } from 'vue';
import { useToast } from "primevue/usetoast";
const text = ref();
const toast = useToast();
const greet = () => {
toast.add({severity: 'info', summary: 'Hello ' + text.value});
}
</script>
<style lang="scss"> <style lang="scss">
.container { .container {
margin: 0 auto; margin: 0 auto;

16
packages/nc-gui-v2/pages/index.vue

@ -1,17 +1,15 @@
<template>
<div class="container">
</div>
</template>
<script setup lang="ts"> <script setup lang="ts">
import {useRouter} from "#app"; import { useRouter } from '#app'
const $router = useRouter() const router = useRouter()
$router.replace('/projects') router.replace('/projects')
</script> </script>
<template>
<div class="container" />
</template>
<style lang="scss"> <style lang="scss">
</style> </style>

79
packages/nc-gui-v2/pages/projects/create.vue

@ -1,13 +1,46 @@
<script lang="ts" setup>
import { ref } from 'vue'
import { useNuxtApp, useRouter } from '#app'
const name = ref('')
const loading = ref(false)
const valid = ref(false)
const { $api } = useNuxtApp()
const $router = useRouter()
const { user } = useUser()
const titleValidationRule = [
v => !!v || 'Title is required',
v => v.length <= 50 || 'Project name exceeds 50 characters',
]
const createProject = async () => {
loading.value = true
try {
const result = (await $api.project.create({
title: name.value,
}))
await $router.push(`/dashboard/${result.id}`)
}
catch (e) {
// todo: toast
// this.$toast.error(await this._extractSdkResponseErrorMsg(e)).goAway(3000)
}
loading.value = false
}
</script>
<template> <template>
<NuxtLayout> <NuxtLayout>
<div class="main justify-center d-flex mx-auto" style="min-height: 600px;overflow: auto"> <div class="main justify-center d-flex mx-auto" style="min-height: 600px;overflow: auto">
<v-form ref="form" v-model="valid" @submit.prevent="createProject"> <v-form ref="form" v-model="valid" @submit.prevent="createProject">
<v-card style="width:530px;margin-top: 100px" class="mx-auto"> <v-card style="width:530px;margin-top: 100px" class="mx-auto">
<!-- Create Project --> <!-- Create Project -->
<v-container class="pb-10 px-12" style="padding-top: 43px !important;"> <v-container class="pb-10 px-12" style="padding-top: 43px !important;">
<h1 class="mt-4 mb-4 text-center"> <h1 class="mt-4 mb-4 text-center">
<!-- {{ $t('activity.createProject') }}--> <!-- {{ $t('activity.createProject') }} -->
Create Project Create Project
</h1> </h1>
<div class="mx-auto" style="width:350px"> <div class="mx-auto" style="width:350px">
@ -18,7 +51,7 @@
class="nc-metadb-project-name" class="nc-metadb-project-name"
label="Project name" label="Project name"
/> />
<!-- :rules="titleValidationRule"--> <!-- :rules="titleValidationRule" -->
</div> </div>
<div class="text-center"> <div class="text-center">
<v-btn <v-btn
@ -32,7 +65,7 @@
mdi-rocket-launch-outline mdi-rocket-launch-outline
</v-icon> </v-icon>
<!-- Create --> <!-- Create -->
<!-- <span class="mr-1">{{ // $t("general.create") }}</span>--> <!-- <span class="mr-1">{{ // $t("general.create") }}</span> -->
<span class="mr-1"> Create project </span> <span class="mr-1"> Create project </span>
</v-btn> </v-btn>
</div> </div>
@ -43,44 +76,6 @@
</NuxtLayout> </NuxtLayout>
</template> </template>
<script lang="ts" setup>
import { useNuxtApp, useRouter } from "#app";
import { ref } from "vue";
const name = ref('');
const loading = ref(false);
const valid = ref(false);
const { $api } = useNuxtApp();
const $router = useRouter();
const {user} = useUser()
const titleValidationRule = [
v => !!v || "Title is required",
v => v.length <= 50 || "Project name exceeds 50 characters"
];
const createProject = async () => {
loading.value = true;
try {
const result = (await $api.project.create({
title: name.value
}));
await $router.push( `/dashboard/${result.id}`);
} catch (e) {
// todo: toast
// this.$toast.error(await this._extractSdkResponseErrorMsg(e)).goAway(3000)
}
loading.value = false;
};
</script>
<style scoped> <style scoped>
/deep/ label { /deep/ label {
font-size: .75rem; font-size: .75rem;

118
packages/nc-gui-v2/pages/projects/createExternal.vue

@ -1,13 +1,65 @@
<script lang="ts" setup>
import { ref } from 'vue'
import { useNuxtApp, useRouter } from '#app'
const name = ref('')
const loading = ref(false)
const valid = ref(false)
const projectDatasource = reactive({
client: 'mysql2',
connection: {
user: 'root',
password: 'password',
port: 3306,
host: 'localhost',
database: '',
},
})
const { $api } = useNuxtApp()
const $router = useRouter()
const { user } = useUser()
const titleValidationRule = [
v => !!v || 'Title is required',
v => v.length <= 50 || 'Project name exceeds 50 characters',
]
const createProject = async () => {
loading.value = true
try {
const result = await $api.project.create({
title: name.value,
bases: [
{
type: projectDatasource.client,
config: projectDatasource,
// inflection_column: inflection.column_name,
// inflection_table: inflection.table_name
},
],
external: true,
})
await $router.push(`/dashboard/${result.id}`)
}
catch (e) {
// todo: toast
// this.$toast.error(await this._extractSdkResponseErrorMsg(e)).goAway(3000)
}
loading.value = false
}
</script>
<template> <template>
<NuxtLayout> <NuxtLayout>
<div class="main justify-center d-flex mx-auto" style="min-height: 600px;overflow: auto"> <div class="main justify-center d-flex mx-auto" style="min-height: 600px;overflow: auto">
<v-form ref="form" v-model="valid" @submit.prevent="createProject"> <v-form ref="form" v-model="valid" @submit.prevent="createProject">
<v-card style="width:530px;margin-top: 100px" class="mx-auto"> <v-card style="width:530px;margin-top: 100px" class="mx-auto">
<!-- Create Project --> <!-- Create Project -->
<v-container class="pb-10 px-12" style="padding-top: 43px !important;"> <v-container class="pb-10 px-12" style="padding-top: 43px !important;">
<h1 class="mt-4 mb-4 text-center"> <h1 class="mt-4 mb-4 text-center">
<!-- {{ $t('activity.createProject') }}--> <!-- {{ $t('activity.createProject') }} -->
Create Project Create Project
</h1> </h1>
<div class="mx-auto" style="width:350px"> <div class="mx-auto" style="width:350px">
@ -18,10 +70,9 @@
class="nc-metadb-project-name" class="nc-metadb-project-name"
label="Project name" label="Project name"
/> />
<!-- :rules="titleValidationRule"--> <!-- :rules="titleValidationRule" -->
</div> </div>
<v-container fluid> <v-container fluid>
<v-row> <v-row>
<v-col cols="6"> <v-col cols="6">
@ -83,7 +134,7 @@
mdi-rocket-launch-outline mdi-rocket-launch-outline
</v-icon> </v-icon>
<!-- Create --> <!-- Create -->
<!-- <span class="mr-1">{{ // $t("general.create") }}</span>--> <!-- <span class="mr-1">{{ // $t("general.create") }}</span> -->
<span class="mr-1"> Create project </span> <span class="mr-1"> Create project </span>
</v-btn> </v-btn>
</div> </div>
@ -94,63 +145,6 @@
</NuxtLayout> </NuxtLayout>
</template> </template>
<script lang="ts" setup>
import { useNuxtApp, useRouter } from "#app";
import { ref } from "vue";
const name = ref('');
const loading = ref(false);
const valid = ref(false);
const projectDatasource = reactive({
client:'mysql2',
connection:{
user: 'root',
password: 'password',
port: 3306,
host: 'localhost',
database: '',
}
});
const { $api } = useNuxtApp();
const $router = useRouter();
const {user} = useUser()
const titleValidationRule = [
v => !!v || "Title is required",
v => v.length <= 50 || "Project name exceeds 50 characters"
];
const createProject = async () => {
loading.value = true;
try {
const result= await $api.project.create({
title: name.value,
bases: [
{
type: projectDatasource.client,
config: projectDatasource,
// inflection_column: inflection.column_name,
// inflection_table: inflection.table_name
}
],
external: true
})
await $router.push( `/dashboard/${result.id}`);
} catch (e) {
// todo: toast
// this.$toast.error(await this._extractSdkResponseErrorMsg(e)).goAway(3000)
}
loading.value = false;
};
</script>
<style scoped> <style scoped>
/deep/ label { /deep/ label {
font-size: .75rem; font-size: .75rem;

121
packages/nc-gui-v2/pages/projects/index.vue

@ -1,28 +1,46 @@
<template> <script setup lang="ts">
<NuxtLayout> import { useRouter } from '#app'
<v-navigation-drawer color="" permanent></v-navigation-drawer>
<v-main>
<v-container>
const { $api } = useNuxtApp()
const { user } = useUser()
<div class="pa-2 d-flex mb-10"> const $router = useRouter()
<v-spacer></v-spacer>
<v-btn size="small" class="caption text-capitalize mr-2" color="primary" @click="createProject">Create Project</v-btn> const projects = ref()
<v-btn size="small" class="caption text-capitalize mr-2" color="primary" @click="createExtProject">Create External Project</v-btn>
</div> const loadProjects = async () => {
const projectsResponse = await $api.project.list({}, {
headers: {
'xc-auth': user.token,
},
})
projects.value = projectsResponse.list
}
<!-- tod const navigateToDashboard = async (project) => {
o: move to layout or create a reusable component --> await $router.push(`/dashboard/${project.id}`)
<!-- <div class="nc-container">--> }
<!-- <div class="nc-topbar shadow-2">-->
<!-- </div>-->
<!-- <div class="nc-sidebar shadow-2 p-4 overflow-y-auto">-->
<!-- </div>--> onMounted(async () => {
<!-- <div class="nc-content p-4 overflow-auto">--> await loadProjects()
<v-row> })
<v-col cols="4" v-for="project in projects" :key="project.id"> </script>
<template>
<NuxtLayout>
<v-navigation-drawer color="" permanent />
<v-main>
<v-container>
<div class="pa-2 d-flex mb-10">
<v-spacer />
<v-btn size="small" class="caption text-capitalize mr-2" color="primary" @click="createProject">
Create Project
</v-btn>
<v-btn size="small" class="caption text-capitalize mr-2" color="primary" @click="createExtProject">
Create External Project
</v-btn>
</div><v-row>
<v-col v-for="project in projects" :key="project.id" cols="4">
<v-card @click="navigateToDashboard(project)"> <v-card @click="navigateToDashboard(project)">
<v-card-title> <v-card-title>
<div class="text-center"> <div class="text-center">
@ -30,72 +48,9 @@
</div> </div>
</v-card-title> </v-card-title>
</v-card> </v-card>
</v-col> </v-col>
</v-row> </v-row>
</v-container> </v-container>
<!-- </div>-->
<!-- </div>-->
</v-main> </v-main>
</NuxtLayout> </NuxtLayout>
</template> </template>
<script setup lang="ts">
import { useRouter } from "#app";
const { $api } = useNuxtApp();
const { user } = useUser();
const $router = useRouter();
const projects = ref();
const loadProjects = async () => {
const projectsResponse = await $api.project.list();
projects.value = projectsResponse.list;
};
const navigateToDashboard = async (project) => {
await $router.push("/dashboard/" + project.id);
};
const createProject =()=> $router.push('/projects/create')
const createExtProject =()=> $router.push('/projects/createExternal')
onMounted(async () => {
await loadProjects();
});
</script>
<style scoped lang="scss">
//.nc-container {
// .nc-topbar {
// position: fixed;
// top: 0;
// left: 0;
// height: 50px;
// width: 100%;
// z-index: 5;
// }
//
// .nc-sidebar {
// position: fixed;
// top: 50px;
// left: 0;
// height: calc(100% - 50px);
// width: 250px;
// }
//
// .nc-content {
// position: fixed;
// top: 50px;
// left: 250px;
// height: calc(100% - 50px);
// width: calc(100% - 250px);
// }
//}
</style>

19
packages/nc-gui-v2/pages/sample.vue

@ -1,18 +1,17 @@
<template>
<div>
<Sidebar :visible="true" position="left" :dismissable="false">
Content
</Sidebar>
</div>
</template>
<script> <script>
export default { export default {
name: "dashboard" name: 'Dashboard',
} }
</script> </script>
<template>
<div>
<Sidebar :visible="true" position="left" :dismissable="false">
Content
</Sidebar>
</div>
</template>
<style scoped> <style scoped>
</style> </style>

73
packages/nc-gui-v2/pages/signin.vue

@ -1,24 +1,55 @@
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { useUser } from '~/composables/user'
import { extractSdkResponseErrorMsg } from '~/helpers/errorUtils'
import { useNuxtApp, useRouter } from '#app'
const { $api } = useNuxtApp()
const $router = useRouter()
const valid = ref()
const error = ref()
const form = reactive({
email: '',
password: '',
})
const { user, setToken } = useUser()
const signIn = async () => {
error.value = null
try {
const { token } = await $api.auth.signin(form)
await setToken(token)
await $router.push('/projects')
}
catch (e) {
error.value = await extractSdkResponseErrorMsg(e)
}
}
</script>
<template> <template>
<div> <div>
<!-- Enter your work email --> <!-- Enter your work email -->
<v-card class="pa-10 mx-auto mt-10" style="max-width: 500px"> <v-card class="pa-10 mx-auto mt-10" style="max-width: 500px">
<v-card-text> <v-card-text>
<v-alert v-if="error" density="medium" class="mb-10" type="error">
<v-alert density="medium" class="mb-10" v-if="error" type="error">{{ error }}</v-alert> {{ error }}
</v-alert>
<div class="p-float-label "> <div class="p-float-label ">
<v-text-field label="Email" id="email" type="text" v-model="form.email" style="width:100%"/> <v-text-field id="email" v-model="form.email" label="Email" type="text" style="width:100%" />
</div> </div>
<!-- Enter your password --> <!-- Enter your password -->
<div class="p-float-label "> <div class="p-float-label ">
<v-text-field label="Password" id="password" type="password" v-model="form.password" style="width:100%"/> <v-text-field id="password" v-model="form.password" label="Password" type="password" style="width:100%" />
</div> </div>
<div class="text-center"> <div class="text-center">
<v-btn <v-btn
class="" class=""
@click="signIn" @click="signIn"
> >
<b>Sign In</b> <b>Sign In</b>
</v-btn> </v-btn>
@ -26,38 +57,8 @@
</v-card-text> </v-card-text>
</v-card> </v-card>
</div> </div>
</template> </template>
<script setup lang="ts">
import {ref, reactive} from 'vue'
import {useUser} from "~/composables/user";
import {extractSdkResponseErrorMsg} from "~/helpers/errorUtils";
import {useNuxtApp, useRouter} from "#app";
const { $api} = useNuxtApp()
const $router = useRouter()
const valid = ref()
const error = ref()
const form = reactive({
email: '',
password: ''
})
const {user, setToken} = useUser()
const signIn = async () => {
error.value = null
try {
const {token} = await $api.auth.signin(form)
await setToken(token)
await $router.push('/projects')
} catch (e) {
error.value = await extractSdkResponseErrorMsg(e)
}
}
</script>
<style scoped> <style scoped>
</style> </style>

63
packages/nc-gui-v2/pages/signup.vue

@ -1,18 +1,46 @@
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { useUser } from '~/composables/user'
import { extractSdkResponseErrorMsg } from '~/helpers/errorUtils'
const { $api, $router } = useNuxtApp()
const valid = ref()
const error = ref()
const form = reactive({
email: '',
password: '',
})
const { user, setToken } = useUser()
const signUp = async () => {
error.value = null
try {
const { token } = await $api.auth.signup(form)
await setToken(token)
$router.push('/projects')
}
catch (e) {
error.value = await extractSdkResponseErrorMsg(e)
}
}
</script>
<template> <template>
<div> <div>
<!-- Enter your work email --> <!-- Enter your work email -->
<v-card class="pa-10 mx-auto mt-10" style="max-width: 500px"> <v-card class="pa-10 mx-auto mt-10" style="max-width: 500px">
<v-card-text> <v-card-text>
<v-alert v-if="error" density="medium" class="mb-4" type="error">
<v-alert density="medium" class="mb-4" v-if="error" type="error">{{ error }}</v-alert> {{ error }}
</v-alert>
<div class="p-float-label "> <div class="p-float-label ">
<v-text-field label="Email" id="email" type="text" v-model="form.email" style="width:100%"/> <v-text-field id="email" v-model="form.email" label="Email" type="text" style="width:100%" />
</div> </div>
<!-- Enter your password --> <!-- Enter your password -->
<div class="p-float-label "> <div class="p-float-label ">
<v-text-field label="Password" id="password" type="password" v-model="form.password" style="width:100%"/> <v-text-field id="password" v-model="form.password" label="Password" type="password" style="width:100%" />
</div> </div>
<div class="text-center"> <div class="text-center">
@ -26,35 +54,8 @@
</v-card-text> </v-card-text>
</v-card> </v-card>
</div> </div>
</template> </template>
<script setup lang="ts">
import {ref, reactive} from 'vue'
import {useUser} from "~/composables/user";
import {extractSdkResponseErrorMsg} from "~/helpers/errorUtils";
const {$api, $router} = useNuxtApp()
const valid = ref()
const error = ref()
const form = reactive({
email: '',
password: ''
})
const {user, setToken} = useUser()
const signUp = async () => {
error.value = null
try {
const {token} = await $api.auth.signup(form)
await setToken(token)
$router.push('/projects')
} catch (e) {
error.value = await extractSdkResponseErrorMsg(e)
}
}
</script>
<style scoped> <style scoped>
</style> </style>

34
packages/nc-gui-v2/plugins/api.ts

@ -1,35 +1,23 @@
import { useNuxtApp } from "#app"; import { Api } from 'nocodb-sdk'
import { Api } from "nocodb-sdk"; import { defineNuxtPlugin } from 'nuxt3/app'
import { defineNuxtPlugin } from "nuxt3/app";
export default defineNuxtPlugin((nuxtApp) => { export default defineNuxtPlugin((nuxtApp) => {
const api = getApi(null, null)
nuxtApp.provide('api', api)
// Doing something with nuxtApp })
const api = getApi(null, null);
// nuxtApp.provide("api", api);
return {
provide: {
api
}
};
});
export function getApi($store, $axios) { export function getApi($store, $axios) {
const api = new Api({ const api = new Api({
baseURL: "http://localhost:8080", baseURL: 'http://localhost:8080',
headers: { headers: {
"xc-auth": $store?.state?.users?.token 'xc-auth': $store?.state?.users?.token,
} },
}); })
if ($axios) { if ($axios) {
// overwrite with nuxt axios instance // overwrite with nuxt axios instance
api.instance = $axios; api.instance = $axios
} }
return api; return api
} }

4
packages/nc-gui-v2/plugins/primevue.ts

@ -12,7 +12,7 @@
// import Dropdown from "primevue/dropdown"; // import Dropdown from "primevue/dropdown";
// import ToastService from "primevue/toastservice"; // import ToastService from "primevue/toastservice";
// //
export default defineNuxtPlugin(nuxtApp => { export default defineNuxtPlugin((nuxtApp) => {
// nuxtApp.vueApp.use(PrimeVue, { ripple: true }); // nuxtApp.vueApp.use(PrimeVue, { ripple: true });
// nuxtApp.vueApp.use(ToastService); // nuxtApp.vueApp.use(ToastService);
// nuxtApp.vueApp.component("Button", Button); // nuxtApp.vueApp.component("Button", Button);
@ -26,4 +26,4 @@ export default defineNuxtPlugin(nuxtApp => {
// nuxtApp.vueApp.component("Dropdown", Dropdown); // nuxtApp.vueApp.component("Dropdown", Dropdown);
// nuxtApp.vueApp.component("Column", Column); // nuxtApp.vueApp.component("Column", Column);
// //other components that you need // //other components that you need
}); })

13
packages/nc-gui-v2/plugins/vuetify.ts

@ -1,21 +1,12 @@
import { createVuetify } from 'vuetify' import { createVuetify } from 'vuetify'
// import { import { defineNuxtPlugin } from 'nuxt/app'
// VApp,
// VAppBar,
// VBtn
// } from 'vuetify/components'
import {defineNuxtPlugin} from "nuxt/app";
// Import everything // Import everything
import * as components from 'vuetify/components' import * as components from 'vuetify/components'
export default defineNuxtPlugin((nuxtApp) => { export default defineNuxtPlugin((nuxtApp) => {
const vuetify = createVuetify({ const vuetify = createVuetify({
components/*: { components,
VApp,
VAppBar,
VBtn*/
// }
}) })
nuxtApp.vueApp.use(vuetify) nuxtApp.vueApp.use(vuetify)
}) })

3
packages/nc-gui-v2/tsconfig.json

@ -1,5 +1,4 @@
{ {
// https://v3.nuxtjs.org/concepts/typescript // https://v3.nuxtjs.org/concepts/typescript
"extends": "./.nuxt/tsconfig.json", "extends": "./.nuxt/tsconfig.json"
} }

Loading…
Cancel
Save