Browse Source

feat: add proper progressbar for excel import

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/765/head
Pranav C 3 years ago
parent
commit
dad9e39f54
  1. 44
      packages/nc-gui/components/import/excelImport.vue
  2. 20
      packages/nc-gui/components/templates/createProjectFromTemplateBtn.vue
  3. 4
      packages/nc-gui/store/meta.js
  4. 1
      packages/nc-gui/store/sqlMgr.js
  5. 2
      packages/nocodb/src/example/try.ts
  6. 10
      packages/nocodb/src/lib/noco/NcProjectBuilder.ts
  7. 2
      packages/nocodb/src/lib/noco/meta/NcMetaIO.ts
  8. 4
      packages/nocodb/src/lib/noco/meta/NcMetaIOImpl.ts

44
packages/nc-gui/components/import/excelImport.vue

@ -26,7 +26,14 @@
<v-tooltip bottom>
<template #activator="{on}">
<input ref="file" type="file" style="display: none" accept=".xlsx, .xls" @change="_change($event)">
<input
ref="file"
class="nc-excel-import-input"
type="file"
style="display: none"
accept=".xlsx, .xls"
@change="_change($event)"
>
<v-btn
v-if="!hideLabel"
@ -51,6 +58,7 @@
<v-spacer />
<create-project-from-template-btn
:loader-message.sync="loaderMessage"
:progress.sync="progress"
:template-data="templateData"
:import-data="importData"
/>
@ -61,7 +69,17 @@
<v-overlay :value="loaderMessage" z-index="99999" opacity=".9">
<div class="d-flex flex-column align-center">
<v-progress-circular indeterminate size="100" width="15" class="mb-10" />
<v-progress-circular
v-if="progress !== null "
:rotate="360"
:size="100"
:width="15"
:value="progress"
>
{{ progress }}%
</v-progress-circular>
<v-progress-circular v-else indeterminate size="100" width="15" class="mb-10" />
<span class="title">{{ loaderMessage }}</span>
</div>
</v-overlay>
@ -87,7 +105,8 @@ export default {
templateData: null,
importData: null,
dragOver: false,
loaderMessage: null
loaderMessage: null,
progress: null
}
},
computed: {
@ -115,20 +134,31 @@ export default {
this._file(files[0])
}
},
_file(file) {
this.loaderMessage = 'Loading excel file...'
async _file(file) {
this.loaderMessage = 'Loading excel file'
let i = 0
const int = setInterval(() => {
this.loaderMessage = `Loading excel file${'.'.repeat(++i % 4)}`
}, 1000)
this.dropOrUpload = false
console.time('excelImport')
const reader = new FileReader()
reader.onload = (e) => {
const ab = e.target.result
const templateGenerator = new ExcelTemplateAdapter(file.name, ab)
templateGenerator.parse()
this.templateData = templateGenerator.getTemplate()
this.importData = templateGenerator.getData()
console.timeEnd('excelImport')
this.loaderMessage = null
clearInterval(int)
}
const handleEvent = (event) => {
this.loaderMessage = `${event.type}: ${event.loaded} bytes transferred`
}
reader.addEventListener('progress', handleEvent)
reader.onerror = () => {
this.loaderMessage = null
}

20
packages/nc-gui/components/templates/createProjectFromTemplateBtn.vue

@ -45,7 +45,8 @@ export default {
loading: Boolean,
templateData: Object,
importData: Object,
loaderMessage: String
loaderMessage: String,
progress: Number
},
data() {
return {
@ -82,7 +83,6 @@ export default {
this.projectCreation = true
try {
const interv = setInterval(() => {
debugger
this.loaderMessagesIndex = this.loaderMessagesIndex < this.loaderMessages.length - 1 ? this.loaderMessagesIndex + 1 : 6
this.$emit('update:loaderMessage', this.loaderMessages[this.loaderMessagesIndex])
}, 1000)
@ -118,12 +118,13 @@ export default {
this.projectCreation = false
},
async importDataToProject({ projectId, projectType, prefix = '' }) {
this.$store.commit('project/MutProjectId', projectId)
// this.$store.commit('project/MutProjectId', projectId)
this.$ncApis.setProjectId(projectId)
let total = 0; let progress = 0
await Promise.all(Object.entries(this.importData).map(async([table, data]) => {
await this.$store.dispatch('meta/ActLoadMeta', {
tn: `${prefix}${table}`
tn: `${prefix}${table}`, project_id: projectId
})
// todo: get table name properly
@ -131,11 +132,16 @@ export default {
table: `${prefix}${table}`,
type: projectType
})
total += data.length
for (let i = 0; i < data.length; i += 500) {
console.log(data[i])
await api.insertBulk(data.slice(i, i + 500))
this.$emit('update:loaderMessage', `Importing data : ${progress}/${total}`)
this.$emit('update:progress', Math.round(progress && 100 * progress / total))
const batchData = data.slice(i, i + 500)
await api.insertBulk(batchData)
progress += batchData.length
}
this.$emit('update:progress', null)
}))
}
}

4
packages/nc-gui/store/meta.js

@ -16,7 +16,7 @@ export const mutations = {
}
export const actions = {
async ActLoadMeta({ state, commit, dispatch }, { tn, env = '_noco', dbAlias = 'db', force }) {
async ActLoadMeta({ state, commit, dispatch }, { tn, env = '_noco', dbAlias = 'db', force, project_id }) {
if (!force && state.loading[tn]) {
return await new Promise((resolve) => {
const unsubscribe = this.app.store.subscribe((s) => {
@ -34,7 +34,7 @@ export const actions = {
key: tn,
value: true
})
const model = await dispatch('sqlMgr/ActSqlOp', [{ env, dbAlias }, 'tableXcModelGet', { tn }], { root: true })
const model = await dispatch('sqlMgr/ActSqlOp', [{ env, dbAlias, project_id }, 'tableXcModelGet', { tn }], { root: true })
const meta = JSON.parse(model.meta)
commit('MutMeta', {
key: tn,

1
packages/nc-gui/store/sqlMgr.js

@ -361,7 +361,6 @@ export const actions = {
dispatch
}, [args, op, opArgs, cusHeaders, cusAxiosOptions, queryParams, returnResponse]) {
const params = {}
params.project_id = rootState.project.projectId
if (this.$router.currentRoute && this.$router.currentRoute.params) {
if (this.$router.currentRoute.params.project_id) {

2
packages/nocodb/src/example/try.ts

@ -24,7 +24,7 @@ process.env.NC_DB = url;
config,
''
);
await app.ncMeta.projectStatusUpdate(config.title, 'started');
await app.ncMeta.projectStatusUpdate(project.id, 'started');
await app.ncMeta.projectAddUser(project.id, 1, 'owner,creator');
}
}

10
packages/nocodb/src/lib/noco/NcProjectBuilder.ts

@ -48,7 +48,7 @@ export default class NcProjectBuilder {
this.startTime = Date.now();
const allRoutesInfo: any[] = [];
await this.app.ncMeta.projectStatusUpdate(this.title, 'starting');
await this.app.ncMeta.projectStatusUpdate(this.id, 'starting');
await this.syncMigration();
await this._createApiBuilder();
this.initApiInfoRoute();
@ -72,10 +72,10 @@ export default class NcProjectBuilder {
}
this.app.projectRouter.use(`/nc/${this.id}`, this.router);
await this.app.ncMeta.projectStatusUpdate(this.title, 'started');
await this.app.ncMeta.projectStatusUpdate(this.id, 'started');
} catch (e) {
console.log(e);
await this.app.ncMeta.projectStatusUpdate(this.title, 'stopped');
await this.app.ncMeta.projectStatusUpdate(this.id, 'stopped');
}
}
@ -458,7 +458,7 @@ export default class NcProjectBuilder {
case 'projectStop':
this.router.stack.splice(0, this.router.stack.length);
this.apiBuilders.splice(0, this.apiBuilders.length);
await this.app.ncMeta.projectStatusUpdate(this.title, 'stopped');
await this.app.ncMeta.projectStatusUpdate(this.id, 'stopped');
NcProjectBuilder.triggerGarbageCollect();
this.app.ncMeta.audit(this.id, null, 'nc_audit', {
op_type: 'PROJECT',
@ -862,7 +862,7 @@ export default class NcProjectBuilder {
public async reInit() {
this.router.stack.splice(0, this.router.stack.length);
this.apiBuilders.splice(0, this.apiBuilders.length);
await this.app.ncMeta.projectStatusUpdate(this.title, 'stopped');
await this.app.ncMeta.projectStatusUpdate(this.id, 'stopped');
const dbs = this.config?.envs?.[this.appConfig.workingEnv]?.db;
if (!dbs || !dbs.length) {

2
packages/nocodb/src/lib/noco/meta/NcMetaIO.ts

@ -173,7 +173,7 @@ export default abstract class NcMetaIO {
): Promise<any>;
public abstract projectStatusUpdate(
projectName: string,
projectId: string,
status: string
): Promise<any>;

4
packages/nocodb/src/lib/noco/meta/NcMetaIOImpl.ts

@ -507,7 +507,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
}
public async projectStatusUpdate(
projectName: string,
projectId: string,
status: string
): Promise<any> {
return this.knexConnection('nc_projects')
@ -515,7 +515,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
status
})
.where({
title: projectName
id: projectId
});
}

Loading…
Cancel
Save