@firecms/collection_editor 3.0.0 → 3.1.0-canary.1df3b2c
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.
- package/dist/ConfigControllerProvider.d.ts +6 -0
- package/dist/api/generateCollectionApi.d.ts +71 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.es.js +9677 -5837
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +9653 -5813
- package/dist/index.umd.js.map +1 -1
- package/dist/types/collection_editor_controller.d.ts +14 -0
- package/dist/types/collection_inference.d.ts +8 -2
- package/dist/types/config_controller.d.ts +31 -1
- package/dist/ui/AddKanbanColumnAction.d.ts +11 -0
- package/dist/ui/KanbanSetupAction.d.ts +10 -0
- package/dist/ui/collection_editor/AICollectionGeneratorPopover.d.ts +33 -0
- package/dist/ui/collection_editor/AIModifiedPathsContext.d.ts +20 -0
- package/dist/ui/collection_editor/CollectionDetailsForm.d.ts +2 -3
- package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +20 -0
- package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +3 -1
- package/dist/ui/collection_editor/CollectionJsonImportDialog.d.ts +7 -0
- package/dist/ui/collection_editor/CollectionYupValidation.d.ts +9 -13
- package/dist/ui/collection_editor/DisplaySettingsForm.d.ts +3 -0
- package/dist/ui/collection_editor/EntityActionsEditTab.d.ts +2 -1
- package/dist/ui/collection_editor/ExtendSettingsForm.d.ts +14 -0
- package/dist/ui/collection_editor/GeneralSettingsForm.d.ts +7 -0
- package/dist/ui/collection_editor/KanbanConfigSection.d.ts +4 -0
- package/dist/ui/collection_editor/PropertyEditView.d.ts +6 -1
- package/dist/ui/collection_editor/PropertyTree.d.ts +2 -1
- package/dist/ui/collection_editor/SubcollectionsEditTab.d.ts +2 -1
- package/dist/ui/collection_editor/ViewModeSwitch.d.ts +6 -0
- package/dist/ui/collection_editor/properties/EnumPropertyField.d.ts +2 -1
- package/dist/ui/collection_editor/properties/conditions/ConditionsEditor.d.ts +10 -0
- package/dist/ui/collection_editor/properties/conditions/ConditionsPanel.d.ts +2 -0
- package/dist/ui/collection_editor/properties/conditions/EnumConditionsEditor.d.ts +6 -0
- package/dist/ui/collection_editor/properties/conditions/index.d.ts +6 -0
- package/dist/ui/collection_editor/properties/conditions/property_paths.d.ts +19 -0
- package/dist/useCollectionEditorPlugin.d.ts +7 -1
- package/dist/utils/validateCollectionJson.d.ts +22 -0
- package/package.json +11 -11
- package/src/ConfigControllerProvider.tsx +81 -47
- package/src/api/generateCollectionApi.ts +119 -0
- package/src/api/index.ts +1 -0
- package/src/index.ts +28 -1
- package/src/types/collection_editor_controller.tsx +16 -3
- package/src/types/collection_inference.ts +15 -2
- package/src/types/config_controller.tsx +37 -1
- package/src/ui/AddKanbanColumnAction.tsx +203 -0
- package/src/ui/EditorCollectionActionStart.tsx +1 -2
- package/src/ui/HomePageEditorCollectionAction.tsx +41 -13
- package/src/ui/KanbanSetupAction.tsx +38 -0
- package/src/ui/MissingReferenceWidget.tsx +1 -1
- package/src/ui/NewCollectionButton.tsx +1 -1
- package/src/ui/PropertyAddColumnComponent.tsx +1 -1
- package/src/ui/collection_editor/AICollectionGeneratorPopover.tsx +225 -0
- package/src/ui/collection_editor/AIModifiedPathsContext.tsx +88 -0
- package/src/ui/collection_editor/CollectionDetailsForm.tsx +209 -258
- package/src/ui/collection_editor/CollectionEditorDialog.tsx +226 -173
- package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +130 -67
- package/src/ui/collection_editor/CollectionJsonImportDialog.tsx +171 -0
- package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +190 -91
- package/src/ui/collection_editor/DisplaySettingsForm.tsx +333 -0
- package/src/ui/collection_editor/EntityActionsEditTab.tsx +106 -96
- package/src/ui/collection_editor/EntityActionsSelectDialog.tsx +6 -7
- package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +1 -3
- package/src/ui/collection_editor/EnumForm.tsx +147 -100
- package/src/ui/collection_editor/ExtendSettingsForm.tsx +93 -0
- package/src/ui/collection_editor/GeneralSettingsForm.tsx +335 -0
- package/src/ui/collection_editor/GetCodeDialog.tsx +57 -36
- package/src/ui/collection_editor/KanbanConfigSection.tsx +207 -0
- package/src/ui/collection_editor/LayoutModeSwitch.tsx +22 -41
- package/src/ui/collection_editor/PropertyEditView.tsx +205 -141
- package/src/ui/collection_editor/PropertyFieldPreview.tsx +1 -1
- package/src/ui/collection_editor/PropertyTree.tsx +130 -58
- package/src/ui/collection_editor/SubcollectionsEditTab.tsx +171 -162
- package/src/ui/collection_editor/UnsavedChangesDialog.tsx +0 -2
- package/src/ui/collection_editor/ViewModeSwitch.tsx +41 -0
- package/src/ui/collection_editor/properties/BlockPropertyField.tsx +0 -2
- package/src/ui/collection_editor/properties/BooleanPropertyField.tsx +1 -0
- package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +117 -35
- package/src/ui/collection_editor/properties/EnumPropertyField.tsx +28 -21
- package/src/ui/collection_editor/properties/MapPropertyField.tsx +0 -2
- package/src/ui/collection_editor/properties/MarkdownPropertyField.tsx +115 -39
- package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +1 -5
- package/src/ui/collection_editor/properties/StoragePropertyField.tsx +23 -2
- package/src/ui/collection_editor/properties/conditions/ConditionsEditor.tsx +861 -0
- package/src/ui/collection_editor/properties/conditions/ConditionsPanel.tsx +28 -0
- package/src/ui/collection_editor/properties/conditions/EnumConditionsEditor.tsx +599 -0
- package/src/ui/collection_editor/properties/conditions/index.ts +6 -0
- package/src/ui/collection_editor/properties/conditions/property_paths.ts +92 -0
- package/src/ui/collection_editor/properties/validation/ValidationPanel.tsx +1 -1
- package/src/useCollectionEditorPlugin.tsx +32 -17
- package/src/utils/validateCollectionJson.ts +380 -0
|
@@ -17,6 +17,7 @@ import { CollectionEditorPermissionsBuilder } from "./types/config_permissions";
|
|
|
17
17
|
import { CollectionInference } from "./types/collection_inference";
|
|
18
18
|
import { PropertyFormDialog } from "./ui/collection_editor/PropertyEditView";
|
|
19
19
|
import { PersistedCollection } from "./types/persisted_collection";
|
|
20
|
+
import { CollectionGenerationCallback } from "./api/generateCollectionApi";
|
|
20
21
|
|
|
21
22
|
export const ConfigControllerContext = React.createContext<CollectionsConfigController>({} as any);
|
|
22
23
|
export const CollectionEditorContext = React.createContext<CollectionEditorController>({} as any);
|
|
@@ -57,21 +58,28 @@ export interface ConfigControllerProviderProps {
|
|
|
57
58
|
|
|
58
59
|
onAnalyticsEvent?: (event: string, params?: object) => void;
|
|
59
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Callback function for generating/modifying collections.
|
|
63
|
+
* The plugin is API-agnostic - the consumer provides the implementation.
|
|
64
|
+
*/
|
|
65
|
+
generateCollection?: CollectionGenerationCallback;
|
|
66
|
+
|
|
60
67
|
}
|
|
61
68
|
|
|
62
69
|
export const ConfigControllerProvider = React.memo(
|
|
63
70
|
function ConfigControllerProvider({
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
children,
|
|
72
|
+
collectionConfigController,
|
|
73
|
+
configPermissions,
|
|
74
|
+
reservedGroups,
|
|
75
|
+
collectionInference,
|
|
76
|
+
extraView,
|
|
77
|
+
getUser,
|
|
78
|
+
getData,
|
|
79
|
+
onAnalyticsEvent,
|
|
80
|
+
pathSuggestions,
|
|
81
|
+
generateCollection
|
|
82
|
+
}: PropsWithChildren<ConfigControllerProviderProps>) {
|
|
75
83
|
|
|
76
84
|
const navigation = useNavigationController();
|
|
77
85
|
const navigate = useNavigate();
|
|
@@ -89,9 +97,12 @@ export const ConfigControllerProvider = React.memo(
|
|
|
89
97
|
group?: string,
|
|
90
98
|
name?: string
|
|
91
99
|
},
|
|
100
|
+
copyFrom?: PersistedCollection,
|
|
92
101
|
redirect: boolean,
|
|
93
102
|
existingEntities?: Entity<any>[],
|
|
94
103
|
pathSuggestions?: string[];
|
|
104
|
+
initialView?: "general" | "display" | "properties";
|
|
105
|
+
expandKanban?: boolean;
|
|
95
106
|
}>();
|
|
96
107
|
|
|
97
108
|
const [currentPropertyDialog, setCurrentPropertyDialog] = React.useState<{
|
|
@@ -104,7 +115,8 @@ export const ConfigControllerProvider = React.memo(
|
|
|
104
115
|
fullPath?: string,
|
|
105
116
|
parentCollectionIds: string[],
|
|
106
117
|
collectionEditable: boolean;
|
|
107
|
-
existingEntities?: Entity<any>[]
|
|
118
|
+
existingEntities?: Entity<any>[];
|
|
119
|
+
collection?: PersistedCollection;
|
|
108
120
|
}>();
|
|
109
121
|
|
|
110
122
|
const defaultConfigPermissions: CollectionEditorPermissionsBuilder = useCallback(() => ({
|
|
@@ -114,17 +126,21 @@ export const ConfigControllerProvider = React.memo(
|
|
|
114
126
|
}), []);
|
|
115
127
|
|
|
116
128
|
const editCollection = ({
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
129
|
+
id,
|
|
130
|
+
fullPath,
|
|
131
|
+
parentCollectionIds,
|
|
132
|
+
parentCollection,
|
|
133
|
+
existingEntities,
|
|
134
|
+
initialView,
|
|
135
|
+
expandKanban
|
|
136
|
+
}: {
|
|
123
137
|
id?: string,
|
|
124
138
|
fullPath?: string,
|
|
125
139
|
parentCollectionIds: string[],
|
|
126
140
|
parentCollection?: PersistedCollection,
|
|
127
|
-
existingEntities?: Entity<any>[]
|
|
141
|
+
existingEntities?: Entity<any>[],
|
|
142
|
+
initialView?: "general" | "display" | "properties",
|
|
143
|
+
expandKanban?: boolean
|
|
128
144
|
}) => {
|
|
129
145
|
console.debug("Edit collection", id, fullPath, parentCollectionIds, parentCollection);
|
|
130
146
|
onAnalyticsEvent?.("edit_collection", {
|
|
@@ -139,19 +155,21 @@ export const ConfigControllerProvider = React.memo(
|
|
|
139
155
|
parentCollection,
|
|
140
156
|
redirect: false,
|
|
141
157
|
existingEntities,
|
|
142
|
-
pathSuggestions
|
|
158
|
+
pathSuggestions,
|
|
159
|
+
initialView,
|
|
160
|
+
expandKanban
|
|
143
161
|
});
|
|
144
162
|
};
|
|
145
163
|
|
|
146
164
|
const editProperty = ({
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
165
|
+
propertyKey,
|
|
166
|
+
property,
|
|
167
|
+
editedCollectionId,
|
|
168
|
+
currentPropertiesOrder,
|
|
169
|
+
parentCollectionIds,
|
|
170
|
+
collection,
|
|
171
|
+
existingEntities
|
|
172
|
+
}: {
|
|
155
173
|
propertyKey?: string,
|
|
156
174
|
property?: Property,
|
|
157
175
|
currentPropertiesOrder?: string[],
|
|
@@ -180,17 +198,19 @@ export const ConfigControllerProvider = React.memo(
|
|
|
180
198
|
editedCollectionId,
|
|
181
199
|
parentCollectionIds,
|
|
182
200
|
collectionEditable: collection?.editable === undefined || collection?.editable === true,
|
|
183
|
-
existingEntities
|
|
201
|
+
existingEntities,
|
|
202
|
+
collection
|
|
184
203
|
});
|
|
185
204
|
};
|
|
186
205
|
|
|
187
206
|
const createCollection = ({
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
207
|
+
parentCollectionIds,
|
|
208
|
+
parentCollection,
|
|
209
|
+
initialValues,
|
|
210
|
+
copyFrom,
|
|
211
|
+
redirect,
|
|
212
|
+
sourceClick
|
|
213
|
+
}: {
|
|
194
214
|
parentCollectionIds: string[],
|
|
195
215
|
parentCollection?: PersistedCollection
|
|
196
216
|
initialValues?: {
|
|
@@ -198,6 +218,7 @@ export const ConfigControllerProvider = React.memo(
|
|
|
198
218
|
path?: string,
|
|
199
219
|
name?: string
|
|
200
220
|
},
|
|
221
|
+
copyFrom?: PersistedCollection,
|
|
201
222
|
redirect: boolean,
|
|
202
223
|
sourceClick?: string
|
|
203
224
|
}) => {
|
|
@@ -205,10 +226,11 @@ export const ConfigControllerProvider = React.memo(
|
|
|
205
226
|
parentCollectionIds,
|
|
206
227
|
parentCollection,
|
|
207
228
|
initialValues,
|
|
229
|
+
copyFrom,
|
|
208
230
|
redirect,
|
|
209
231
|
sourceClick
|
|
210
232
|
});
|
|
211
|
-
onAnalyticsEvent?.("create_collection", {
|
|
233
|
+
onAnalyticsEvent?.(copyFrom ? "duplicate_collection" : "create_collection", {
|
|
212
234
|
parentCollectionIds,
|
|
213
235
|
parentCollection,
|
|
214
236
|
initialValues,
|
|
@@ -220,6 +242,7 @@ export const ConfigControllerProvider = React.memo(
|
|
|
220
242
|
parentCollectionIds,
|
|
221
243
|
parentCollection,
|
|
222
244
|
initialValues,
|
|
245
|
+
copyFrom,
|
|
223
246
|
redirect,
|
|
224
247
|
pathSuggestions
|
|
225
248
|
});
|
|
@@ -248,6 +271,7 @@ export const ConfigControllerProvider = React.memo(
|
|
|
248
271
|
reservedGroups={reservedGroups}
|
|
249
272
|
extraView={extraView}
|
|
250
273
|
getUser={getUser}
|
|
274
|
+
generateCollection={generateCollection}
|
|
251
275
|
handleClose={(collection) => {
|
|
252
276
|
if (currentDialog?.redirect) {
|
|
253
277
|
if (collection && currentDialog?.isNewCollection && !currentDialog.parentCollectionIds.length) {
|
|
@@ -256,7 +280,7 @@ export const ConfigControllerProvider = React.memo(
|
|
|
256
280
|
}
|
|
257
281
|
}
|
|
258
282
|
setCurrentDialog(undefined);
|
|
259
|
-
}}/>
|
|
283
|
+
}} />
|
|
260
284
|
|
|
261
285
|
{/* Used for editing properties*/}
|
|
262
286
|
<PropertyFormDialog
|
|
@@ -267,17 +291,27 @@ export const ConfigControllerProvider = React.memo(
|
|
|
267
291
|
autoOpenTypeSelect={!currentPropertyDialog ? false : !currentPropertyDialog?.propertyKey}
|
|
268
292
|
inArray={false}
|
|
269
293
|
collectionEditable={currentPropertyDialog?.collectionEditable ?? false}
|
|
270
|
-
getData={getData && currentPropertyDialog?.editedCollectionId
|
|
271
|
-
? () => {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
294
|
+
getData={currentPropertyDialog?.existingEntities || (getData && currentPropertyDialog?.editedCollectionId)
|
|
295
|
+
? async () => {
|
|
296
|
+
let data: object[] = [];
|
|
297
|
+
// First, use existing entities if available (already loaded in table)
|
|
298
|
+
if (currentPropertyDialog?.existingEntities) {
|
|
299
|
+
data = currentPropertyDialog.existingEntities.map(e => e.values);
|
|
300
|
+
}
|
|
301
|
+
// If getData is available and we have a path, also fetch from database
|
|
302
|
+
if (getData && currentPropertyDialog?.editedCollectionId) {
|
|
303
|
+
console.debug("Get data for property, path:", currentPropertyDialog?.editedCollectionId);
|
|
304
|
+
const resolvedPath = navigation.resolveIdsFrom(currentPropertyDialog.editedCollectionId!);
|
|
305
|
+
const fetchedData = await getData(resolvedPath, []);
|
|
306
|
+
data.push(...fetchedData);
|
|
307
|
+
}
|
|
308
|
+
return data;
|
|
275
309
|
}
|
|
276
310
|
: undefined}
|
|
277
311
|
onPropertyChanged={({
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
312
|
+
id,
|
|
313
|
+
property
|
|
314
|
+
}) => {
|
|
281
315
|
if (!currentPropertyDialog) return;
|
|
282
316
|
if (!id) return;
|
|
283
317
|
const newProperty = !(currentPropertyDialog.propertyKey);
|
|
@@ -330,11 +364,11 @@ export const ConfigControllerProvider = React.memo(
|
|
|
330
364
|
}}
|
|
331
365
|
initialErrors={{}}
|
|
332
366
|
forceShowErrors={false}
|
|
333
|
-
existingPropertyKeys={[]}
|
|
367
|
+
existingPropertyKeys={currentPropertyDialog?.collection?.properties ? Object.keys(currentPropertyDialog.collection.properties) : []}
|
|
334
368
|
allowDataInference={true}
|
|
335
369
|
propertyConfigs={propertyConfigs}
|
|
336
370
|
property={currentPropertyDialog?.property}
|
|
337
|
-
propertyKey={currentPropertyDialog?.propertyKey}/>
|
|
371
|
+
propertyKey={currentPropertyDialog?.propertyKey} />
|
|
338
372
|
|
|
339
373
|
</CollectionEditorContext.Provider>
|
|
340
374
|
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { EntityCollection } from "@firecms/core";
|
|
2
|
+
|
|
3
|
+
export interface GenerateCollectionRequest {
|
|
4
|
+
/** User's natural language description of what they want */
|
|
5
|
+
prompt: string;
|
|
6
|
+
|
|
7
|
+
/** Other collections in the project (for context/relationships). Limit to 30. */
|
|
8
|
+
existingCollections: Partial<EntityCollection>[];
|
|
9
|
+
|
|
10
|
+
/** Optional for generate, required for modifications. If provided, modifies this collection */
|
|
11
|
+
existingCollection?: Partial<EntityCollection>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Operation types for modifying a collection */
|
|
15
|
+
export type CollectionOperationType = "add" | "modify" | "delete";
|
|
16
|
+
|
|
17
|
+
/** A single operation describing what changed */
|
|
18
|
+
export interface CollectionOperation {
|
|
19
|
+
op: CollectionOperationType;
|
|
20
|
+
path: string;
|
|
21
|
+
value?: any;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Result from collection generation, including optional delta operations */
|
|
25
|
+
export interface GenerateCollectionResult {
|
|
26
|
+
collection: EntityCollection;
|
|
27
|
+
operations?: CollectionOperation[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Callback type for generating or modifying a collection.
|
|
32
|
+
* The plugin is API-agnostic - consumers implement the actual API call.
|
|
33
|
+
*/
|
|
34
|
+
export type CollectionGenerationCallback = (
|
|
35
|
+
request: GenerateCollectionRequest
|
|
36
|
+
) => Promise<GenerateCollectionResult>;
|
|
37
|
+
|
|
38
|
+
export class CollectionGenerationApiError extends Error {
|
|
39
|
+
public code?: string;
|
|
40
|
+
|
|
41
|
+
constructor(message: string, code?: string) {
|
|
42
|
+
super(message);
|
|
43
|
+
this.code = code;
|
|
44
|
+
this.name = "CollectionGenerationApiError";
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Default endpoint for AI collection generation
|
|
50
|
+
*/
|
|
51
|
+
export const DEFAULT_COLLECTION_GENERATION_ENDPOINT = "https://api.firecms.co/collections/generate";
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Props for building a collection generation callback
|
|
55
|
+
*/
|
|
56
|
+
export interface BuildCollectionGenerationCallbackProps {
|
|
57
|
+
/**
|
|
58
|
+
* Function to get the auth token (e.g., from Firebase Auth)
|
|
59
|
+
* This is typically `authController.getAuthToken` from `@firecms/firebase`
|
|
60
|
+
*/
|
|
61
|
+
getAuthToken: () => Promise<string>;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Optional custom API endpoint for collection generation.
|
|
65
|
+
* Defaults to the FireCMS SaaS API endpoint.
|
|
66
|
+
*/
|
|
67
|
+
apiEndpoint?: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Build a callback for AI collection generation.
|
|
72
|
+
* This helper allows self-hosted FireCMS users to enable the AI collection
|
|
73
|
+
* generation feature.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* import { useCollectionEditorPlugin, buildCollectionGenerationCallback } from "@firecms/collection_editor";
|
|
78
|
+
* import { useFirebaseAuthController } from "@firecms/firebase";
|
|
79
|
+
*
|
|
80
|
+
* const authController = useFirebaseAuthController({ firebaseApp });
|
|
81
|
+
*
|
|
82
|
+
* const collectionEditorPlugin = useCollectionEditorPlugin({
|
|
83
|
+
* // ... other props
|
|
84
|
+
* generateCollection: buildCollectionGenerationCallback({
|
|
85
|
+
* getAuthToken: authController.getAuthToken
|
|
86
|
+
* })
|
|
87
|
+
* });
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export function buildCollectionGenerationCallback({
|
|
91
|
+
getAuthToken,
|
|
92
|
+
apiEndpoint = DEFAULT_COLLECTION_GENERATION_ENDPOINT
|
|
93
|
+
}: BuildCollectionGenerationCallbackProps): CollectionGenerationCallback {
|
|
94
|
+
return async (request) => {
|
|
95
|
+
const token = await getAuthToken();
|
|
96
|
+
const response = await fetch(apiEndpoint, {
|
|
97
|
+
method: "POST",
|
|
98
|
+
headers: {
|
|
99
|
+
"Content-Type": "application/json",
|
|
100
|
+
Authorization: `Bearer ${token}`
|
|
101
|
+
},
|
|
102
|
+
body: JSON.stringify(request)
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
if (!response.ok) {
|
|
106
|
+
const errorData = await response.json().catch(() => ({}));
|
|
107
|
+
throw new CollectionGenerationApiError(
|
|
108
|
+
errorData.error || "Failed to generate collection",
|
|
109
|
+
errorData.code
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const data = await response.json();
|
|
114
|
+
return {
|
|
115
|
+
collection: data.data.collection,
|
|
116
|
+
operations: data.data.operations
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
}
|
package/src/api/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./generateCollectionApi";
|
package/src/index.ts
CHANGED
|
@@ -13,9 +13,14 @@ export {
|
|
|
13
13
|
editableProperty, removeNonEditableProperties
|
|
14
14
|
} from "./utils/entities";
|
|
15
15
|
export * from "./utils/collections";
|
|
16
|
+
export {
|
|
17
|
+
validateCollectionJson,
|
|
18
|
+
type CollectionValidationError,
|
|
19
|
+
type CollectionValidationResult
|
|
20
|
+
} from "./utils/validateCollectionJson";
|
|
16
21
|
|
|
17
22
|
export type {
|
|
18
|
-
CollectionsConfigController, DeleteCollectionParams, SaveCollectionParams, UpdateCollectionParams
|
|
23
|
+
CollectionsConfigController, DeleteCollectionParams, SaveCollectionParams, UpdateCollectionParams, CollectionsSetupInfo, UpdatePropertiesOrderParams, UpdateKanbanColumnsOrderParams
|
|
19
24
|
} from "./types/config_controller";
|
|
20
25
|
export type {
|
|
21
26
|
CollectionEditorController
|
|
@@ -31,6 +36,28 @@ export type {
|
|
|
31
36
|
CollectionInference
|
|
32
37
|
} from "./types/collection_inference";
|
|
33
38
|
|
|
39
|
+
export {
|
|
40
|
+
buildCollectionGenerationCallback,
|
|
41
|
+
CollectionGenerationApiError,
|
|
42
|
+
DEFAULT_COLLECTION_GENERATION_ENDPOINT
|
|
43
|
+
} from "./api/generateCollectionApi";
|
|
44
|
+
|
|
45
|
+
export type {
|
|
46
|
+
CollectionGenerationCallback,
|
|
47
|
+
GenerateCollectionRequest,
|
|
48
|
+
GenerateCollectionResult,
|
|
49
|
+
CollectionOperation,
|
|
50
|
+
CollectionOperationType,
|
|
51
|
+
BuildCollectionGenerationCallbackProps
|
|
52
|
+
} from "./api/generateCollectionApi";
|
|
53
|
+
|
|
34
54
|
export { MissingReferenceWidget } from "./ui/MissingReferenceWidget";
|
|
35
55
|
|
|
36
56
|
export * from "./ui/collection_editor/util";
|
|
57
|
+
|
|
58
|
+
export {
|
|
59
|
+
PropertyForm,
|
|
60
|
+
PropertyFormDialog,
|
|
61
|
+
type PropertyFormProps,
|
|
62
|
+
type OnPropertyChangedParams
|
|
63
|
+
} from "./ui/collection_editor/PropertyEditView";
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
import { CollectionEditorPermissionsBuilder } from "./config_permissions";
|
|
3
2
|
import { Entity, Property } from "@firecms/core";
|
|
4
3
|
import { PersistedCollection } from "./persisted_collection";
|
|
@@ -14,15 +13,29 @@ export interface CollectionEditorController {
|
|
|
14
13
|
fullPath?: string,
|
|
15
14
|
parentCollectionIds: string[],
|
|
16
15
|
parentCollection?: PersistedCollection,
|
|
17
|
-
existingEntities?: Entity<any>[]
|
|
16
|
+
existingEntities?: Entity<any>[],
|
|
17
|
+
/**
|
|
18
|
+
* Initial view to open: "general", "display", or "properties"
|
|
19
|
+
*/
|
|
20
|
+
initialView?: "general" | "display" | "properties",
|
|
21
|
+
/**
|
|
22
|
+
* If true, expand the Kanban configuration section
|
|
23
|
+
*/
|
|
24
|
+
expandKanban?: boolean
|
|
18
25
|
}) => void;
|
|
19
26
|
|
|
20
27
|
createCollection: (props: {
|
|
21
28
|
initialValues?: {
|
|
22
29
|
group?: string,
|
|
23
30
|
path?: string,
|
|
24
|
-
name?: string
|
|
31
|
+
name?: string,
|
|
32
|
+
databaseId?: string
|
|
25
33
|
},
|
|
34
|
+
/**
|
|
35
|
+
* A collection to duplicate from. If provided, the new collection will be
|
|
36
|
+
* pre-populated with the same properties (but with empty name, path, and id).
|
|
37
|
+
*/
|
|
38
|
+
copyFrom?: PersistedCollection,
|
|
26
39
|
parentCollectionIds: string[],
|
|
27
40
|
parentCollection?: PersistedCollection,
|
|
28
41
|
redirect: boolean,
|
|
@@ -1,6 +1,19 @@
|
|
|
1
|
-
import { EntityCollection } from "@firecms/core";
|
|
1
|
+
import { EntityCollection, FilterValues } from "@firecms/core";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This function is used to infer the configuration of a collection given its path.
|
|
5
|
+
* @param path - The path of the collection
|
|
6
|
+
* @param collectionGroup - Whether this is a collection group query
|
|
7
|
+
* @param parentCollectionPaths - Array of parent collection paths for subcollections
|
|
8
|
+
* @param databaseId - Optional database ID for multi-database setups
|
|
9
|
+
* @param initialFilter - Optional filter values from the collection configuration
|
|
10
|
+
* @param initialSort - Optional sort configuration from the collection
|
|
5
11
|
*/
|
|
6
|
-
export type CollectionInference = (
|
|
12
|
+
export type CollectionInference = (
|
|
13
|
+
path: string,
|
|
14
|
+
collectionGroup: boolean,
|
|
15
|
+
parentCollectionPaths: string[],
|
|
16
|
+
databaseId?: string,
|
|
17
|
+
initialFilter?: FilterValues<string>,
|
|
18
|
+
initialSort?: [string, "asc" | "desc"]
|
|
19
|
+
) => Promise<Partial<EntityCollection> | null>;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import { CMSType, NavigationGroupMapping, Property } from "@firecms/core";
|
|
1
|
+
import { CMSType, EntityCollection, NavigationGroupMapping, Property } from "@firecms/core";
|
|
2
2
|
import { PersistedCollection } from "./persisted_collection";
|
|
3
3
|
|
|
4
|
+
export interface CollectionsSetupInfo {
|
|
5
|
+
status: "ongoing" | "complete" | "error";
|
|
6
|
+
error: string | null;
|
|
7
|
+
}
|
|
8
|
+
|
|
4
9
|
/**
|
|
5
10
|
* Use this controller to access the configuration that is stored externally,
|
|
6
11
|
* and not defined in code.
|
|
@@ -11,6 +16,12 @@ export interface CollectionsConfigController {
|
|
|
11
16
|
|
|
12
17
|
collections?: PersistedCollection[];
|
|
13
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Status information about the automatic collections setup process.
|
|
21
|
+
* Stored in the project config document at `collectionsSetup`.
|
|
22
|
+
*/
|
|
23
|
+
collectionsSetup?: CollectionsSetupInfo;
|
|
24
|
+
|
|
14
25
|
getCollection: (id: string) => PersistedCollection;
|
|
15
26
|
|
|
16
27
|
saveCollection: <M extends { [Key: string]: CMSType }>(params: SaveCollectionParams<M>) => Promise<void>;
|
|
@@ -21,6 +32,16 @@ export interface CollectionsConfigController {
|
|
|
21
32
|
|
|
22
33
|
deleteCollection: (props: DeleteCollectionParams) => Promise<void>;
|
|
23
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Update the properties order of a collection (used for column reordering).
|
|
37
|
+
*/
|
|
38
|
+
updatePropertiesOrder: (params: UpdatePropertiesOrderParams) => Promise<void>;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Update the Kanban columns order for a collection.
|
|
42
|
+
*/
|
|
43
|
+
updateKanbanColumnsOrder: (params: UpdateKanbanColumnsOrderParams) => Promise<void>;
|
|
44
|
+
|
|
24
45
|
navigationEntries: NavigationGroupMapping[];
|
|
25
46
|
saveNavigationEntries: (entries: NavigationGroupMapping[]) => Promise<void>;
|
|
26
47
|
|
|
@@ -61,3 +82,18 @@ export type DeleteCollectionParams = {
|
|
|
61
82
|
id: string,
|
|
62
83
|
parentCollectionIds?: string[]
|
|
63
84
|
}
|
|
85
|
+
|
|
86
|
+
export type UpdatePropertiesOrderParams = {
|
|
87
|
+
fullPath: string;
|
|
88
|
+
parentCollectionIds: string[];
|
|
89
|
+
collection: EntityCollection<any>;
|
|
90
|
+
newPropertiesOrder: string[];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export type UpdateKanbanColumnsOrderParams = {
|
|
94
|
+
fullPath: string;
|
|
95
|
+
parentCollectionIds: string[];
|
|
96
|
+
collection: EntityCollection<any>;
|
|
97
|
+
kanbanColumnProperty: string;
|
|
98
|
+
newColumnsOrder: string[];
|
|
99
|
+
}
|