|
|
@ -14,6 +14,8 @@ import utc from 'dayjs/plugin/utc'; |
|
|
|
import tinycolor from 'tinycolor2'; |
|
|
|
import tinycolor from 'tinycolor2'; |
|
|
|
import { importData, importLTARData } from './readAndProcessData'; |
|
|
|
import { importData, importLTARData } from './readAndProcessData'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import EntityMap from './EntityMap'; |
|
|
|
|
|
|
|
|
|
|
|
dayjs.extend(utc); |
|
|
|
dayjs.extend(utc); |
|
|
|
|
|
|
|
|
|
|
|
const selectColors = { |
|
|
|
const selectColors = { |
|
|
@ -67,32 +69,28 @@ export default async ( |
|
|
|
syncDB: AirtableSyncConfig, |
|
|
|
syncDB: AirtableSyncConfig, |
|
|
|
progress: (data: { msg?: string; level?: any }) => void |
|
|
|
progress: (data: { msg?: string; level?: any }) => void |
|
|
|
) => { |
|
|
|
) => { |
|
|
|
const sMap = { |
|
|
|
const sMapEM = new EntityMap('aTblId', 'ncId', 'ncName', 'ncParent'); |
|
|
|
mapTbl: {}, |
|
|
|
await sMapEM.init(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const sMap = { |
|
|
|
// static mapping records between aTblId && ncId
|
|
|
|
// static mapping records between aTblId && ncId
|
|
|
|
addToMappingTbl(aTblId, ncId, ncName, parent?) { |
|
|
|
async addToMappingTbl(aTblId, ncId, ncName, ncParent?) { |
|
|
|
this.mapTbl[aTblId] = { |
|
|
|
await sMapEM.addRow({ aTblId, ncId, ncName, ncParent }); |
|
|
|
ncId: ncId, |
|
|
|
|
|
|
|
ncParent: parent, |
|
|
|
|
|
|
|
// name added to assist in quick debug
|
|
|
|
|
|
|
|
ncName: ncName, |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
// get NcID from airtable ID
|
|
|
|
// get NcID from airtable ID
|
|
|
|
getNcIdFromAtId(aId) { |
|
|
|
async getNcIdFromAtId(aId) { |
|
|
|
return this.mapTbl[aId]?.ncId; |
|
|
|
return (await sMapEM.getRow('aTblId', aId, ['ncId']))?.ncId; |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
// get nc Parent from airtable ID
|
|
|
|
// get nc Parent from airtable ID
|
|
|
|
getNcParentFromAtId(aId) { |
|
|
|
async getNcParentFromAtId(aId) { |
|
|
|
return this.mapTbl[aId]?.ncParent; |
|
|
|
return (await sMapEM.getRow('aTblId', aId, ['ncParent']))?.ncParent; |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
// get nc-title from airtable ID
|
|
|
|
// get nc-title from airtable ID
|
|
|
|
getNcNameFromAtId(aId) { |
|
|
|
async getNcNameFromAtId(aId) { |
|
|
|
return this.mapTbl[aId]?.ncName; |
|
|
|
return (await sMapEM.getRow('aTblId', aId, ['ncName']))?.ncName; |
|
|
|
}, |
|
|
|
}, |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
@ -333,8 +331,8 @@ export default async ( |
|
|
|
// let ncCol = ncTbl.columns.find(x => x.title === aTblField.cn);
|
|
|
|
// let ncCol = ncTbl.columns.find(x => x.title === aTblField.cn);
|
|
|
|
// return ncCol;
|
|
|
|
// return ncCol;
|
|
|
|
|
|
|
|
|
|
|
|
const ncTblId = sMap.getNcParentFromAtId(aTblFieldId); |
|
|
|
const ncTblId = await sMap.getNcParentFromAtId(aTblFieldId); |
|
|
|
const ncColId = sMap.getNcIdFromAtId(aTblFieldId); |
|
|
|
const ncColId = await sMap.getNcIdFromAtId(aTblFieldId); |
|
|
|
|
|
|
|
|
|
|
|
// not migrated column, skip
|
|
|
|
// not migrated column, skip
|
|
|
|
if (ncColId === undefined || ncTblId === undefined) return 0; |
|
|
|
if (ncColId === undefined || ncTblId === undefined) return 0; |
|
|
@ -424,7 +422,7 @@ export default async ( |
|
|
|
|
|
|
|
|
|
|
|
// retrieve additional options associated with selected data types
|
|
|
|
// retrieve additional options associated with selected data types
|
|
|
|
//
|
|
|
|
//
|
|
|
|
function getNocoTypeOptions(col: any): any { |
|
|
|
async function getNocoTypeOptions(col: any): Promise<any> { |
|
|
|
switch (col.type) { |
|
|
|
switch (col.type) { |
|
|
|
case 'select': |
|
|
|
case 'select': |
|
|
|
case 'multiSelect': { |
|
|
|
case 'multiSelect': { |
|
|
@ -457,7 +455,7 @@ export default async ( |
|
|
|
: tinycolor.random().toHexString(), |
|
|
|
: tinycolor.random().toHexString(), |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
sMap.addToMappingTbl( |
|
|
|
await sMap.addToMappingTbl( |
|
|
|
(value as any).id, |
|
|
|
(value as any).id, |
|
|
|
undefined, |
|
|
|
undefined, |
|
|
|
(value as any).name |
|
|
|
(value as any).name |
|
|
@ -472,7 +470,7 @@ export default async ( |
|
|
|
|
|
|
|
|
|
|
|
// convert to Nc schema (basic, excluding relations)
|
|
|
|
// convert to Nc schema (basic, excluding relations)
|
|
|
|
//
|
|
|
|
//
|
|
|
|
function tablesPrepare(tblSchema: any[]) { |
|
|
|
async function tablesPrepare(tblSchema: any[]) { |
|
|
|
const tables: any[] = []; |
|
|
|
const tables: any[] = []; |
|
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < tblSchema.length; ++i) { |
|
|
|
for (let i = 0; i < tblSchema.length; ++i) { |
|
|
@ -569,7 +567,7 @@ export default async ( |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// additional column parameters when applicable
|
|
|
|
// additional column parameters when applicable
|
|
|
|
const colOptions = getNocoTypeOptions(col); |
|
|
|
const colOptions = await getNocoTypeOptions(col); |
|
|
|
|
|
|
|
|
|
|
|
switch (colOptions.type) { |
|
|
|
switch (colOptions.type) { |
|
|
|
case 'select': |
|
|
|
case 'select': |
|
|
@ -602,7 +600,7 @@ export default async ( |
|
|
|
|
|
|
|
|
|
|
|
async function nocoCreateBaseSchema(aTblSchema) { |
|
|
|
async function nocoCreateBaseSchema(aTblSchema) { |
|
|
|
// base schema preparation: exclude
|
|
|
|
// base schema preparation: exclude
|
|
|
|
const tables: any[] = tablesPrepare(aTblSchema); |
|
|
|
const tables: any[] = await tablesPrepare(aTblSchema); |
|
|
|
|
|
|
|
|
|
|
|
// for each table schema, create nc table
|
|
|
|
// for each table schema, create nc table
|
|
|
|
for (let idx = 0; idx < tables.length; idx++) { |
|
|
|
for (let idx = 0; idx < tables.length; idx++) { |
|
|
@ -696,7 +694,7 @@ export default async ( |
|
|
|
if (!nc_isLinkExists(aTblLinkColumns[i].id)) { |
|
|
|
if (!nc_isLinkExists(aTblLinkColumns[i].id)) { |
|
|
|
// parent table ID
|
|
|
|
// parent table ID
|
|
|
|
// let srcTableId = (await nc_getTableSchema(aTblSchema[idx].name)).id;
|
|
|
|
// let srcTableId = (await nc_getTableSchema(aTblSchema[idx].name)).id;
|
|
|
|
const srcTableId = sMap.getNcIdFromAtId(aTblSchema[idx].id); |
|
|
|
const srcTableId = await sMap.getNcIdFromAtId(aTblSchema[idx].id); |
|
|
|
|
|
|
|
|
|
|
|
// find child table name from symmetric column ID specified
|
|
|
|
// find child table name from symmetric column ID specified
|
|
|
|
// self link, symmetricColumnId field will be undefined
|
|
|
|
// self link, symmetricColumnId field will be undefined
|
|
|
@ -911,7 +909,7 @@ export default async ( |
|
|
|
|
|
|
|
|
|
|
|
// parent table ID
|
|
|
|
// parent table ID
|
|
|
|
// let srcTableId = (await nc_getTableSchema(aTblSchema[idx].name)).id;
|
|
|
|
// let srcTableId = (await nc_getTableSchema(aTblSchema[idx].name)).id;
|
|
|
|
const srcTableId = sMap.getNcIdFromAtId(aTblSchema[idx].id); |
|
|
|
const srcTableId = await sMap.getNcIdFromAtId(aTblSchema[idx].id); |
|
|
|
const srcTableSchema = ncSchema.tablesById[srcTableId]; |
|
|
|
const srcTableSchema = ncSchema.tablesById[srcTableId]; |
|
|
|
|
|
|
|
|
|
|
|
if (aTblColumns.length) { |
|
|
|
if (aTblColumns.length) { |
|
|
@ -939,10 +937,10 @@ export default async ( |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const ncRelationColumnId = sMap.getNcIdFromAtId( |
|
|
|
const ncRelationColumnId = await sMap.getNcIdFromAtId( |
|
|
|
aTblColumns[i].typeOptions.relationColumnId |
|
|
|
aTblColumns[i].typeOptions.relationColumnId |
|
|
|
); |
|
|
|
); |
|
|
|
const ncLookupColumnId = sMap.getNcIdFromAtId( |
|
|
|
const ncLookupColumnId = await sMap.getNcIdFromAtId( |
|
|
|
aTblColumns[i].typeOptions.foreignTableRollupColumnId |
|
|
|
aTblColumns[i].typeOptions.foreignTableRollupColumnId |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
@ -1015,10 +1013,10 @@ export default async ( |
|
|
|
const srcTableId = nestedLookupTbl[0].srcTableId; |
|
|
|
const srcTableId = nestedLookupTbl[0].srcTableId; |
|
|
|
const srcTableSchema = ncSchema.tablesById[srcTableId]; |
|
|
|
const srcTableSchema = ncSchema.tablesById[srcTableId]; |
|
|
|
|
|
|
|
|
|
|
|
const ncRelationColumnId = sMap.getNcIdFromAtId( |
|
|
|
const ncRelationColumnId = await sMap.getNcIdFromAtId( |
|
|
|
nestedLookupTbl[0].typeOptions.relationColumnId |
|
|
|
nestedLookupTbl[0].typeOptions.relationColumnId |
|
|
|
); |
|
|
|
); |
|
|
|
const ncLookupColumnId = sMap.getNcIdFromAtId( |
|
|
|
const ncLookupColumnId = await sMap.getNcIdFromAtId( |
|
|
|
nestedLookupTbl[0].typeOptions.foreignTableRollupColumnId |
|
|
|
nestedLookupTbl[0].typeOptions.foreignTableRollupColumnId |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
@ -1101,7 +1099,7 @@ export default async ( |
|
|
|
|
|
|
|
|
|
|
|
// parent table ID
|
|
|
|
// parent table ID
|
|
|
|
// let srcTableId = (await nc_getTableSchema(aTblSchema[idx].name)).id;
|
|
|
|
// let srcTableId = (await nc_getTableSchema(aTblSchema[idx].name)).id;
|
|
|
|
const srcTableId = sMap.getNcIdFromAtId(aTblSchema[idx].id); |
|
|
|
const srcTableId = await sMap.getNcIdFromAtId(aTblSchema[idx].id); |
|
|
|
const srcTableSchema = ncSchema.tablesById[srcTableId]; |
|
|
|
const srcTableSchema = ncSchema.tablesById[srcTableId]; |
|
|
|
|
|
|
|
|
|
|
|
if (aTblColumns.length) { |
|
|
|
if (aTblColumns.length) { |
|
|
@ -1146,10 +1144,10 @@ export default async ( |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const ncRelationColumnId = sMap.getNcIdFromAtId( |
|
|
|
const ncRelationColumnId = await sMap.getNcIdFromAtId( |
|
|
|
aTblColumns[i].typeOptions.relationColumnId |
|
|
|
aTblColumns[i].typeOptions.relationColumnId |
|
|
|
); |
|
|
|
); |
|
|
|
const ncRollupColumnId = sMap.getNcIdFromAtId( |
|
|
|
const ncRollupColumnId = await sMap.getNcIdFromAtId( |
|
|
|
aTblColumns[i].typeOptions.foreignTableRollupColumnId |
|
|
|
aTblColumns[i].typeOptions.foreignTableRollupColumnId |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
@ -1219,10 +1217,10 @@ export default async ( |
|
|
|
const srcTableId = nestedLookupTbl[0].srcTableId; |
|
|
|
const srcTableId = nestedLookupTbl[0].srcTableId; |
|
|
|
const srcTableSchema = ncSchema.tablesById[srcTableId]; |
|
|
|
const srcTableSchema = ncSchema.tablesById[srcTableId]; |
|
|
|
|
|
|
|
|
|
|
|
const ncRelationColumnId = sMap.getNcIdFromAtId( |
|
|
|
const ncRelationColumnId = await sMap.getNcIdFromAtId( |
|
|
|
nestedLookupTbl[0].typeOptions.relationColumnId |
|
|
|
nestedLookupTbl[0].typeOptions.relationColumnId |
|
|
|
); |
|
|
|
); |
|
|
|
const ncLookupColumnId = sMap.getNcIdFromAtId( |
|
|
|
const ncLookupColumnId = await sMap.getNcIdFromAtId( |
|
|
|
nestedLookupTbl[0].typeOptions.foreignTableRollupColumnId |
|
|
|
nestedLookupTbl[0].typeOptions.foreignTableRollupColumnId |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
@ -1278,7 +1276,7 @@ export default async ( |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
const pColId = aTblSchema[idx].primaryColumnId; |
|
|
|
const pColId = aTblSchema[idx].primaryColumnId; |
|
|
|
const ncColId = sMap.getNcIdFromAtId(pColId); |
|
|
|
const ncColId = await sMap.getNcIdFromAtId(pColId); |
|
|
|
|
|
|
|
|
|
|
|
// skip primary column configuration if we field not migrated
|
|
|
|
// skip primary column configuration if we field not migrated
|
|
|
|
if (ncColId) { |
|
|
|
if (ncColId) { |
|
|
@ -1288,7 +1286,7 @@ export default async ( |
|
|
|
recordPerfStats(_perfStart, 'dbTableColumn.primaryColumnSet'); |
|
|
|
recordPerfStats(_perfStart, 'dbTableColumn.primaryColumnSet'); |
|
|
|
|
|
|
|
|
|
|
|
// update schema
|
|
|
|
// update schema
|
|
|
|
const ncTblId = sMap.getNcIdFromAtId(aTblSchema[idx].id); |
|
|
|
const ncTblId = await sMap.getNcIdFromAtId(aTblSchema[idx].id); |
|
|
|
await updateNcTblSchemaById(ncTblId); |
|
|
|
await updateNcTblSchemaById(ncTblId); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -1408,7 +1406,7 @@ export default async ( |
|
|
|
|
|
|
|
|
|
|
|
case UITypes.MultiSelect: |
|
|
|
case UITypes.MultiSelect: |
|
|
|
rec[key] = value |
|
|
|
rec[key] = value |
|
|
|
.map((v) => { |
|
|
|
?.map((v) => { |
|
|
|
if (v === '') { |
|
|
|
if (v === '') { |
|
|
|
return 'nc_empty'; |
|
|
|
return 'nc_empty'; |
|
|
|
} |
|
|
|
} |
|
|
@ -1567,7 +1565,7 @@ export default async ( |
|
|
|
async function nocoConfigureFormView(sDB, aTblSchema) { |
|
|
|
async function nocoConfigureFormView(sDB, aTblSchema) { |
|
|
|
if (!sDB.options.syncViews) return; |
|
|
|
if (!sDB.options.syncViews) return; |
|
|
|
for (let idx = 0; idx < aTblSchema.length; idx++) { |
|
|
|
for (let idx = 0; idx < aTblSchema.length; idx++) { |
|
|
|
const tblId = sMap.getNcIdFromAtId(aTblSchema[idx].id); |
|
|
|
const tblId = await sMap.getNcIdFromAtId(aTblSchema[idx].id); |
|
|
|
const formViews = aTblSchema[idx].views.filter((x) => x.type === 'form'); |
|
|
|
const formViews = aTblSchema[idx].views.filter((x) => x.type === 'form'); |
|
|
|
|
|
|
|
|
|
|
|
const configuredViews = rtc.view.grid + rtc.view.gallery + rtc.view.form; |
|
|
|
const configuredViews = rtc.view.grid + rtc.view.gallery + rtc.view.form; |
|
|
@ -1639,7 +1637,7 @@ export default async ( |
|
|
|
|
|
|
|
|
|
|
|
async function nocoConfigureGridView(sDB, aTblSchema) { |
|
|
|
async function nocoConfigureGridView(sDB, aTblSchema) { |
|
|
|
for (let idx = 0; idx < aTblSchema.length; idx++) { |
|
|
|
for (let idx = 0; idx < aTblSchema.length; idx++) { |
|
|
|
const tblId = sMap.getNcIdFromAtId(aTblSchema[idx].id); |
|
|
|
const tblId = await sMap.getNcIdFromAtId(aTblSchema[idx].id); |
|
|
|
const gridViews = aTblSchema[idx].views.filter((x) => x.type === 'grid'); |
|
|
|
const gridViews = aTblSchema[idx].views.filter((x) => x.type === 'grid'); |
|
|
|
|
|
|
|
|
|
|
|
let viewCnt = idx; |
|
|
|
let viewCnt = idx; |
|
|
@ -1955,7 +1953,7 @@ export default async ( |
|
|
|
// one of not migrated column;
|
|
|
|
// one of not migrated column;
|
|
|
|
if (!colSchema) { |
|
|
|
if (!colSchema) { |
|
|
|
updateMigrationSkipLog( |
|
|
|
updateMigrationSkipLog( |
|
|
|
sMap.getNcNameFromAtId(viewId), |
|
|
|
await sMap.getNcNameFromAtId(viewId), |
|
|
|
colSchema.title, |
|
|
|
colSchema.title, |
|
|
|
colSchema.uidt, |
|
|
|
colSchema.uidt, |
|
|
|
`filter config skipped; column not migrated` |
|
|
|
`filter config skipped; column not migrated` |
|
|
@ -1970,7 +1968,7 @@ export default async ( |
|
|
|
if (datatype === UITypes.Date || datatype === UITypes.DateTime) { |
|
|
|
if (datatype === UITypes.Date || datatype === UITypes.DateTime) { |
|
|
|
// skip filters over data datatype
|
|
|
|
// skip filters over data datatype
|
|
|
|
updateMigrationSkipLog( |
|
|
|
updateMigrationSkipLog( |
|
|
|
sMap.getNcNameFromAtId(viewId), |
|
|
|
await sMap.getNcNameFromAtId(viewId), |
|
|
|
colSchema.title, |
|
|
|
colSchema.title, |
|
|
|
colSchema.uidt, |
|
|
|
colSchema.uidt, |
|
|
|
`filter config skipped; filter over date datatype not supported` |
|
|
|
`filter config skipped; filter over date datatype not supported` |
|
|
@ -1990,7 +1988,7 @@ export default async ( |
|
|
|
fk_column_id: columnId, |
|
|
|
fk_column_id: columnId, |
|
|
|
logical_op: f.conjunction, |
|
|
|
logical_op: f.conjunction, |
|
|
|
comparison_op: filterMap[filter.operator], |
|
|
|
comparison_op: filterMap[filter.operator], |
|
|
|
value: sMap.getNcNameFromAtId(filter.value[i]), |
|
|
|
value: await sMap.getNcNameFromAtId(filter.value[i]), |
|
|
|
}; |
|
|
|
}; |
|
|
|
ncFilters.push(fx); |
|
|
|
ncFilters.push(fx); |
|
|
|
} |
|
|
|
} |
|
|
@ -2001,7 +1999,7 @@ export default async ( |
|
|
|
fk_column_id: columnId, |
|
|
|
fk_column_id: columnId, |
|
|
|
logical_op: f.conjunction, |
|
|
|
logical_op: f.conjunction, |
|
|
|
comparison_op: filterMap[filter.operator], |
|
|
|
comparison_op: filterMap[filter.operator], |
|
|
|
value: sMap.getNcNameFromAtId(filter.value), |
|
|
|
value: await sMap.getNcNameFromAtId(filter.value), |
|
|
|
}; |
|
|
|
}; |
|
|
|
ncFilters.push(fx); |
|
|
|
ncFilters.push(fx); |
|
|
|
} |
|
|
|
} |
|
|
@ -2097,7 +2095,7 @@ export default async ( |
|
|
|
|
|
|
|
|
|
|
|
// rest of the columns from airtable- retain order & visibility property
|
|
|
|
// rest of the columns from airtable- retain order & visibility property
|
|
|
|
for (let j = 0; j < c.length; j++) { |
|
|
|
for (let j = 0; j < c.length; j++) { |
|
|
|
const ncColumnId = sMap.getNcIdFromAtId(c[j].columnId); |
|
|
|
const ncColumnId = await sMap.getNcIdFromAtId(c[j].columnId); |
|
|
|
const ncViewColumnId = await nc_getViewColumnId( |
|
|
|
const ncViewColumnId = await nc_getViewColumnId( |
|
|
|
viewId, |
|
|
|
viewId, |
|
|
|
viewType, |
|
|
|
viewType, |
|
|
@ -2243,7 +2241,7 @@ export default async ( |
|
|
|
sDB: syncDB, |
|
|
|
sDB: syncDB, |
|
|
|
logDetailed, |
|
|
|
logDetailed, |
|
|
|
}); |
|
|
|
}); |
|
|
|
rtc.data.records += recordsMap[ncTbl.id].length; |
|
|
|
rtc.data.records += await recordsMap[ncTbl.id].getCount(); |
|
|
|
|
|
|
|
|
|
|
|
logDetailed(`Data inserted from ${ncTbl.title}`); |
|
|
|
logDetailed(`Data inserted from ${ncTbl.title}`); |
|
|
|
} |
|
|
|
} |
|
|
|