@rebasepro/cms 0.19.2-canary.gef769df → 0.20.0

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.
@@ -8380,15 +8380,26 @@ function getRandomId$1() {
8380
8380
  //#endregion
8381
8381
  //#region src/data_import/utils/file_headers.ts
8382
8382
  /**
8383
- * Extract column headers from the first row of an ExcelJS worksheet.
8384
- * Returns an array of header strings in column order.
8385
- */
8386
- function getWorksheetHeaders(worksheet) {
8387
- const headers = [];
8388
- worksheet.getRow(1).eachCell({ includeEmpty: false }, (cell, colNumber) => {
8389
- headers[colNumber - 1] = cell.text ?? `Column${colNumber}`;
8383
+ * Read the header names out of the first row.
8384
+ *
8385
+ * A column whose header is blank is left out entirely, so it contributes
8386
+ * neither a field nor a value — the same intent as the old `filter(Boolean)`,
8387
+ * without the shift.
8388
+ */
8389
+ function getWorksheetHeaders(headerRow) {
8390
+ const byColumn = /* @__PURE__ */ new Map();
8391
+ const order = [];
8392
+ headerRow.forEach((cell, index) => {
8393
+ if (cell === null || cell === void 0) return;
8394
+ const name = (cell instanceof Date ? cell.toISOString() : String(cell)).trim();
8395
+ if (!name) return;
8396
+ byColumn.set(index, name);
8397
+ order.push(name);
8390
8398
  });
8391
- return headers.filter(Boolean);
8399
+ return {
8400
+ byColumn,
8401
+ order
8402
+ };
8392
8403
  }
8393
8404
  //#endregion
8394
8405
  //#region src/data_import/utils/transforms.ts
@@ -8579,10 +8590,15 @@ function parseCsvToObjects(text) {
8579
8590
  }
8580
8591
  //#endregion
8581
8592
  //#region src/data_import/utils/file_to_json.ts
8582
- var excelJsModule;
8583
- function loadExcelJs() {
8584
- excelJsModule ??= import("exceljs").then((mod) => mod.default ?? mod);
8585
- return excelJsModule;
8593
+ var xlsxReader;
8594
+ function loadXlsxReader() {
8595
+ xlsxReader ??= import("read-excel-file/browser").then((mod) => {
8596
+ const candidate = mod.default ?? mod;
8597
+ const fn = typeof candidate === "function" ? candidate : candidate?.default;
8598
+ if (typeof fn !== "function") throw new Error("read-excel-file did not resolve to a function");
8599
+ return fn;
8600
+ });
8601
+ return xlsxReader;
8586
8602
  }
8587
8603
  /**
8588
8604
  * Whether this file is delimited text rather than a workbook.
@@ -8646,27 +8662,49 @@ function convertFileToJson(file) {
8646
8662
  reader.onload = async function(e) {
8647
8663
  try {
8648
8664
  const buffer = e.target?.result;
8649
- const workbook = new (await (loadExcelJs())).Workbook();
8650
- await workbook.xlsx.load(buffer);
8651
- const worksheet = workbook.worksheets[0];
8652
- if (!worksheet) {
8665
+ const readXlsxFile = await loadXlsxReader();
8666
+ const magic = new Uint8Array(buffer, 0, Math.min(2, buffer.byteLength));
8667
+ if (magic[0] !== 80 || magic[1] !== 75) {
8668
+ reject(/* @__PURE__ */ new Error(`'${file.name}' is not a readable .xlsx workbook. Export it again as .xlsx, or save it as .csv.`));
8669
+ return;
8670
+ }
8671
+ let sheets;
8672
+ try {
8673
+ sheets = await readXlsxFile(buffer);
8674
+ } catch (readError) {
8675
+ console.debug("Spreadsheet reader failed", readError);
8676
+ reject(/* @__PURE__ */ new Error("No worksheets found in file — it has no sheets, or none this reader can open."));
8677
+ return;
8678
+ }
8679
+ const firstSheet = sheets[0];
8680
+ if (!firstSheet) {
8653
8681
  reject(/* @__PURE__ */ new Error("No worksheets found in file"));
8654
8682
  return;
8655
8683
  }
8656
- const headers = getWorksheetHeaders(worksheet);
8684
+ const [headerRow, ...dataRows] = firstSheet.data;
8685
+ if (!headerRow) {
8686
+ reject(/* @__PURE__ */ new Error("The spreadsheet is empty"));
8687
+ return;
8688
+ }
8689
+ const headers = getWorksheetHeaders(headerRow);
8690
+ if (headers.order.length === 0) {
8691
+ reject(/* @__PURE__ */ new Error("The spreadsheet has no column headers in its first row"));
8692
+ return;
8693
+ }
8657
8694
  const parsedData = [];
8658
- worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
8659
- if (rowNumber === 1) return;
8695
+ for (const row of dataRows) {
8696
+ if (row.every((cell) => cell === null || cell === void 0)) continue;
8660
8697
  const obj = {};
8661
- row.eachCell({ includeEmpty: false }, (cell, colNumber) => {
8662
- const header = headers[colNumber - 1];
8663
- if (header && !isPrototypePollutingKey(header)) obj[header] = cell.value;
8698
+ row.forEach((cell, index) => {
8699
+ if (cell === null || cell === void 0) return;
8700
+ const header = headers.byColumn.get(index);
8701
+ if (header && !isPrototypePollutingKey(header)) obj[header] = cell;
8664
8702
  });
8665
8703
  parsedData.push(obj);
8666
- });
8704
+ }
8667
8705
  resolve({
8668
8706
  data: toImportRows(parsedData),
8669
- propertiesOrder: headers
8707
+ propertiesOrder: headers.order
8670
8708
  });
8671
8709
  } catch (err) {
8672
8710
  console.error("Error parsing Excel file", err);
@@ -9556,8 +9594,8 @@ function EditorCollectionAction({ path, parentCollectionSlugs, parentEntityIds,
9556
9594
  }
9557
9595
  //#endregion
9558
9596
  //#region src/components/CollectionViewBinding/CollectionViewActions.tsx
9559
- var ImportCollectionAction = lazyChunk(() => import("./import-p3gl9dxg.js").then((n) => n.t).then((m) => ({ default: m.ImportCollectionAction })));
9560
- var ExportCollectionAction = lazyChunk(() => import("./export-BZZGtpg2.js").then((n) => n.t).then((m) => ({ default: m.ExportCollectionAction })));
9597
+ var ImportCollectionAction = lazyChunk(() => import("./import-C4VQ0rwO.js").then((n) => n.t).then((m) => ({ default: m.ImportCollectionAction })));
9598
+ var ExportCollectionAction = lazyChunk(() => import("./export-DJoGYb89.js").then((n) => n.t).then((m) => ({ default: m.ExportCollectionAction })));
9561
9599
  function CollectionViewActions({ collection, relativePath, parentCollectionSlugs, parentEntityIds, onNewClick, onAddExistingClick, onMultipleDeleteClick, selectionEnabled, path, selectionController, tableController, collectionEntitiesCount, compact, children, openNewDocument }) {
9562
9600
  const context = useAdminContext();
9563
9601
  const { canCreate, canDelete } = usePermissions();
@@ -10530,9 +10568,22 @@ function CollectionListViewBinding({ collection, tableController, onEntityClick,
10530
10568
  * silently drop.
10531
10569
  */
10532
10570
  const sortableKeys = useMemo(() => new Set(getSortablePropertyOptions(resolvedCollection.properties).map((option) => option.key)), [resolvedCollection.properties]);
10533
- /** The row's identity cell: the leading column, or the title slot. */
10571
+ /**
10572
+ * The row's identity cell — the thumbnail, the title and the subtitle.
10573
+ *
10574
+ * Labelled by the title slot, because that is what the cell renders. In
10575
+ * column mode it used to be labelled by `listProperties[0]` instead, which
10576
+ * was right only when the two happened to be the same property and a lie
10577
+ * whenever they were not: `listProperties: ["roles", "createdAt"]` on the
10578
+ * users collection put a "Roles" header over the name-and-email cell, and
10579
+ * the roles themselves appeared in no column at all — the header was the
10580
+ * only trace of the property the developer had asked for.
10581
+ *
10582
+ * The first list property is therefore only consumed here when it *is* the
10583
+ * title; otherwise it stays in {@link declaredColumns} and gets a cell.
10584
+ */
10534
10585
  const titleColumn = useMemo(() => {
10535
- const key = columnMode ? resolvedCollection.listProperties?.[0] : titlePropertyKey;
10586
+ const key = titlePropertyKey ?? (columnMode ? resolvedCollection.listProperties?.[0] : void 0);
10536
10587
  if (!key) return void 0;
10537
10588
  const property = resolvedCollection.properties[key];
10538
10589
  return {
@@ -10558,7 +10609,7 @@ function CollectionListViewBinding({ collection, tableController, onEntityClick,
10558
10609
  */
10559
10610
  const declaredColumns = useMemo(() => {
10560
10611
  if (columnMode) {
10561
- const keys = resolvedCollection.listProperties.slice(1);
10612
+ const keys = resolvedCollection.listProperties.filter((key) => key !== titleColumn?.key);
10562
10613
  return keys.flatMap((key, index) => {
10563
10614
  const property = resolvedCollection.properties[key];
10564
10615
  if (!property) return [];
@@ -10610,6 +10661,7 @@ function CollectionListViewBinding({ collection, tableController, onEntityClick,
10610
10661
  }, [
10611
10662
  columnMode,
10612
10663
  resolvedCollection,
10664
+ titleColumn?.key,
10613
10665
  slotKeys.tagsKey,
10614
10666
  statusPropertyKey,
10615
10667
  datePropertyKey,
@@ -11903,7 +11955,7 @@ function JsonPreviewBinding({ values }) {
11903
11955
  }
11904
11956
  //#endregion
11905
11957
  //#region src/components/EntityInspector.tsx
11906
- var EntityHistoryView = lazyChunk(() => import("./history-jlpXPTks.js").then((m) => ({ default: m.EntityHistoryView })));
11958
+ var EntityHistoryView = lazyChunk(() => import("./history-BBpsdTrJ.js").then((m) => ({ default: m.EntityHistoryView })));
11907
11959
  /**
11908
11960
  * Raw values and revision history, as an inspector rather than as tabs.
11909
11961
  *
@@ -25040,4 +25092,4 @@ function getFullIdPath(propertyKey, propertyNamespace) {
25040
25092
  //#endregion
25041
25093
  export { NAVIGATION_DEFAULT_GROUP_NAME as $, getEntityTitlePropertyKeyForEntity as $n, getCollectionBySlugWithin as $t, getFieldId as A, NumberPropertyPreview as An, convertDataToEntity as At, MapFieldBinding as B, RelationPreview as Bn, detectCsvDelimiter as Bt, EntityFormBinding as C, ReadOnlyFieldBinding as Cn, getIconForProperty as Cr, EntityCardBinding as Ct, getDefaultFieldConfig as D, ArrayOfMapsPreview as Dn, getResolvedPropertyInPath as Dr, useCollectionEditorDialogsState as Dt, DEFAULT_FIELD_CONFIGS as E, FieldHelperText as En, getPropertyInPath$1 as Er, ConfigControllerProvider as Et, SelectFieldBinding as F, ArrayOneOfPreview as Fn, ImportSaveInProgress as Ft, useSelectionDialog as G, SidePanelControllerContext as Gn, SearchIconsView as Gt, DateTimeFieldBinding as H, InlineEntityListPreview as Hn, parseCsvToObjects as Ht, RepeatFieldBinding as I, ArrayOfStringsPreview as In, IMPORT_BATCH_SIZE as It, useBuildUrlController as J, useCollectionRegistryController as Jn, BreadcrumbsProvider as Jt, SelectionTableBinding as K, useSidePanel as Kn, FieldCaption as Kt, ReferenceFieldBinding as L, ArrayPropertyEnumPreview as Ln, saveImportedEntities as Lt, TextFieldBinding as M, DatePreview as Mn, processValueMapping as Mt, SwitchFieldBinding as N, KeyValuePreview as Nn, getInferenceType as Nt, getDefaultFieldId as O, PropertyPreview as On, isReferenceProperty as Or, ImportNewPropertyFieldPreview as Ot, StorageUploadFieldBinding as P, MapPropertyPreview as Pn, useImportConfig as Pt, useResolvedCollections as Q, getEntityTitlePropertyKey as Qn, addInitialSlash as Qt, MultiSelectFieldBinding as R, ArrayEnumPreview as Rn, ImportFileUpload as Rt, isSchemaChangeCancelled as S, useClearRestoreValue as Sn, getDefaultPropertiesOrder as Sr, CollectionCardViewBinding as St, PropertyFieldBinding as T, LabelWithIcon as Tn, getPropertiesWithPropertiesOrder as Tr, useCollectionEditorController as Tt, BlockFieldBinding as U, ReferencePreview as Un, ArrayContainer as Ut, KeyValueFieldBinding as V, ArrayOfReferencesPreview as Vn, parseCsvRows as Vt, ArrayOfReferencesFieldBinding as W, EntityPreviewBinding as Wn, PropertyConfigBadge as Wt, useTopLevelNavigation as X, useResolvedUser as Xn, resolveEntityView as Xt, useBuildNavigationStateController as Y, getUserLabel as Yn, resolveEntityAction as Yt, useResolvedViews as Z, getEntityPreviewKeys as Zn, mergeEntityActions as Zt, useCollectionsConfigController as _, useNavigationStateController as _n, LABEL_ICON_SIZE as _r, editEntityAction as _t, namespaceToPropertiesPath as a, resolveCollectionPathIds$1 as an, SkeletonPropertyComponent as ar, getEntityViewWidth as at, asUnavailable as b, SelectableTableContext as bn, PropertyIdCopyTooltip as br, DetailViewBinding as bt, buildCollectionGenerationCallback as c, useSelectionController as cn, renderSkeletonImageThumbnail as cr, useSafeSnackbarController as ct, fromSerializableCollectionConfigs as d, SelectableTable as dn, ImagePreview as dr, getInitialEntityValues as dt, getCollectionPathsCombinations as en, ArrayPropertyPreview as er, useBuildCollectionRegistryController as et, fromSerializableProperties as f, CollectionRowActions as fn, EmptyValue as fr, removeEmptyContainers as ft, toSerializableProperty as g, NavigationStateContext as gn, FieldBlock as gr, deleteEntityAction as gt, toSerializableProperties as h, useUrlController as hn, RecordMeta as hr, copyEntityAction as ht, namespaceToPropertiesOrderPath as i, removeTrailingSlash$1 as in, StorageThumbnailInternal as ir, buildSidePanelsFromUrl as it, VectorFieldBinding as j, BooleanPreview as jn, flattenEntry as jt, getFieldConfig as k, UserPreview as kn, isRelationProperty as kr, DataNewPropertiesMapping as kt, validateCollectionJson as l, VirtualTableInput$1 as ln, renderSkeletonText as lr, extractTouchedValues as lt, toSerializableCollectionConfig as m, UrlContext as mn, FormRail as mr, CollectionViewBinding as mt, getFullIdPath as n, removeInitialAndTrailingSlashes$1 as nn, EnumValuesChip as nr, resolveNavigationFrom as nt, CollectionGenerationApiError as o, resolveOpenEntityMode as on, renderSkeletonCaptionText as or, useBuildSidePanel as ot, fromSerializableProperty as p, useAdminContext as pn, FormSections as pr, zodToFormErrors as pt, SideDialogs as q, CollectionRegistryContext as qn, useBreadcrumbsController as qt, idToPropertiesPath as r, removeInitialSlash as rn, StorageThumbnail as rr, useResolvedNavigationFrom as rt, DEFAULT_COLLECTION_GENERATION_ENDPOINT as s, resolveViewMode as sn, renderSkeletonIcon as sr, EditViewBinding as st, getFullId as t, getLastSegment$1 as tn, StringPropertyPreview as tr, useHistory as tt, fromSerializableCollectionConfig as u, CollectionTableBinding as un, UrlComponentPreview as ur, getChanges as ut, LiveSchemaError as v, useSideDialogsController as vn, isSelfLabellingProperty as vr, resetPasswordAction as vt, EntityForm as w, LabelWithIconAndTooltip as wn, getIconForWidget as wr, CollectionViewActions as wt, createLiveSchemaClient as x, ArrayCustomShapedFieldBinding as xn, getBracketNotation as xr, EntityViewBinding as xt, SchemaChangeCancelled as y, SideDialogsControllerContext as yn, spanClass as yr, CreationResultDialog as yt, MarkdownEditorFieldBinding as z, ArrayOfStorageComponentsPreview as zn, convertFileToJson as zt };
25042
25094
 
25043
- //# sourceMappingURL=util-BNe7DTtO.js.map
25095
+ //# sourceMappingURL=util-4oPxPkbp.js.map