Browse Source

feat(nc-gui): allow Auto-Select Field Types in Excel & JSON import

pull/4135/head
Wing-Kam Wong 2 years ago
parent
commit
2dc5045891
  1. 2
      packages/nc-gui/components/dlg/QuickImport.vue
  2. 143
      packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts
  3. 12
      packages/nc-gui/utils/parsers/JSONTemplateAdapter.ts

2
packages/nc-gui/components/dlg/QuickImport.vue

@ -454,7 +454,7 @@ const beforeUpload = (file: UploadFile) => {
<a-input-number v-model:value="importState.parserConfig.maxRowsToParse" :min="1" :max="50000" /> <a-input-number v-model:value="importState.parserConfig.maxRowsToParse" :min="1" :max="50000" />
</a-form-item> </a-form-item>
<a-form-item v-if="isImportTypeCsv" class="!my-2"> <a-form-item class="!my-2">
<a-checkbox v-model:checked="importState.parserConfig.autoSelectFieldTypes"> <a-checkbox v-model:checked="importState.parserConfig.autoSelectFieldTypes">
<span class="caption">Auto-Select Field Types</span> <span class="caption">Auto-Select Field Types</span>
</a-checkbox> </a-checkbox>

143
packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts

@ -114,86 +114,89 @@ export default class ExcelTemplateAdapter extends TemplateGenerator {
column_name: cn, column_name: cn,
ref_column_name: cn, ref_column_name: cn,
meta: {}, meta: {},
uidt: UITypes.SingleLineText,
} }
const cellId = this.xlsx.utils.encode_cell({ if (this.config.autoSelectFieldTypes) {
c: range.s.c + col, const cellId = this.xlsx.utils.encode_cell({
r: columnNameRowExist, c: range.s.c + col,
}) r: columnNameRowExist,
const cellProps = ws[cellId] || {} })
column.uidt = excelTypeToUidt[cellProps.t] || UITypes.SingleLineText const cellProps = ws[cellId] || {}
column.uidt = excelTypeToUidt[cellProps.t] || UITypes.SingleLineText
if (column.uidt === UITypes.SingleLineText) {
// check for long text if (column.uidt === UITypes.SingleLineText) {
if (isMultiLineTextType(rows)) { // check for long text
column.uidt = UITypes.LongText if (isMultiLineTextType(rows)) {
} column.uidt = UITypes.LongText
}
if (isEmailType(rows)) { if (isEmailType(rows)) {
column.uidt = UITypes.Email column.uidt = UITypes.Email
} }
if (isUrlType(rows)) { if (isUrlType(rows)) {
column.uidt = UITypes.URL column.uidt = UITypes.URL
} else {
const vals = rows
.slice(columnNameRowExist ? 1 : 0)
.map((r: any) => r[col])
.filter((v: any) => v !== null && v !== undefined && v.toString().trim() !== '')
const checkboxType = isCheckboxType(vals)
if (checkboxType.length === 1) {
column.uidt = UITypes.Checkbox
} else { } else {
// Single Select / Multi Select const vals = rows
Object.assign(column, extractMultiOrSingleSelectProps(vals)) .slice(columnNameRowExist ? 1 : 0)
.map((r: any) => r[col])
.filter((v: any) => v !== null && v !== undefined && v.toString().trim() !== '')
const checkboxType = isCheckboxType(vals)
if (checkboxType.length === 1) {
column.uidt = UITypes.Checkbox
} else {
// Single Select / Multi Select
Object.assign(column, extractMultiOrSingleSelectProps(vals))
}
} }
} } else if (column.uidt === UITypes.Number) {
} else if (column.uidt === UITypes.Number) { if (
if ( rows.slice(1, this.config.maxRowsToParse).some((v: any) => {
rows.slice(1, this.config.maxRowsToParse).some((v: any) => { return v && v[col] && parseInt(v[col]) !== +v[col]
return v && v[col] && parseInt(v[col]) !== +v[col]
})
) {
column.uidt = UITypes.Decimal
}
if (
rows.slice(1, this.config.maxRowsToParse).every((v: any, i: any) => {
const cellId = this.xlsx.utils.encode_cell({
c: range.s.c + col,
r: i + columnNameRowExist,
}) })
) {
column.uidt = UITypes.Decimal
}
if (
rows.slice(1, this.config.maxRowsToParse).every((v: any, i: any) => {
const cellId = this.xlsx.utils.encode_cell({
c: range.s.c + col,
r: i + columnNameRowExist,
})
const cellObj = ws[cellId] const cellObj = ws[cellId]
return !cellObj || (cellObj.w && cellObj.w.startsWith('$')) return !cellObj || (cellObj.w && cellObj.w.startsWith('$'))
})
) {
column.uidt = UITypes.Currency
}
} else if (column.uidt === UITypes.DateTime) {
// TODO(import): centralise
// hold the possible date format found in the date
const dateFormat: Record<string, number> = {}
if (
rows.slice(1, this.config.maxRowsToParse).every((v: any, i: any) => {
const cellId = this.xlsx.utils.encode_cell({
c: range.s.c + col,
r: i + columnNameRowExist,
}) })
) {
const cellObj = ws[cellId] column.uidt = UITypes.Currency
const isDate = !cellObj || (cellObj.w && cellObj.w.split(' ').length === 1) }
if (isDate && cellObj) { } else if (column.uidt === UITypes.DateTime) {
dateFormat[getDateFormat(cellObj.w)] = (dateFormat[getDateFormat(cellObj.w)] || 0) + 1 // TODO(import): centralise
} // hold the possible date format found in the date
return isDate const dateFormat: Record<string, number> = {}
}) if (
) { rows.slice(1, this.config.maxRowsToParse).every((v: any, i: any) => {
column.uidt = UITypes.Date const cellId = this.xlsx.utils.encode_cell({
// take the date format with the max occurrence c: range.s.c + col,
column.meta.date_format = r: i + columnNameRowExist,
Object.keys(dateFormat).reduce((x, y) => (dateFormat[x] > dateFormat[y] ? x : y)) || 'YYYY/MM/DD' })
const cellObj = ws[cellId]
const isDate = !cellObj || (cellObj.w && cellObj.w.split(' ').length === 1)
if (isDate && cellObj) {
dateFormat[getDateFormat(cellObj.w)] = (dateFormat[getDateFormat(cellObj.w)] || 0) + 1
}
return isDate
})
) {
column.uidt = UITypes.Date
// take the date format with the max occurrence
column.meta.date_format =
Object.keys(dateFormat).reduce((x, y) => (dateFormat[x] > dateFormat[y] ? x : y)) || 'YYYY/MM/DD'
}
} }
} }
table.columns.push(column) table.columns.push(column)

12
packages/nc-gui/utils/parsers/JSONTemplateAdapter.ts

@ -89,17 +89,17 @@ export default class JSONTemplateAdapter extends TemplateGenerator {
} }
} else { } else {
const cn = path.join('_').replace(/\W/g, '_').trim() const cn = path.join('_').replace(/\W/g, '_').trim()
const column: Record<string, any> = { const column: Record<string, any> = {
column_name: cn, column_name: cn,
ref_column_name: cn, ref_column_name: cn,
uidt: UITypes.SingleLineText,
path, path,
} }
if (this.config.autoSelectFieldTypes) {
column.uidt = jsonTypeToUidt[typeof firstRowVal] || UITypes.SingleLineText column.uidt = jsonTypeToUidt[typeof firstRowVal] || UITypes.SingleLineText
const colData = jsonData.map((r: any) => extractNestedData(r, path))
const colData = jsonData.map((r: any) => extractNestedData(r, path)) Object.assign(column, getColumnUIDTAndMetas(colData, column.uidt))
Object.assign(column, getColumnUIDTAndMetas(colData, column.uidt)) }
columns.push(column) columns.push(column)
} }

Loading…
Cancel
Save