@rebasepro/cms 0.23.0 → 0.24.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.
Files changed (62) hide show
  1. package/dist/{CollectionEditorDialog-DLHCka00.js → CollectionEditorDialog-p5-I-Apu.js} +81 -42
  2. package/dist/CollectionEditorDialog-p5-I-Apu.js.map +1 -0
  3. package/dist/{PropertyEditView-_pu5hzZn.js → PropertyEditView-DDB_X-00.js} +4 -4
  4. package/dist/PropertyEditView-DDB_X-00.js.map +1 -0
  5. package/dist/{RouterCollectionsStudioView-ChPNl_uU.js → RouterCollectionsStudioView-SGBV4CMg.js} +4 -4
  6. package/dist/{RouterCollectionsStudioView-ChPNl_uU.js.map → RouterCollectionsStudioView-SGBV4CMg.js.map} +1 -1
  7. package/dist/{SchemaChangeDialog-BeP0A4MJ.js → SchemaChangeDialog-CcFSXvkK.js} +33 -12
  8. package/dist/SchemaChangeDialog-CcFSXvkK.js.map +1 -0
  9. package/dist/collection_editor/_cms_internals.d.ts +2 -1
  10. package/dist/collection_editor/liveSchemaClient.d.ts +38 -18
  11. package/dist/collection_editor/serializable_types.d.ts +2 -0
  12. package/dist/collection_editor/types/config_controller.d.ts +11 -0
  13. package/dist/collection_editor/useLiveSchemaEditing.d.ts +5 -5
  14. package/dist/collection_editor/useLocalCollectionsConfigController.d.ts +7 -0
  15. package/dist/collection_editor_ui.js +5 -5
  16. package/dist/components/ClearFilterSortButton.d.ts +7 -1
  17. package/dist/components/CollectionViewBinding/CollectionViewActions.d.ts +6 -1
  18. package/dist/components/CollectionViewBinding/CollectionViewBinding.d.ts +5 -2
  19. package/dist/components/CollectionViewBinding/FiltersDialog.d.ts +5 -0
  20. package/dist/components/EditViewBinding.d.ts +7 -1
  21. package/dist/components/EntityIdentityBar.d.ts +29 -4
  22. package/dist/components/NavigationLoadingErrorView.d.ts +16 -0
  23. package/dist/components/common/ActionMenuLabel.d.ts +15 -0
  24. package/dist/components/common/default_entity_actions.d.ts +37 -0
  25. package/dist/data_import/components/ImportConversionProblems.d.ts +11 -0
  26. package/dist/data_import/components/index.d.ts +1 -0
  27. package/dist/data_import/utils/data.d.ts +81 -4
  28. package/dist/data_import/utils/import_columns.d.ts +48 -0
  29. package/dist/editor/editor.d.ts +7 -1
  30. package/dist/editor/extensions/Image.d.ts +22 -1
  31. package/dist/editor/hooks/useProseMirror.d.ts +4 -1
  32. package/dist/editor.js +69 -7
  33. package/dist/editor.js.map +1 -1
  34. package/dist/{export-4bJWdlDK.js → export-DCHuPD1a.js} +4 -4
  35. package/dist/export-DCHuPD1a.js.map +1 -0
  36. package/dist/form/form_utils.d.ts +24 -0
  37. package/dist/form/resolve_form_properties.d.ts +26 -0
  38. package/dist/{history-BElrZ5Rw.js → history-CBd6SBRs.js} +3 -2
  39. package/dist/{history-BElrZ5Rw.js.map → history-CBd6SBRs.js.map} +1 -1
  40. package/dist/hooks/useRecordActions.d.ts +28 -6
  41. package/dist/hooks/useReferencePaths.d.ts +21 -0
  42. package/dist/hooks/useStorageReferenceResolver.d.ts +23 -0
  43. package/dist/{import-TCgkTVlS.js → import-DjQoRrIU.js} +34 -52
  44. package/dist/import-DjQoRrIU.js.map +1 -0
  45. package/dist/index.js +189 -115
  46. package/dist/index.js.map +1 -1
  47. package/dist/preview/components/StorageMarkdown.d.ts +10 -0
  48. package/dist/preview/util.d.ts +4 -0
  49. package/dist/util/caller_scopes.d.ts +15 -0
  50. package/dist/util/entity_actions.d.ts +37 -1
  51. package/dist/util/fit_inline_actions.d.ts +20 -0
  52. package/dist/{util-DybQBkug.js → util-BRvKFMLa.js} +4546 -3163
  53. package/dist/util-BRvKFMLa.js.map +1 -0
  54. package/dist/{util-CC0ozHoD.js → util-D7ebttKT.js} +6 -2
  55. package/dist/{util-CC0ozHoD.js.map → util-D7ebttKT.js.map} +1 -1
  56. package/package.json +9 -9
  57. package/dist/CollectionEditorDialog-DLHCka00.js.map +0 -1
  58. package/dist/PropertyEditView-_pu5hzZn.js.map +0 -1
  59. package/dist/SchemaChangeDialog-BeP0A4MJ.js.map +0 -1
  60. package/dist/export-4bJWdlDK.js.map +0 -1
  61. package/dist/import-TCgkTVlS.js.map +0 -1
  62. package/dist/util-DybQBkug.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { $t as PropertyConfigBadge, A as getFieldId, At as guessIdColumn, Dn as CollectionTableBinding, Ft as useImportConfig, It as ImportSaveInProgress, Mn as useUrlController, Ot as ImportNewPropertyFieldPreview, Pn as useNavigationStateController, Pt as getInferenceType, S as isSchemaChangeCancelled, Tn as useSelectionController, Tt as useCollectionEditorController, _ as useCollectionsConfigController, ct as useSafeSnackbarController, en as SearchIconsView, i as namespaceToPropertiesOrderPath, jt as convertDataToEntity, k as getFieldConfig, kt as DataNewPropertiesMapping, l as validateCollectionJson, m as toSerializableCollectionConfig, n as getFullIdPath, o as CollectionGenerationApiError, r as idToPropertiesPath, t as getFullId, tn as FieldCaption, ur as useCollectionRegistryController, zt as ImportFileUpload } from "./util-DybQBkug.js";
3
- import { a as updatePropertyFromWidget, c as useAIModifiedPaths, i as supportedFields, n as PropertyForm, o as PropertyTree, r as PropertyFormDialog, s as AIModifiedPathsProvider } from "./PropertyEditView-_pu5hzZn.js";
2
+ import { A as getFieldId, At as ImportNewPropertyFieldPreview, Bn as useUrlController, Dt as useCollectionEditorController, Ft as convertImportData, Hn as useNavigationStateController, Ht as getInferenceType, Mn as useSelectionController, Mt as guessIdColumn, Nt as ImportConversionProblems, Pn as CollectionTableBinding, S as isSchemaChangeCancelled, Ut as useImportConfig, Wt as ImportSaveInProgress, _ as useCollectionsConfigController, cn as SearchIconsView, ct as useSafeSnackbarController, i as namespaceToPropertiesOrderPath, jt as DataNewPropertiesMapping, k as getFieldConfig, l as validateCollectionJson, ln as FieldCaption, m as toSerializableCollectionConfig, n as getFullIdPath, o as CollectionGenerationApiError, qt as ImportFileUpload, r as idToPropertiesPath, sn as PropertyConfigBadge, t as getFullId, yr as useCollectionRegistryController } from "./util-BRvKFMLa.js";
3
+ import { a as updatePropertyFromWidget, c as useAIModifiedPaths, i as supportedFields, n as PropertyForm, o as PropertyTree, r as PropertyFormDialog, s as AIModifiedPathsProvider } from "./PropertyEditView-DDB_X-00.js";
4
4
  import * as React$1 from "react";
5
5
  import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
6
6
  import { Alert, AppWindow, ArrowLeftIcon, BooleanSwitchWithLabel, Button, Card, CheckIcon, Chip, CircularProgress, CircularProgressCenter, CodeIcon, ColumnsIcon, Container, CopyIcon, DebouncedTextField, Dialog, DialogActions, DialogContent, DialogTitle, ErrorBoundary, FileIcon, FileSearchIcon, FileTextIcon, IconButton, KanbanIcon, KeyIcon, LayoutGridIcon, ListIcon, LoadingButton, Menu, MultiSelect, MultiSelectItem, PanelLeftIcon, Paper, PlusIcon, Select, SelectItem, ShoppingCartIcon, SquareIcon, Tab, TableIcon, Tabs, TextField, ToggleButtonGroup, Tooltip, Trash2Icon, Typography, UserIcon, XIcon, cls, coolIconKeys, defaultBorderMixin, iconSize } from "@rebasepro/ui";
@@ -24,6 +24,7 @@ var CollectionEditorSchema = z.object({
24
24
  //#region src/collection_editor/ui/collection_editor/GeneralSettingsForm.tsx
25
25
  function GeneralSettingsForm({ isNewCollection, existingPaths, existingIds, parentCollection, renderExtraCollectionFields, standalone }) {
26
26
  const { values, setFieldValue, handleChange, touched, errors, setFieldTouched, submitCount } = useFormex();
27
+ const { t } = useTranslation();
27
28
  const [iconDialogOpen, setIconDialogOpen] = useState(false);
28
29
  const configControllerFromContext = useCollectionsConfigController();
29
30
  const configController = standalone ? { readOnly: false } : configControllerFromContext;
@@ -59,9 +60,10 @@ function GeneralSettingsForm({ isNewCollection, existingPaths, existingIds, pare
59
60
  onDatabaseIdUpdate: updateDatabaseId
60
61
  }),
61
62
  /* @__PURE__ */ jsx(Tooltip, {
62
- title: "Change icon",
63
+ title: t("change_icon"),
63
64
  asChild: true,
64
65
  children: /* @__PURE__ */ jsx(IconButton, {
66
+ "aria-label": t("change_icon"),
65
67
  shape: "square",
66
68
  disabled: configController?.readOnly,
67
69
  onClick: () => setIconDialogOpen(true),
@@ -788,6 +790,7 @@ function collectionToCode(collection) {
788
790
  function CollectionPropertiesEditorForm({ showErrors, isNewCollection, propertyErrorsRef, onPropertyError, setDirty, extraIcon, getUser, getData, doCollectionInference, propertyConfigs, propertyTypePresets, hiddenPropertyTypes, renderExtraPropertyFields, standalone }) {
789
791
  const { values, setFieldValue, setFieldError, setFieldTouched, errors, dirty } = useFormex();
790
792
  const snackbarController = useSafeSnackbarController();
793
+ const { t } = useTranslation();
791
794
  const configControllerFromContext = useCollectionsConfigController();
792
795
  const configController = standalone ? { readOnly: false } : configControllerFromContext;
793
796
  const largeLayout = useLargeLayout();
@@ -1009,15 +1012,17 @@ function CollectionPropertiesEditorForm({ showErrors, isNewCollection, propertyE
1009
1012
  title: "Add new properties based on data",
1010
1013
  asChild: true,
1011
1014
  children: /* @__PURE__ */ jsx(IconButton, {
1015
+ "aria-label": "Add new properties based on data",
1012
1016
  size: "small",
1013
1017
  disabled: inferringProperties,
1014
1018
  onClick: inferPropertiesFromData,
1015
1019
  children: inferringProperties ? /* @__PURE__ */ jsx(CircularProgress, { size: "smallest" }) : /* @__PURE__ */ jsx(FileSearchIcon, { size: iconSize.smallest })
1016
1020
  })
1017
1021
  }), /* @__PURE__ */ jsx(Tooltip, {
1018
- title: "Add new property",
1022
+ title: t("studio_property_add_column"),
1019
1023
  asChild: true,
1020
1024
  children: /* @__PURE__ */ jsx(IconButton, {
1025
+ "aria-label": t("studio_property_add_column"),
1021
1026
  size: "small",
1022
1027
  disabled: configController?.readOnly,
1023
1028
  onClick: () => setNewPropertyDialogOpen(true),
@@ -2258,54 +2263,72 @@ function CollectionEditorImportDataPreview({ importConfig, properties, propertie
2258
2263
  const authController = useAuthController();
2259
2264
  const registry = useCollectionRegistryController();
2260
2265
  const [loading, setLoading] = useState(false);
2266
+ const [problems, setProblems] = useState([]);
2261
2267
  async function loadEntities() {
2262
- const mappedData = importConfig.importData.map((d) => convertDataToEntity(authController, registry, d, importConfig.idColumn, importConfig.headersMapping, properties, "TEMP_PATH", importConfig.defaultValues));
2263
- importConfig.setEntities(mappedData);
2268
+ const converted = convertImportData(authController, registry, importConfig.importData, importConfig.idColumn, importConfig.headersMapping, properties, "TEMP_PATH", importConfig.defaultValues);
2269
+ importConfig.setEntities(converted.entities);
2270
+ setProblems(converted.problems);
2264
2271
  }
2265
2272
  useEffect(() => {
2266
2273
  loadEntities().finally(() => setLoading(false));
2267
2274
  }, []);
2268
2275
  const selectionController = useSelectionController();
2269
2276
  if (loading) return /* @__PURE__ */ jsx(CircularProgressCenter, {});
2270
- return /* @__PURE__ */ jsx(CollectionTableBinding, {
2271
- title: /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Typography, {
2272
- variant: "subtitle2",
2273
- children: "Imported data preview"
2274
- }), /* @__PURE__ */ jsx(Typography, {
2275
- variant: "caption",
2276
- children: "Entities with the same id will be overwritten"
2277
- })] }),
2278
- tableController: {
2279
- data: importConfig.entities,
2280
- dataLoading: false,
2281
- noMoreToLoad: false
2282
- },
2283
- endAdornment: /* @__PURE__ */ jsx("div", { className: "h-12" }),
2284
- filterable: false,
2285
- sortable: false,
2286
- selectionController,
2287
- displayedColumnIds: propertiesOrder.map((p) => ({
2288
- key: p,
2289
- disabled: false
2290
- })),
2291
- openEntityMode: "side_panel",
2292
- properties,
2293
- enablePopupIcon: false
2277
+ return /* @__PURE__ */ jsxs("div", {
2278
+ className: "flex flex-col h-full w-full",
2279
+ children: [/* @__PURE__ */ jsx(ImportConversionProblems, { problems }), /* @__PURE__ */ jsx("div", {
2280
+ className: "flex-1 min-h-0",
2281
+ children: /* @__PURE__ */ jsx(CollectionTableBinding, {
2282
+ title: /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Typography, {
2283
+ variant: "subtitle2",
2284
+ children: "Imported data preview"
2285
+ }), /* @__PURE__ */ jsx(Typography, {
2286
+ variant: "caption",
2287
+ children: "Entities with the same id will be overwritten"
2288
+ })] }),
2289
+ tableController: {
2290
+ data: importConfig.entities,
2291
+ dataLoading: false,
2292
+ noMoreToLoad: false
2293
+ },
2294
+ endAdornment: /* @__PURE__ */ jsx("div", { className: "h-12" }),
2295
+ filterable: false,
2296
+ sortable: false,
2297
+ selectionController,
2298
+ displayedColumnIds: propertiesOrder.map((p) => ({
2299
+ key: p,
2300
+ disabled: false
2301
+ })),
2302
+ openEntityMode: "side_panel",
2303
+ properties,
2304
+ enablePopupIcon: false
2305
+ })
2306
+ })]
2294
2307
  });
2295
2308
  }
2296
2309
  //#endregion
2297
2310
  //#region src/collection_editor/ui/collection_editor/import/clean_import_data.ts
2298
2311
  function cleanPropertiesFromImport(properties, parentSlug = "") {
2299
- const result = Object.keys(properties).reduce((acc, key) => {
2312
+ const taken = /* @__PURE__ */ new Set();
2313
+ const uniqueSlug = (key, index) => {
2314
+ const base = slugify(key) || `column_${index + 1}`;
2315
+ let slug = base;
2316
+ for (let n = 2; taken.has(slug); n++) slug = `${base}_${n}`;
2317
+ taken.add(slug);
2318
+ return slug;
2319
+ };
2320
+ const result = Object.keys(properties).reduce((acc, key, index) => {
2300
2321
  const property = properties[key];
2301
- const slug = slugify(key);
2322
+ const slug = uniqueSlug(key, index);
2302
2323
  const fullSlug = parentSlug ? `${parentSlug}.${slug}` : slug;
2303
2324
  if (property.type === "map" && property.properties) {
2304
2325
  const slugifiedResult = cleanPropertiesFromImport(property.properties, fullSlug);
2326
+ const childMapping = Object.fromEntries(Object.entries(slugifiedResult.headersMapping).map(([childKey, childSlug]) => [`${key}.${childKey}`, childSlug]));
2305
2327
  return {
2306
2328
  headersMapping: {
2307
2329
  ...acc.headersMapping,
2308
- [key]: fullSlug
2330
+ [key]: fullSlug,
2331
+ ...childMapping
2309
2332
  },
2310
2333
  properties: {
2311
2334
  ...acc.properties,
@@ -3097,11 +3120,17 @@ function CollectionEditorInternal({ isNewCollection, configController, editedCol
3097
3120
  if (visibleTabs && !visibleTabs.includes(currentView)) setCurrentView(visibleTabs[0] || "general");
3098
3121
  }, [visibleTabs, currentView]);
3099
3122
  const [error, setError] = React$1.useState();
3100
- const saveCollection = (updatedCollection) => {
3123
+ /**
3124
+ * `baseline` is what the form was loaded with: the controller saves the
3125
+ * difference between it and `updatedCollection`, so only what the person
3126
+ * changed is written. Never for a new collection, which is saved whole.
3127
+ */
3128
+ const saveCollection = (updatedCollection, baseline) => {
3101
3129
  const id = updatedCollection.slug;
3102
3130
  return configController.saveCollection({
3103
3131
  id,
3104
3132
  collectionData: updatedCollection,
3133
+ baseline: isNewCollection ? void 0 : baseline,
3105
3134
  previousId: editedCollectionId,
3106
3135
  parentCollectionSlugs
3107
3136
  }).then(() => {
@@ -3175,7 +3204,7 @@ function CollectionEditorInternal({ isNewCollection, configController, editedCol
3175
3204
  console.debug("Submitting collection", newCollectionState);
3176
3205
  try {
3177
3206
  if (!isNewCollection) {
3178
- if (await saveCollection(newCollectionState)) {
3207
+ if (await saveCollection(newCollectionState, formexController.initialValues)) {
3179
3208
  aiModifiedPaths?.clearAllPaths();
3180
3209
  formexController.resetForm({ values: newCollectionState });
3181
3210
  handleClose(newCollectionState);
@@ -3304,6 +3333,14 @@ function CollectionEditorInternal({ isNewCollection, configController, editedCol
3304
3333
  message: "Collection deleted",
3305
3334
  type: "success"
3306
3335
  });
3336
+ }, (e) => {
3337
+ setDeleteRequested(false);
3338
+ if (isSchemaChangeCancelled(e)) return;
3339
+ console.error(e);
3340
+ snackbarController.open({
3341
+ type: "error",
3342
+ message: "Error deleting collection: " + (e instanceof Error ? e.message : String(e))
3343
+ });
3307
3344
  });
3308
3345
  };
3309
3346
  const onWelcomeScreenContinue = (importData, propertiesOrder) => {
@@ -3431,7 +3468,7 @@ function CollectionEditorInternal({ isNewCollection, configController, editedCol
3431
3468
  type: "info",
3432
3469
  message: "Data imported successfully"
3433
3470
  });
3434
- await saveCollection(values);
3471
+ await saveCollection(values, formController.initialValues);
3435
3472
  handleClose(importedCollection);
3436
3473
  }
3437
3474
  }),
@@ -3467,7 +3504,6 @@ function CollectionEditorInternal({ isNewCollection, configController, editedCol
3467
3504
  hiddenPropertyTypes,
3468
3505
  renderExtraPropertyFields,
3469
3506
  extraIcon: extraView?.icon && /* @__PURE__ */ jsx(IconButton, {
3470
- color: "primary",
3471
3507
  onClick: () => setCurrentView("extra_view"),
3472
3508
  children: extraView.icon
3473
3509
  }),
@@ -3567,11 +3603,14 @@ function CollectionEditorInternal({ isNewCollection, configController, editedCol
3567
3603
  open: deleteRequested,
3568
3604
  onAccept: deleteCollection,
3569
3605
  onCancel: () => setDeleteRequested(false),
3570
- title: /* @__PURE__ */ jsx(Fragment, { children: "Delete the stored config?" }),
3606
+ title: /* @__PURE__ */ jsx(Fragment, { children: "Delete this collection?" }),
3571
3607
  body: /* @__PURE__ */ jsxs(Fragment, { children: [
3572
- " This will ",
3573
- /* @__PURE__ */ jsx("b", { children: "not delete any data" }),
3574
- ", only the stored config, and reset to the code state."
3608
+ "Deletes ",
3609
+ /* @__PURE__ */ jsxs("code", { children: [collection?.slug, ".ts"] }),
3610
+ " from your collections and its entry in",
3611
+ " ",
3612
+ /* @__PURE__ */ jsx("code", { children: "index.ts" }),
3613
+ ", and commits that. The table and its rows stay in the database. Refused while another collection links to this one."
3575
3614
  ] })
3576
3615
  })]
3577
3616
  });
@@ -3627,4 +3666,4 @@ var validateId = (value, isNewCollection, existingPaths, existingIds) => {
3627
3666
  //#endregion
3628
3667
  export { CollectionEditorDialog as n, CollectionEditorDialog_exports as r, CollectionEditor as t };
3629
3668
 
3630
- //# sourceMappingURL=CollectionEditorDialog-DLHCka00.js.map
3669
+ //# sourceMappingURL=CollectionEditorDialog-p5-I-Apu.js.map