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>
<!-- <NuxtLayout>-->
<!-- <NuxtPage />-->
<!-- </NuxtLayout>-->
<NuxtPage/>
<!-- <NuxtLayout> -->
<!-- <NuxtPage /> -->
<!-- </NuxtLayout> -->
<NuxtPage />
</template>

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

@ -1,44 +1,29 @@
<template>
<div>
<v-tabs density="compact" v-model="activeTab">
<script setup lang="ts">
import { useTabs } from '~/composables/tabs'
<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-window v-model="activeTab">
<v-window-item
v-for="(tab,i) in tabs"
v-for="(tab, i) of tabs"
:key="i"
:value="i"
>
<TabsSmartsheet :tab-meta="tab" />
</v-window-item>
</v-window>
</div>
</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>

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>
<div>
<v-list density="medium">
<v-list-item v-for="table in tables" class="p-2 text-sm pointer"
@click="addTab({type:'table',title:table.title, id:table.id})">
{{ table.title }}
</v-list-item>
<v-list-item
v-for="table in tables" class="p-2 text-sm pointer"
@click="addTab({ type: 'table', title: table.title, id: table.id })"
>
{{ table.title }}
</v-list-item>
</v-list>
</div>
</template>
<script setup lang="ts">
import {useProject} from "~/composables/project";
import {useTabs} from "~/composables/tabs";
const {tables} = useProject()
const {addTab} = useTabs()
</script>
<style scoped>
.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>
<div>
<div class="card">
<v-table>
<thead>
<tr>
<th v-for="col in meta.columns">
{{ col.title }}
</th>
</tr>
<tr>
<th v-for="col in meta.columns">
{{ col.title }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="(row,i) in rows" :key="i">
<th v-for="col in meta.columns" :key="col.title">
{{ row[col.title] }}
</th>
</tr>
<tr v-for="(row, i) in rows" :key="i">
<th v-for="col in meta.columns" :key="col.title">
{{ row[col.title] }}
</th>
</tr>
</tbody>
<!-- <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}}">
{{ d && (Array.isArray(d) ? d : [d]).map(c1 => c1[Object.keys(c1)[1]]).join(', ') }}
</template>
</Column>-->
</Column> -->
</v-table>
</div>
</div>
</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>

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">
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({
tabMeta: Object
const { tabMeta } = defineProps({
tabMeta: Object,
})
const {getMeta, metas} = useMetas()
const { getMeta, metas } = useMetas()
const meta = computed(() => {
return metas.value?.[tabMeta?.id]
})
onMounted(async () => {
await getMeta(tabMeta?.id)
await getMeta(tabMeta?.id)
})
watch(() => tabMeta && tabMeta?.id, async (newVal, oldVal) => {
if (newVal !== oldVal) {
if (newVal !== oldVal)
await getMeta(newVal)
}
})
</script>
<template>
<div>
<template v-if="meta && tabMeta">
<SmartsheetGrid :meta="meta" :tab-meta="tabMeta" />
</template>
</div>
</template>
<style scoped>
</style>

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

@ -1,20 +1,18 @@
import {useNuxtApp, useState} from "#app";
import {Api, TableType} from "nocodb-sdk";
import {useUser} from "~/composables/user";
import {useProject} from "~/composables/project";
import type { Api, TableType } from 'nocodb-sdk'
import { useNuxtApp, useState } from '#app'
import { useUser } from '~/composables/user'
import { useProject } from '~/composables/project'
export const useMetas = () => {
const {$api} = useNuxtApp()
const {user} = useUser()
const {tables} = useProject()
const { $api } = useNuxtApp()
const { user } = useUser()
const { tables } = useProject()
const metas = useState<{ [idOrTitle: string]: TableType | any }>('metas', () => ({}))
const getMeta = async (tableIdOrTitle: string, force = false) => {
if (!force && metas[tableIdOrTitle]) {
if (!force && metas[tableIdOrTitle])
return metas[tableIdOrTitle]
}
const modelId = (tables.value.find(t => t.title === tableIdOrTitle || t.id === tableIdOrTitle) || {}).id
if (!modelId) {
@ -24,18 +22,18 @@ export const useMetas = () => {
const model = await $api.dbTable.read(modelId, {
headers: {
'xc-auth': user.token
}
'xc-auth': user.token,
},
})
metas.value = {
...metas.value,
[model.id]: model,
[model.title]: model
[model.title]: 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 {Api, TableType} from "nocodb-sdk";
import {useUser} from "~/composables/user";
import type { TableType } from 'nocodb-sdk'
import { useNuxtApp } from '#app'
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 loadTables = async () => {
@ -15,13 +14,12 @@ export const useProject = () => {
tables.value = tablesResponse.list
}
const loadProject = async (projectId:string) => {
const loadProject = async (projectId: string) => {
const projectResponse = await $api.project.read(projectId)
console.log(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 {
type: 'table' | 'view',
title: string,
id:string
type: 'table' | 'view'
title: string
id: string
}
export const useTabs = () => {
const tabs = useState<Array<TabItem>>('tabs', () => [])
const activeTab = useState<number>('activeTab', ()=>0)
const activeTab = useState<number>('activeTab', () => 0)
const addTab = (tabMeta: TabItem) => {
tabs.value = [...(tabs.value || []), tabMeta]
@ -18,5 +18,5 @@ export const useTabs = () => {
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 {Api} from "nocodb-sdk";
import {useNuxtApp} from "#app";
import { store } from 'nuxt3-store'
import { useNuxtApp } from '#app'
export const useUser = () =>{
const user = store({
export const useUser = () => {
const user = store({
name: 'user',
type: 'localstorage',
value: {token: null, user : null},
value: { token: null, user: null },
reactiveType: 'reactive',
version: '1.0.0'
version: '1.0.0',
})
const {$api} = useNuxtApp()
const { $api } = useNuxtApp()
const route = useRoute()
const router = useRouter()
const getUser =async (args = {}) => {
const getUser = async (args = {}) => {
const userInfo = await $api.auth.me(args, {
headers: {
'xc-auth': user.value.token
}
'xc-auth': user.value.token,
},
})
user.user = userInfo
}
const setToken = (token) => {
const setToken = (token) => {
user.token = token
}
$api?.instance?.interceptors.request.use((config) => {
config.headers['xc-gui'] = 'true'
if (user?.token) {
if (user?.token)
config.headers['xc-auth'] = user?.token
}
if (!config.url.endsWith('/user/me') && !config.url.endsWith('/admin/roles')) {
// config.headers['xc-preview'] = store.state.users.previewAs
}
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
}
}
return config
@ -82,13 +77,13 @@ export const useUser = () =>{
// Try request again with new token
return $api.instance.post('/auth/refresh-token', null, {
withCredentials: true
withCredentials: true,
})
.then((token) => {
// New request with new token
const config = error.config
config.headers['xc-auth'] = token.data.token
user.token = token.data.token
user.token = token.data.token
return new Promise((resolve, reject) => {
$api.instance.request(config).then((response) => {
@ -99,12 +94,13 @@ export const useUser = () =>{
})
})
.catch(async (error) => {
//todo: clear token
// todo: clear token
// await store.dispatch('users/ActSignOut')
setToken(null)
if (store.state.project.appInfo.firstUser) {
router.replace('/')
} else {
}
else {
// $toast.clear()
// $toast.info('Token Expired. Please login again.', {
// 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}) {
if (!e || !e.response) { return e.message }
export async function extractSdkResponseErrorMsg(e: Error & { response: any }) {
if (!e || !e.response) return e.message
let msg
if (e.response.data instanceof Blob) {
try {
msg = JSON.parse(await e.response.data.text()).msg
} catch {
}
catch {
msg = 'Some internal error occurred'
}
} else {
}
else {
msg = e.response.data.msg || e.response.data.message || 'Some internal 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>
<div class="">
<!-- <div class="topbar">-->
<!-- </div>-->
<!-- <div class="sidebar">-->
<!-- </div>-->
<!-- <div class="content">-->
<!-- <div class="topbar"> -->
<!-- </div> -->
<!-- <div class="sidebar"> -->
<!-- </div> -->
<!-- <div class="content"> -->
<v-layout>
<v-app-bar color=""></v-app-bar>
<slot></slot>
<v-app-bar color="" />
<slot />
</v-layout>
<!-- </div>-->
<!-- </div> -->
</div>
</template>
<script>
export default {
name: "default"
}
</script>
<style scoped>
</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
export default defineNuxtConfig({
// modules: ['@nuxtjs/tailwindcss'],
// buildModules: [
// 'nuxt-vite'
// ],
modules: ['nuxt3-store'],
ssr:false,
plugins: [
// '~/plugins/vuetify.ts',
// '~/plugins/api.ts',
],
ssr: false,
css: ['vuetify/lib/styles/main.sass'],
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: {
define: {
'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"
},
"devDependencies": {
"@antfu/eslint-config": "^0.25.2",
"@nuxtjs/tailwindcss": "^5.1.2",
"fibers": "^5.0.1",
"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>
<v-navigation-drawer color="" permanent>
<DashboardTreeView></DashboardTreeView>
<DashboardTreeView />
</v-navigation-drawer>
<v-main>
<v-container>
<DashboardTabView></DashboardTabView>
<DashboardTabView />
</v-container>
</v-main>
</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>
<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">
.nc-container {
.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>
<div class="container">
<Card style="width:500px">
<template #title>
Signup
</template>
<template #content>
<InputText type="text" v-model="value" label="Email"/>
</template>
<InputText v-model="value" type="text" label="Email" />
</template>
<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>
</Card>
</div>
</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">
.container {
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">
import {useRouter} from "#app";
import { useRouter } from '#app'
const $router = useRouter()
const router = useRouter()
$router.replace('/projects')
router.replace('/projects')
</script>
<template>
<div class="container" />
</template>
<style lang="scss">
</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>
<NuxtLayout>
<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-card style="width:530px;margin-top: 100px" class="mx-auto">
<!-- Create Project -->
<v-container class="pb-10 px-12" style="padding-top: 43px !important;">
<h1 class="mt-4 mb-4 text-center">
<!-- {{ $t('activity.createProject') }}-->
<!-- {{ $t('activity.createProject') }} -->
Create Project
</h1>
<div class="mx-auto" style="width:350px">
@ -18,7 +51,7 @@
class="nc-metadb-project-name"
label="Project name"
/>
<!-- :rules="titleValidationRule"-->
<!-- :rules="titleValidationRule" -->
</div>
<div class="text-center">
<v-btn
@ -32,7 +65,7 @@
mdi-rocket-launch-outline
</v-icon>
<!-- Create -->
<!-- <span class="mr-1">{{ // $t("general.create") }}</span>-->
<!-- <span class="mr-1">{{ // $t("general.create") }}</span> -->
<span class="mr-1"> Create project </span>
</v-btn>
</div>
@ -43,44 +76,6 @@
</NuxtLayout>
</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>
/deep/ label {
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>
<NuxtLayout>
<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-card style="width:530px;margin-top: 100px" class="mx-auto">
<!-- Create Project -->
<v-container class="pb-10 px-12" style="padding-top: 43px !important;">
<h1 class="mt-4 mb-4 text-center">
<!-- {{ $t('activity.createProject') }}-->
<!-- {{ $t('activity.createProject') }} -->
Create Project
</h1>
<div class="mx-auto" style="width:350px">
@ -18,10 +70,9 @@
class="nc-metadb-project-name"
label="Project name"
/>
<!-- :rules="titleValidationRule"-->
<!-- :rules="titleValidationRule" -->
</div>
<v-container fluid>
<v-row>
<v-col cols="6">
@ -83,7 +134,7 @@
mdi-rocket-launch-outline
</v-icon>
<!-- Create -->
<!-- <span class="mr-1">{{ // $t("general.create") }}</span>-->
<!-- <span class="mr-1">{{ // $t("general.create") }}</span> -->
<span class="mr-1"> Create project </span>
</v-btn>
</div>
@ -94,63 +145,6 @@
</NuxtLayout>
</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>
/deep/ label {
font-size: .75rem;

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

@ -1,28 +1,46 @@
<template>
<NuxtLayout>
<v-navigation-drawer color="" permanent></v-navigation-drawer>
<v-main>
<v-container>
<script setup lang="ts">
import { useRouter } from '#app'
const { $api } = useNuxtApp()
const { user } = useUser()
<div class="pa-2 d-flex mb-10">
<v-spacer></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>
const $router = useRouter()
const projects = ref()
const loadProjects = async () => {
const projectsResponse = await $api.project.list({}, {
headers: {
'xc-auth': user.token,
},
})
projects.value = projectsResponse.list
}
<!-- tod
o: move to layout or create a reusable component -->
<!-- <div class="nc-container">-->
<!-- <div class="nc-topbar shadow-2">-->
<!-- </div>-->
<!-- <div class="nc-sidebar shadow-2 p-4 overflow-y-auto">-->
const navigateToDashboard = async (project) => {
await $router.push(`/dashboard/${project.id}`)
}
<!-- </div>-->
<!-- <div class="nc-content p-4 overflow-auto">-->
<v-row>
<v-col cols="4" v-for="project in projects" :key="project.id">
onMounted(async () => {
await loadProjects()
})
</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-title>
<div class="text-center">
@ -30,72 +48,9 @@
</div>
</v-card-title>
</v-card>
</v-col>
</v-row>
</v-container>
<!-- </div>-->
<!-- </div>-->
</v-main>
</NuxtLayout>
</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>
export default {
name: "dashboard"
name: 'Dashboard',
}
</script>
<template>
<div>
<Sidebar :visible="true" position="left" :dismissable="false">
Content
</Sidebar>
</div>
</template>
<style scoped>
</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>
<div>
<!-- Enter your work email -->
<v-card class="pa-10 mx-auto mt-10" style="max-width: 500px">
<v-card-text>
<v-alert density="medium" class="mb-10" v-if="error" type="error">{{ error }}</v-alert>
<v-alert v-if="error" density="medium" class="mb-10" type="error">
{{ error }}
</v-alert>
<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>
<!-- Enter your password -->
<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 class="text-center">
<v-btn
class=""
@click="signIn"
class=""
@click="signIn"
>
<b>Sign In</b>
</v-btn>
@ -26,38 +57,8 @@
</v-card-text>
</v-card>
</div>
</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>

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>
<div>
<!-- Enter your work email -->
<v-card class="pa-10 mx-auto mt-10" style="max-width: 500px">
<v-card-text>
<v-alert density="medium" class="mb-4" v-if="error" type="error">{{ error }}</v-alert>
<v-alert v-if="error" density="medium" class="mb-4" type="error">
{{ error }}
</v-alert>
<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>
<!-- Enter your password -->
<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 class="text-center">
@ -26,35 +54,8 @@
</v-card-text>
</v-card>
</div>
</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>

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

@ -1,35 +1,23 @@
import { useNuxtApp } from "#app";
import { Api } from "nocodb-sdk";
import { defineNuxtPlugin } from "nuxt3/app";
import { Api } from 'nocodb-sdk'
import { defineNuxtPlugin } from 'nuxt3/app'
export default defineNuxtPlugin((nuxtApp) => {
const api = getApi(null, null)
// Doing something with nuxtApp
const api = getApi(null, null);
// nuxtApp.provide("api", api);
return {
provide: {
api
}
};
});
nuxtApp.provide('api', api)
})
export function getApi($store, $axios) {
const api = new Api({
baseURL: "http://localhost:8080",
baseURL: 'http://localhost:8080',
headers: {
"xc-auth": $store?.state?.users?.token
}
});
'xc-auth': $store?.state?.users?.token,
},
})
if ($axios) {
// 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 ToastService from "primevue/toastservice";
//
export default defineNuxtPlugin(nuxtApp => {
export default defineNuxtPlugin((nuxtApp) => {
// nuxtApp.vueApp.use(PrimeVue, { ripple: true });
// nuxtApp.vueApp.use(ToastService);
// nuxtApp.vueApp.component("Button", Button);
@ -26,4 +26,4 @@ export default defineNuxtPlugin(nuxtApp => {
// nuxtApp.vueApp.component("Dropdown", Dropdown);
// nuxtApp.vueApp.component("Column", Column);
// //other components that you need
});
})

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

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

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

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

Loading…
Cancel
Save