diff --git a/packages/nc-gui/components/template/Editor.vue b/packages/nc-gui/components/template/Editor.vue
index c984474c2b..915ecccb2f 100644
--- a/packages/nc-gui/components/template/Editor.vue
+++ b/packages/nc-gui/components/template/Editor.vue
@@ -1,6 +1,8 @@
@@ -649,7 +683,6 @@ function handleEditableTnChange(idx: number) {
-
+ >
+
+
+
+ The field is too large to be converted to {{ option.label }}
+
+ {{ option.label }}
+
+
+
diff --git a/packages/nc-gui/package-lock.json b/packages/nc-gui/package-lock.json
index 860fb59dd2..81a45e80bb 100644
--- a/packages/nc-gui/package-lock.json
+++ b/packages/nc-gui/package-lock.json
@@ -33,7 +33,7 @@
"vue-github-button": "^3.0.3",
"vue-i18n": "^9.2.2",
"vuedraggable": "^4.1.0",
- "xlsx": "^0.17.3"
+ "xlsx": "^0.18.5"
},
"devDependencies": {
"@antfu/eslint-config": "^0.26.0",
@@ -4220,16 +4220,9 @@
}
},
"node_modules/adler-32": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.2.0.tgz",
- "integrity": "sha512-/vUqU/UY4MVeFsg+SsK6c+/05RZXIHZMGJA+PX5JyWI0ZRcBpupnRuPLU/NXXoFwMYCPCoxIfElM2eS+DUXCqQ==",
- "dependencies": {
- "exit-on-epipe": "~1.0.1",
- "printj": "~1.1.0"
- },
- "bin": {
- "adler32": "bin/adler32.njs"
- },
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
+ "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==",
"engines": {
"node": ">=0.8"
}
@@ -4882,14 +4875,6 @@
"node": ">=0.8"
}
},
- "node_modules/cfb/node_modules/adler-32": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
- "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==",
- "engines": {
- "node": ">=0.8"
- }
- },
"node_modules/chai": {
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz",
@@ -7964,14 +7949,6 @@
"url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
- "node_modules/exit-on-epipe": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz",
- "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==",
- "engines": {
- "node": ">=0.8"
- }
- },
"node_modules/expand-template": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
@@ -13103,17 +13080,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/printj": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz",
- "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==",
- "bin": {
- "printj": "bin/printj.njs"
- },
- "engines": {
- "node": ">=0.8"
- }
- },
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@@ -16433,14 +16399,14 @@
}
},
"node_modules/xlsx": {
- "version": "0.17.5",
- "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.17.5.tgz",
- "integrity": "sha512-lXNU0TuYsvElzvtI6O7WIVb9Zar1XYw7Xb3VAx2wn8N/n0whBYrCnHMxtFyIiUU1Wjf09WzmLALDfBO5PqTb1g==",
+ "version": "0.18.5",
+ "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
+ "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
"dependencies": {
- "adler-32": "~1.2.0",
- "cfb": "^1.1.4",
+ "adler-32": "~1.3.0",
+ "cfb": "~1.2.1",
"codepage": "~1.15.0",
- "crc-32": "~1.2.0",
+ "crc-32": "~1.2.1",
"ssf": "~0.11.2",
"wmf": "~1.0.1",
"word": "~0.3.0"
@@ -19663,13 +19629,9 @@
"peer": true
},
"adler-32": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.2.0.tgz",
- "integrity": "sha512-/vUqU/UY4MVeFsg+SsK6c+/05RZXIHZMGJA+PX5JyWI0ZRcBpupnRuPLU/NXXoFwMYCPCoxIfElM2eS+DUXCqQ==",
- "requires": {
- "exit-on-epipe": "~1.0.1",
- "printj": "~1.1.0"
- }
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
+ "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A=="
},
"agent-base": {
"version": "6.0.2",
@@ -20132,13 +20094,6 @@
"requires": {
"adler-32": "~1.3.0",
"crc-32": "~1.2.0"
- },
- "dependencies": {
- "adler-32": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
- "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A=="
- }
}
},
"chai": {
@@ -22346,11 +22301,6 @@
"strip-final-newline": "^2.0.0"
}
},
- "exit-on-epipe": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz",
- "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw=="
- },
"expand-template": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
@@ -26135,11 +26085,6 @@
"integrity": "sha512-6UqkYefdogmzqAZWzJ7laYeJnaXDy2/J+ZqiiMtS7t7OfpXWTlaeGMwX8U6EFvPV/YWWEKRkS8hKS4k60WHTOg==",
"dev": true
},
- "printj": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz",
- "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ=="
- },
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@@ -28599,14 +28544,14 @@
"requires": {}
},
"xlsx": {
- "version": "0.17.5",
- "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.17.5.tgz",
- "integrity": "sha512-lXNU0TuYsvElzvtI6O7WIVb9Zar1XYw7Xb3VAx2wn8N/n0whBYrCnHMxtFyIiUU1Wjf09WzmLALDfBO5PqTb1g==",
+ "version": "0.18.5",
+ "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
+ "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
"requires": {
- "adler-32": "~1.2.0",
- "cfb": "^1.1.4",
+ "adler-32": "~1.3.0",
+ "cfb": "~1.2.1",
"codepage": "~1.15.0",
- "crc-32": "~1.2.0",
+ "crc-32": "~1.2.1",
"ssf": "~0.11.2",
"wmf": "~1.0.1",
"word": "~0.3.0"
diff --git a/packages/nc-gui/package.json b/packages/nc-gui/package.json
index 2d4df35bce..17202ef833 100644
--- a/packages/nc-gui/package.json
+++ b/packages/nc-gui/package.json
@@ -42,7 +42,7 @@
"vue-github-button": "^3.0.3",
"vue-i18n": "^9.2.2",
"vuedraggable": "^4.1.0",
- "xlsx": "^0.17.3"
+ "xlsx": "^0.18.5"
},
"devDependencies": {
"@antfu/eslint-config": "^0.26.0",
diff --git a/packages/nc-gui/utils/dateTimeUtils.ts b/packages/nc-gui/utils/dateTimeUtils.ts
index 5272df19de..a1f55a62ca 100644
--- a/packages/nc-gui/utils/dateTimeUtils.ts
+++ b/packages/nc-gui/utils/dateTimeUtils.ts
@@ -42,3 +42,12 @@ export function validateDateWithUnknownFormat(v: string) {
}
return res
}
+
+export function getDateFormat(v: string) {
+ for (const format of dateFormats) {
+ if (dayjs(v, format, true).isValid()) {
+ return format
+ }
+ }
+ return 'YYYY/MM/DD'
+}
diff --git a/packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts b/packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts
index 6e1b9ea4c9..8bfe2323b4 100644
--- a/packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts
+++ b/packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts
@@ -72,6 +72,9 @@ export default class ExcelTemplateAdapter extends TemplateGenerator {
parse() {
const tableNamePrefixRef: Record = {}
+ // TODO: find the upper bound / make it configurable
+ const maxSelectOptionsAllowed = 64
+
for (let i = 0; i < this.wb.SheetNames.length; i++) {
const columnNamePrefixRef: Record = { id: 0 }
const sheet: any = this.wb.SheetNames[i]
@@ -128,8 +131,6 @@ export default class ExcelTemplateAdapter extends TemplateGenerator {
ref_column_name: cn,
}
- table.columns.push(column)
-
// const cellId = `${col.toString(26).split('').map(s => (parseInt(s, 26) + 10).toString(36).toUpperCase())}2`;
const cellId = this.xlsx.utils.encode_cell({
c: range.s.c + col,
@@ -153,11 +154,8 @@ export default class ExcelTemplateAdapter extends TemplateGenerator {
if (checkboxType.length === 1) {
column.uidt = UITypes.Checkbox
} else {
- // todo: optimize
- // check column is multi or single select by comparing unique values
- // todo:
if (vals.some((v: any) => v && v.toString().includes(','))) {
- let flattenedVals = vals.flatMap((v: any) =>
+ const flattenedVals = vals.flatMap((v: any) =>
v
? v
.toString()
@@ -165,19 +163,41 @@ export default class ExcelTemplateAdapter extends TemplateGenerator {
.split(/\s*,\s*/)
: [],
)
- const uniqueVals = (flattenedVals = flattenedVals.filter(
- (v: any, i: any, arr: any) => i === arr.findIndex((v1: any) => v.toLowerCase() === v1.toLowerCase()),
- ))
- if (flattenedVals.length > uniqueVals.length && uniqueVals.length <= Math.ceil(flattenedVals.length / 2)) {
- column.uidt = UITypes.MultiSelect
+
+ // TODO: handle case sensitive case
+ const uniqueVals = [...new Set(flattenedVals.map((v: any) => v.toString().trim().toLowerCase()))]
+
+ if (uniqueVals.length > maxSelectOptionsAllowed) {
+ // too many options are detected, convert the column to SingleLineText instead
+ column.uidt = UITypes.SingleLineText
+ // _disableSelect is used to disable the in TemplateEditor
+ column._disableSelect = true
+ } else {
+ // assume the column type is multiple select if there are repeated values
+ if (flattenedVals.length > uniqueVals.length && uniqueVals.length <= Math.ceil(flattenedVals.length / 2)) {
+ column.uidt = UITypes.MultiSelect
+ }
+ // set dtxp here so that users can have the options even they switch the type from other types to MultiSelect
+ // once it's set, dtxp needs to be reset if the final column type is not MultiSelect
column.dtxp = `'${uniqueVals.join("','")}'`
}
} else {
- const uniqueVals = vals
- .map((v: any) => v.toString().trim())
- .filter((v: any, i: any, arr: any) => i === arr.findIndex((v1: any) => v.toLowerCase() === v1.toLowerCase()))
- if (vals.length > uniqueVals.length && uniqueVals.length <= Math.ceil(vals.length / 2)) {
- column.uidt = UITypes.SingleSelect
+ // TODO: handle case sensitive case
+ const uniqueVals = [...new Set(vals.map((v: any) => v.toString().trim().toLowerCase()))]
+
+ if (uniqueVals.length > maxSelectOptionsAllowed) {
+ // too many options are detected, convert the column to SingleLineText instead
+ column.uidt = UITypes.SingleLineText
+ // _disableSelect is used to disable the in TemplateEditor
+ column._disableSelect = true
+ } else {
+ // assume the column type is single select if there are repeated values
+ // once it's set, dtxp needs to be reset if the final column type is not Single Select
+ if (vals.length > uniqueVals.length && uniqueVals.length <= Math.ceil(vals.length / 2)) {
+ column.uidt = UITypes.SingleSelect
+ }
+ // set dtxp here so that users can have the options even they switch the type from other types to SingleSelect
+ // once it's set, dtxp needs to be reset if the final column type is not SingleSelect
column.dtxp = `'${uniqueVals.join("','")}'`
}
}
@@ -220,6 +240,7 @@ export default class ExcelTemplateAdapter extends TemplateGenerator {
column.uidt = UITypes.Date
}
}
+ table.columns.push(column)
}
let rowIndex = 0