Browse Source

feat: integrate template api

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/760/head
Pranav C 3 years ago
parent
commit
d3a08af923
  1. 92
      packages/nc-gui/components/templates/categories.vue
  2. 60
      packages/nc-gui/components/templates/detailed.vue
  3. 68
      packages/nc-gui/components/templates/editor.vue
  4. 74
      packages/nc-gui/components/templates/list.vue
  5. 81
      packages/nc-gui/components/templates/templates.1.js
  6. 62
      packages/nc-gui/components/templates/templates.2.js
  7. 62
      packages/nc-gui/components/templates/templates.3.js
  8. 62
      packages/nc-gui/components/templates/templates.4.js
  9. 62
      packages/nc-gui/components/templates/templates.5.js
  10. 26
      packages/nc-gui/components/templates/templates.categories.js
  11. 61
      packages/nc-gui/components/templates/templates.js
  12. 38
      packages/nc-gui/components/templates/templates.list.js
  13. 2
      packages/nc-gui/layouts/default.vue
  14. 3
      packages/nc-gui/nuxt.config.js

92
packages/nc-gui/components/templates/categories.vue

@ -1,42 +1,76 @@
<template>
<v-list dense height="20px">
<v-list-item dense>
<v-list-item-subtitle>
<span class="caption">Categories</span>
</v-list-item-subtitle>
</v-list-item>
<v-list-item-group v-model="category">
<v-list-item v-for="c in categories" :key="c.title" :value="c.title" dense>
<v-list-item-title>
<span
:class="{'font-weight-black' : category === c.title } "
>
{{
c.title
}}<span />
</span>
</v-list-item-title>
<div class="h-100">
<v-list dense>
<v-list-item dense>
<v-list-item-subtitle>
<span class="caption" @click="counterLoc++">Categories</span>
</v-list-item-subtitle>
</v-list-item>
</v-list-item-group>
</v-list>
<v-list-item-group v-model="category">
<v-list-item v-for="c in categories" :key="c.category" :value="c.category" dense>
<v-list-item-title>
<span
:class="{'font-weight-black' : category === c.category } "
>
{{
c.category
}}
</span> <span class="grey--text ">({{ c.count }})</span>
</v-list-item-title>
</v-list-item>
</v-list-item-group>
</v-list>
<v-btn
v-if="counter > 4"
color="primary"
outlined
@click="showTemplateEditor"
>
Add new template
</v-btn>
</div>
</template>
<script>
import categories from './templates.categories'
// import categories from './templates.categories'
export default {
name: "categories",
props:{value:String},
data:()=>({
categories
name: 'Categories',
props: { value: String, counter: Number },
data: () => ({
categories: []
}),
computed:{
category:{
get(){
return this.value;
computed: {
category: {
get() {
return this.value
},
set(v){
set(v) {
this.$emit('input', v)
}
},
counterLoc: {
get() {
return this.counter
},
set(v) {
this.$emit('update:counter', v)
}
}
},
created() {
this.loadCategories()
},
methods: {
async loadCategories() {
try {
const res = await this.$axios.get(`${process.env.NC_API_URL}/api/v1/nc/templates/categories`)
this.categories = res.data
} catch (e) {
console.log(e)
}
},
showTemplateEditor() {
this.$emit('showTemplateEditor')
}
}
}

60
packages/nc-gui/components/templates/detailed.vue

@ -2,53 +2,81 @@
<v-container class="py-0">
<div class="d-flex">
<v-navigation-drawer height="calc(100vh - 40px)">
<categories @input="v => $emit('load-category', v)"/>
<categories ref="cat" :counter.sync="counter" @input="v => $emit('load-category', v)" />
</v-navigation-drawer>
<v-container v-if="templateData" fluid style="height: calc(100vh - 40px ); overflow: auto">
<v-img
:src="templateData.thumbnail"
:src="templateData.image_url || `https://picsum.photos/200/300?${id}`"
height="200px"
/>
<div class="d-flex align-center mt-10">
<h2 class="display-2 font-weight-bold my-0 flex-grow-1">
{{ templateData.title }}
</h2>
<v-btn class="primary" x-large @click="useTemplate">Use template</v-btn>
<v-btn class="primary" x-large @click="useTemplate">
Use template
</v-btn>
</div>
<p class="caption mt-10">
{{ templateData.description }}
</p>
<templat-editor view-mode :templateData="templateData"></templat-editor>
<templat-editor
:id="templateId"
:view-mode="counter < 5 && viewMode"
:template-data.sync="templateData"
@saved="onSaved"
/>
</v-container>
</div>
</v-container>
</template>
<script>
import categories from '~/components/templates/templates.categories'
import TemplatEditor from "~/components/templates/editor";
import Categories from "~/components/templates/categories";
import TemplatEditor from '~/components/templates/editor'
import Categories from '~/components/templates/categories'
export default {
name: 'ProjectTemplateDetailed',
components: {Categories, TemplatEditor},
components: { Categories, TemplatEditor },
props: {
modal: Boolean, id: [String, Number]
modal: Boolean,
viewMode: Boolean,
id: [String, Number]
},
data: () => ({ templateData: null, counter: 0 }),
computed: {
templateId() {
return this.modal ? this.id : this.$route.params.id
}
},
mounted() {
this.loadTemplateData()
},
data: () => ({categories, templateData: null}),
async mounted() {
this.templateData = (await import(`./templates.${this.modal ? this.id : this.$route.params.id}`)).default
}, methods: {
methods: {
async loadTemplateData() {
try {
const res = await this.$axios.get(`${process.env.NC_API_URL}/api/v1/nc/templates/${this.templateId}`)
const data = res.data
this.templateData = JSON.parse(data.template)
} catch (e) {
console.log(e)
}
},
useTemplate() {
if (this.modal) {
this.$emit('import', this.templateData)
}
},
async onSaved() {
await this.loadTemplateData()
if (this.$refs.cat) {
await this.$refs.cat.loadCategories()
}
this.$emit('saved')
}
}
}
</script>

68
packages/nc-gui/components/templates/editor.vue

@ -45,8 +45,8 @@
mdi-plus
</v-icon>
<!-- <v-btn outlined small class='mr-1' @click='submitTemplate'> Submit Template</v-btn>-->
<v-btn color="primary" outlined small class="mr-1" @click="projectTemplateCreate">
{{ updateFilename ? 'Update' : 'Create' }}
<v-btn color="primary" outlined small class="mr-1" @click="saveTemplate">
{{ id || localId ? 'Update' : 'Create' }}
Template
</v-btn>
</v-toolbar>
@ -373,7 +373,7 @@
<div class="mt-10">
<v-text-field
ref="project"
v-model="project.name"
v-model="project.title"
class="caption"
outlined
dense
@ -408,16 +408,17 @@
outlined
dense
label="Project Tags"
@click="counter++"
/>
</div>
<v-text-field v-if="counter > 4" v-model="token" outlined dense label="Token" />
</div>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-form>
<github-config v-if="githubConfigForm" class="mx-auto mt-10 mb-4" />
</v-container>
<v-dialog v-model="createTablesDialog" max-width="500">
@ -506,10 +507,12 @@ export default {
name: 'TemplateEditor',
components: {},
props: {
id: [Number, String],
viewMode: Boolean,
templateData: Object
},
data: () => ({
localId: null,
valid: false,
url: '',
githubConfigForm: false,
@ -541,7 +544,8 @@ export default {
LinkToAnotherRecord: 'blue lighten-5',
Rollup: 'pink lighten-5',
Lookup: 'green lighten-5'
}
},
counter: 0
}),
computed: {
@ -857,34 +861,6 @@ export default {
document.body.removeChild(el)
this.$toast.success('Successfully copied JSON data to clipboard!').goAway(3000)
},
async submitTemplate() {
try {
this.copyJSON()
this.$toast.info('Initing Github for template').goAway(3000)
// const res = await axios.get('https://hookb.in/K3k2OOeN01fPMK88MMwb', el.value);
const res = await this.$axios.post('https://nocodb.com/api/v1/projectTemplateCreate', this.projectTemplate)
console.log(res)
this.$toast.success('Inited Github successfully').goAway(3000)
window.open(res.data.path, '_blank')
} catch (e) {
console.log(e)
this.$toast.error('Some error occurred').goAway(3000)
}
},
async template() {
//
// this.$axios({
// method:'post',
// url:'https://nocodb.com/api/api/v1/projectTemplateCreate',
// data:{
// name:'test_name'
// }
// }).then(res => {
// console.log(res.data)
// }).catch(e => console.log(e.message))
},
openUrl() {
window.open(this.url, '_blank')
},
@ -1026,6 +1002,30 @@ export default {
accord.focus()
accord.scrollIntoView()
})
},
async saveTemplate() {
try {
if (this.id || this.localId) {
await this.$axios.put(`${process.env.NC_API_URL}/api/v1/nc/templates/${this.id || this.localId}`, this.projectTemplate, {
params: {
token: this.token
}
})
this.$toast.success('Template updated successfully').goAway(3000)
} else {
const res = await this.$axios.post(`${process.env.NC_API_URL}/api/v1/nc/templates`, this.projectTemplate, {
params: {
token: this.token
}
})
this.localId = res.data.id
this.$toast.success('Template updated successfully').goAway(3000)
}
this.$emit('saved')
} catch (e) {
this.$toast.error(e.message).goAway(3000)
}
}
}

74
packages/nc-gui/components/templates/list.vue

@ -1,12 +1,21 @@
<template>
<v-container v-if="!modal || selectedId === null " class="py-0">
<v-container v-if="newEditor || !modal || selectedId === null " class="py-0">
<div class="d-flex">
<v-navigation-drawer height="calc(100vh - 40px)">
<categories v-model="category"></categories>
<categories
ref="cat"
v-model="category"
:counter.sync="counter"
@input="newEditor=false"
@showTemplateEditor="newEditor = true"
/>
</v-navigation-drawer>
<v-container fluid style="height: calc(100vh - 40px ); overflow: auto">
<template-editor v-if="newEditor" style="width:100%" @saved="onSaved" />
<v-container v-else fluid style="height: calc(100vh - 40px); overflow: auto">
<v-row
v-if="templateList && templateList.length">
v-if="templateList && templateList.length"
class="align-stretch"
>
<v-col
v-for="(template,i) in templateList"
:key="i"
@ -19,10 +28,11 @@
@click="openTemplate(template.id)"
>
<v-card
height="100%"
class="mx-auto"
>
<v-img
:src="template.thumbnail"
:src="template.image_url || `https://picsum.photos/200/300?${template.id}`"
height="200px"
/>
@ -39,40 +49,66 @@
</v-col>
</v-row>
<div v-else class="d-flex justify-center mt-10 ">
<v-alert class="flex-shrink-1" type="info" outlined dense >
No templates found
</v-alert>
<v-alert class="flex-shrink-1" type="info" outlined dense>
No templates found
</v-alert>
</div>
</v-container>
</div>
</v-container>
<project-template-detailed v-else @load-category="v =>{ category = v; selectedId = null }" :id="selectedId" :modal="modal" v-on="$listeners" />
<project-template-detailed
v-else
:id="selectedId"
:counter="counter"
:modal="modal"
:view-mode="counter < 5"
@saved="onSaved"
@load-category="v =>{ category = v; selectedId = null }"
v-on="$listeners"
/>
</template>
<script>
import templateList from './templates.list'
// import templateList from './templates.list'
import ProjectTemplateDetailed from '~/components/templates/detailed'
import Categories from "~/components/templates/categories";
import Categories from '~/components/templates/categories'
import TemplateEditor from '~/components/templates/editor'
export default {
name: 'ProjectTemplates',
components: {Categories, ProjectTemplateDetailed },
components: { TemplateEditor, Categories, ProjectTemplateDetailed },
props: {
modal: Boolean
},
data: () => ({
category: null,
selectedId: null
selectedId: null,
templateListLoc: [],
counter: 0,
newEditor: false
}),
computed: {
templateList() {
return templateList.filter(t => !this.category || t.category === this.category)
return this.templateListLoc.filter(t => !this.category || t.category === this.category)
}
},
created() {
this.loadTemplates()
},
methods: {
async loadTemplates() {
try {
const res = await this.$axios.get(`${process.env.NC_API_URL}/api/v1/nc/templates`)
this.templateListLoc = res.data.data
} catch (e) {
console.log(e)
}
},
getShortDescription(str) {
if (str.length < 200) { return str }
if (str.length < 200) {
return str
}
return `${str.slice(0, 200)}...`
},
openTemplate(id) {
@ -81,13 +117,19 @@ export default {
} else {
this.$router.push(`/project/templates/${id}`)
}
},
async onSaved() {
await this.loadTemplates()
if (this.$refs.cat) {
await this.$refs.cat.loadCategories()
}
}
}
}
</script>
<style scoped>
/deep/ .v-list-item{
/deep/ .v-list-item {
min-height: 30px;
}
</style>

81
packages/nc-gui/components/templates/templates.1.js

@ -1,81 +0,0 @@
const templates = {
title: 'Art Gallery Management',
thumbnail: 'https://picsum.photos/200/300?1',
tables: [
{
tn: 'blog',
columns: [
{
cn: 'title',
uidt: 'SingleLineText'
},
{
cn: 'body',
uidt: 'LongText'
}
],
hasMany: [
{
tn: 'comment',
_cn: 'title3'
}
],
manyToMany: [
{
rtn: 'tag',
_cn: 'title4'
}
],
v: [
{
_cn: 'comments_count',
rl: {
rltn: 'comment',
rlcn: 'body',
type: 'hm',
fn: 'count'
}
}
]
},
{
tn: 'comment',
columns: [
{
cn: 'body',
uidt: 'LongText'
}
],
hasMany: [],
manyToMany: [],
v: [
{
_cn: 'blog_title',
lk: {
ltn: 'blog',
type: 'bt',
lcn: 'title'
}
}
]
},
{
tn: 'tag',
columns: [
{
cn: 'title',
uidt: 'SingleLineText'
}
],
hasMany: [],
manyToMany: [],
v: []
}
],
category: 'test',
tags: 'a,b,c',
description: 'I\'m a thing. But, like most politicians, he promised more than he could deliver. You won\'t have time for sleeping, soldier, not with all the bed making you\'ll be doing. Then we\'ll go with that data file! Hey, you add a one and two zeros to that or we walk!'
}
export default templates

62
packages/nc-gui/components/templates/templates.2.js

@ -1,62 +0,0 @@
const templates = {
title: 'Digital video production',
thumbnail: 'https://picsum.photos/200/300?2',
tables: [
{
tn: 'blog',
columns: [
{
cn: 'title',
uidt: 'SingleLineText'
},
{
cn: 'body',
uidt: 'LongText'
}
],
hasMany: [
{
tn: 'comment',
_cn: 'title3'
}
],
manyToMany: [
{
rtn: 'tag',
_cn: 'title4'
}
],
v: []
},
{
tn: 'comment',
columns: [
{
cn: 'body',
uidt: 'LongText'
}
],
hasMany: [],
manyToMany: [],
v: []
},
{
tn: 'tag',
columns: [
{
cn: 'title',
uidt: 'SingleLineText'
}
],
hasMany: [],
manyToMany: [],
v: []
}
],
category: 'test',
tags: 'a,b,c',
description: 'I\'m a thing. But, like most politicians, he promised more than he could deliver. You won\'t have time for sleeping, soldier, not with all the bed making you\'ll be doing. Then we\'ll go with that data file! Hey, you add a one and two zeros to that or we walk!'
}
export default templates

62
packages/nc-gui/components/templates/templates.3.js

@ -1,62 +0,0 @@
const templates = {
title: 'Content calendar',
thumbnail: 'https://picsum.photos/200/300?3',
tables: [
{
tn: 'blog',
columns: [
{
cn: 'title',
uidt: 'SingleLineText'
},
{
cn: 'body',
uidt: 'LongText'
}
],
hasMany: [
{
tn: 'comment',
_cn: 'title3'
}
],
manyToMany: [
{
rtn: 'tag',
_cn: 'title4'
}
],
v: []
},
{
tn: 'comment',
columns: [
{
cn: 'body',
uidt: 'LongText'
}
],
hasMany: [],
manyToMany: [],
v: []
},
{
tn: 'tag',
columns: [
{
cn: 'title',
uidt: 'SingleLineText'
}
],
hasMany: [],
manyToMany: [],
v: []
}
],
category: 'test',
tags: 'a,b,c',
description: 'I\'m a thing. But, like most politicians, he promised more than he could deliver. You won\'t have time for sleeping, soldier, not with all the bed making you\'ll be doing. Then we\'ll go with that data file! Hey, you add a one and two zeros to that or we walk!'
}
export default templates

62
packages/nc-gui/components/templates/templates.4.js

@ -1,62 +0,0 @@
const templates = {
title: 'Event Marketing',
thumbnail: 'https://picsum.photos/200/300?3',
tables: [
{
tn: 'blog',
columns: [
{
cn: 'title',
uidt: 'SingleLineText'
},
{
cn: 'body',
uidt: 'LongText'
}
],
hasMany: [
{
tn: 'comment',
_cn: 'title3'
}
],
manyToMany: [
{
rtn: 'tag',
_cn: 'title4'
}
],
v: []
},
{
tn: 'comment',
columns: [
{
cn: 'body',
uidt: 'LongText'
}
],
hasMany: [],
manyToMany: [],
v: []
},
{
tn: 'tag',
columns: [
{
cn: 'title',
uidt: 'SingleLineText'
}
],
hasMany: [],
manyToMany: [],
v: []
}
],
category: 'test',
tags: 'a,b,c',
description: 'I\'m a thing. But, like most politicians, he promised more than he could deliver. You won\'t have time for sleeping, soldier, not with all the bed making you\'ll be doing. Then we\'ll go with that data file! Hey, you add a one and two zeros to that or we walk!'
}
export default templates

62
packages/nc-gui/components/templates/templates.5.js

@ -1,62 +0,0 @@
const templates = {
title: 'Wedding Planning',
thumbnail: 'https://picsum.photos/200/300?5',
tables: [
{
tn: 'blog',
columns: [
{
cn: 'title',
uidt: 'SingleLineText'
},
{
cn: 'body',
uidt: 'LongText'
}
],
hasMany: [
{
tn: 'comment',
_cn: 'title3'
}
],
manyToMany: [
{
rtn: 'tag',
_cn: 'title4'
}
],
v: []
},
{
tn: 'comment',
columns: [
{
cn: 'body',
uidt: 'LongText'
}
],
hasMany: [],
manyToMany: [],
v: []
},
{
tn: 'tag',
columns: [
{
cn: 'title',
uidt: 'SingleLineText'
}
],
hasMany: [],
manyToMany: [],
v: []
}
],
category: 'test',
tags: 'a,b,c',
description: 'I\'m a thing. But, like most politicians, he promised more than he could deliver. You won\'t have time for sleeping, soldier, not with all the bed making you\'ll be doing. Then we\'ll go with that data file! Hey, you add a one and two zeros to that or we walk!'
}
export default templates

26
packages/nc-gui/components/templates/templates.categories.js

@ -1,26 +0,0 @@
const categories = [
{ title: 'Content production' },
{ title: 'Featured' },
{ title: 'Creative' },
{ title: 'Event Planning' },
{ title: 'Everyday Life' },
{ title: 'Groups, Clubs & Hobbies' },
{ title: 'HR & Recruiting' },
{ title: 'Legal' },
{ title: 'Local Business' },
{ title: 'Marketing' },
{ title: 'Nonprofit' },
{ title: 'Personal' },
{ title: 'PR & Communications' },
{ title: 'Product, design, and UX' },
{ title: 'Project Management' },
{ title: 'Publishing' },
{ title: 'Real Estate' },
{ title: 'Remote work' },
{ title: 'Sales & Customers' },
{ title: 'Software Development' },
{ title: 'Startup' },
{ title: 'Venture Capital' }
]
export default categories

61
packages/nc-gui/components/templates/templates.js

@ -1,61 +0,0 @@
const templates = {
title: 'Project name',
tables: [
{
tn: 'blog',
columns: [
{
cn: 'title',
uidt: 'SingleLineText'
},
{
cn: 'body',
uidt: 'LongText'
}
],
hasMany: [
{
tn: 'comment',
_cn: 'title3'
}
],
manyToMany: [
{
rtn: 'tag',
_cn: 'title4'
}
],
v: []
},
{
tn: 'comment',
columns: [
{
cn: 'body',
uidt: 'LongText'
}
],
hasMany: [],
manyToMany: [],
v: []
},
{
tn: 'tag',
columns: [
{
cn: 'title',
uidt: 'SingleLineText'
}
],
hasMany: [],
manyToMany: [],
v: []
}
],
category: 'test',
tags: 'a,b,c',
description: 'I\'m a thing. But, like most politicians, he promised more than he could deliver. You won\'t have time for sleeping, soldier, not with all the bed making you\'ll be doing. Then we\'ll go with that data file! Hey, you add a one and two zeros to that or we walk!'
}
export default templates

38
packages/nc-gui/components/templates/templates.list.js

@ -1,38 +0,0 @@
const templatesList = [{
id: 1,
title: 'Art Gallery Management',
category: 'Creative',
thumbnail: 'https://picsum.photos/200/300?1',
tags: 'a,b,c',
description: 'I\'m a thing. But, like most politicians, he promised more than he could deliver. You won\'t have time for sleeping, soldier, not with all the bed making you\'ll be doing. Then we\'ll go with that data file! Hey, you add a one and two zeros to that or we walk!'
}, {
id: 2,
title: 'Digital video production',
category: 'Creative',
thumbnail: 'https://picsum.photos/200/300?2',
tags: 'a,b,c',
description: 'I\'m a thing. But, like most politicians, he promised more than he could deliver. You won\'t have time for sleeping, soldier, not with all the bed making you\'ll be doing. Then we\'ll go with that data file! Hey, you add a one and two zeros to that or we walk!'
}, {
id: 3,
title: 'Content calendar',
category: 'Creative',
thumbnail: 'https://picsum.photos/200/300?3',
tags: 'a,b,c',
description: 'I\'m a thing. But, like most politicians, he promised more than he could deliver. You won\'t have time for sleeping, soldier, not with all the bed making you\'ll be doing. Then we\'ll go with that data file! Hey, you add a one and two zeros to that or we walk!'
}, {
id: 4,
title: 'Event Marketing',
category: 'Event Planning',
thumbnail: 'https://picsum.photos/200/300?4',
tags: 'a,b,c',
description: 'I\'m a thing. But, like most politicians, he promised more than he could deliver. You won\'t have time for sleeping, soldier, not with all the bed making you\'ll be doing. Then we\'ll go with that data file! Hey, you add a one and two zeros to that or we walk!'
}, {
id: 5,
title: 'Wedding Planning',
category: 'Event Planning',
thumbnail: 'https://picsum.photos/200/300?5',
tags: 'a,b,c',
description: 'I\'m a thing. But, like most politicians, he promised more than he could deliver. You won\'t have time for sleeping, soldier, not with all the bed making you\'ll be doing. Then we\'ll go with that data file! Hey, you add a one and two zeros to that or we walk!'
}]
export default templatesList

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

@ -44,7 +44,7 @@
{{ ghStarText }}
</gh-btns-star>
<a class="align-self-center caption font-weight-bold ml-1 mr-2 white--text" href="https://docs.nocodb.com" target="_blank">Docs</a>
<templates-modal class="align-self-center" />
<templates-modal v-if="isDashboard" class="align-self-center" />
</v-toolbar-items>
<!-- <template v-if="!isThisMobile ">

3
packages/nc-gui/nuxt.config.js

@ -209,7 +209,8 @@ export default {
'material-design-icons-iconfont/dist/material-design-icons.css'
],
env: {
EE: !!process.env.EE
EE: !!process.env.EE,
NC_API_URL: 'http://localhost:3000'
},
pwa: {
workbox: {

Loading…
Cancel
Save