@maxax/ui 1.1.72 → 1.1.74

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/_commonjsHelpers-Bc2YnDe1.cjs +8 -0
  2. package/dist/_commonjsHelpers-Bc2YnDe1.cjs.map +1 -0
  3. package/dist/_commonjsHelpers-DWwsNxpa.js +9 -0
  4. package/dist/_commonjsHelpers-DWwsNxpa.js.map +1 -0
  5. package/dist/components/basic-button-group/BasicButtonGroup.vue.d.ts +3 -1
  6. package/dist/components/basic-button-group/BasicButtonGroup.vue.d.ts.map +1 -1
  7. package/dist/components/basic-button-group/components/ButtonGroupItem.vue.d.ts.map +1 -1
  8. package/dist/components/basic-button-group/hooks/use-button-group-schema.d.ts.map +1 -1
  9. package/dist/components/basic-button-group/types/button-group.d.ts +4 -0
  10. package/dist/components/basic-button-group/types/button-group.d.ts.map +1 -1
  11. package/dist/components/basic-button-group/types/component.d.ts +3 -1
  12. package/dist/components/basic-button-group/types/component.d.ts.map +1 -1
  13. package/dist/components/basic-button-import-max/BasicButtonImportMax.vue.d.ts +653 -702
  14. package/dist/components/basic-button-import-max/BasicButtonImportMax.vue.d.ts.map +1 -1
  15. package/dist/components/basic-button-import-max/PreviewModal.vue.d.ts +17 -465
  16. package/dist/components/basic-button-import-max/PreviewModal.vue.d.ts.map +1 -1
  17. package/dist/components/basic-button-import-max/UploadModal.vue.d.ts +4 -1
  18. package/dist/components/basic-button-import-max/UploadModal.vue.d.ts.map +1 -1
  19. package/dist/components/basic-button-import-max/interface.d.ts +36 -0
  20. package/dist/components/basic-button-import-max/interface.d.ts.map +1 -1
  21. package/dist/components/basic-button-import-max/utils.d.ts +16 -0
  22. package/dist/components/basic-button-import-max/utils.d.ts.map +1 -0
  23. package/dist/components/basic-edit-batch/components/EditBatchItem.vue.d.ts.map +1 -1
  24. package/dist/components/basic-form/components/FormItem.vue.d.ts.map +1 -1
  25. package/dist/components/basic-message-box/interface.d.ts.map +1 -1
  26. package/dist/components/basic-table/BasicTable.vue.d.ts +1 -0
  27. package/dist/components/basic-table/BasicTable.vue.d.ts.map +1 -1
  28. package/dist/components/basic-table/export-xlsx.d.ts +28 -0
  29. package/dist/components/basic-table/export-xlsx.d.ts.map +1 -0
  30. package/dist/components/basic-table/index.d.ts +1 -0
  31. package/dist/components/basic-table/index.d.ts.map +1 -1
  32. package/dist/components/basic-table/interface.d.ts +2 -0
  33. package/dist/components/basic-table/interface.d.ts.map +1 -1
  34. package/dist/exceljs.min-Bt5AZfbx.js +23122 -0
  35. package/dist/exceljs.min-Bt5AZfbx.js.map +1 -0
  36. package/dist/exceljs.min-DvM7I02X.cjs +23121 -0
  37. package/dist/exceljs.min-DvM7I02X.cjs.map +1 -0
  38. package/dist/index.cjs +454 -81
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.mjs +454 -81
  41. package/dist/index.mjs.map +1 -1
  42. package/dist/locale/lang/en.d.ts.map +1 -1
  43. package/dist/locale/lang/zh-cn.d.ts.map +1 -1
  44. package/dist/locales.cjs +49 -10
  45. package/dist/locales.cjs.map +1 -1
  46. package/dist/locales.mjs +45 -6
  47. package/dist/locales.mjs.map +1 -1
  48. package/dist/theme-chalk/components/basicButtonGroup.scss +17 -1
  49. package/dist/theme-chalk/components/basicButtonImportMax.scss +102 -13
  50. package/dist/theme-chalk/index.css +1 -1
  51. package/dist/theme-chalk/light.css +1 -1
  52. package/dist/{zh-cn-C7lMkB1L.cjs → zh-cn-BdENqlAc.cjs} +16 -3
  53. package/dist/zh-cn-BdENqlAc.cjs.map +1 -0
  54. package/dist/{zh-cn-DUJD5NdW.js → zh-cn-KPfh6ZPA.js} +16 -3
  55. package/dist/zh-cn-KPfh6ZPA.js.map +1 -0
  56. package/package.json +6 -5
  57. package/dist/zh-cn-C7lMkB1L.cjs.map +0 -1
  58. package/dist/zh-cn-DUJD5NdW.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -11,7 +11,7 @@ const dayjs = require("dayjs");
11
11
  const hooks = require("@maxax/hooks");
12
12
  const dateFns = require("date-fns");
13
13
  const elementResizeDetectorMaker = require("element-resize-detector");
14
- const zhCn = require("./zh-cn-C7lMkB1L.cjs");
14
+ const zhCn = require("./zh-cn-BdENqlAc.cjs");
15
15
  function tryOnScopeDispose(fn, failSilently) {
16
16
  if (vue.getCurrentScope()) {
17
17
  vue.onScopeDispose(fn, failSilently);
@@ -7853,20 +7853,21 @@ const _sfc_main$H = /* @__PURE__ */ vue.defineComponent({
7853
7853
  return vue.createVNode("span", null, [getLabel]);
7854
7854
  }
7855
7855
  function renderComponent() {
7856
+ var _a;
7856
7857
  const {
7857
7858
  renderComponentContent
7858
7859
  } = props.schema;
7859
7860
  const {
7860
7861
  size
7861
7862
  } = props.buttonGroupProps;
7863
+ const icon = (_a = props.schema.icon) != null ? _a : vue.unref(getComponentsProps).icon;
7862
7864
  const propsData = {
7863
- clearable: true,
7864
7865
  size,
7865
- type: "primary",
7866
7866
  ...vue.unref(getComponentsProps),
7867
7867
  disabled: vue.unref(getDisable),
7868
7868
  loading: vue.unref(getLoading)
7869
7869
  };
7870
+ delete propsData.icon;
7870
7871
  const on = {
7871
7872
  onClick: (ev) => {
7872
7873
  if (!props.schema.validate) {
@@ -7907,18 +7908,25 @@ const _sfc_main$H = /* @__PURE__ */ vue.defineComponent({
7907
7908
  ...propsData,
7908
7909
  ...on
7909
7910
  };
7911
+ const iconSlot = icon ? {
7912
+ icon: () => vue.createVNode(XBasicSvgIcon, {
7913
+ "icon": icon
7914
+ }, null)
7915
+ } : {};
7910
7916
  if (!renderComponentContent) {
7911
- let _slot;
7912
- return vue.createVNode(naiveUi.NButton, compAttr, _isSlot$3(_slot = renderButtonLabel()) ? _slot : {
7913
- default: () => [_slot]
7917
+ return vue.createVNode(naiveUi.NButton, compAttr, {
7918
+ default: () => renderButtonLabel(),
7919
+ ...iconSlot
7914
7920
  });
7915
7921
  }
7916
7922
  const compSlot = utils.isFunction(renderComponentContent) ? {
7917
7923
  ...renderComponentContent(vue.unref(getValues), {
7918
7924
  disabled: vue.unref(getDisable)
7919
- })
7925
+ }),
7926
+ ...iconSlot
7920
7927
  } : {
7921
- default: () => renderComponentContent
7928
+ default: () => renderComponentContent,
7929
+ ...iconSlot
7922
7930
  };
7923
7931
  return vue.createVNode(naiveUi.NButton, compAttr, _isSlot$3(compSlot) ? compSlot : {
7924
7932
  default: () => [compSlot]
@@ -8074,9 +8082,24 @@ function useButtonGroupEvents({ getSchema, schemaRef }) {
8074
8082
  setSchema
8075
8083
  };
8076
8084
  }
8085
+ const DEFAULT_RETURN_BUTTON_SCHEMA = {
8086
+ field: "buttonReturn",
8087
+ component: "Button",
8088
+ label: () => t("max.basic.back"),
8089
+ message: () => t("max.basic.confirmReturn"),
8090
+ confirm: () => window.history.back(),
8091
+ componentProps: {
8092
+ type: "default",
8093
+ bordered: true
8094
+ }
8095
+ };
8077
8096
  function useButtonGroupSchema({ getProps, schemaRef }) {
8078
8097
  const getSchema = vue.computed(() => {
8079
- const schemas = utils.cloneDeep(vue.unref(schemaRef) || vue.unref(getProps).schemas || []);
8098
+ const props = vue.unref(getProps);
8099
+ const schemas = utils.cloneDeep(vue.unref(schemaRef) || props.schemas || []);
8100
+ if (props.showReturnButton && !schemas.some((schema) => schema.field === DEFAULT_RETURN_BUTTON_SCHEMA.field)) {
8101
+ schemas.unshift(utils.cloneDeep(DEFAULT_RETURN_BUTTON_SCHEMA));
8102
+ }
8080
8103
  return schemas;
8081
8104
  });
8082
8105
  return { getSchema };
@@ -8084,18 +8107,20 @@ function useButtonGroupSchema({ getProps, schemaRef }) {
8084
8107
  const _sfc_main$G = /* @__PURE__ */ vue.defineComponent({
8085
8108
  __name: "BasicButtonGroup",
8086
8109
  props: {
8087
- showReturnButton: { type: Boolean },
8110
+ showReturnButton: { type: Boolean, default: true },
8088
8111
  size: {},
8089
8112
  disabled: { type: Boolean },
8090
8113
  readonly: { type: Boolean },
8091
8114
  schemas: { default: () => [] },
8092
8115
  mergeDynamicData: {},
8116
+ placement: { default: "left" },
8093
8117
  compact: { type: Boolean }
8094
8118
  },
8095
8119
  emits: ["click"],
8096
8120
  setup(__props, { expose: __expose, emit: __emit }) {
8097
8121
  const props = __props;
8098
8122
  const { t: t2 } = useLocale();
8123
+ const { e } = useNamespace("basic-button-group");
8099
8124
  const attrs = vue.useAttrs();
8100
8125
  const schemaRef = vue.ref(null);
8101
8126
  vue.ref(null);
@@ -8111,6 +8136,14 @@ const _sfc_main$G = /* @__PURE__ */ vue.defineComponent({
8111
8136
  schemaRef
8112
8137
  });
8113
8138
  const getBindValue = vue.computed(() => ({ ...lodashEs.omit(attrs, ["data-max-id"]), ...vue.unref(getProps) }));
8139
+ const getLeftSchema = vue.computed(() => vue.unref(getSchema).filter((schema) => {
8140
+ var _a;
8141
+ return ((_a = schema.placement) != null ? _a : vue.unref(getProps).placement) === "left";
8142
+ }));
8143
+ const getRightSchema = vue.computed(() => vue.unref(getSchema).filter((schema) => {
8144
+ var _a;
8145
+ return ((_a = schema.placement) != null ? _a : vue.unref(getProps).placement) === "right";
8146
+ }));
8114
8147
  vue.watch(
8115
8148
  () => props.schemas,
8116
8149
  (schemas) => {
@@ -8140,12 +8173,9 @@ const _sfc_main$G = /* @__PURE__ */ vue.defineComponent({
8140
8173
  function handleClick({ values: values2 }) {
8141
8174
  var _a;
8142
8175
  const { field, schema } = values2;
8143
- if (field === "buttonReturn") {
8144
- window.history.back();
8145
- return;
8146
- }
8147
- if (schema.message) {
8148
- XBasicMessageBox.confirm(schema.message, t2("max.basic.warning"), schema.messageBoxProps || {}).then(() => {
8176
+ const message = utils.isFunction(schema.message) ? schema.message(values2) : schema.message;
8177
+ if (message) {
8178
+ XBasicMessageBox.confirm(message, t2("max.basic.warning"), schema.messageBoxProps || {}).then(() => {
8149
8179
  var _a2;
8150
8180
  (_a2 = schema.confirm) == null ? void 0 : _a2.call(schema, { field, schema, action: "confirm" });
8151
8181
  }).catch(() => {
@@ -8161,24 +8191,51 @@ const _sfc_main$G = /* @__PURE__ */ vue.defineComponent({
8161
8191
  });
8162
8192
  return (_ctx, _cache) => {
8163
8193
  return vue.openBlock(), vue.createElementBlock("div", vue.mergeProps({ class: vue.unref(getWrapperClass) }, getBindValue.value), [
8164
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(getSchema), (schema) => {
8165
- return vue.openBlock(), vue.createBlock(_sfc_main$H, {
8166
- key: schema.field,
8167
- schema,
8168
- "button-group-action-type": buttonGroupActionType,
8169
- "button-group-props": getProps.value,
8170
- onClick: handleClick
8171
- }, vue.createSlots({ _: 2 }, [
8172
- vue.renderList(Object.keys(vue.unref(slots)), (item) => {
8173
- return {
8174
- name: item,
8175
- fn: vue.withCtx((data) => [
8176
- vue.renderSlot(_ctx.$slots, item, vue.mergeProps({ ref_for: true }, data || {}))
8177
- ])
8178
- };
8179
- })
8180
- ]), 1032, ["schema", "button-group-props"]);
8181
- }), 128))
8194
+ vue.createElementVNode("div", {
8195
+ class: vue.normalizeClass(vue.unref(e)("left"))
8196
+ }, [
8197
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(getLeftSchema.value, (schema) => {
8198
+ return vue.openBlock(), vue.createBlock(_sfc_main$H, {
8199
+ key: schema.field,
8200
+ schema,
8201
+ "button-group-action-type": buttonGroupActionType,
8202
+ "button-group-props": getProps.value,
8203
+ onClick: handleClick
8204
+ }, vue.createSlots({ _: 2 }, [
8205
+ vue.renderList(Object.keys(vue.unref(slots)), (item) => {
8206
+ return {
8207
+ name: item,
8208
+ fn: vue.withCtx((data) => [
8209
+ vue.renderSlot(_ctx.$slots, item, vue.mergeProps({ ref_for: true }, data || {}))
8210
+ ])
8211
+ };
8212
+ })
8213
+ ]), 1032, ["schema", "button-group-props"]);
8214
+ }), 128))
8215
+ ], 2),
8216
+ getRightSchema.value.length ? (vue.openBlock(), vue.createElementBlock("div", {
8217
+ key: 0,
8218
+ class: vue.normalizeClass(vue.unref(e)("right"))
8219
+ }, [
8220
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(getRightSchema.value, (schema) => {
8221
+ return vue.openBlock(), vue.createBlock(_sfc_main$H, {
8222
+ key: schema.field,
8223
+ schema,
8224
+ "button-group-action-type": buttonGroupActionType,
8225
+ "button-group-props": getProps.value,
8226
+ onClick: handleClick
8227
+ }, vue.createSlots({ _: 2 }, [
8228
+ vue.renderList(Object.keys(vue.unref(slots)), (item) => {
8229
+ return {
8230
+ name: item,
8231
+ fn: vue.withCtx((data) => [
8232
+ vue.renderSlot(_ctx.$slots, item, vue.mergeProps({ ref_for: true }, data || {}))
8233
+ ])
8234
+ };
8235
+ })
8236
+ ]), 1032, ["schema", "button-group-props"]);
8237
+ }), 128))
8238
+ ], 2)) : vue.createCommentVNode("", true)
8182
8239
  ], 16);
8183
8240
  };
8184
8241
  }
@@ -8198,6 +8255,121 @@ const FETCH_SETTING$1 = {
8198
8255
  totalField: "totalCount"
8199
8256
  };
8200
8257
  const DEFAULT_SIZE = "small";
8258
+ const defaultHeaderBackgroundColor = "f2f2f2";
8259
+ const defaultCellFontColor = "000000";
8260
+ const defaultCellBorderColor = "e0e0e0";
8261
+ const defaultCellBorderStyle = "thin";
8262
+ async function getExcelJS() {
8263
+ const ExcelJS = await Promise.resolve().then(() => require("./exceljs.min-DvM7I02X.cjs")).then((n) => n.exceljs_min);
8264
+ return ExcelJS.default || ExcelJS;
8265
+ }
8266
+ function getColumnWidth(column) {
8267
+ const width = Number(column.width || ("minWidth" in column ? column.minWidth : void 0));
8268
+ if (Number.isFinite(width) && width > 0) {
8269
+ return Math.max(10, Math.ceil(width / 7.2));
8270
+ }
8271
+ return 18;
8272
+ }
8273
+ function normalizeExportXlsxColumns(columns = []) {
8274
+ return columns.filter((column) => column.field && ("visible" in column ? column.visible !== false : true)).map((column) => ({
8275
+ field: String(column.field),
8276
+ title: String(column.title || column.field),
8277
+ width: getColumnWidth(column)
8278
+ }));
8279
+ }
8280
+ function normalizeExcelCellValue(value) {
8281
+ if (value === null || value === void 0) return "";
8282
+ if (Array.isArray(value) || typeof value === "object") return JSON.stringify(value);
8283
+ return value;
8284
+ }
8285
+ function getDefaultBorderStyle() {
8286
+ return {
8287
+ top: { style: defaultCellBorderStyle, color: { argb: defaultCellBorderColor } },
8288
+ left: { style: defaultCellBorderStyle, color: { argb: defaultCellBorderColor } },
8289
+ bottom: { style: defaultCellBorderStyle, color: { argb: defaultCellBorderColor } },
8290
+ right: { style: defaultCellBorderStyle, color: { argb: defaultCellBorderColor } }
8291
+ };
8292
+ }
8293
+ function setExcelCellStyle(excelCell, align = "left") {
8294
+ excelCell.protection = {
8295
+ locked: false
8296
+ };
8297
+ excelCell.alignment = {
8298
+ vertical: "middle",
8299
+ horizontal: align
8300
+ };
8301
+ }
8302
+ function downloadXlsxBlob(blob, filename) {
8303
+ const linkElem = document.createElement("a");
8304
+ linkElem.target = "_blank";
8305
+ linkElem.download = `${filename}.xlsx`;
8306
+ linkElem.href = URL.createObjectURL(blob);
8307
+ document.body.appendChild(linkElem);
8308
+ linkElem.click();
8309
+ document.body.removeChild(linkElem);
8310
+ URL.revokeObjectURL(linkElem.href);
8311
+ }
8312
+ async function exportRowsToXlsx(options) {
8313
+ const ExcelObj = await getExcelJS();
8314
+ if (!ExcelObj) return false;
8315
+ const columns = normalizeExportXlsxColumns(options.columns);
8316
+ const workbook = new ExcelObj.Workbook();
8317
+ const worksheet = workbook.addWorksheet(options.sheetName || "Sheet1");
8318
+ workbook.creator = "maxax-ui";
8319
+ worksheet.columns = columns.map((column) => ({
8320
+ header: column.title,
8321
+ key: column.field,
8322
+ width: column.width || 18
8323
+ }));
8324
+ worksheet.addRows(
8325
+ options.data.map((row) => {
8326
+ return columns.reduce((record, column) => {
8327
+ record[column.field] = normalizeExcelCellValue(row[column.field]);
8328
+ return record;
8329
+ }, {});
8330
+ })
8331
+ );
8332
+ const headerRow = worksheet.getRow(1);
8333
+ headerRow.height = 22;
8334
+ headerRow.eachCell((excelCell) => {
8335
+ setExcelCellStyle(excelCell);
8336
+ Object.assign(excelCell, {
8337
+ font: {
8338
+ bold: true,
8339
+ size: 14,
8340
+ color: { argb: defaultCellFontColor }
8341
+ },
8342
+ fill: {
8343
+ type: "pattern",
8344
+ pattern: "solid",
8345
+ fgColor: { argb: defaultHeaderBackgroundColor }
8346
+ },
8347
+ border: getDefaultBorderStyle()
8348
+ });
8349
+ });
8350
+ worksheet.eachRow((excelRow, rowNumber) => {
8351
+ if (rowNumber > 1) {
8352
+ excelRow.height = 22;
8353
+ excelRow.eachCell((excelCell) => {
8354
+ setExcelCellStyle(excelCell);
8355
+ Object.assign(excelCell, {
8356
+ font: {
8357
+ size: 14,
8358
+ color: { argb: defaultCellFontColor }
8359
+ },
8360
+ border: getDefaultBorderStyle()
8361
+ });
8362
+ });
8363
+ }
8364
+ });
8365
+ const buffer = await workbook.xlsx.writeBuffer();
8366
+ const blob = new Blob([buffer], { type: "application/octet-stream" });
8367
+ if (options.download === false) {
8368
+ return { type: "application/octet-stream", content: "", blob };
8369
+ }
8370
+ downloadXlsxBlob(blob, options.filename || "export");
8371
+ return true;
8372
+ }
8201
8373
  function handleFieldColumn(columns) {
8202
8374
  columns.forEach((column) => {
8203
8375
  column.field || (column.field = column.type || "");
@@ -9346,6 +9518,15 @@ const _sfc_main$F = /* @__PURE__ */ vue.defineComponent({
9346
9518
  function getInstance() {
9347
9519
  return tableElRef.value;
9348
9520
  }
9521
+ async function exportXlsx(options = {}) {
9522
+ return exportRowsToXlsx({
9523
+ filename: "export",
9524
+ sheetName: "Sheet1",
9525
+ columns: getColumns(),
9526
+ data: getDataSource(),
9527
+ ...options
9528
+ });
9529
+ }
9349
9530
  const tableAction = {
9350
9531
  emit,
9351
9532
  reload,
@@ -9370,6 +9551,7 @@ const _sfc_main$F = /* @__PURE__ */ vue.defineComponent({
9370
9551
  getSearchInfo,
9371
9552
  setColumns,
9372
9553
  getColumns,
9554
+ exportXlsx,
9373
9555
  getCacheColumns,
9374
9556
  setCacheColumns,
9375
9557
  setCacheColumnsByField,
@@ -30720,6 +30902,32 @@ vxeTable.VxeUI.setConfig({
30720
30902
  zIndex: 2e3
30721
30903
  });
30722
30904
  const XBasicTable = utils.withInstall(_sfc_main$F);
30905
+ const IMPORT_PREVIEW_ROW_NO_FIELD = "rowNo";
30906
+ const IMPORT_PREVIEW_ERROR_FIELD = "errorMsg";
30907
+ function isErrorRow(row) {
30908
+ return Boolean(row == null ? void 0 : row[IMPORT_PREVIEW_ERROR_FIELD]);
30909
+ }
30910
+ function getPreviewColumns(columns = [], options) {
30911
+ const { errorTitle, rowNoTitle } = options;
30912
+ const visibleColumns = columns.filter((column) => column.visible !== false);
30913
+ const hasRowNoColumn = visibleColumns.some((column) => column.field === IMPORT_PREVIEW_ROW_NO_FIELD);
30914
+ const hasErrorColumn = visibleColumns.some((column) => column.field === IMPORT_PREVIEW_ERROR_FIELD);
30915
+ return [...hasRowNoColumn ? [] : [{ field: IMPORT_PREVIEW_ROW_NO_FIELD, title: rowNoTitle, width: 90, fixed: "left" }], ...hasErrorColumn ? [] : [{ field: IMPORT_PREVIEW_ERROR_FIELD, title: errorTitle, minWidth: 180, fixed: "left" }], ...columns];
30916
+ }
30917
+ function getExcelColumns(columns = [], options) {
30918
+ return getPreviewColumns(columns, options).filter((column) => column.field && column.visible !== false).map((column) => ({
30919
+ field: String(column.field),
30920
+ title: String(column.title || column.field),
30921
+ width: getExcelColumnWidth(column)
30922
+ }));
30923
+ }
30924
+ function getExcelColumnWidth(column) {
30925
+ const width = Number(column.width || column.minWidth);
30926
+ if (Number.isFinite(width) && width > 0) {
30927
+ return Math.max(10, Math.ceil(width / 7.2));
30928
+ }
30929
+ return 18;
30930
+ }
30723
30931
  const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
30724
30932
  __name: "PreviewModal",
30725
30933
  props: {
@@ -30727,9 +30935,17 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
30727
30935
  previewColumns: {},
30728
30936
  previewTableProps: {},
30729
30937
  previewTitle: {},
30730
- showPreviewCount: { type: Boolean, default: true }
30731
- },
30732
- emits: ["confirm", "cancel"],
30938
+ showPreviewCount: { type: Boolean, default: true },
30939
+ showPreviewToolbar: { type: Boolean, default: true },
30940
+ showPreviewFilter: { type: Boolean, default: true },
30941
+ showExportErrorButton: { type: Boolean, default: true },
30942
+ showDeleteErrorButton: { type: Boolean, default: true },
30943
+ rowNoColumnTitle: {},
30944
+ errorColumnTitle: {},
30945
+ exportErrorFileName: { default: "import-error-data" },
30946
+ exportErrorHandler: {}
30947
+ },
30948
+ emits: ["confirm", "cancel", "deleteError"],
30733
30949
  setup(__props, { expose: __expose, emit: __emit }) {
30734
30950
  const props = __props;
30735
30951
  const emit = __emit;
@@ -30738,12 +30954,14 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
30738
30954
  const { t: t2 } = useLocale();
30739
30955
  const tableData = vue.ref([]);
30740
30956
  const errorData = vue.ref([]);
30957
+ const previewFilter = vue.ref("all");
30741
30958
  const { visible, show, hide } = useBasicDrawerModal({
30742
30959
  async onShow(context) {
30743
30960
  var _a, _b;
30744
30961
  await vue.nextTick();
30745
30962
  const list = ((_a = context.data) == null ? void 0 : _a.list) || [];
30746
- const errorList = list.filter((item) => item.errorMsg);
30963
+ const errorList = list.filter((item) => isErrorRow(item));
30964
+ previewFilter.value = "all";
30747
30965
  tableData.value = list;
30748
30966
  errorData.value = errorList;
30749
30967
  (_b = basicTableRef.value) == null ? void 0 : _b.setTableData(list);
@@ -30752,6 +30970,25 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
30752
30970
  const previewModalStyle = vue.computed(() => {
30753
30971
  return { width: props.previewWidth || "900px" };
30754
30972
  });
30973
+ const rowNoColumnTitle = vue.computed(() => props.rowNoColumnTitle || t2("max.import.rowNo"));
30974
+ const errorColumnTitle = vue.computed(() => props.errorColumnTitle || t2("max.import.errorMessage"));
30975
+ const normalDataCount = vue.computed(() => Math.max(tableData.value.length - errorData.value.length, 0));
30976
+ const previewFilterOptions = vue.computed(() => [
30977
+ { label: t2("max.import.showAllData"), value: "all" },
30978
+ { label: t2("max.import.showErrorRows"), value: "error" },
30979
+ { label: t2("max.import.showNormalRows"), value: "normal" }
30980
+ ]);
30981
+ const filteredTableData = vue.computed(() => {
30982
+ if (previewFilter.value === "error") return errorData.value;
30983
+ if (previewFilter.value === "normal") return tableData.value.filter((item) => !isErrorRow(item));
30984
+ return tableData.value;
30985
+ });
30986
+ const tableColumns = vue.computed(
30987
+ () => getPreviewColumns(props.previewColumns, {
30988
+ errorTitle: errorColumnTitle.value,
30989
+ rowNoTitle: rowNoColumnTitle.value
30990
+ })
30991
+ );
30755
30992
  const previewTableBindValues = vue.computed(() => {
30756
30993
  return {
30757
30994
  border: "inner",
@@ -30761,11 +30998,62 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
30761
30998
  toolbarConfig: {
30762
30999
  enabled: false
30763
31000
  },
31001
+ virtualYConfig: {
31002
+ enabled: true,
31003
+ gt: 0
31004
+ },
31005
+ showIndexColumn: false,
30764
31006
  showCheckboxColumn: false,
30765
31007
  ...props.previewTableProps,
30766
- columns: props.previewColumns || []
31008
+ columns: tableColumns.value
30767
31009
  };
30768
31010
  });
31011
+ function syncPreviewTableData() {
31012
+ var _a;
31013
+ (_a = basicTableRef.value) == null ? void 0 : _a.setTableData(filteredTableData.value);
31014
+ }
31015
+ function onPreviewFilterChange() {
31016
+ syncPreviewTableData();
31017
+ }
31018
+ async function onExportErrorData() {
31019
+ var _a;
31020
+ if (errorData.value.length === 0) return;
31021
+ if (props.exportErrorHandler) {
31022
+ await props.exportErrorHandler({
31023
+ columns: tableColumns.value,
31024
+ rows: errorData.value
31025
+ });
31026
+ return;
31027
+ }
31028
+ const columns = getExcelColumns(props.previewColumns, {
31029
+ errorTitle: errorColumnTitle.value,
31030
+ rowNoTitle: rowNoColumnTitle.value
31031
+ });
31032
+ await ((_a = basicTableRef.value) == null ? void 0 : _a.exportXlsx({
31033
+ columns,
31034
+ filename: props.exportErrorFileName,
31035
+ data: errorData.value,
31036
+ sheetName: t2("max.import.errorDataSheetName")
31037
+ }));
31038
+ }
31039
+ function deleteErrorData() {
31040
+ const deletedErrors = [...errorData.value];
31041
+ tableData.value = tableData.value.filter((item) => !isErrorRow(item));
31042
+ errorData.value = [];
31043
+ previewFilter.value = "all";
31044
+ syncPreviewTableData();
31045
+ emit("deleteError", { data: tableData.value, errors: deletedErrors });
31046
+ }
31047
+ function onDeleteErrorData() {
31048
+ if (errorData.value.length === 0) return;
31049
+ XBasicMessageBox.confirm(t2("max.import.confirmDeleteErrorData"), t2("max.basic.warning"), {
31050
+ confirmButtonText: t2("max.import.confirm"),
31051
+ cancelButtonText: t2("max.import.cancel")
31052
+ }).then(() => {
31053
+ deleteErrorData();
31054
+ }).catch(() => {
31055
+ });
31056
+ }
30769
31057
  function onConfirm() {
30770
31058
  var _a;
30771
31059
  const records = ((_a = basicTableRef.value) == null ? void 0 : _a.getSelectRows()) || [];
@@ -30778,7 +31066,7 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
30778
31066
  return (_ctx, _cache) => {
30779
31067
  return vue.openBlock(), vue.createBlock(vue.unref(naiveUi.NModal), {
30780
31068
  show: vue.unref(visible),
30781
- "onUpdate:show": _cache[0] || (_cache[0] = ($event) => vue.isRef(visible) ? visible.value = $event : null),
31069
+ "onUpdate:show": _cache[1] || (_cache[1] = ($event) => vue.isRef(visible) ? visible.value = $event : null),
30782
31070
  segmented: { footer: "soft" },
30783
31071
  closable: false,
30784
31072
  preset: "card",
@@ -30820,10 +31108,10 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
30820
31108
  ], 2)
30821
31109
  ]),
30822
31110
  default: vue.withCtx(() => [
30823
- vue.renderSlot(_ctx.$slots, "preview-table-before", {
30824
- tableData: tableData.value,
30825
- errorData: errorData.value
30826
- }, () => [
31111
+ props.showPreviewToolbar ? (vue.openBlock(), vue.createElementBlock("div", {
31112
+ key: 0,
31113
+ class: vue.normalizeClass(vue.unref(em)("preview-toolbar"))
31114
+ }, [
30827
31115
  props.showPreviewCount ? (vue.openBlock(), vue.createElementBlock("span", {
30828
31116
  key: 0,
30829
31117
  class: vue.normalizeClass(vue.unref(em)("preview-count"))
@@ -30833,9 +31121,64 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
30833
31121
  }, vue.toDisplayString(vue.unref(t2)("max.import.totalCount")) + ": " + vue.toDisplayString(tableData.value.length), 3),
30834
31122
  vue.createElementVNode("span", {
30835
31123
  class: vue.normalizeClass(vue.unref(em)("error-count"))
30836
- }, vue.toDisplayString(vue.unref(t2)("max.import.errorCount")) + ": " + vue.toDisplayString(errorData.value.length), 3)
30837
- ], 2)) : vue.createCommentVNode("", true)
30838
- ]),
31124
+ }, vue.toDisplayString(vue.unref(t2)("max.import.errorCount")) + ": " + vue.toDisplayString(errorData.value.length), 3),
31125
+ vue.createElementVNode("span", {
31126
+ class: vue.normalizeClass(vue.unref(em)("normal-count"))
31127
+ }, vue.toDisplayString(vue.unref(t2)("max.import.normalCount")) + ": " + vue.toDisplayString(normalDataCount.value), 3)
31128
+ ], 2)) : vue.createCommentVNode("", true),
31129
+ vue.createElementVNode("span", {
31130
+ class: vue.normalizeClass(vue.unref(em)("preview-actions"))
31131
+ }, [
31132
+ props.showPreviewFilter ? (vue.openBlock(), vue.createBlock(vue.unref(naiveUi.NSelect), {
31133
+ key: 0,
31134
+ value: previewFilter.value,
31135
+ "onUpdate:value": [
31136
+ _cache[0] || (_cache[0] = ($event) => previewFilter.value = $event),
31137
+ onPreviewFilterChange
31138
+ ],
31139
+ class: vue.normalizeClass(vue.unref(em)("filter-select")),
31140
+ options: previewFilterOptions.value
31141
+ }, null, 8, ["value", "class", "options"])) : vue.createCommentVNode("", true),
31142
+ props.showExportErrorButton ? (vue.openBlock(), vue.createBlock(vue.unref(XBasicButton), {
31143
+ key: 1,
31144
+ type: "error",
31145
+ secondary: "",
31146
+ icon: "ri:download-2-line",
31147
+ disabled: errorData.value.length === 0,
31148
+ onClick: onExportErrorData
31149
+ }, {
31150
+ default: vue.withCtx(() => [
31151
+ vue.createTextVNode(vue.toDisplayString(vue.unref(t2)("max.import.exportErrorData")), 1)
31152
+ ]),
31153
+ _: 1
31154
+ }, 8, ["disabled"])) : vue.createCommentVNode("", true),
31155
+ props.showDeleteErrorButton ? (vue.openBlock(), vue.createBlock(vue.unref(XBasicButton), {
31156
+ key: 2,
31157
+ secondary: "",
31158
+ icon: "ri:delete-bin-line",
31159
+ disabled: errorData.value.length === 0,
31160
+ onClick: onDeleteErrorData
31161
+ }, {
31162
+ default: vue.withCtx(() => [
31163
+ vue.createTextVNode(vue.toDisplayString(vue.unref(t2)("max.import.deleteErrorData")), 1)
31164
+ ]),
31165
+ _: 1
31166
+ }, 8, ["disabled"])) : vue.createCommentVNode("", true)
31167
+ ], 2)
31168
+ ], 2)) : props.showPreviewCount ? (vue.openBlock(), vue.createElementBlock("span", {
31169
+ key: 1,
31170
+ class: vue.normalizeClass(vue.unref(em)("preview-count"))
31171
+ }, [
31172
+ vue.createElementVNode("span", {
31173
+ class: vue.normalizeClass(vue.unref(em)("total-count"))
31174
+ }, vue.toDisplayString(vue.unref(t2)("max.import.totalCount")) + ": " + vue.toDisplayString(tableData.value.length), 3),
31175
+ vue.createElementVNode("span", {
31176
+ class: vue.normalizeClass(vue.unref(em)("error-count"))
31177
+ }, vue.toDisplayString(vue.unref(t2)("max.import.errorCount")) + ": " + vue.toDisplayString(errorData.value.length), 3),
31178
+ vue.createElementVNode("span", {
31179
+ class: vue.normalizeClass(vue.unref(em)("normal-count"))
31180
+ }, vue.toDisplayString(vue.unref(t2)("max.import.normalCount")) + ": " + vue.toDisplayString(normalDataCount.value), 3)
31181
+ ], 2)) : vue.createCommentVNode("", true),
30839
31182
  vue.createElementVNode("div", {
30840
31183
  class: vue.normalizeClass(vue.unref(em)("preview-table"))
30841
31184
  }, [
@@ -30843,13 +31186,9 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
30843
31186
  ref_key: "basicTableRef",
30844
31187
  ref: basicTableRef
30845
31188
  }), null, 16)
30846
- ], 2),
30847
- vue.renderSlot(_ctx.$slots, "preview-table-after", {
30848
- tableData: tableData.value,
30849
- errorData: errorData.value
30850
- })
31189
+ ], 2)
30851
31190
  ]),
30852
- _: 3
31191
+ _: 1
30853
31192
  }, 8, ["show", "class", "style"]);
30854
31193
  };
30855
31194
  }
@@ -30860,7 +31199,9 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
30860
31199
  props: {
30861
31200
  width: {},
30862
31201
  showTplButton: { type: Boolean },
30863
- showCoverSwitch: { type: Boolean }
31202
+ showCoverSwitch: { type: Boolean },
31203
+ maxSize: { default: 50 },
31204
+ accept: { default: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" }
30864
31205
  },
30865
31206
  emits: ["confirm", "downloadTemplate"],
30866
31207
  setup(__props, { expose: __expose, emit: __emit }) {
@@ -30879,9 +31220,9 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
30879
31220
  return { width: props.width || "630px" };
30880
31221
  });
30881
31222
  const beforeUpload = (file) => {
30882
- const isLt2M = (file.size || 0) / 1024 / 1024 < 50;
30883
- if (!isLt2M) {
30884
- XBasicNotification.error(t2("max.import.fileSizeLimit"));
31223
+ const isInSize = (file.size || 0) / 1024 / 1024 < props.maxSize;
31224
+ if (!isInSize) {
31225
+ XBasicNotification.error(t2("max.import.fileSizeLimit").replace("{max}", String(props.maxSize)));
30885
31226
  return false;
30886
31227
  }
30887
31228
  return false;
@@ -30966,7 +31307,7 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
30966
31307
  "show-upload-list": "",
30967
31308
  type: "drag",
30968
31309
  "max-count": 1,
30969
- accept: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
31310
+ accept: props.accept
30970
31311
  }, {
30971
31312
  default: vue.withCtx(() => [
30972
31313
  vue.createElementVNode("p", {
@@ -30982,7 +31323,7 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
30982
31323
  }, vue.toDisplayString(vue.unref(t2)("max.import.uploadTip")), 3)
30983
31324
  ]),
30984
31325
  _: 1
30985
- }, 8, ["file-list"]),
31326
+ }, 8, ["file-list", "accept"]),
30986
31327
  props.showTplButton ? (vue.openBlock(), vue.createElementBlock("div", {
30987
31328
  key: 0,
30988
31329
  class: vue.normalizeClass(vue.unref(em)("tips"))
@@ -31013,6 +31354,8 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
31013
31354
  props: {
31014
31355
  showTplButton: { type: Boolean, default: true },
31015
31356
  showCoverSwitch: { type: Boolean },
31357
+ maxSize: {},
31358
+ accept: {},
31016
31359
  width: {},
31017
31360
  previewWidth: {},
31018
31361
  href: {},
@@ -31021,16 +31364,27 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
31021
31364
  beforeFetchImport: {},
31022
31365
  afterFetchImport: {},
31023
31366
  listField: { default: "resultList" },
31367
+ rowNoField: { default: IMPORT_PREVIEW_ROW_NO_FIELD },
31368
+ errorField: { default: IMPORT_PREVIEW_ERROR_FIELD },
31369
+ rowNoColumnTitle: {},
31370
+ errorColumnTitle: {},
31024
31371
  previewColumns: {},
31025
31372
  previewTableProps: {},
31026
31373
  previewTitle: {},
31027
31374
  showPreviewCount: { type: Boolean, default: true },
31375
+ showPreviewToolbar: { type: Boolean, default: true },
31376
+ showPreviewFilter: { type: Boolean, default: true },
31377
+ showExportErrorButton: { type: Boolean, default: true },
31378
+ showDeleteErrorButton: { type: Boolean, default: true },
31379
+ exportErrorFileName: {},
31380
+ exportErrorHandler: {},
31381
+ blockSaveWhenError: { type: Boolean, default: true },
31028
31382
  saveApi: {},
31029
31383
  beforeSaveInterceptor: {},
31030
31384
  beforeFetchSave: {},
31031
31385
  afterFetchSave: {}
31032
31386
  },
31033
- emits: ["import", "preview", "save"],
31387
+ emits: ["import", "preview", "save", "deleteError"],
31034
31388
  setup(__props, { emit: __emit }) {
31035
31389
  const props = __props;
31036
31390
  const emit = __emit;
@@ -31042,8 +31396,8 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
31042
31396
  const currentFile = vue.ref(null);
31043
31397
  const currentChecked = vue.ref(false);
31044
31398
  async function runBeforeSaveGuard(payload) {
31045
- if (payload.errors.length > 0) {
31046
- XBasicNotification.error("存在校验失败的数据,请检查");
31399
+ if (props.blockSaveWhenError && payload.errors.length > 0) {
31400
+ XBasicNotification.error(t2("max.import.validationFailed"));
31047
31401
  return false;
31048
31402
  }
31049
31403
  if (!props.beforeSaveInterceptor || !lodashEs.isFunction(props.beforeSaveInterceptor)) return true;
@@ -31060,6 +31414,20 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
31060
31414
  return false;
31061
31415
  }
31062
31416
  }
31417
+ function normalizePreviewRows(rows = []) {
31418
+ return rows.map((item) => {
31419
+ const row = { ...item };
31420
+ const rowNo = props.rowNoField ? lodashEs.get(item, props.rowNoField) : void 0;
31421
+ const errorMsg = props.errorField ? lodashEs.get(item, props.errorField) : void 0;
31422
+ if (row[IMPORT_PREVIEW_ROW_NO_FIELD] === void 0 && rowNo !== void 0) {
31423
+ row[IMPORT_PREVIEW_ROW_NO_FIELD] = rowNo;
31424
+ }
31425
+ if (row[IMPORT_PREVIEW_ERROR_FIELD] === void 0 && errorMsg !== void 0) {
31426
+ row[IMPORT_PREVIEW_ERROR_FIELD] = errorMsg;
31427
+ }
31428
+ return row;
31429
+ });
31430
+ }
31063
31431
  async function onImport(file, checked, showPreview = false) {
31064
31432
  var _a, _b, _c, _d;
31065
31433
  const { importApi, beforeFetchImport, afterFetchImport } = props;
@@ -31076,6 +31444,7 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
31076
31444
  if (afterFetchImport && lodashEs.isFunction(afterFetchImport)) {
31077
31445
  resultItems = await afterFetchImport(resultItems) || resultItems;
31078
31446
  }
31447
+ resultItems = normalizePreviewRows(resultItems);
31079
31448
  currentFile.value = file;
31080
31449
  currentChecked.value = checked;
31081
31450
  (_b = previewModalRef.value) == null ? void 0 : _b.show({ type: "other", data: { list: resultItems } });
@@ -31135,7 +31504,10 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
31135
31504
  }
31136
31505
  try {
31137
31506
  const params = props.beforeFetchSave ? props.beforeFetchSave({ data, records }) : { dtoList: data };
31138
- const res = await props.saveApi(params);
31507
+ let res = await props.saveApi(params);
31508
+ if (props.afterFetchSave && lodashEs.isFunction(props.afterFetchSave)) {
31509
+ res = await props.afterFetchSave(res) || res;
31510
+ }
31139
31511
  emit("save", { data: res, checked: currentChecked.value, file: currentFile.value, records });
31140
31512
  } catch (error) {
31141
31513
  console.error(error);
@@ -31148,6 +31520,9 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
31148
31520
  var _a;
31149
31521
  (_a = uploadModalRef.value) == null ? void 0 : _a.show({ type: "other" });
31150
31522
  }
31523
+ function onDeleteError(payload) {
31524
+ emit("deleteError", payload);
31525
+ }
31151
31526
  return (_ctx, _cache) => {
31152
31527
  return vue.openBlock(), vue.createElementBlock("span", null, [
31153
31528
  vue.createElementVNode("div", {
@@ -31171,9 +31546,11 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
31171
31546
  width: props.width,
31172
31547
  "show-tpl-button": props.showTplButton,
31173
31548
  "show-cover-switch": props.showCoverSwitch,
31549
+ "max-size": props.maxSize,
31550
+ accept: props.accept,
31174
31551
  onConfirm: onUploadConfirm,
31175
31552
  onDownloadTemplate: onExport
31176
- }, null, 8, ["width", "show-tpl-button", "show-cover-switch"]),
31553
+ }, null, 8, ["width", "show-tpl-button", "show-cover-switch", "max-size", "accept"]),
31177
31554
  vue.createVNode(_sfc_main$2, {
31178
31555
  ref_key: "previewModalRef",
31179
31556
  ref: previewModalRef,
@@ -31182,23 +31559,17 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
31182
31559
  "preview-table-props": props.previewTableProps,
31183
31560
  "preview-title": props.previewTitle,
31184
31561
  "show-preview-count": props.showPreviewCount,
31185
- onConfirm: onPreviewConfirm
31186
- }, vue.createSlots({ _: 2 }, [
31187
- _ctx.$slots["preview-table-before"] ? {
31188
- name: "preview-table-before",
31189
- fn: vue.withCtx((slotProps) => [
31190
- vue.renderSlot(_ctx.$slots, "preview-table-before", vue.normalizeProps(vue.guardReactiveProps(slotProps)))
31191
- ]),
31192
- key: "0"
31193
- } : void 0,
31194
- _ctx.$slots["preview-table-after"] ? {
31195
- name: "preview-table-after",
31196
- fn: vue.withCtx((slotProps) => [
31197
- vue.renderSlot(_ctx.$slots, "preview-table-after", vue.normalizeProps(vue.guardReactiveProps(slotProps)))
31198
- ]),
31199
- key: "1"
31200
- } : void 0
31201
- ]), 1032, ["preview-width", "preview-columns", "preview-table-props", "preview-title", "show-preview-count"])
31562
+ "show-preview-toolbar": props.showPreviewToolbar,
31563
+ "show-preview-filter": props.showPreviewFilter,
31564
+ "show-export-error-button": props.showExportErrorButton,
31565
+ "show-delete-error-button": props.showDeleteErrorButton,
31566
+ "row-no-column-title": props.rowNoColumnTitle,
31567
+ "error-column-title": props.errorColumnTitle,
31568
+ "export-error-file-name": props.exportErrorFileName,
31569
+ "export-error-handler": props.exportErrorHandler,
31570
+ onConfirm: onPreviewConfirm,
31571
+ onDeleteError
31572
+ }, null, 8, ["preview-width", "preview-columns", "preview-table-props", "preview-title", "show-preview-count", "show-preview-toolbar", "show-preview-filter", "show-export-error-button", "show-delete-error-button", "row-no-column-title", "error-column-title", "export-error-file-name", "export-error-handler"])
31202
31573
  ]);
31203
31574
  };
31204
31575
  }
@@ -31435,11 +31806,13 @@ exports.basicUploadProps = basicUploadProps;
31435
31806
  exports.configProviderProps = configProviderProps;
31436
31807
  exports.default = installer;
31437
31808
  exports.detectFlexGapSupported = detectFlexGapSupported;
31809
+ exports.exportRowsToXlsx = exportRowsToXlsx;
31438
31810
  exports.formatterFCN = formatterFCN;
31439
31811
  exports.formatterFCR = formatterFCR;
31440
31812
  exports.formatterFYN = formatterFYN;
31441
31813
  exports.install = install;
31442
31814
  exports.makeInstaller = makeInstaller;
31815
+ exports.normalizeExportXlsxColumns = normalizeExportXlsxColumns;
31443
31816
  exports.notificationTypes = notificationTypes;
31444
31817
  exports.provideGlobalConfig = provideGlobalConfig;
31445
31818
  exports.responsiveArray = responsiveArray;