mirror of https://github.com/nocodb/nocodb
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
303 lines
8.7 KiB
303 lines
8.7 KiB
3 years ago
|
<template>
|
||
|
<div>
|
||
3 years ago
|
<v-btn
|
||
|
:loading="projectCreation"
|
||
|
:disabled="projectCreation"
|
||
|
class="primary nc-btn-use-template"
|
||
|
x-large
|
||
|
@click="useTemplate('rest')"
|
||
|
>
|
||
|
<slot>Use template</slot>
|
||
|
</v-btn>
|
||
3 years ago
|
</div>
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
3 years ago
|
import { SqlUiFactory } from 'nocodb-sdk'
|
||
3 years ago
|
import colors from '~/mixins/colors'
|
||
|
|
||
|
export default {
|
||
|
name: 'CreateProjectFromTemplateBtn',
|
||
|
mixins: [colors],
|
||
|
props: {
|
||
3 years ago
|
quickImport: Boolean,
|
||
3 years ago
|
loading: Boolean,
|
||
3 years ago
|
importToProject: Boolean,
|
||
3 years ago
|
templateData: [Array, Object],
|
||
3 years ago
|
importData: [Array, Object],
|
||
|
valid: {
|
||
|
default: true,
|
||
|
type: Boolean
|
||
|
},
|
||
|
validationErrorMsg: {
|
||
|
default: 'Please fill all the required values',
|
||
|
type: String
|
||
|
},
|
||
|
createGqlText: {
|
||
|
default: 'Create GQL Project',
|
||
|
type: String
|
||
|
},
|
||
|
createRestText: {
|
||
|
default: 'Create REST Project',
|
||
|
type: String
|
||
|
}
|
||
3 years ago
|
},
|
||
|
data() {
|
||
|
return {
|
||
3 years ago
|
localTemplateData: null,
|
||
3 years ago
|
projectCreation: false,
|
||
3 years ago
|
tableCreation: false,
|
||
3 years ago
|
loaderMessagesIndex: 0,
|
||
|
loaderMessages: [
|
||
|
'Setting up new database configs',
|
||
|
'Inferring database schema',
|
||
|
'Generating APIs.',
|
||
|
'Generating APIs..',
|
||
|
'Generating APIs...',
|
||
|
'Generating APIs....',
|
||
|
'Please wait',
|
||
|
'Please wait.',
|
||
|
'Please wait..',
|
||
|
'Please wait...',
|
||
|
'Please wait..',
|
||
|
'Please wait.',
|
||
|
'Please wait',
|
||
|
'Please wait.',
|
||
|
'Please wait..',
|
||
|
'Please wait...',
|
||
|
'Please wait..',
|
||
|
'Please wait.',
|
||
|
'Please wait..',
|
||
|
'Please wait...'
|
||
|
]
|
||
|
}
|
||
|
},
|
||
3 years ago
|
watch: {
|
||
|
templateData: {
|
||
|
deep: true,
|
||
|
handler(data) {
|
||
|
this.localTemplateData = JSON.parse(JSON.stringify(data))
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
created() {
|
||
|
this.localTemplateData = JSON.parse(JSON.stringify(this.templateData))
|
||
|
},
|
||
|
|
||
3 years ago
|
methods: {
|
||
|
async useTemplate(projectType) {
|
||
3 years ago
|
if (!this.valid) {
|
||
|
return this.$toast.error(this.validationErrorMsg).goAway(3000)
|
||
|
}
|
||
|
|
||
3 years ago
|
// this.$emit('useTemplate', type)
|
||
3 years ago
|
// this.projectCreation = true
|
||
3 years ago
|
let interv
|
||
3 years ago
|
try {
|
||
3 years ago
|
interv = setInterval(() => {
|
||
3 years ago
|
this.loaderMessagesIndex = this.loaderMessagesIndex < this.loaderMessages.length - 1 ? this.loaderMessagesIndex + 1 : 6
|
||
3 years ago
|
this.$store.commit('loader/MutMessage', this.loaderMessages[this.loaderMessagesIndex])
|
||
3 years ago
|
}, 1000)
|
||
|
|
||
3 years ago
|
const projectId = this.$store.state.project.project.id
|
||
|
let firstTable = null
|
||
3 years ago
|
|
||
3 years ago
|
// Not available now
|
||
3 years ago
|
if (this.importToProject) {
|
||
3 years ago
|
// this.$store.commit('loader/MutMessage', 'Importing excel template')
|
||
|
|
||
|
// const res = await this.$store.dispatch('sqlMgr/ActSqlOp', [{
|
||
|
// // todo: extract based on active
|
||
|
// dbAlias: 'db', // this.nodes.dbAlias,
|
||
|
// env: '_noco'
|
||
|
// }, 'xcModelsCreateFromTemplate', {
|
||
|
// template: this.templateData
|
||
|
// }])
|
||
|
|
||
|
// if (res && res.tables && res.tables.length) {
|
||
|
// this.$toast.success(`Imported ${res.tables.length} tables successfully`).goAway(3000)
|
||
|
// } else {
|
||
|
// this.$toast.success('Template imported successfully').goAway(3000)
|
||
|
// }
|
||
3 years ago
|
|
||
3 years ago
|
// projectId = this.$route.params.project_id
|
||
|
// prefix = this.$store.getters['project/GtrProjectPrefix']
|
||
3 years ago
|
} else {
|
||
3 years ago
|
// Create tables
|
||
|
try {
|
||
3 years ago
|
for (const t of this.localTemplateData.tables) {
|
||
3 years ago
|
// enrich system fields if not provided
|
||
|
// e.g. id, created_at, updated_at
|
||
|
const systemColumns = SqlUiFactory
|
||
3 years ago
|
.create({ client: this.$store.state.project.project.bases[0].type })
|
||
3 years ago
|
.getNewTableColumns()
|
||
3 years ago
|
.filter(c => c.column_name !== 'title')
|
||
3 years ago
|
|
||
3 years ago
|
for (const systemColumn of systemColumns) {
|
||
|
if (!t.columns.some(c => c.column_name.toLowerCase() === systemColumn.column_name.toLowerCase())) {
|
||
|
t.columns.push(systemColumn)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// set pk & rqd if ID is provided
|
||
|
for (const column of t.columns) {
|
||
|
if (column.column_name.toLowerCase() === 'id' && !('pk' in column)) {
|
||
|
column.pk = true
|
||
|
column.rqd = true
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// create table
|
||
|
const table = await this.$api.dbTable.create(projectId, {
|
||
3 years ago
|
table_name: t.table_name,
|
||
3 years ago
|
title: '',
|
||
3 years ago
|
columns: t.columns
|
||
3 years ago
|
})
|
||
3 years ago
|
t.table_title = table.title
|
||
3 years ago
|
|
||
|
// open the first table after import
|
||
|
if (firstTable === null) {
|
||
|
firstTable = table
|
||
|
}
|
||
|
|
||
|
// set primary value
|
||
|
await this.$api.dbTableColumn.primaryColumnSet(table.columns[0].id)
|
||
3 years ago
|
}
|
||
3 years ago
|
this.tableCreation = true
|
||
3 years ago
|
} catch (e) {
|
||
|
this.$toast
|
||
|
.error(await this._extractSdkResponseErrorMsg(e))
|
||
|
.goAway(3000)
|
||
3 years ago
|
this.tableCreation = false
|
||
|
} finally {
|
||
|
clearInterval(interv)
|
||
3 years ago
|
}
|
||
3 years ago
|
}
|
||
3 years ago
|
|
||
3 years ago
|
if (!this.tableCreation) {
|
||
|
// failed to create table
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// Bulk import data
|
||
|
if (this.importData) {
|
||
|
this.$store.commit('loader/MutMessage', 'Importing excel data to project')
|
||
3 years ago
|
await this.importDataToProject()
|
||
3 years ago
|
}
|
||
3 years ago
|
|
||
3 years ago
|
// reload table list
|
||
|
this.$store.dispatch('project/_loadTables', {
|
||
|
dbKey: '0.projectJson.envs._noco.db.0',
|
||
|
key: '0.projectJson.envs._noco.db.0.tables',
|
||
|
_nodes: {
|
||
|
dbAlias: 'db',
|
||
|
env: '_noco',
|
||
|
type: 'tableDir'
|
||
3 years ago
|
}
|
||
3 years ago
|
}).then(() => {
|
||
|
// add tab - choose the first one if multiple tables are created
|
||
|
this.$store.dispatch('tabs/loadFirstCreatedTableTab', {
|
||
|
title: firstTable.title
|
||
|
}).then((item) => {
|
||
|
// set active tab - choose the first one if multiple tables are created
|
||
|
this.$nextTick(() => {
|
||
|
this.$router.push({
|
||
|
query: {
|
||
|
name: item.name || '',
|
||
|
dbalias: (item._nodes && item._nodes.dbAlias) || '',
|
||
|
type: (item._nodes && item._nodes.type) || 'table'
|
||
|
}
|
||
|
})
|
||
|
})
|
||
|
})
|
||
3 years ago
|
})
|
||
|
|
||
3 years ago
|
// confetti effect
|
||
|
this.simpleAnim()
|
||
3 years ago
|
} catch (e) {
|
||
|
console.log(e)
|
||
3 years ago
|
this.$toast
|
||
|
.error(await this._extractSdkResponseErrorMsg(e))
|
||
|
.goAway(3000)
|
||
3 years ago
|
} finally {
|
||
3 years ago
|
clearInterval(interv)
|
||
3 years ago
|
this.$store.commit('loader/MutMessage', null)
|
||
|
this.projectCreation = false
|
||
|
this.tableCreation = false
|
||
3 years ago
|
this.$emit('closeModal')
|
||
3 years ago
|
}
|
||
|
},
|
||
3 years ago
|
async importDataToProject() {
|
||
3 years ago
|
let total = 0
|
||
|
let progress = 0
|
||
3 years ago
|
const projectName = this.$store.state.project.project.title
|
||
3 years ago
|
await Promise.all(this.localTemplateData.tables.map(v => (async(tableMeta) => {
|
||
3 years ago
|
const tableName = tableMeta.table_title
|
||
3 years ago
|
const data = this.importData[tableMeta.ref_table_name]
|
||
3 years ago
|
total += data.length
|
||
|
for (let i = 0; i < data.length; i += 500) {
|
||
3 years ago
|
this.$store.commit('loader/MutMessage', `Importing data to ${projectName}: ${progress}/${total} records`)
|
||
3 years ago
|
this.$store.commit('loader/MutProgress', Math.round(progress && 100 * progress / total))
|
||
|
const batchData = this.remapColNames(data.slice(i, i + 500), tableMeta.columns)
|
||
3 years ago
|
await this.$api.dbTableRow.bulkCreate(
|
||
|
'noco',
|
||
|
projectName,
|
||
3 years ago
|
tableName,
|
||
3 years ago
|
batchData
|
||
|
)
|
||
3 years ago
|
progress += batchData.length
|
||
|
}
|
||
|
this.$store.commit('loader/MutClear')
|
||
3 years ago
|
})(v)))
|
||
3 years ago
|
},
|
||
|
remapColNames(batchData, columns) {
|
||
|
return batchData.map(data => (columns || []).reduce((aggObj, col) => ({
|
||
|
...aggObj,
|
||
3 years ago
|
[col.column_name]: data[col.ref_column_name || col.column_name]
|
||
3 years ago
|
}), {})
|
||
|
)
|
||
3 years ago
|
},
|
||
|
simpleAnim() {
|
||
|
const count = 200
|
||
|
const defaults = {
|
||
|
origin: { y: 0.7 }
|
||
|
}
|
||
|
|
||
|
function fire(particleRatio, opts) {
|
||
|
window.confetti(Object.assign({}, defaults, opts, {
|
||
|
particleCount: Math.floor(count * particleRatio)
|
||
|
}))
|
||
|
}
|
||
|
|
||
|
fire(0.25, {
|
||
|
spread: 26,
|
||
|
startVelocity: 55
|
||
|
})
|
||
|
fire(0.2, {
|
||
|
spread: 60
|
||
|
})
|
||
|
fire(0.35, {
|
||
|
spread: 100,
|
||
|
decay: 0.91,
|
||
|
scalar: 0.8
|
||
|
})
|
||
|
fire(0.1, {
|
||
|
spread: 120,
|
||
|
startVelocity: 25,
|
||
|
decay: 0.92,
|
||
|
scalar: 1.2
|
||
|
})
|
||
|
fire(0.1, {
|
||
|
spread: 120,
|
||
|
startVelocity: 45
|
||
|
})
|
||
3 years ago
|
}
|
||
|
}
|
||
|
}
|
||
|
</script>
|
||
|
|
||
|
<style scoped>
|
||
|
|
||
3 years ago
|
</style>
|