@rebasepro/admin 0.7.0 → 0.8.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 (100) hide show
  1. package/LICENSE +21 -0
  2. package/dist/{CollectionEditorDialog-iGgS4rLX.js → CollectionEditorDialog-BO_aQ-Z4.js} +7 -7
  3. package/dist/CollectionEditorDialog-BO_aQ-Z4.js.map +1 -0
  4. package/dist/{PropertyEditView-C9yhLyja.js → PropertyEditView-DKzOpMjR.js} +64 -38
  5. package/dist/PropertyEditView-DKzOpMjR.js.map +1 -0
  6. package/dist/{RouterCollectionsStudioView-Dqx27GD8.js → RouterCollectionsStudioView-BQTIExjA.js} +4 -4
  7. package/dist/{RouterCollectionsStudioView-Dqx27GD8.js.map → RouterCollectionsStudioView-BQTIExjA.js.map} +1 -1
  8. package/dist/collection_editor/_cms_internals.d.ts +1 -1
  9. package/dist/collection_editor/api/generateCollectionApi.d.ts +3 -2
  10. package/dist/collection_editor/serializable_types.d.ts +5 -9
  11. package/dist/collection_editor/serializable_utils.d.ts +2 -2
  12. package/dist/collection_editor/ui/collection_editor/CollectionEditorDialog.d.ts +1 -2
  13. package/dist/collection_editor_ui.js +4 -4
  14. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
  15. package/dist/components/EntityCollectionTable/index.d.ts +1 -1
  16. package/dist/components/RebaseCMS.d.ts +1 -1
  17. package/dist/components/SelectableTable/SelectionStore.d.ts +12 -21
  18. package/dist/components/field_configs.d.ts +1 -1
  19. package/dist/editor/editor.d.ts +0 -6
  20. package/dist/editor.js +1 -3
  21. package/dist/editor.js.map +1 -1
  22. package/dist/form/components/StorageUploadProgress.d.ts +6 -1
  23. package/dist/form/index.d.ts +0 -1
  24. package/dist/{history-ChHgyyvM.js → history-B3cqBzEV.js} +2 -2
  25. package/dist/{history-ChHgyyvM.js.map → history-B3cqBzEV.js.map} +1 -1
  26. package/dist/index.d.ts +1 -1
  27. package/dist/index.js +2 -2
  28. package/dist/preview/components/StorageThumbnail.d.ts +3 -1
  29. package/dist/{src-DOX2nOyh.js → src-cxV1ODRG.js} +178 -460
  30. package/dist/src-cxV1ODRG.js.map +1 -0
  31. package/dist/types/components/PropertyPreviewProps.d.ts +2 -1
  32. package/dist/types/fields.d.ts +4 -6
  33. package/package.json +18 -18
  34. package/src/collection_editor/_cms_internals.ts +1 -1
  35. package/src/collection_editor/api/generateCollectionApi.ts +3 -2
  36. package/src/collection_editor/pgColumnToProperty.ts +2 -2
  37. package/src/collection_editor/serializable_types.ts +14 -27
  38. package/src/collection_editor/serializable_utils.ts +25 -37
  39. package/src/collection_editor/ui/collection_editor/AICollectionGeneratorPopover.tsx +2 -2
  40. package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +41 -24
  41. package/src/collection_editor/ui/collection_editor/PropertyEditView.tsx +0 -9
  42. package/src/collection_editor/ui/collection_editor/properties/StoragePropertyField.tsx +35 -1
  43. package/src/collection_editor/ui/collection_editor/templates/blog_template.ts +1 -1
  44. package/src/collection_editor/ui/collection_editor/utils/supported_fields.tsx +0 -1
  45. package/src/collection_editor/ui/collection_editor/utils/update_property_for_widget.ts +7 -29
  46. package/src/collection_editor/useJsonCollectionsConfigController.tsx +2 -2
  47. package/src/components/DefaultDrawer.tsx +1 -1
  48. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +11 -9
  49. package/src/components/EntityCollectionTable/fields/TableMultipleRelationField.tsx +2 -1
  50. package/src/components/EntityCollectionTable/fields/TableRelationField.tsx +2 -1
  51. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +23 -20
  52. package/src/components/EntityCollectionTable/index.tsx +1 -1
  53. package/src/components/EntityCollectionTable/table_bindings.tsx +24 -44
  54. package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +1 -1
  55. package/src/components/EntityCollectionView/EntityCollectionListView.tsx +12 -1
  56. package/src/components/EntityCollectionView/EntityCollectionView.tsx +8 -25
  57. package/src/components/EntityCollectionView/hooks/useCollectionInlineEditor.ts +1 -1
  58. package/src/components/EntityCollectionView/useBoardDataController.tsx +12 -40
  59. package/src/components/EntityCollectionView/useEntityPreviewSlots.ts +3 -3
  60. package/src/components/EntityDetailView.tsx +2 -2
  61. package/src/components/EntityEditView.tsx +2 -2
  62. package/src/components/EntityEditViewFormActions.tsx +3 -3
  63. package/src/components/HomePage/ContentHomePage.tsx +1 -1
  64. package/src/components/RebaseCMS.tsx +2 -3
  65. package/src/components/RebaseNavigation.tsx +3 -2
  66. package/src/components/RelationSelector.tsx +2 -2
  67. package/src/components/SelectableTable/SelectableTable.tsx +11 -3
  68. package/src/components/SelectableTable/SelectionStore.ts +18 -48
  69. package/src/components/common/default_entity_actions.tsx +15 -4
  70. package/src/components/field_configs.tsx +0 -14
  71. package/src/editor/editor.tsx +4 -7
  72. package/src/form/EntityFormActions.tsx +2 -2
  73. package/src/form/EntityFormBinding.tsx +1 -1
  74. package/src/form/components/StorageUploadProgress.tsx +9 -2
  75. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +12 -1
  76. package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +4 -4
  77. package/src/form/field_bindings/RelationFieldBinding.tsx +5 -7
  78. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +19 -15
  79. package/src/form/index.tsx +0 -1
  80. package/src/index.ts +1 -1
  81. package/src/preview/PropertyPreview.tsx +1 -16
  82. package/src/preview/components/StorageThumbnail.tsx +24 -7
  83. package/src/types/components/PropertyPreviewProps.tsx +1 -1
  84. package/src/types/fields.tsx +2 -7
  85. package/src/util/previews.ts +20 -0
  86. package/src/util/propertyConfigMapper.ts +3 -3
  87. package/src/util/property_utils.tsx +1 -2
  88. package/dist/CollectionEditorDialog-iGgS4rLX.js.map +0 -1
  89. package/dist/PropertyEditView-C9yhLyja.js.map +0 -1
  90. package/dist/components/EntityCollectionTable/fields/VirtualTableDateField.d.ts +0 -12
  91. package/dist/components/EntityCollectionTable/fields/VirtualTableInput.d.ts +0 -10
  92. package/dist/components/EntityCollectionTable/fields/VirtualTableNumberInput.d.ts +0 -9
  93. package/dist/components/EntityCollectionTable/fields/VirtualTableSwitch.d.ts +0 -8
  94. package/dist/form/field_bindings/ReferenceAsStringFieldBinding.d.ts +0 -11
  95. package/dist/src-DOX2nOyh.js.map +0 -1
  96. package/src/components/EntityCollectionTable/fields/VirtualTableDateField.tsx +0 -39
  97. package/src/components/EntityCollectionTable/fields/VirtualTableInput.tsx +0 -90
  98. package/src/components/EntityCollectionTable/fields/VirtualTableNumberInput.tsx +0 -83
  99. package/src/components/EntityCollectionTable/fields/VirtualTableSwitch.tsx +0 -32
  100. package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +0 -141
@@ -2,7 +2,8 @@ import React, { useEffect } from "react";
2
2
 
3
3
  import { renderSkeletonImageThumbnail } from "../property_previews/SkeletonPropertyComponent";
4
4
  import { UrlComponentPreview } from "./UrlComponentPreview";
5
- import { ErrorView, useStorageSource } from "@rebasepro/core";
5
+ import { ErrorView, useStorageSource, useStorageSources } from "@rebasepro/core";
6
+ import { resolveStorageSource } from "@rebasepro/common";
6
7
  import { DownloadConfig, FileType } from "@rebasepro/types";
7
8
  import type { PreviewSize } from "../../types/components/PropertyPreviewProps";
8
9
  import { Skeleton } from "@rebasepro/ui";
@@ -12,6 +13,8 @@ type StorageThumbnailProps = {
12
13
  size: PreviewSize;
13
14
  interactive?: boolean;
14
15
  fill?: boolean;
16
+ /** Key of the storage source backing this property (`StorageConfig.storageSource`). */
17
+ storageSourceKey?: string;
15
18
  };
16
19
 
17
20
  /**
@@ -24,7 +27,8 @@ function areEqual(prevProps: StorageThumbnailProps, nextProps: StorageThumbnailP
24
27
  prevProps.storagePathOrDownloadUrl === nextProps.storagePathOrDownloadUrl &&
25
28
  prevProps.storeUrl === nextProps.storeUrl &&
26
29
  prevProps.interactive === nextProps.interactive &&
27
- prevProps.fill === nextProps.fill;
30
+ prevProps.fill === nextProps.fill &&
31
+ prevProps.storageSourceKey === nextProps.storageSourceKey;
28
32
  }
29
33
 
30
34
  const URL_CACHE: Record<string, DownloadConfig> = {};
@@ -34,13 +38,26 @@ export function StorageThumbnailInternal({
34
38
  interactive,
35
39
  storagePathOrDownloadUrl,
36
40
  size,
37
- fill
41
+ fill,
42
+ storageSourceKey
38
43
  }: StorageThumbnailProps) {
39
44
 
40
45
  const [error, setError] = React.useState<Error | undefined>(undefined);
41
- const storage = useStorageSource();
46
+ const defaultStorage = useStorageSource();
47
+ const storageSources = useStorageSources();
48
+ // Resolve the per-property backend so previews of `storeUrl: false`
49
+ // properties pointing at a named source hit the right backend.
50
+ const storage = resolveStorageSource({
51
+ sourceKey: storageSourceKey,
52
+ sources: storageSources.sources,
53
+ defaultSource: defaultStorage
54
+ });
42
55
 
43
- const [downloadConfig, setDownloadConfig] = React.useState<DownloadConfig>(URL_CACHE[storagePathOrDownloadUrl]);
56
+ // Cache key is namespaced by source so the same path on two backends
57
+ // does not collide.
58
+ const cacheKey = `${storageSourceKey ?? ""}::${storagePathOrDownloadUrl}`;
59
+
60
+ const [downloadConfig, setDownloadConfig] = React.useState<DownloadConfig>(URL_CACHE[cacheKey]);
44
61
 
45
62
  useEffect(() => {
46
63
  if (!storagePathOrDownloadUrl)
@@ -50,13 +67,13 @@ export function StorageThumbnailInternal({
50
67
  .then(function (downloadConfig) {
51
68
  if (!unmounted) {
52
69
  setDownloadConfig(downloadConfig);
53
- URL_CACHE[storagePathOrDownloadUrl] = downloadConfig;
70
+ URL_CACHE[cacheKey] = downloadConfig;
54
71
  }
55
72
  }).catch(setError);
56
73
  return () => {
57
74
  unmounted = true;
58
75
  };
59
- }, [storagePathOrDownloadUrl]);
76
+ }, [storagePathOrDownloadUrl, cacheKey]);
60
77
 
61
78
  if (!storagePathOrDownloadUrl) return null;
62
79
 
@@ -15,7 +15,7 @@ export interface PropertyPreviewProps<P extends Property | Property, CustomProps
15
15
  */
16
16
  propertyKey?: string;
17
17
 
18
- value: any;
18
+ value: InferPropertyType<P> | any;
19
19
 
20
20
  /**
21
21
  * Property this display is related to, now strongly typed to P
@@ -19,7 +19,6 @@ export type DefaultFieldConfig =
19
19
  | "multi_number_select"
20
20
  | "file_upload"
21
21
  | "multi_file_upload"
22
- | "reference_as_string"
23
22
  | "reference"
24
23
  | "multi_references"
25
24
  | "relation"
@@ -51,12 +50,8 @@ export interface FieldProps<
51
50
  /**
52
51
  * Current value of this field, inferred from the property type P
53
52
  */
54
- value: any;
55
-
56
- /**
57
- * Set value of field directly
58
- */
59
- setValue: (value: any | null, shouldValidate?: boolean) => void;
53
+ value: InferPropertyType<P> | any;
54
+ setValue: (value: InferPropertyType<P> | null | any, shouldValidate?: boolean) => void;
60
55
 
61
56
  /**
62
57
  * Set value of a different field directly
@@ -8,6 +8,25 @@ function isHiddenProperty(property: Property | undefined): boolean {
8
8
  return Boolean(property.ui?.hideFromCollection);
9
9
  }
10
10
 
11
+ /**
12
+ * Returns true when the property holds file-storage content (single image,
13
+ * array of images, generic upload, …). These properties are rendered by the
14
+ * dedicated image-slot and should NOT appear as regular preview columns.
15
+ */
16
+ function isStorageProperty(property: Property | undefined): boolean {
17
+ if (!property) return false;
18
+ // Single string with storage config
19
+ if (property.type === "string" && property.storage) return true;
20
+ // String displayed as image URL
21
+ if (property.type === "string" && property.ui?.url === "image") return true;
22
+ // Array whose inner element has storage config or image URL
23
+ if (property.type === "array" && property.of && !Array.isArray(property.of)) {
24
+ const inner = property.of;
25
+ if (inner.type === "string" && (inner.storage || inner.ui?.url === "image")) return true;
26
+ }
27
+ return false;
28
+ }
29
+
11
30
  export function getEntityPreviewKeys(
12
31
  authController: AuthController,
13
32
  targetCollection: EntityCollection<any>,
@@ -33,6 +52,7 @@ export function getEntityPreviewKeys(
33
52
  .filter(key => {
34
53
  const property = targetCollection.properties[key];
35
54
  return property && !isPropertyBuilder(property) && !isReferenceProperty(property) && !isHiddenProperty(property)
55
+ && !isStorageProperty(property as Property)
36
56
  && (hasExplicitOrder || !isRelationProperty(property));
37
57
  }).slice(0, limit);
38
58
  }
@@ -44,10 +44,10 @@ export function mapPropertyToConfig(property: Property): CollectionPropertyConfi
44
44
  if (property.enum) {
45
45
  base.enum = mapEnumValues(property.enum);
46
46
  }
47
- if (property.multiline) base.multiline = true;
47
+ if (property.ui?.multiline) base.multiline = true;
48
48
  if (property.ui?.previewAsTag) base.previewAsTag = true;
49
- if (property.url || property.ui?.url) base.url = property.url ?? property.ui?.url;
50
- if (property.ui?.markdown || property.markdown) base.markdown = true;
49
+ if (property.ui?.url) base.url = property.ui.url;
50
+ if (property.ui?.markdown) base.markdown = true;
51
51
  if (property.storage) base.storage = true;
52
52
  if (property.email) base.email = true;
53
53
  }
@@ -1,6 +1,6 @@
1
1
 
2
2
  import type { Properties } from "@rebasepro/types";
3
- import type { EntityCollection, MapProperty, Property, PropertyConfig, StringProperty } from "@rebasepro/types";
3
+ import type { EntityCollection, MapProperty, Property, PropertyConfig } from "@rebasepro/types";
4
4
  import React from "react";
5
5
 
6
6
  import { isPropertyBuilder } from "@rebasepro/common";
@@ -75,7 +75,6 @@ function getDefaultIconForProperty(property: Property): LucideIcon {
75
75
  if (property.ui?.url) return GlobeIcon;
76
76
  if (property.email) return MailIcon;
77
77
  if (property.ui?.multiline || property.ui?.markdown) return AlignLeftIcon;
78
- if ((property as StringProperty).reference) return LinkIcon;
79
78
  return TextIcon;
80
79
  }
81
80
  case "number":