From 02fc7da2247653bdf9499ec7010d7ecbfdab4e80 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Sun, 25 Sep 2022 23:35:57 +0800 Subject: [PATCH 01/15] feat(nc-gui): enrich .dt & save dtxp for singleSelect / multiSelect --- .../utils/parsers/ExcelTemplateAdapter.ts | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts b/packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts index 85c631d2a2..511c4b5cdf 100644 --- a/packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts +++ b/packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts @@ -103,13 +103,11 @@ export default class ExcelTemplateAdapter extends TemplateGenerator { } columnNamePrefixRef[cn] = 0 - const column: Record = { + let column: Record = { column_name: cn, 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 = XLSX.utils.encode_cell({ c: range.s.c + col, @@ -118,6 +116,11 @@ export default class ExcelTemplateAdapter extends TemplateGenerator { const cellProps = ws[cellId] || {} column.uidt = excelTypeToUidt[cellProps.t] || UITypes.SingleLineText + const { sqlUi } = useProject() + + // enrich data type for Template Editor to process + column = { ...column, ...sqlUi?.value?.getDataTypeForUiType({ uidt: column.uidt }) } + // todo: optimize if (column.uidt === UITypes.SingleLineText) { // check for long text @@ -148,18 +151,26 @@ export default class ExcelTemplateAdapter extends TemplateGenerator { const uniqueVals = (flattenedVals = flattenedVals.filter( (v: any, i: any, arr: any) => i === arr.findIndex((v1: any) => v.toLowerCase() === v1.toLowerCase()), )) + // 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 - column.dtxp = `'${uniqueVals.join("','")}'` } + // 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 { + // 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 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 - column.dtxp = `'${uniqueVals.join("','")}'` } + // 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 MultiSelect + column.dtxp = `'${uniqueVals.join("','")}'` } } } @@ -200,6 +211,7 @@ export default class ExcelTemplateAdapter extends TemplateGenerator { column.uidt = UITypes.Date } } + table.columns.push(column) } let rowIndex = 0 From 39ccc6ed849fee8205d7d93ea37afccb5fc208e9 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Sun, 25 Sep 2022 23:39:12 +0800 Subject: [PATCH 02/15] feat(nc-gui): reset dtxp & remove dt for importing single / multi select --- packages/nc-gui/components/template/Editor.vue | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/nc-gui/components/template/Editor.vue b/packages/nc-gui/components/template/Editor.vue index f0d7dbd6c6..f27bf1bc8a 100644 --- a/packages/nc-gui/components/template/Editor.vue +++ b/packages/nc-gui/components/template/Editor.vue @@ -1,6 +1,6 @@ - + > + + + + {{ option.label }} + + + From 480e9cef03943a1dbc848263aa2328cc5da3020b Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Wed, 5 Oct 2022 13:01:53 +0800 Subject: [PATCH 08/15] feat(nc-gui): convert col to SingleLineText if detected options are greater than maxSelectOptionsAllowed --- .../utils/parsers/ExcelTemplateAdapter.ts | 59 +++++++++++-------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts b/packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts index 445281ad8e..067db0f817 100644 --- a/packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts +++ b/packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts @@ -72,6 +72,8 @@ export default class ExcelTemplateAdapter extends TemplateGenerator { parse() { const tableNamePrefixRef: Record = {} + const maxSelectOptionsAllowed = 100 + for (let i = 0; i < this.wb.SheetNames.length; i++) { const columnNamePrefixRef: Record = { id: 0 } const sheet: any = this.wb.SheetNames[i] @@ -151,9 +153,6 @@ 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) => v @@ -163,29 +162,43 @@ 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()), - )) - // 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 + + // 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("','")}'` } - // 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 { - // 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 - 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("','")}'` } - // 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("','")}'` } } } From 665b0d576469795d694fee0eb673faabdd7ba302 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Wed, 5 Oct 2022 16:27:48 +0800 Subject: [PATCH 09/15] chore(nc-gui): lint --- packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts b/packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts index 067db0f817..c453388557 100644 --- a/packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts +++ b/packages/nc-gui/utils/parsers/ExcelTemplateAdapter.ts @@ -154,7 +154,7 @@ export default class ExcelTemplateAdapter extends TemplateGenerator { column.uidt = UITypes.Checkbox } else { if (vals.some((v: any) => v && v.toString().includes(','))) { - let flattenedVals = vals.flatMap((v: any) => + const flattenedVals = vals.flatMap((v: any) => v ? v .toString() From 10f01996a9a5eda44426e0975e1894dfe6fa975f Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Wed, 5 Oct 2022 16:35:43 +0800 Subject: [PATCH 10/15] feat(nc-gui): bumb xlsx version to include fizzydate fix --- packages/nc-gui/package-lock.json | 93 +++++++------------------------ packages/nc-gui/package.json | 2 +- 2 files changed, 20 insertions(+), 75 deletions(-) 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", From b635e3c121f7240d4bf7c102ebf5c8598e5bc51f Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Wed, 5 Oct 2022 19:20:47 +0800 Subject: [PATCH 11/15] feat(nc-gui): handle import datetime --- .../nc-gui/components/template/Editor.vue | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/packages/nc-gui/components/template/Editor.vue b/packages/nc-gui/components/template/Editor.vue index 30ee644a57..073c0b5e2f 100644 --- a/packages/nc-gui/components/template/Editor.vue +++ b/packages/nc-gui/components/template/Editor.vue @@ -1,4 +1,6 @@