@rebasepro/admin-types 0.10.1-canary.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 (72) hide show
  1. package/LICENSE +21 -0
  2. package/dist/admin_collection.d.ts +464 -0
  3. package/dist/augment.d.ts +66 -0
  4. package/dist/collections.d.ts +226 -0
  5. package/dist/controllers/analytics_controller.d.ts +7 -0
  6. package/dist/controllers/auth.d.ts +110 -0
  7. package/dist/controllers/customization_controller.d.ts +61 -0
  8. package/dist/controllers/dialogs_controller.d.ts +36 -0
  9. package/dist/controllers/index.d.ts +10 -0
  10. package/dist/controllers/local_config_persistence.d.ts +20 -0
  11. package/dist/controllers/navigation.d.ts +225 -0
  12. package/dist/controllers/registry.d.ts +80 -0
  13. package/dist/controllers/side_dialogs_controller.d.ts +67 -0
  14. package/dist/controllers/side_panel_controller.d.ts +97 -0
  15. package/dist/controllers/snackbar.d.ts +24 -0
  16. package/dist/index.d.ts +18 -0
  17. package/dist/index.es.js +92 -0
  18. package/dist/index.es.js.map +1 -0
  19. package/dist/react_component_ref.d.ts +43 -0
  20. package/dist/rebase_context.d.ts +68 -0
  21. package/dist/types/breadcrumbs.d.ts +26 -0
  22. package/dist/types/builders.d.ts +15 -0
  23. package/dist/types/component_overrides.d.ts +196 -0
  24. package/dist/types/entity_actions.d.ts +105 -0
  25. package/dist/types/entity_link_builder.d.ts +7 -0
  26. package/dist/types/entity_views.d.ts +95 -0
  27. package/dist/types/export_import.d.ts +21 -0
  28. package/dist/types/formex.d.ts +40 -0
  29. package/dist/types/index.d.ts +15 -0
  30. package/dist/types/locales.d.ts +4 -0
  31. package/dist/types/modify_collections.d.ts +5 -0
  32. package/dist/types/plugins.d.ts +277 -0
  33. package/dist/types/property_config.d.ts +74 -0
  34. package/dist/types/property_options.d.ts +154 -0
  35. package/dist/types/slots.d.ts +263 -0
  36. package/dist/types/translations.d.ts +915 -0
  37. package/dist/types/user_management_delegate.d.ts +22 -0
  38. package/package.json +103 -0
  39. package/src/admin_collection.ts +582 -0
  40. package/src/augment.ts +60 -0
  41. package/src/collections.ts +256 -0
  42. package/src/controllers/analytics_controller.tsx +57 -0
  43. package/src/controllers/auth.ts +121 -0
  44. package/src/controllers/customization_controller.tsx +72 -0
  45. package/src/controllers/dialogs_controller.tsx +37 -0
  46. package/src/controllers/index.ts +10 -0
  47. package/src/controllers/local_config_persistence.tsx +22 -0
  48. package/src/controllers/navigation.ts +264 -0
  49. package/src/controllers/registry.ts +96 -0
  50. package/src/controllers/side_dialogs_controller.tsx +82 -0
  51. package/src/controllers/side_panel_controller.tsx +112 -0
  52. package/src/controllers/snackbar.ts +29 -0
  53. package/src/index.ts +20 -0
  54. package/src/react_component_ref.ts +52 -0
  55. package/src/rebase_context.ts +81 -0
  56. package/src/types/breadcrumbs.ts +27 -0
  57. package/src/types/builders.ts +18 -0
  58. package/src/types/component_overrides.ts +244 -0
  59. package/src/types/entity_actions.tsx +127 -0
  60. package/src/types/entity_link_builder.ts +8 -0
  61. package/src/types/entity_views.tsx +114 -0
  62. package/src/types/export_import.ts +26 -0
  63. package/src/types/formex.ts +45 -0
  64. package/src/types/index.ts +15 -0
  65. package/src/types/locales.ts +81 -0
  66. package/src/types/modify_collections.tsx +6 -0
  67. package/src/types/plugins.tsx +346 -0
  68. package/src/types/property_config.tsx +95 -0
  69. package/src/types/property_options.ts +169 -0
  70. package/src/types/slots.tsx +309 -0
  71. package/src/types/translations.ts +1026 -0
  72. package/src/types/user_management_delegate.ts +23 -0
@@ -0,0 +1,81 @@
1
+ import type { AnalyticsController } from "./controllers/analytics_controller";
2
+ import type { AuthController } from "./controllers/auth";
3
+ import type { UserConfigurationPersistence } from "./controllers/local_config_persistence";
4
+ import type { DatabaseAdmin } from "@rebasepro/types";
5
+ import type { RebaseCallContext } from "@rebasepro/types";
6
+ import type { User } from "@rebasepro/types";
7
+
8
+ /**
9
+ * Context that includes the internal controllers and contexts used by the app.
10
+ * Some controllers and context included in this context can be accessed
11
+ * directly from their respective hooks.
12
+ * @group Hooks and utilities
13
+ * @see useRebaseContext
14
+ */
15
+ export type RebaseContext<USER extends User = User, AuthControllerType extends AuthController<USER> = AuthController<USER>> = RebaseCallContext<USER> & {
16
+
17
+ authController: AuthControllerType;
18
+
19
+ /**
20
+ * Controller mapping strings to collections
21
+ */
22
+ collectionRegistryController?: import("@rebasepro/types").CollectionRegistryController;
23
+
24
+ /**
25
+ * Controller for navigation state
26
+ */
27
+ navigationStateController?: import("./controllers/navigation").NavigationStateController;
28
+
29
+ /**
30
+ * Controller for side dialogs (side sheets)
31
+ */
32
+ sideDialogsController?: import("./controllers/side_dialogs_controller").SideDialogsController;
33
+
34
+ /**
35
+ * Controller to open the side panel displaying entity forms
36
+ */
37
+ sidePanelController?: import("./controllers/side_panel_controller").SidePanelController;
38
+
39
+ /**
40
+ * Controller resolving URLs in the CMS
41
+ */
42
+ urlController?: import("./controllers/navigation").UrlController;
43
+
44
+ /**
45
+ * Controller to handle simple confirmation and alert dialogs
46
+ */
47
+ dialogsController?: import("./controllers/dialogs_controller").DialogsController;
48
+
49
+ /**
50
+ * Controller for CMS customization
51
+ */
52
+ customizationController?: import("./controllers/customization_controller").CustomizationController;
53
+
54
+ /**
55
+ * Controller for effective role
56
+ */
57
+ effectiveRoleController?: { effectiveRole: string | null, setEffectiveRole: (role: string | null) => void };
58
+
59
+ /**
60
+ * Use this controller to access data stored in the browser for the user
61
+ */
62
+ userConfigPersistence?: UserConfigurationPersistence;
63
+
64
+ /**
65
+ * Callback to send analytics events
66
+ */
67
+ analyticsController?: AnalyticsController;
68
+
69
+
70
+ /**
71
+ * Administrative database operations (SQL, schema discovery).
72
+ * Only available in developer/admin contexts.
73
+ */
74
+ databaseAdmin?: DatabaseAdmin;
75
+
76
+ /**
77
+ * Controller for snackbars
78
+ */
79
+ snackbarController?: import("./controllers/snackbar").SnackbarController;
80
+
81
+ };
@@ -0,0 +1,27 @@
1
+ export interface BreadcrumbEntry {
2
+ title: string;
3
+ url: string;
4
+ /**
5
+ * Optional entity count for collection breadcrumbs.
6
+ * - undefined: not applicable (e.g., entity breadcrumb, custom view)
7
+ * - null: loading
8
+ * - number: loaded count
9
+ */
10
+ count?: number | null;
11
+ /**
12
+ * Unique identifier for this breadcrumb (e.g., collection path).
13
+ * Used to update count without replacing entire breadcrumb array.
14
+ */
15
+ id?: string;
16
+ }
17
+
18
+ export interface BreadcrumbsController {
19
+ breadcrumbs: BreadcrumbEntry[];
20
+ set: (props: {
21
+ breadcrumbs: BreadcrumbEntry[];
22
+ }) => void;
23
+ /**
24
+ * Update the count for a specific breadcrumb by ID.
25
+ */
26
+ updateCount: (id: string, count: number | null | undefined) => void;
27
+ }
@@ -0,0 +1,18 @@
1
+ import type { AuthController } from "../controllers/auth";
2
+ import type { RebaseData } from "@rebasepro/types";
3
+ import type { User } from "@rebasepro/types";
4
+
5
+ import type { AppView } from "../controllers/navigation";
6
+ import type { AdminCollection } from "@rebasepro/admin-types";
7
+
8
+ export type CollectionConfigsBuilder<EC extends AdminCollection = AdminCollection> = (params: {
9
+ user: User | null,
10
+ authController: AuthController,
11
+ data: RebaseData
12
+ }) => EC[] | Promise<EC[]>;
13
+
14
+ export type AppViewsBuilder = (params: {
15
+ user: User | null,
16
+ authController: AuthController,
17
+ data: RebaseData
18
+ }) => AppView[] | Promise<AppView[]>;
@@ -0,0 +1,244 @@
1
+ import type React from "react";
2
+ import type { Property } from "@rebasepro/types";
3
+ import type { WhereFilterOp } from "@rebasepro/types";
4
+
5
+ // ── Scoped component name unions ──────────────────────────────────────
6
+
7
+ /**
8
+ * Components that can only be overridden at the **app level** via the
9
+ * `components` prop on `<Rebase>`.
10
+ *
11
+ * These are shell-level / global components that exist outside of any
12
+ * specific collection context.
13
+ *
14
+ * @group Component Overrides
15
+ */
16
+ export type AppComponentName =
17
+ // ── Shell / Layout ──
18
+ | "Shell.AppBar"
19
+ | "Shell.Drawer"
20
+ | "Shell.DrawerNavigationItem"
21
+ | "Shell.DrawerNavigationGroup"
22
+
23
+ // ── Home Page ──
24
+ | "HomePage"
25
+ | "HomePage.CollectionCard"
26
+
27
+ // ── Auth ──
28
+ | "Auth.LoginView";
29
+
30
+ /**
31
+ * Components that can be overridden at the **collection level**
32
+ * (on an individual collection definition) or at the **app level**
33
+ * (as a default for all collections).
34
+ *
35
+ * When set at the app level, these act as defaults. When set on a
36
+ * specific collection, they override the app-level default for that
37
+ * collection only.
38
+ *
39
+ * @group Component Overrides
40
+ */
41
+ export type CollectionComponentName =
42
+ // ── Collection View ──
43
+ | "Collection.View"
44
+ | "Collection.Table"
45
+ | "Collection.Card"
46
+ | "Collection.EmptyState"
47
+ | "Collection.Actions"
48
+ | "Collection.FilterField"
49
+
50
+ // ── Entity / Form ──
51
+ | "Entity.Form"
52
+ | "EditView.FormActions"
53
+ | "DetailView"
54
+ | "Entity.SidePanel"
55
+ | "EntityPreview"
56
+ | "Entity.MissingReference";
57
+
58
+ /**
59
+ * All overridable component names across all scopes.
60
+ * @group Component Overrides
61
+ */
62
+ export type OverridableComponentName = AppComponentName | CollectionComponentName;
63
+
64
+ /**
65
+ * Props received by a filter field component — whether it is a built-in
66
+ * per-type field, a property-level replacement (`property.ui.Filter`), or a
67
+ * `"Collection.FilterField"` override.
68
+ *
69
+ * The `operators` list is **already resolved**: it is the intersection of the
70
+ * engine's {@link DataSourceCapabilities.filterOperators}, the property-type
71
+ * defaults, and any `property.ui.filterOperators` narrowing. A custom field
72
+ * should only offer operators from this list — anything else may throw at
73
+ * query time on engines that cannot execute it.
74
+ *
75
+ * @example
76
+ * ```tsx
77
+ * function MyStatusFilter({ value, setValue, operators }: FilterFieldBindingProps) {
78
+ * return (
79
+ * <select
80
+ * value={value?.[1] as string ?? ""}
81
+ * onChange={e => setValue(e.target.value ? ["==", e.target.value] : undefined)}>
82
+ * <option value="">Any</option>
83
+ * <option value="active">Active</option>
84
+ * <option value="archived">Archived</option>
85
+ * </select>
86
+ * );
87
+ * }
88
+ * ```
89
+ *
90
+ * @group Component Overrides
91
+ */
92
+ export interface FilterFieldBindingProps {
93
+ /** Key of the property being filtered (the column id). */
94
+ propertyKey: string;
95
+
96
+ /**
97
+ * The resolved property. For array properties this is the **item**
98
+ * property (`property.of`), with `isArray` set to true.
99
+ */
100
+ property: Property;
101
+
102
+ /** True when the underlying property is an array of `property`. */
103
+ isArray: boolean;
104
+
105
+ /**
106
+ * Operators this field may offer, already narrowed by engine
107
+ * capabilities, property-type defaults, and `property.ui.filterOperators`.
108
+ */
109
+ operators: readonly WhereFilterOp[];
110
+
111
+ /** Current filter condition for this property, if any. */
112
+ value?: [WhereFilterOp, unknown];
113
+
114
+ /** Set (or clear, with `undefined`) the filter condition. */
115
+ setValue: (value?: [WhereFilterOp, unknown]) => void;
116
+
117
+ /** Display title for the field (usually the property name). */
118
+ title?: string;
119
+
120
+ /**
121
+ * Coordination flags used by fields that open their own dialogs
122
+ * (e.g. the reference picker hides the parent filters dialog).
123
+ */
124
+ hidden?: boolean;
125
+ setHidden?: (hidden: boolean) => void;
126
+ }
127
+
128
+ // ── Override entry ────────────────────────────────────────────────────
129
+
130
+ /**
131
+ * A single component override entry.
132
+ *
133
+ * - **Eject mode** (default): Your component fully replaces the built-in one.
134
+ * It receives the same props as the original.
135
+ *
136
+ * - **Wrap mode** (`wrap: true`): Your component wraps the original. The
137
+ * built-in component is passed as `OriginalComponent` in props, so you can
138
+ * render it inside your custom layout/logic.
139
+ *
140
+ * @example
141
+ * ```tsx
142
+ * // Eject — full replacement
143
+ * { Component: MyCustomAppBar }
144
+ *
145
+ * // Wrap — augment the original
146
+ * {
147
+ * Component: ({ OriginalComponent, ...props }) => (
148
+ * <div>
149
+ * <MyBanner />
150
+ * <OriginalComponent {...props} />
151
+ * </div>
152
+ * ),
153
+ * wrap: true
154
+ * }
155
+ * ```
156
+ *
157
+ * @group Component Overrides
158
+ */
159
+ export interface ComponentOverride<P = Record<string, unknown>> {
160
+ /**
161
+ * The replacement component. Receives the same props as the built-in
162
+ * component it replaces.
163
+ *
164
+ * When `wrap` is true, an additional `OriginalComponent` prop is injected
165
+ * containing the default component, allowing you to render it within
166
+ * your custom wrapper.
167
+ */
168
+ Component: React.ComponentType<P>;
169
+
170
+ /**
171
+ * When true, the original default component is injected as the
172
+ * `OriginalComponent` prop into your Component, enabling the
173
+ * wrapping pattern (similar to Docusaurus's `--wrap` swizzle mode).
174
+ *
175
+ * When false or omitted, your component fully replaces the default
176
+ * (similar to Docusaurus's `--eject` swizzle mode).
177
+ *
178
+ * @default false
179
+ */
180
+ wrap?: boolean;
181
+ }
182
+
183
+ // ── Override maps by scope ────────────────────────────────────────────
184
+
185
+ /**
186
+ * Collection-scoped overrides. Only collection-level components
187
+ * can be overridden here.
188
+ *
189
+ * Set on a collection's `components` field to customize
190
+ * components for that specific collection.
191
+ *
192
+ * @example
193
+ * ```tsx
194
+ * const productsCollection = {
195
+ * name: "Products",
196
+ * slug: "products",
197
+ * components: {
198
+ * "Entity.Form": { Component: ProductForm },
199
+ * "Collection.EmptyState": { Component: ProductsEmptyState },
200
+ * "Collection.Card": { Component: ProductCard },
201
+ * }
202
+ * };
203
+ * ```
204
+ *
205
+ * @group Component Overrides
206
+ */
207
+ export type CollectionComponentOverrideMap = {
208
+ [K in CollectionComponentName]?: ComponentOverride;
209
+ };
210
+
211
+ /**
212
+ * App-level overrides. Includes both app-only components (Shell, HomePage, Auth)
213
+ * and collection-level components (as defaults for all collections).
214
+ *
215
+ * Pass this to the `components` prop on `<Rebase>`.
216
+ *
217
+ * Collection-level components set here act as **defaults** — they apply to all
218
+ * collections unless a specific collection overrides them in its own
219
+ * `components`.
220
+ *
221
+ * @example
222
+ * ```tsx
223
+ * <Rebase
224
+ * client={client}
225
+ * components={{
226
+ * // App-level: only available here
227
+ * "Shell.AppBar": { Component: MyAppBar },
228
+ * "HomePage": { Component: MyDashboard },
229
+ *
230
+ * // Collection defaults: apply to ALL collections
231
+ * "EditView.FormActions": {
232
+ * Component: MyFormActions,
233
+ * wrap: true
234
+ * },
235
+ * "Collection.EmptyState": { Component: MyEmptyState },
236
+ * }}
237
+ * />
238
+ * ```
239
+ *
240
+ * @group Component Overrides
241
+ */
242
+ export type ComponentOverrideMap = {
243
+ [K in OverridableComponentName]?: ComponentOverride;
244
+ };
@@ -0,0 +1,127 @@
1
+ import React from "react";
2
+ import type { Entity } from "@rebasepro/types";
3
+
4
+ import type { SelectionController } from "../collections";
5
+ import type { FormContext } from "./entity_views";
6
+ import type { User } from "@rebasepro/types";
7
+ import type { RebaseContext } from "../rebase_context";
8
+ import type { SidePanelController } from "../controllers/side_panel_controller";
9
+ import type { AdminCollection } from "@rebasepro/admin-types";
10
+
11
+ /**
12
+ * A entity action is a custom action that can be performed on a entity.
13
+ * They are displayed in the entity view and in the collection view.
14
+ */
15
+ export interface EntityAction<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
16
+ /**
17
+ * Title of the action
18
+ */
19
+ name: string;
20
+
21
+ /**
22
+ * Key of the action. You only need to provide this if you want to
23
+ * override the default actions, or if you are not passing the action
24
+ * directly to the `entityActions` prop of a collection.
25
+ * You can define your actions at the app level, in which case you
26
+ * must provide a key.
27
+ * The default actions are:
28
+ * - edit
29
+ * - delete
30
+ * - copy
31
+ */
32
+ key?: string;
33
+
34
+ /**
35
+ * Icon of the action
36
+ */
37
+ icon?: React.ReactElement;
38
+
39
+ /**
40
+ * Callback when the action is clicked
41
+ * @param props
42
+ */
43
+ onClick(props: EntityActionClickProps<M, USER>): Promise<void> | void;
44
+
45
+ /**
46
+ * Optional callback in case you want to disable the action
47
+ * @param props
48
+ */
49
+ isEnabled?(props: EntityActionClickProps<M, USER>): boolean;
50
+
51
+ /**
52
+ * When true, this action is rendered inline on each row in the list view.
53
+ * By default, entity actions only appear in the table view and entity form.
54
+ * Use this for actions that should be easily accessible regardless of view mode.
55
+ */
56
+ showActionsInListView?: boolean;
57
+
58
+ /**
59
+ * Show this action collapsed in the menu of the collection view.
60
+ * Defaults to true
61
+ * If false, the action will be shown in the menu
62
+ */
63
+ collapsed?: boolean;
64
+
65
+ /**
66
+ * Show this action in the form, defaults to true
67
+ */
68
+ includeInForm?: boolean;
69
+
70
+ }
71
+
72
+ export type EntityActionClickProps<M extends Record<string, unknown>, USER extends User = User> = {
73
+ entity?: Entity<M>;
74
+ context?: RebaseContext<USER>;
75
+
76
+ path?: string;
77
+ collection?: AdminCollection<M>;
78
+
79
+ /**
80
+ * Optional form context, present if the action is being called from a form.
81
+ * This allows you to access the form state and methods, including modifying the form values.
82
+ */
83
+ formContext?: FormContext;
84
+
85
+ /**
86
+ * Present if this actions is being called from a side dialog only
87
+ */
88
+ sidePanelController?: SidePanelController;
89
+
90
+ /**
91
+ * Is the action being called from the collection view or from the entity form view?
92
+ */
93
+ view: "collection" | "form";
94
+
95
+ /**
96
+ * If the action is rendered in the form, is it open in a side panel or full screen?
97
+ */
98
+ openEntityMode?: "side_panel" | "full_screen" | "split" | "dialog";
99
+
100
+ /**
101
+ * Optional selection controller, present if the action is being called from a collection view
102
+ */
103
+ selectionController?: SelectionController;
104
+
105
+ /**
106
+ * Optional highlight function to highlight the entity in the collection view
107
+ * @param entity
108
+ */
109
+ highlightEntity?: (entity: Entity<Record<string, unknown>>) => void;
110
+
111
+ /**
112
+ * Optional unhighlight function to remove the highlight from the entity in the collection view
113
+ * @param entity
114
+ */
115
+ unhighlightEntity?: (entity: Entity<Record<string, unknown>>) => void;
116
+
117
+ /**
118
+ * Optional function to navigate back (e.g. when deleting a entity or navigating from a form)
119
+ */
120
+ navigateBack?: () => void;
121
+
122
+ /**
123
+ * Callback to be called when the collection changes, e.g. after a entity is deleted or created.
124
+ */
125
+ onCollectionChange?: () => void;
126
+
127
+ };
@@ -0,0 +1,8 @@
1
+ import { Entity } from "@rebasepro/types";
2
+
3
+ /**
4
+ * @group Models
5
+ */
6
+ export type EntityLinkBuilder<M extends Record<string, unknown> = Record<string, unknown>> = ({ entity }: {
7
+ entity: Entity<M>
8
+ }) => string;
@@ -0,0 +1,114 @@
1
+ import React from "react";
2
+ import type { Entity, EntityValues } from "@rebasepro/types";
3
+
4
+ import type { FormexController } from "./formex";
5
+ import type { ComponentRef } from "@rebasepro/types";
6
+ import type { AdminCollection } from "@rebasepro/admin-types";
7
+
8
+ /**
9
+ * Context passed to custom fields and entity views.
10
+ * @group Form custom fields
11
+ */
12
+ export interface FormContext<M extends Record<string, unknown> = Record<string, unknown>> {
13
+
14
+ /**
15
+ * Current values of the entity
16
+ */
17
+ values: M;
18
+
19
+ /**
20
+ * Update the value of a field
21
+ */
22
+ setFieldValue: (key: string, value: unknown, shouldValidate?: boolean) => void;
23
+
24
+ /**
25
+ * Quietly persist the entity to the database without any UI feedback
26
+ * (no validation, no snackbar, no form reset).
27
+ * Use this for programmatic/background saves from custom views.
28
+ */
29
+ save: (values: M) => void;
30
+
31
+ /**
32
+ * Submit the form — validates, saves, resets the form, and shows
33
+ * a success snackbar. This is what the Save button calls.
34
+ * Use this from custom views when you want the full "user saved" experience.
35
+ */
36
+ submit: () => void;
37
+
38
+ /**
39
+ * Collection of the entity being modified
40
+ */
41
+ collection?: AdminCollection<M>;
42
+
43
+ /**
44
+ * Entity id, it can be undefined if it's a new entity
45
+ */
46
+ entityId?: string | number;
47
+
48
+ /**
49
+ * Path this entity is located at
50
+ */
51
+ path?: string;
52
+
53
+ status: "new" | "existing" | "copy";
54
+
55
+ entity?: Entity<M>;
56
+
57
+ savingError?: Error;
58
+
59
+ openEntityMode?: "side_panel" | "full_screen" | "split" | "dialog";
60
+
61
+ /**
62
+ * The underlying formex controller that powers the form.
63
+ */
64
+ formex: FormexController<M>;
65
+
66
+ disabled: boolean;
67
+
68
+ /**
69
+ * Whether the form context is in read-only detail view mode.
70
+ * Custom entity views can use this to adjust their rendering.
71
+ */
72
+ readOnly?: boolean;
73
+ }
74
+
75
+ export type EntityCustomView<M extends Record<string, unknown> = Record<string, unknown>> = {
76
+ key: string;
77
+ name: string;
78
+ icon?: string | React.ReactNode;
79
+ tabComponent?: React.ReactNode;
80
+ includeActions?: boolean | "bottom";
81
+ Builder?: ComponentRef<EntityCustomViewParams<M>>;
82
+ position?: "start" | "end";
83
+ };
84
+
85
+ /**
86
+ * Configuration to replace the default entity form with a custom component.
87
+ * The Builder receives the same props as entity view tabs (entity, formContext, etc.)
88
+ * and has full control over the UI.
89
+ *
90
+ * The form tab still appears in the tab bar but renders your Builder
91
+ * instead of the auto-generated field form.
92
+ *
93
+ * @group Models
94
+ */
95
+ export type FormViewConfig<M extends Record<string, unknown> = Record<string, unknown>> = {
96
+ /**
97
+ * Custom component that replaces the default form.
98
+ */
99
+ Builder: ComponentRef<EntityCustomViewParams<M>>;
100
+ /**
101
+ * If true, the save/delete action bar is rendered alongside the custom view.
102
+ * Defaults to true.
103
+ */
104
+ includeActions?: boolean;
105
+ };
106
+
107
+ export interface EntityCustomViewParams<M extends Record<string, unknown> = Record<string, unknown>> {
108
+ collection: AdminCollection<M>;
109
+ entity?: Entity<M>;
110
+ modifiedValues?: EntityValues<M>;
111
+ formContext: FormContext<M>;
112
+ parentCollectionSlugs?: string[];
113
+ parentEntityIds?: string[];
114
+ }
@@ -0,0 +1,26 @@
1
+ import type { Entity } from "@rebasepro/types";
2
+ import type { User } from "@rebasepro/types";
3
+ import type { RebaseContext } from "../rebase_context";
4
+
5
+ /**
6
+ * You can use this configuration to add additional fields to the data
7
+ * exports
8
+ * @group Models
9
+ */
10
+ export interface ExportConfig<USER extends User = User> {
11
+ additionalFields: ExportMappingFunction<USER>[];
12
+ }
13
+
14
+ /**
15
+ * @group Models
16
+ */
17
+ export interface ExportMappingFunction<USER extends User = User> {
18
+ key: string;
19
+ builder: ({
20
+ entity,
21
+ context
22
+ }: {
23
+ entity: Entity,
24
+ context: RebaseContext<USER>
25
+ }) => Promise<string> | string;
26
+ }
@@ -0,0 +1,45 @@
1
+ import React, { FormEvent } from "react";
2
+
3
+ export type FormexController<T = unknown> = {
4
+ values: T;
5
+ initialValues: T;
6
+ setValues: (values: T) => void;
7
+ setFieldValue: (key: string, value: unknown, shouldValidate?: boolean) => void;
8
+ touched: Record<string, boolean>;
9
+ setFieldTouched: (key: string, touched: boolean, shouldValidate?: boolean) => void;
10
+ setTouched: (touched: Record<string, boolean>) => void;
11
+ dirty: boolean;
12
+ setDirty: (dirty: boolean) => void;
13
+ setSubmitCount: (submitCount: number) => void;
14
+ errors: Record<string, string>;
15
+ setFieldError: (key: string, error?: string) => void;
16
+ handleChange: (event: React.SyntheticEvent) => void,
17
+ handleBlur: (event: React.FocusEvent) => void,
18
+ handleSubmit: (event?: FormEvent<HTMLFormElement>) => void;
19
+ validate: () => void;
20
+ resetForm: (props?: FormexResetProps<T>) => void;
21
+ submitCount: number;
22
+ isSubmitting: boolean;
23
+ setSubmitting: (isSubmitting: boolean) => void;
24
+ isValidating: boolean;
25
+ /**
26
+ * The version of the form. This is incremented every time the form is reset
27
+ * or the form is submitted.
28
+ */
29
+ version: number;
30
+
31
+ debugId?: string;
32
+
33
+ undo: () => void;
34
+ redo: () => void;
35
+
36
+ canUndo: boolean;
37
+ canRedo: boolean;
38
+ }
39
+
40
+ export type FormexResetProps<T = unknown> = {
41
+ values?: T;
42
+ submitCount?: number;
43
+ errors?: Record<string, string>;
44
+ touched?: Record<string, boolean>;
45
+ };