@rebasepro/admin 0.2.1 → 0.2.4

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 (214) hide show
  1. package/dist/{CollectionEditorDialog-BXIh2AXg.js → CollectionEditorDialog-D0VqpLPO.js} +73 -256
  2. package/dist/CollectionEditorDialog-D0VqpLPO.js.map +1 -0
  3. package/dist/{CollectionsStudioView-jR8iz_ja.js → CollectionsStudioView-Bc3Rxxc2.js} +5 -4
  4. package/dist/{CollectionsStudioView-jR8iz_ja.js.map → CollectionsStudioView-Bc3Rxxc2.js.map} +1 -1
  5. package/dist/{ExportCollectionAction-CMdiiv1L.js → ExportCollectionAction-Ckc-09BQ.js} +4 -3
  6. package/dist/ExportCollectionAction-Ckc-09BQ.js.map +1 -0
  7. package/dist/{ImportCollectionAction-C05lE0IW.js → ImportCollectionAction-BqjIrC3Z.js} +3 -2
  8. package/dist/{ImportCollectionAction-C05lE0IW.js.map → ImportCollectionAction-BqjIrC3Z.js.map} +1 -1
  9. package/dist/{PropertyEditView-BB5xjnhZ.js → PropertyEditView-CvRSV-A2.js} +430 -445
  10. package/dist/PropertyEditView-CvRSV-A2.js.map +1 -0
  11. package/dist/collection_editor/ConfigControllerProvider.d.ts +0 -5
  12. package/dist/collection_editor/index.d.ts +0 -1
  13. package/dist/collection_editor/types/collection_editor_controller.d.ts +0 -2
  14. package/dist/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +3 -3
  15. package/dist/collection_editor/ui/collection_editor/properties/RelationPropertyField.d.ts +1 -7
  16. package/dist/collection_editor_ui.js +3 -3
  17. package/dist/components/ArrayContainer.d.ts +2 -2
  18. package/dist/components/DefaultAppBar.d.ts +18 -1
  19. package/dist/components/DefaultDrawer.d.ts +51 -3
  20. package/dist/components/EntityCollectionTable/fields/TableStorageUpload.d.ts +2 -2
  21. package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +2 -2
  22. package/dist/components/EntityCollectionTable/table_bindings.d.ts +4 -3
  23. package/dist/components/EntityCollectionView/hooks/useKanbanDragAndDrop.d.ts +4 -3
  24. package/dist/components/EntityEditView.d.ts +2 -1
  25. package/dist/components/HomePage/HomePageDnD.d.ts +3 -3
  26. package/dist/components/PropertyCollectionView.d.ts +1 -1
  27. package/dist/components/PropertyIdCopyTooltip.d.ts +1 -1
  28. package/dist/components/SelectableTable/SelectionStore.d.ts +4 -1
  29. package/dist/components/SelectableTable/filters/BooleanFilterField.d.ts +2 -2
  30. package/dist/components/SelectableTable/filters/DateTimeFilterField.d.ts +2 -2
  31. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +2 -2
  32. package/dist/components/SelectableTable/filters/StringNumberFilterField.d.ts +2 -2
  33. package/dist/components/admin/RolesView.d.ts +3 -3
  34. package/dist/components/admin/UsersView.d.ts +3 -3
  35. package/dist/components/app/Drawer.d.ts +8 -1
  36. package/dist/data_export/export/export.d.ts +3 -3
  37. package/dist/editor/components/editor-bubble.d.ts +5 -1
  38. package/dist/editor/components/image-bubble.d.ts +5 -1
  39. package/dist/editor/components/index.d.ts +3 -3
  40. package/dist/editor/components/table-bubble.d.ts +5 -1
  41. package/dist/editor/nodeViews/ReactNodeView.d.ts +4 -1
  42. package/dist/editor/useProseMirror.d.ts +2 -2
  43. package/dist/editor/utils/remove_classes.d.ts +1 -1
  44. package/dist/editor.js +15 -14
  45. package/dist/editor.js.map +1 -1
  46. package/dist/form/EntityForm.d.ts +2 -2
  47. package/dist/form/components/StorageUploadProgress.d.ts +2 -2
  48. package/dist/form/field_bindings/MultiSelectFieldBinding.d.ts +1 -1
  49. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +1 -1
  50. package/dist/form/validation.d.ts +3 -3
  51. package/dist/hooks/navigation/useResolvedCollections.d.ts +6 -0
  52. package/dist/hooks/navigation/useResolvedViews.d.ts +3 -4
  53. package/dist/{index-BAM9KCmM.js → index-BCcLwgfe.js} +3 -2
  54. package/dist/{index-BAM9KCmM.js.map → index-BCcLwgfe.js.map} +1 -1
  55. package/dist/{index-D5OQhv-T.js → index-DY2k5TtG.js} +3 -3
  56. package/dist/index-DY2k5TtG.js.map +1 -0
  57. package/dist/{index-CoSNm3e3.js → index-UQOMHwt1.js} +3 -3
  58. package/dist/index-UQOMHwt1.js.map +1 -0
  59. package/dist/index.d.ts +1 -1
  60. package/dist/index.js +2813 -372
  61. package/dist/index.js.map +1 -1
  62. package/dist/{markdown-z2Ir7Cgo.js → markdown-DD2JDU1X.js} +2 -2
  63. package/dist/markdown-DD2JDU1X.js.map +1 -0
  64. package/dist/preview/components/UrlComponentPreview.d.ts +1 -0
  65. package/dist/types/components/EntityFormActionsProps.d.ts +1 -1
  66. package/dist/types/components/EntityFormProps.d.ts +2 -2
  67. package/dist/types/fields.d.ts +1 -1
  68. package/dist/{util-DtbWD7LF.js → util-ZM9gQuCv.js} +2104 -2071
  69. package/dist/util-ZM9gQuCv.js.map +1 -0
  70. package/package.json +10 -9
  71. package/src/collection_editor/ConfigControllerProvider.tsx +3 -13
  72. package/src/collection_editor/index.ts +1 -3
  73. package/src/collection_editor/types/collection_editor_controller.tsx +0 -3
  74. package/src/collection_editor/ui/EditorCollectionAction.tsx +1 -6
  75. package/src/collection_editor/ui/EditorCollectionActionStart.tsx +1 -6
  76. package/src/collection_editor/ui/EditorEntityAction.tsx +1 -6
  77. package/src/collection_editor/ui/HomePageEditorCollectionAction.tsx +7 -14
  78. package/src/collection_editor/ui/NewCollectionCard.tsx +1 -5
  79. package/src/collection_editor/ui/PropertyAddColumnComponent.tsx +3 -8
  80. package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +1 -10
  81. package/src/collection_editor/ui/collection_editor/CollectionJsonImportDialog.tsx +8 -12
  82. package/src/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.tsx +21 -21
  83. package/src/collection_editor/ui/collection_editor/CollectionRLSTab.tsx +4 -4
  84. package/src/collection_editor/ui/collection_editor/EnumForm.tsx +1 -1
  85. package/src/collection_editor/ui/collection_editor/properties/BlockPropertyField.tsx +3 -3
  86. package/src/collection_editor/ui/collection_editor/properties/CommonPropertyFields.tsx +3 -3
  87. package/src/collection_editor/ui/collection_editor/properties/DateTimePropertyField.tsx +8 -8
  88. package/src/collection_editor/ui/collection_editor/properties/EnumPropertyField.tsx +5 -5
  89. package/src/collection_editor/ui/collection_editor/properties/MapPropertyField.tsx +2 -2
  90. package/src/collection_editor/ui/collection_editor/properties/MarkdownPropertyField.tsx +5 -5
  91. package/src/collection_editor/ui/collection_editor/properties/NumberPropertyField.tsx +5 -5
  92. package/src/collection_editor/ui/collection_editor/properties/ReferencePropertyField.tsx +2 -2
  93. package/src/collection_editor/ui/collection_editor/properties/RelationPropertyField.tsx +37 -57
  94. package/src/collection_editor/ui/collection_editor/properties/RepeatPropertyField.tsx +2 -2
  95. package/src/collection_editor/ui/collection_editor/properties/StoragePropertyField.tsx +8 -8
  96. package/src/collection_editor/ui/collection_editor/properties/StringPropertyField.tsx +5 -5
  97. package/src/collection_editor/ui/collection_editor/properties/UrlPropertyField.tsx +3 -2
  98. package/src/collection_editor/ui/collection_editor/properties/VectorPropertyField.tsx +2 -2
  99. package/src/collection_editor/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +2 -2
  100. package/src/collection_editor/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +1 -1
  101. package/src/collection_editor/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +4 -7
  102. package/src/collection_editor/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +4 -4
  103. package/src/collection_editor/validateCollectionJson.ts +88 -1
  104. package/src/components/ArrayContainer.tsx +3 -3
  105. package/src/components/DefaultAppBar.tsx +52 -31
  106. package/src/components/DefaultDrawer.tsx +279 -66
  107. package/src/components/DrawerNavigationItem.tsx +1 -1
  108. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +6 -5
  109. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +9 -7
  110. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +5 -5
  111. package/src/components/EntityCollectionTable/fields/VirtualTableNumberInput.tsx +12 -9
  112. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +2 -2
  113. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +1 -1
  114. package/src/components/EntityCollectionTable/table_bindings.tsx +5 -4
  115. package/src/components/EntityCollectionView/EntityCollectionView.tsx +6 -4
  116. package/src/components/EntityCollectionView/hooks/useCollectionInlineEditor.ts +1 -1
  117. package/src/components/EntityCollectionView/hooks/useKanbanDragAndDrop.ts +7 -6
  118. package/src/components/EntityDetailView.tsx +46 -24
  119. package/src/components/EntityEditView.tsx +51 -28
  120. package/src/components/EntityEditViewFormActions.tsx +4 -4
  121. package/src/components/EntityPreview.tsx +9 -4
  122. package/src/components/HomePage/HomePageDnD.tsx +3 -2
  123. package/src/components/PropertyCollectionView.tsx +1 -1
  124. package/src/components/PropertyIdCopyTooltip.tsx +1 -1
  125. package/src/components/RebaseLayout.tsx +5 -1
  126. package/src/components/RebaseNavigation.tsx +2 -2
  127. package/src/components/RebaseRouteDefs.tsx +4 -7
  128. package/src/components/RebaseShell.tsx +16 -13
  129. package/src/components/SearchIconsView.tsx +1 -8
  130. package/src/components/SelectableTable/SelectableTable.tsx +8 -11
  131. package/src/components/SelectableTable/SelectionStore.ts +1 -1
  132. package/src/components/SelectableTable/filters/BooleanFilterField.tsx +3 -3
  133. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +3 -3
  134. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +5 -5
  135. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +3 -3
  136. package/src/components/SideEntityProvider.tsx +2 -1
  137. package/src/components/admin/RolesView.tsx +7 -2
  138. package/src/components/admin/UsersView.tsx +12 -6
  139. package/src/components/app/Drawer.tsx +9 -1
  140. package/src/components/app/Scaffold.tsx +5 -1
  141. package/src/data_export/export/export.ts +17 -17
  142. package/src/data_import/components/DataNewPropertiesMapping.tsx +1 -1
  143. package/src/editor/components/editor-bubble.tsx +32 -9
  144. package/src/editor/components/image-bubble.tsx +27 -11
  145. package/src/editor/components/index.ts +3 -3
  146. package/src/editor/components/table-bubble.tsx +79 -17
  147. package/src/editor/extensions/HighlightDecorationExtension.ts +3 -2
  148. package/src/editor/nodeViews/ReactNodeView.tsx +1 -1
  149. package/src/editor/nodeViews/TaskItemComponent.tsx +9 -8
  150. package/src/editor/schema.ts +135 -59
  151. package/src/editor/selectors/link-selector.tsx +8 -5
  152. package/src/editor/useProseMirror.ts +2 -2
  153. package/src/editor/utils/remove_classes.ts +6 -5
  154. package/src/form/EntityForm.tsx +15 -15
  155. package/src/form/EntityFormActions.tsx +2 -2
  156. package/src/form/PropertyFieldBinding.tsx +64 -64
  157. package/src/form/components/FieldHelperText.tsx +4 -4
  158. package/src/form/components/StorageUploadProgress.tsx +2 -2
  159. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +1 -1
  160. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +1 -1
  161. package/src/form/field_bindings/BlockFieldBinding.tsx +54 -53
  162. package/src/form/field_bindings/KeyValueFieldBinding.tsx +290 -289
  163. package/src/form/field_bindings/MapFieldBinding.tsx +2 -2
  164. package/src/form/field_bindings/MultiSelectFieldBinding.tsx +2 -2
  165. package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +1 -1
  166. package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +1 -1
  167. package/src/form/field_bindings/ReferenceFieldBinding.tsx +8 -6
  168. package/src/form/field_bindings/RelationFieldBinding.tsx +4 -4
  169. package/src/form/field_bindings/RepeatFieldBinding.tsx +1 -1
  170. package/src/form/field_bindings/SelectFieldBinding.tsx +1 -1
  171. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +84 -84
  172. package/src/form/field_bindings/SwitchFieldBinding.tsx +16 -16
  173. package/src/form/field_bindings/TextFieldBinding.tsx +77 -73
  174. package/src/form/field_bindings/UserSelectFieldBinding.tsx +17 -17
  175. package/src/form/validation.ts +43 -43
  176. package/src/hooks/navigation/useBuildNavigationStateController.tsx +3 -5
  177. package/src/hooks/navigation/useResolvedCollections.ts +27 -7
  178. package/src/hooks/navigation/useResolvedViews.tsx +24 -44
  179. package/src/index.ts +2 -0
  180. package/src/preview/PropertyPreview.tsx +2 -2
  181. package/src/preview/components/ImagePreview.tsx +2 -1
  182. package/src/preview/components/UrlComponentPreview.tsx +11 -2
  183. package/src/preview/components/UserPreview.tsx +1 -1
  184. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +2 -2
  185. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +4 -4
  186. package/src/preview/property_previews/ArrayOfRelationsPreview.tsx +3 -3
  187. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +3 -3
  188. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +3 -2
  189. package/src/preview/property_previews/ArrayOneOfPreview.tsx +6 -8
  190. package/src/preview/property_previews/ArrayPropertyEnumPreview.tsx +1 -1
  191. package/src/preview/property_previews/ArrayPropertyPreview.tsx +3 -3
  192. package/src/preview/property_previews/MapPropertyPreview.tsx +4 -3
  193. package/src/preview/property_previews/NumberPropertyPreview.tsx +5 -3
  194. package/src/preview/property_previews/StringPropertyPreview.tsx +10 -8
  195. package/src/types/components/EntityFormActionsProps.tsx +1 -1
  196. package/src/types/components/EntityFormProps.tsx +2 -2
  197. package/src/types/fields.tsx +2 -2
  198. package/dist/CollectionEditorDialog-BXIh2AXg.js.map +0 -1
  199. package/dist/ContentHomePage-BQZWuOFb.js +0 -1784
  200. package/dist/ContentHomePage-BQZWuOFb.js.map +0 -1
  201. package/dist/ExportCollectionAction-CMdiiv1L.js.map +0 -1
  202. package/dist/PropertyEditView-BB5xjnhZ.js.map +0 -1
  203. package/dist/RoleChip-QtUFXeTp.js +0 -67
  204. package/dist/RoleChip-QtUFXeTp.js.map +0 -1
  205. package/dist/RolesView-CULIHWZ9.js +0 -437
  206. package/dist/RolesView-CULIHWZ9.js.map +0 -1
  207. package/dist/UsersView-D7_AtJ44.js +0 -408
  208. package/dist/UsersView-D7_AtJ44.js.map +0 -1
  209. package/dist/collection_editor/types/config_permissions.d.ts +0 -19
  210. package/dist/index-CoSNm3e3.js.map +0 -1
  211. package/dist/index-D5OQhv-T.js.map +0 -1
  212. package/dist/markdown-z2Ir7Cgo.js.map +0 -1
  213. package/dist/util-DtbWD7LF.js.map +0 -1
  214. package/src/collection_editor/types/config_permissions.ts +0 -20
@@ -2,6 +2,7 @@ import React, { useMemo } from "react";
2
2
  import {
3
3
  useRebaseRegistry
4
4
  } from "@rebasepro/core";
5
+ import { ErrorBoundary } from "@rebasepro/ui";
5
6
 
6
7
  import { RebaseAuthGate } from "./RebaseAuthGate";
7
8
  import { RebaseNavigation } from "./RebaseNavigation";
@@ -51,19 +52,21 @@ export function RebaseShell(props: RebaseShellProps) {
51
52
  return (
52
53
  <RebaseAuthGate>
53
54
  <RebaseNavigation>
54
- <RebaseRouteDefs
55
- layout={
56
- <RebaseLayout
57
- title={title}
58
- appBar={appBar}
59
- drawer={drawer}
60
- autoOpenDrawer={autoOpenDrawer}
61
- devViews={devViews}
62
- />
63
- }
64
- >
65
- {children}
66
- </RebaseRouteDefs>
55
+ <ErrorBoundary fullPage>
56
+ <RebaseRouteDefs
57
+ layout={
58
+ <RebaseLayout
59
+ title={title}
60
+ appBar={appBar}
61
+ drawer={drawer}
62
+ autoOpenDrawer={autoOpenDrawer}
63
+ devViews={devViews}
64
+ />
65
+ }
66
+ >
67
+ {children}
68
+ </RebaseRouteDefs>
69
+ </ErrorBoundary>
67
70
  </RebaseNavigation>
68
71
  </RebaseAuthGate>
69
72
  );
@@ -10,18 +10,11 @@ import {
10
10
  SearchBar,
11
11
  Tooltip
12
12
  } from "@rebasepro/ui";
13
- import { iconsSearch, iconSynonyms } from "@rebasepro/core";
13
+ import { iconsSearch } from "@rebasepro/core";
14
14
  import { useTranslation } from "@rebasepro/core";
15
15
 
16
16
  const UPDATE_SEARCH_INDEX_WAIT_MS = 220;
17
17
 
18
- if (iconSynonyms && process.env.NODE_ENV !== "production") {
19
- Object.keys(iconSynonyms).forEach((icon: string) => {
20
- if (!iconKeys.includes(icon)) {
21
- console.warn(`The icon ${icon} no longer exists. Remove it from \`iconSynonyms\``);
22
- }
23
- });
24
- }
25
18
 
26
19
  function toPascalCase(str: string): string {
27
20
  return str.split(/[-_]/).map(word => word.charAt(0).toUpperCase() + word.slice(1)).join('');
@@ -243,11 +243,11 @@ export const SelectableTable = function SelectableTable<M extends Record<string,
243
243
  ref={ref}>
244
244
 
245
245
  <VirtualTable
246
- data={data}
246
+ data={data as any}
247
247
  columns={columns}
248
248
  // @ts-ignore
249
249
  cellRenderer={cellRenderer}
250
- onRowClick={inlineEditing ? undefined : (onEntityClick ? onRowClick : undefined)}
250
+ onRowClick={inlineEditing ? undefined : (onEntityClick ? (onRowClick as any) : undefined)}
251
251
  onEndReached={loadNextPage}
252
252
  onResetPagination={resetPagination}
253
253
  error={dataLoadingError}
@@ -262,8 +262,8 @@ export const SelectableTable = function SelectableTable<M extends Record<string,
262
262
  initialScroll={initialScroll}
263
263
  onScroll={onScroll}
264
264
  checkFilterCombination={checkFilterCombination}
265
- createFilterField={filterable ? createFilterField : undefined}
266
- rowClassName={useCallback((entity: Entity<M>) => {
265
+ createFilterField={filterable ? (createFilterField as any) : undefined}
266
+ rowClassName={useCallback((entity: any) => {
267
267
  return highlightedRow?.(entity) ? "bg-surface-accent-50 dark:!bg-surface-accent-900" : "";
268
268
  }, [highlightedRow])}
269
269
  className="grow"
@@ -287,16 +287,13 @@ function createFilterField({
287
287
  column,
288
288
  hidden,
289
289
  setHidden
290
- }: FilterFormFieldProps<{
291
- resolvedProperty: Property,
292
- disabled: boolean,
293
- }>): React.ReactNode {
290
+ }: FilterFormFieldProps<any>): React.ReactNode {
294
291
 
295
292
  if (!column.custom) {
296
293
  return null;
297
294
  }
298
295
 
299
- const { resolvedProperty } = column.custom;
296
+ const { resolvedProperty } = column.custom as { resolvedProperty?: Property };
300
297
 
301
298
  const isArray = resolvedProperty?.type === "array";
302
299
  const ofVal = isArray && resolvedProperty ? resolvedProperty.of : undefined;
@@ -316,7 +313,7 @@ function createFilterField({
316
313
  hidden={hidden}
317
314
  setHidden={setHidden}/>;
318
315
  } else if (baseProperty.type === "relation" && baseProperty.relation) {
319
- return <RelationFilterField value={filterValue}
316
+ return <RelationFilterField value={filterValue as any}
320
317
  setValue={setFilterValue}
321
318
  name={id as string}
322
319
  relation={baseProperty.relation}
@@ -350,7 +347,7 @@ function createFilterField({
350
347
  }
351
348
 
352
349
  return (
353
- <div>{`Currently the filter field ${resolvedProperty.type} is not supported`}</div>
350
+ <div>{`Currently the filter field ${resolvedProperty?.type} is not supported`}</div>
354
351
  );
355
352
  }
356
353
 
@@ -43,7 +43,7 @@ export type SelectionStore = ReturnType<typeof createSelectionStore>;
43
43
  * `selected` boolean actually changes (not on every store update).
44
44
  */
45
45
  export function useCellSelected(
46
- store: SelectionStore,
46
+ store: { getSnapshot: () => SelectedCellProps<any> | undefined; subscribe: (listener: () => void) => () => void },
47
47
  propertyKey: string,
48
48
  entityPath: string,
49
49
  entityId: string | number
@@ -5,8 +5,8 @@ import { useTranslation } from "@rebasepro/core";
5
5
 
6
6
  interface BooleanFieldProps {
7
7
  name: string,
8
- value?: [op: VirtualTableWhereFilterOp, fieldValue: any];
9
- setValue: (value?: [op: VirtualTableWhereFilterOp, newValue: any]) => void;
8
+ value?: [op: VirtualTableWhereFilterOp, fieldValue: unknown];
9
+ setValue: (value?: [op: VirtualTableWhereFilterOp, newValue: unknown]) => void;
10
10
  title?: string;
11
11
  }
12
12
 
@@ -37,7 +37,7 @@ export function BooleanFilterField({
37
37
  <div className="w-full">
38
38
  <BooleanSwitchWithLabel
39
39
  size={"medium"}
40
- value={valueSetToTrue}
40
+ value={valueSetToTrue as boolean | null}
41
41
  allowIndeterminate={true}
42
42
  onValueChange={(v: boolean | null) => updateFilter(v === null ? undefined : v)}
43
43
  label={!valueSet
@@ -6,8 +6,8 @@ import { useCustomizationController } from "@rebasepro/core";
6
6
  interface DateTimeFilterFieldProps {
7
7
  name: string,
8
8
  mode?: "date" | "date_time",
9
- value?: [op: VirtualTableWhereFilterOp, fieldValue: any];
10
- setValue: (value?: [op: VirtualTableWhereFilterOp, newValue: any]) => void;
9
+ value?: [op: VirtualTableWhereFilterOp, fieldValue: unknown];
10
+ setValue: (value?: [op: VirtualTableWhereFilterOp, newValue: unknown]) => void;
11
11
  isArray?: boolean;
12
12
  title?: string;
13
13
  timezone?: string;
@@ -46,7 +46,7 @@ export function DateTimeFilterField({
46
46
 
47
47
  const [fieldOperation, fieldValue] = value || [possibleOperations[0], undefined];
48
48
  const [operation, setOperation] = useState<VirtualTableWhereFilterOp | "is-null">(fieldOperation === "==" && fieldValue === null ? "is-null" : fieldOperation);
49
- const [internalValue, setInternalValue] = useState<Date | null | undefined>(fieldValue);
49
+ const [internalValue, setInternalValue] = useState<Date | null | undefined>(fieldValue as Date | null | undefined);
50
50
 
51
51
  const isNullOperation = operation === "is-null";
52
52
 
@@ -11,8 +11,8 @@ import { useCollectionRegistryController } from "../../../index";
11
11
 
12
12
  interface ReferenceFilterFieldProps {
13
13
  name: string,
14
- value?: [op: VirtualTableWhereFilterOp, fieldValue: any];
15
- setValue: (filterValue?: [VirtualTableWhereFilterOp, any]) => void;
14
+ value?: [op: VirtualTableWhereFilterOp, fieldValue: unknown];
15
+ setValue: (filterValue?: [VirtualTableWhereFilterOp, unknown]) => void;
16
16
  isArray?: boolean;
17
17
  path?: string;
18
18
  title?: string;
@@ -60,7 +60,7 @@ export function ReferenceFilterField({
60
60
 
61
61
  const [fieldOperation, fieldValue] = value || [possibleOperations[0], undefined];
62
62
  const [operation, setOperation] = useState<VirtualTableWhereFilterOp>(fieldOperation);
63
- const [internalValue, setInternalValue] = useState<EntityReference | EntityReference[] | undefined | null>(fieldValue);
63
+ const [internalValue, setInternalValue] = useState<EntityReference | EntityReference[] | undefined | null>(fieldValue as EntityReference | EntityReference[] | undefined | null);
64
64
 
65
65
  const selectedEntityIds = internalValue
66
66
  ? (Array.isArray(internalValue) ? internalValue.map((ref) => {
@@ -104,11 +104,11 @@ export function ReferenceFilterField({
104
104
  return path ? collectionRegistryController.getCollection(path) : undefined;
105
105
  }, [path]);
106
106
 
107
- const onSingleEntitySelected = (entity: Entity<any>) => {
107
+ const onSingleEntitySelected = (entity: Entity<Record<string, unknown>>) => {
108
108
  updateFilter(operation, getReferenceFrom(entity));
109
109
  };
110
110
 
111
- const onMultipleEntitiesSelected = (entities: Entity<any>[]) => {
111
+ const onMultipleEntitiesSelected = (entities: Entity<Record<string, unknown>>[]) => {
112
112
  updateFilter(operation, entities.map(e => getReferenceFrom(e)));
113
113
  };
114
114
 
@@ -9,8 +9,8 @@ import { useTranslation } from "@rebasepro/core";
9
9
  interface StringNumberFilterFieldProps {
10
10
  name: string,
11
11
  type: "string" | "number";
12
- value?: [op: VirtualTableWhereFilterOp, fieldValue: any];
13
- setValue: (value?: [op: VirtualTableWhereFilterOp, newValue: any]) => void;
12
+ value?: [op: VirtualTableWhereFilterOp, fieldValue: unknown];
13
+ setValue: (value?: [op: VirtualTableWhereFilterOp, newValue: unknown]) => void;
14
14
  isArray?: boolean;
15
15
  enumValues?: EnumValueConfig[];
16
16
  title?: string;
@@ -57,7 +57,7 @@ export function StringNumberFilterField({
57
57
 
58
58
  const [fieldOperation, fieldValue] = value || [possibleOperations[0], undefined];
59
59
  const [operation, setOperation] = useState<VirtualTableWhereFilterOp | "is-null">(fieldOperation === "==" && fieldValue === null ? "is-null" : fieldOperation);
60
- const [internalValue, setInternalValue] = useState<string | number | string[] | number[] | null | undefined>(fieldValue);
60
+ const [internalValue, setInternalValue] = useState<string | number | string[] | number[] | null | undefined>(fieldValue as string | number | string[] | number[] | null | undefined);
61
61
 
62
62
  const isNullOperation = operation === "is-null";
63
63
 
@@ -1,3 +1,4 @@
1
+ import type { SideEntityController } from "@rebasepro/types";
1
2
  import React from "react";
2
3
  import { useBuildSideEntityController } from "../hooks/useBuildSideEntityController";
3
4
  import { useBuildSideDialogsController } from "../hooks/useBuildSideDialogsController";
@@ -68,7 +69,7 @@ export function SideEntityProvider({ children }: { children: React.ReactNode })
68
69
  * Internal component that auto-registers side entity and breadcrumbs
69
70
  * into the Studio bridge. Must be a child of BreadcrumbsProvider.
70
71
  */
71
- function BridgeAutoRegistrar({ sideEntityController }: { sideEntityController: any }) {
72
+ function BridgeAutoRegistrar({ sideEntityController }: { sideEntityController: SideEntityController }) {
72
73
  const breadcrumbs = useBreadcrumbsController();
73
74
  useBridgeRegistration("sideEntityController", sideEntityController);
74
75
  useBridgeRegistration("breadcrumbs", breadcrumbs);
@@ -1,7 +1,7 @@
1
1
 
2
2
  import React, { useState } from "react";
3
3
  import { useCollectionRegistryController } from "../../index";
4
- import { useSnackbarController, useTranslation } from "@rebasepro/core";
4
+ import { useSnackbarController, useTranslation, useInternalUserManagementController } from "@rebasepro/core";
5
5
  import { getDataSourceCapabilities, Role, SecurityRule, UserManagementDelegate } from "@rebasepro/types";
6
6
  import { useBreadcrumbsController } from "../../index";
7
7
  import {
@@ -38,7 +38,12 @@ import { ConfirmationDialog } from "@rebasepro/core";
38
38
  // ============================================
39
39
  // RolesView Component
40
40
  // ============================================
41
- export function RolesView({ userManagement }: { userManagement: UserManagementDelegate }) {
41
+ export function RolesView({ userManagement: userManagementProp }: { userManagement?: UserManagementDelegate }) {
42
+ const userManagementContext = useInternalUserManagementController();
43
+ const userManagement = userManagementProp ?? userManagementContext;
44
+ if (!userManagement) {
45
+ return null;
46
+ }
42
47
  const { roles, saveRole, deleteRole, loading, allowDefaultRolesCreation, rolesError } = userManagement;
43
48
  const snackbarController = useSnackbarController();
44
49
  const { t } = useTranslation();
@@ -1,7 +1,7 @@
1
1
 
2
2
  import React, { useState, useEffect, useCallback, useRef } from "react";
3
3
  import { User } from "@rebasepro/types";
4
- import { useSnackbarController, useAuthController, useTranslation } from "@rebasepro/core";
4
+ import { useSnackbarController, useAuthController, useTranslation, useInternalUserManagementController } from "@rebasepro/core";
5
5
  import { useBreadcrumbsController } from "../../index";
6
6
  import {
7
7
  Alert,
@@ -50,9 +50,14 @@ const PAGE_SIZE = 25;
50
50
  // ============================================
51
51
  // UsersView Component
52
52
  // ============================================
53
- export function UsersView({ userManagement }: {
54
- userManagement: UserManagementDelegate;
53
+ export function UsersView({ userManagement: userManagementProp }: {
54
+ userManagement?: UserManagementDelegate;
55
55
  }) {
56
+ const userManagementContext = useInternalUserManagementController();
57
+ const userManagement = userManagementProp ?? userManagementContext;
58
+ if (!userManagement) {
59
+ return null;
60
+ }
56
61
  const { roles, saveUser, createUser, deleteUser, resetPassword, loading: delegateLoading, bootstrapAdmin, usersError } = userManagement;
57
62
  const snackbarController = useSnackbarController();
58
63
  const { user: loggedInUser } = useAuthController();
@@ -212,8 +217,8 @@ message: error instanceof Error ? error.message : "Failed to load users" });
212
217
 
213
218
  const totalPages = Math.max(1, Math.ceil(displayTotal / PAGE_SIZE));
214
219
 
215
- // Check if any admin exists
216
- const hasAdmin = allUsers.some(u => u.roles?.includes("admin"));
220
+ // Check if any admin exists (use dedicated flag from delegate, or fallback to array scan)
221
+ const hasAdmin = userManagement.hasAdminUsers ?? allUsers.some(u => u.roles?.includes("admin"));
217
222
 
218
223
  const handleBootstrap = async () => {
219
224
  if (!bootstrapAdmin) return;
@@ -394,9 +399,10 @@ roles: ["w-16", "w-16"] }
394
399
  </Tooltip>
395
400
  )}
396
401
  {deleteUser && (
397
- <Tooltip asChild title={t("delete_this_user")}>
402
+ <Tooltip asChild title={loggedInUser?.uid === user.uid ? (t("cannot_delete_own_account") || "Cannot delete your own account") : t("delete_this_user")}>
398
403
  <IconButton
399
404
  size="small"
405
+ disabled={loggedInUser?.uid === user.uid}
400
406
  onClick={(e) => {
401
407
  e.stopPropagation();
402
408
  setUserToDelete(user);
@@ -13,6 +13,7 @@ export function Drawer({
13
13
  title,
14
14
  logo,
15
15
  logoDestination,
16
+ footerActions,
16
17
  className,
17
18
  style
18
19
  }: {
@@ -20,10 +21,17 @@ export function Drawer({
20
21
  title?: React.ReactNode,
21
22
  logo?: string,
22
23
  logoDestination?: string,
24
+ /**
25
+ * Custom content for the drawer footer actions area (language, theme, user menu).
26
+ * - `undefined` — renders the default `DrawerFooterActions`.
27
+ * - `null` — renders nothing (hides the footer actions).
28
+ * - `ReactNode` — renders the provided custom content.
29
+ */
30
+ footerActions?: React.ReactNode | null,
23
31
  className?: string,
24
32
  style?: React.CSSProperties
25
33
  }) {
26
- const usedChildren = children ?? <DefaultDrawer title={title} logo={logo} logoDestination={logoDestination} className={className} style={style}/>;
34
+ const usedChildren = children ?? <DefaultDrawer title={title} logo={logo} logoDestination={logoDestination} footerActions={footerActions} className={className} style={style}/>;
27
35
  return <>{usedChildren}</>;
28
36
  }
29
37
 
@@ -74,7 +74,11 @@ export const Scaffold = React.memo<PropsWithChildren<ScaffoldProps>>(
74
74
  const [onHover, setOnHover] = React.useState(false);
75
75
 
76
76
  const setOnHoverTrue = useCallback(() => setOnHover(true), []);
77
- const setOnHoverFalse = useCallback(() => setOnHover(false), []);
77
+ const setOnHoverFalse = useCallback(() => {
78
+ // Don't collapse the drawer while a popover/dropdown is open
79
+ if (document.querySelector("[data-radix-popper-content-wrapper]")) return;
80
+ setOnHover(false);
81
+ }, []);
78
82
 
79
83
  const handleDrawerOpen = useCallback(() => {
80
84
  setDrawerOpen(true);
@@ -8,7 +8,7 @@ interface Header {
8
8
 
9
9
  export interface DownloadEntitiesExportParams<M extends Record<string, unknown>> {
10
10
  data: Entity<M>[];
11
- additionalData: Record<string, any>[] | undefined;
11
+ additionalData: Record<string, unknown>[] | undefined;
12
12
  properties: Properties;
13
13
  propertiesOrder: string[] | undefined;
14
14
  name: string;
@@ -52,14 +52,14 @@ export function downloadEntitiesExport<M extends Record<string, unknown>>({
52
52
  }
53
53
  }
54
54
 
55
- export function getEntityCSVExportableData(data: Entity<any>[],
56
- additionalData: Record<string, any>[] | undefined,
55
+ export function getEntityCSVExportableData(data: Entity<Record<string, unknown>>[],
56
+ additionalData: Record<string, unknown>[] | undefined,
57
57
  properties: Properties,
58
58
  headers: Header[],
59
59
  dateExportType: "timestamp" | "string"
60
60
  ) {
61
61
 
62
- const mergedData: any[] = data.map(e => ({
62
+ const mergedData: Record<string, unknown>[] = data.map(e => ({
63
63
  id: e.id,
64
64
  ...processValuesForExport(e.values, properties, "csv", dateExportType)
65
65
  }));
@@ -76,13 +76,13 @@ export function getEntityCSVExportableData(data: Entity<any>[],
76
76
  });
77
77
  }
78
78
 
79
- export function getEntityJsonExportableData(data: Entity<any>[],
80
- additionalData: Record<string, any>[] | undefined,
79
+ export function getEntityJsonExportableData(data: Entity<Record<string, unknown>>[],
80
+ additionalData: Record<string, unknown>[] | undefined,
81
81
  properties: Properties,
82
82
  dateExportType: "timestamp" | "string"
83
83
  ) {
84
84
 
85
- const mergedData: any[] = data.map(e => ({
85
+ const mergedData: Record<string, unknown>[] = data.map(e => ({
86
86
  id: e.id,
87
87
  ...processValuesForExport(e.values, properties, "json", dateExportType)
88
88
  }));
@@ -154,15 +154,15 @@ function getHeaders(property: Property, propertyKey: string, prefix = ""): Heade
154
154
  }
155
155
  }
156
156
 
157
- function processValueForExport(inputValue: any,
157
+ function processValueForExport(inputValue: unknown,
158
158
  property: Property,
159
159
  exportType: "csv" | "json",
160
160
  dateExportType: "timestamp" | "string"
161
- ): any {
161
+ ): unknown {
162
162
 
163
- let value;
163
+ let value: unknown;
164
164
  if (property.type === "map" && property.properties) {
165
- value = processValuesForExport(inputValue, property.properties as Properties, exportType, dateExportType);
165
+ value = processValuesForExport(inputValue as Record<string, unknown>, property.properties as Properties, exportType, dateExportType);
166
166
  } else if (property.type === "array") {
167
167
  if (property.of && Array.isArray(inputValue)) {
168
168
  if (Array.isArray(property.of)) {
@@ -178,7 +178,7 @@ function processValueForExport(inputValue: any,
178
178
  } else {
179
179
  value = inputValue;
180
180
  }
181
- } else if (property.type === "reference" && inputValue && inputValue.isEntityReference && inputValue.isEntityReference()) {
181
+ } else if (property.type === "reference" && inputValue && typeof inputValue === "object" && "isEntityReference" in inputValue && typeof (inputValue as EntityReference).isEntityReference === "function" && (inputValue as EntityReference).isEntityReference()) {
182
182
  const ref = inputValue ? inputValue as EntityReference : undefined;
183
183
  value = ref ? ref.fullPath : null;
184
184
  } else if (property.type === "date" && inputValue instanceof Date) {
@@ -191,11 +191,11 @@ function processValueForExport(inputValue: any,
191
191
  }
192
192
 
193
193
  function processValuesForExport<M extends Record<string, unknown>>
194
- (inputValues: Record<keyof M, any>,
194
+ (inputValues: Record<string, unknown>,
195
195
  properties: Properties,
196
196
  exportType: "csv" | "json",
197
197
  dateExportType: "timestamp" | "string"
198
- ): Record<keyof M, any> {
198
+ ): Record<string, unknown> {
199
199
  const updatedValues = Object.entries(properties)
200
200
  .map(([key, property]) => {
201
201
  const inputValue = inputValues && (inputValues)[key];
@@ -204,14 +204,14 @@ function processValuesForExport<M extends Record<string, unknown>>
204
204
  return ({ [key]: updatedValue });
205
205
  })
206
206
  .reduce((a, b) => ({ ...a,
207
- ...b }), {}) as Record<keyof M, any>;
207
+ ...b }), {}) as Record<string, unknown>;
208
208
  return { ...inputValues,
209
209
  ...updatedValues };
210
210
  }
211
211
 
212
- function entryToCSVRow(entry: any[]) {
212
+ function entryToCSVRow(entry: unknown[]) {
213
213
  return entry
214
- .map((v: any) => {
214
+ .map((v: unknown) => {
215
215
  if (v === null || v === undefined) return "";
216
216
  if (Array.isArray(v))
217
217
  return "\"" + JSON.stringify(v).replaceAll("\"", "\"\"") + "\"";
@@ -143,7 +143,7 @@ export function DataNewPropertiesMapping({
143
143
  defaultValue={getIn(importConfig.defaultValues, key)}
144
144
  onValueChange={(value) => {
145
145
  const newValues = setIn(importConfig.defaultValues, key, value);
146
- importConfig.setDefaultValues(newValues);
146
+ importConfig.setDefaultValues(newValues as Record<string, any>);
147
147
  }}/>
148
148
  </TableCell>
149
149
  </TableRow>;
@@ -1,17 +1,32 @@
1
1
  import { forwardRef, type ReactNode, useEffect, useRef, useState } from "react";
2
2
  import { useProseMirrorContext } from "../hooks/useProseMirrorContext";
3
- import { autoUpdate, computePosition, flip, offset, shift, type VirtualElement } from "@floating-ui/dom";
3
+ import {
4
+ autoUpdate,
5
+ computePosition,
6
+ flip,
7
+ offset,
8
+ shift,
9
+ type VirtualElement,
10
+ type Placement
11
+ } from "@floating-ui/dom";
4
12
  import { NodeSelection } from "prosemirror-state";
5
13
 
6
14
  export interface EditorBubbleProps {
7
15
  children: ReactNode;
8
- options?: any;
16
+ options?: { placement?: Placement; offset?: number };
9
17
  className?: string;
10
18
  }
11
19
 
12
20
  export const EditorBubble = forwardRef<HTMLDivElement, EditorBubbleProps>(
13
- ({ children, options, className }, ref) => {
14
- const { view, state } = useProseMirrorContext();
21
+ ({
22
+ children,
23
+ options,
24
+ className
25
+ }, ref) => {
26
+ const {
27
+ view,
28
+ state
29
+ } = useProseMirrorContext();
15
30
  const menuRef = useRef<HTMLDivElement>(null);
16
31
  const [show, setShow] = useState(false);
17
32
 
@@ -43,7 +58,10 @@ export const EditorBubble = forwardRef<HTMLDivElement, EditorBubbleProps>(
43
58
  useEffect(() => {
44
59
  if (!show || !view || !state || !menuRef.current) return;
45
60
 
46
- const { from, to } = state.selection;
61
+ const {
62
+ from,
63
+ to
64
+ } = state.selection;
47
65
 
48
66
  // Fallback for end selection coords
49
67
  let start = view.coordsAtPos(from);
@@ -83,7 +101,10 @@ export const EditorBubble = forwardRef<HTMLDivElement, EditorBubbleProps>(
83
101
  placement: options?.placement || "top",
84
102
  middleware: [offset(options?.offset || 8), flip(), shift()],
85
103
  strategy: "fixed"
86
- }).then(({ x, y }) => {
104
+ }).then(({
105
+ x,
106
+ y
107
+ }) => {
87
108
  if (menuRef.current) {
88
109
  Object.assign(menuRef.current.style, {
89
110
  left: `${x}px`,
@@ -102,9 +123,11 @@ export const EditorBubble = forwardRef<HTMLDivElement, EditorBubbleProps>(
102
123
  <div
103
124
  ref={menuRef}
104
125
  className={className}
105
- style={{ position: "fixed",
106
- zIndex: 9999,
107
- visibility: "hidden" }}
126
+ style={{
127
+ position: "fixed",
128
+ zIndex: 9999,
129
+ visibility: "hidden"
130
+ }}
108
131
  onMouseDown={(e) => {
109
132
  e.preventDefault(); // Don't lose focus inside ProseMirror
110
133
  }}
@@ -1,18 +1,24 @@
1
1
  import { forwardRef, useEffect, useRef, useState } from "react";
2
2
  import { useProseMirrorContext } from "../hooks/useProseMirrorContext";
3
- import { autoUpdate, computePosition, flip, offset, shift, type VirtualElement } from "@floating-ui/dom";
3
+ import { autoUpdate, computePosition, flip, offset, shift, type VirtualElement, type Placement } from "@floating-ui/dom";
4
4
  import { NodeSelection } from "prosemirror-state";
5
5
  import { TextField, defaultBorderMixin, Typography, cls } from "@rebasepro/ui";
6
6
  import { useTranslation } from "@rebasepro/core";
7
7
 
8
8
  export interface ImageBubbleProps {
9
- options?: any;
9
+ options?: { placement?: Placement; offset?: number };
10
10
  className?: string;
11
11
  }
12
12
 
13
13
  export const ImageBubble = forwardRef<HTMLDivElement, ImageBubbleProps>(
14
- ({ options, className }, ref) => {
15
- const { view, state } = useProseMirrorContext();
14
+ ({
15
+ options,
16
+ className
17
+ }, ref) => {
18
+ const {
19
+ view,
20
+ state
21
+ } = useProseMirrorContext();
16
22
  const { t } = useTranslation();
17
23
  const menuRef = useRef<HTMLDivElement>(null);
18
24
  const [show, setShow] = useState(false);
@@ -23,8 +29,10 @@ export const ImageBubble = forwardRef<HTMLDivElement, ImageBubbleProps>(
23
29
  useEffect(() => {
24
30
  if (!view) return;
25
31
  const handleContextMenu = (e: MouseEvent) => {
26
- const posInfo = view.posAtCoords({ left: e.clientX,
27
- top: e.clientY });
32
+ const posInfo = view.posAtCoords({
33
+ left: e.clientX,
34
+ top: e.clientY
35
+ });
28
36
  if (posInfo && posInfo.inside >= 0) {
29
37
  const node = view.state.doc.nodeAt(posInfo.inside);
30
38
  if (node && node.type.name === "image") {
@@ -56,7 +64,10 @@ top: e.clientY });
56
64
  useEffect(() => {
57
65
  if (!show || !view || !state || !menuRef.current) return;
58
66
 
59
- const { from, to } = state.selection;
67
+ const {
68
+ from,
69
+ to
70
+ } = state.selection;
60
71
  let start = view.coordsAtPos(from);
61
72
  let end = view.coordsAtPos(to);
62
73
 
@@ -92,7 +103,10 @@ top: e.clientY });
92
103
  placement: options?.placement || "bottom",
93
104
  middleware: [offset(options?.offset || 8), flip(), shift()],
94
105
  strategy: "fixed"
95
- }).then(({ x, y }) => {
106
+ }).then(({
107
+ x,
108
+ y
109
+ }) => {
96
110
  if (menuRef.current) {
97
111
  Object.assign(menuRef.current.style, {
98
112
  left: `${x}px`,
@@ -126,9 +140,11 @@ top: e.clientY });
126
140
  return (
127
141
  <div
128
142
  ref={menuRef}
129
- style={{ visibility: "hidden",
130
- position: "fixed",
131
- zIndex: 50 }}
143
+ style={{
144
+ visibility: "hidden",
145
+ position: "fixed",
146
+ zIndex: 50
147
+ }}
132
148
  className={cls("flex flex-col gap-1.5 p-2 w-56 max-w-[90vw] rounded-lg border bg-white dark:bg-surface-800 shadow-lg", defaultBorderMixin, className)}
133
149
  onMouseDown={(e) => {
134
150
  // Prevent mousedown from stealing focus from inputs
@@ -6,9 +6,9 @@ export { TableBubble } from "./table-bubble";
6
6
 
7
7
  export type JSONContent = {
8
8
  type?: string;
9
- attrs?: Record<string, any>;
9
+ attrs?: Record<string, unknown>;
10
10
  content?: JSONContent[];
11
- marks?: { type: string; attrs?: Record<string, any> }[];
11
+ marks?: { type: string; attrs?: Record<string, unknown> }[];
12
12
  text?: string;
13
- [key: string]: any;
13
+ [key: string]: unknown;
14
14
  };