@firecms/collection_editor 3.0.1 → 3.1.0-canary.24c8270
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 +9466 -5588
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +9461 -5583
- 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 +23 -2
- package/dist/ui/AddKanbanColumnAction.d.ts +11 -0
- package/dist/ui/KanbanSetupAction.d.ts +10 -0
- package/dist/ui/collection_editor/AICollectionGeneratorPopover.d.ts +37 -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 +24 -0
- package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +4 -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 +15 -15
- package/src/ConfigControllerProvider.tsx +82 -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 +27 -2
- 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 +242 -0
- package/src/ui/collection_editor/AIModifiedPathsContext.tsx +88 -0
- package/src/ui/collection_editor/CollectionDetailsForm.tsx +212 -259
- package/src/ui/collection_editor/CollectionEditorDialog.tsx +237 -169
- package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +133 -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 +337 -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 +206 -142
- 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/StoragePropertyField.tsx +1 -1
- 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
|
@@ -3,12 +3,24 @@ import equal from "react-fast-compare"
|
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
AdditionalFieldDelegate,
|
|
6
|
+
AIModifiedIndicator,
|
|
6
7
|
CMSType,
|
|
7
8
|
isPropertyBuilder,
|
|
8
9
|
PropertiesOrBuilders,
|
|
9
10
|
PropertyOrBuilder
|
|
10
11
|
} from "@firecms/core";
|
|
11
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
FindInPageIcon,
|
|
14
|
+
defaultBorderMixin,
|
|
15
|
+
DeleteIcon,
|
|
16
|
+
IconButton,
|
|
17
|
+
Menu,
|
|
18
|
+
MenuItem,
|
|
19
|
+
MoreVertIcon,
|
|
20
|
+
Tooltip,
|
|
21
|
+
VerticalAlignBottomIcon,
|
|
22
|
+
VerticalAlignTopIcon
|
|
23
|
+
} from "@firecms/ui";
|
|
12
24
|
import { NonEditablePropertyPreview, PropertyFieldPreview } from "./PropertyFieldPreview";
|
|
13
25
|
import {
|
|
14
26
|
closestCenter,
|
|
@@ -30,24 +42,25 @@ import { restrictToVerticalAxis } from "@dnd-kit/modifiers";
|
|
|
30
42
|
import { CSS } from "@dnd-kit/utilities";
|
|
31
43
|
import { getFullId, getFullIdPath } from "./util";
|
|
32
44
|
import { editableProperty } from "../../utils/entities";
|
|
45
|
+
import { useAIModifiedPaths } from "./AIModifiedPathsContext";
|
|
33
46
|
|
|
34
47
|
export const PropertyTree = React.memo(
|
|
35
48
|
function PropertyTree<M extends {
|
|
36
49
|
[Key: string]: CMSType
|
|
37
50
|
}>({
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
namespace,
|
|
52
|
+
selectedPropertyKey,
|
|
53
|
+
onPropertyClick,
|
|
54
|
+
properties,
|
|
55
|
+
propertiesOrder: propertiesOrderProp,
|
|
56
|
+
additionalFields,
|
|
57
|
+
errors,
|
|
58
|
+
onPropertyMove,
|
|
59
|
+
onPropertyRemove,
|
|
60
|
+
className,
|
|
61
|
+
inferredPropertyKeys,
|
|
62
|
+
collectionEditable
|
|
63
|
+
}: {
|
|
51
64
|
namespace?: string;
|
|
52
65
|
selectedPropertyKey?: string;
|
|
53
66
|
onPropertyClick?: (propertyKey: string, namespace?: string) => void;
|
|
@@ -62,7 +75,15 @@ export const PropertyTree = React.memo(
|
|
|
62
75
|
collectionEditable: boolean;
|
|
63
76
|
}) {
|
|
64
77
|
|
|
65
|
-
|
|
78
|
+
// Filter propertiesOrder to only include top-level keys (no dots) that exist in properties
|
|
79
|
+
// Nested keys like "data.mode" are for column ordering in the table, not for the property editor
|
|
80
|
+
const propertyKeys = Object.keys(properties);
|
|
81
|
+
const filteredOrder = (propertiesOrderProp ?? propertyKeys)
|
|
82
|
+
.filter(key => !key.includes(".") && properties[key as keyof typeof properties]);
|
|
83
|
+
|
|
84
|
+
// Ensure all properties are included (append any missing ones)
|
|
85
|
+
const missingKeys = propertyKeys.filter(key => !filteredOrder.includes(key));
|
|
86
|
+
const propertiesOrder = [...filteredOrder, ...missingKeys];
|
|
66
87
|
|
|
67
88
|
const sensors = useSensors(
|
|
68
89
|
useSensor(PointerSensor, {
|
|
@@ -144,6 +165,7 @@ export const PropertyTree = React.memo(
|
|
|
144
165
|
additionalField={additionalField}
|
|
145
166
|
errors={errors}
|
|
146
167
|
namespace={namespace}
|
|
168
|
+
propertiesOrder={propertiesOrder}
|
|
147
169
|
inferredPropertyKeys={inferredPropertyKeys}
|
|
148
170
|
onPropertyMove={onPropertyMove}
|
|
149
171
|
onPropertyRemove={onPropertyRemove}
|
|
@@ -162,19 +184,20 @@ export const PropertyTree = React.memo(
|
|
|
162
184
|
);
|
|
163
185
|
|
|
164
186
|
export function PropertyTreeEntry({
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
187
|
+
id,
|
|
188
|
+
propertyKey,
|
|
189
|
+
namespace,
|
|
190
|
+
propertyOrBuilder,
|
|
191
|
+
additionalField,
|
|
192
|
+
selectedPropertyKey,
|
|
193
|
+
errors,
|
|
194
|
+
propertiesOrder,
|
|
195
|
+
onPropertyClick,
|
|
196
|
+
onPropertyMove,
|
|
197
|
+
onPropertyRemove,
|
|
198
|
+
inferredPropertyKeys,
|
|
199
|
+
collectionEditable
|
|
200
|
+
}: {
|
|
178
201
|
id: string;
|
|
179
202
|
propertyKey: string;
|
|
180
203
|
namespace?: string;
|
|
@@ -182,6 +205,7 @@ export function PropertyTreeEntry({
|
|
|
182
205
|
additionalField?: AdditionalFieldDelegate<any>;
|
|
183
206
|
selectedPropertyKey?: string;
|
|
184
207
|
errors: Record<string, any>;
|
|
208
|
+
propertiesOrder: string[];
|
|
185
209
|
onPropertyClick?: (propertyKey: string, namespace?: string) => void;
|
|
186
210
|
onPropertyMove?: (propertiesOrder: string[], namespace?: string) => void;
|
|
187
211
|
onPropertyRemove?: (propertyKey: string, namespace?: string) => void;
|
|
@@ -226,6 +250,7 @@ export function PropertyTreeEntry({
|
|
|
226
250
|
onPropertyClick={onPropertyClick}
|
|
227
251
|
onPropertyMove={onPropertyMove}
|
|
228
252
|
onPropertyRemove={onPropertyRemove}
|
|
253
|
+
inferredPropertyKeys={inferredPropertyKeys}
|
|
229
254
|
collectionEditable={collectionEditable}
|
|
230
255
|
/>
|
|
231
256
|
}
|
|
@@ -234,11 +259,17 @@ export function PropertyTreeEntry({
|
|
|
234
259
|
const selected = selectedPropertyKey === fullId;
|
|
235
260
|
const editable = propertyOrBuilder && ((collectionEditable && !isPropertyBuilder(propertyOrBuilder)) || editableProperty(propertyOrBuilder));
|
|
236
261
|
|
|
262
|
+
// Check if this property was AI-modified
|
|
263
|
+
const aiModifiedPaths = useAIModifiedPaths();
|
|
264
|
+
const isAIModified = aiModifiedPaths?.isPathModified(`properties.${propertyKey}`) ?? false;
|
|
265
|
+
|
|
237
266
|
return (
|
|
238
267
|
<div
|
|
239
268
|
ref={setNodeRef}
|
|
240
269
|
style={style}
|
|
241
|
-
className="relative -ml-8"
|
|
270
|
+
className="relative -ml-8 cursor-grab"
|
|
271
|
+
{...attributes}
|
|
272
|
+
{...listeners}
|
|
242
273
|
>
|
|
243
274
|
<div className="relative">
|
|
244
275
|
{subtree && <div
|
|
@@ -247,7 +278,7 @@ export function PropertyTreeEntry({
|
|
|
247
278
|
left: "32px",
|
|
248
279
|
top: "64px",
|
|
249
280
|
bottom: "16px"
|
|
250
|
-
}}/>}
|
|
281
|
+
}} />}
|
|
251
282
|
|
|
252
283
|
<div>
|
|
253
284
|
{!isPropertyBuilder(propertyOrBuilder) && !additionalField && editable
|
|
@@ -256,38 +287,79 @@ export function PropertyTreeEntry({
|
|
|
256
287
|
onClick={onPropertyClick ? () => onPropertyClick(propertyKey, namespace) : undefined}
|
|
257
288
|
includeName={true}
|
|
258
289
|
selected={selected}
|
|
259
|
-
hasError={hasError}/>
|
|
290
|
+
hasError={hasError} />
|
|
260
291
|
: <NonEditablePropertyPreview name={propertyKey}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
292
|
+
property={propertyOrBuilder}
|
|
293
|
+
onClick={onPropertyClick ? () => onPropertyClick(propertyKey, namespace) : undefined}
|
|
294
|
+
selected={selected} />}
|
|
264
295
|
</div>
|
|
265
296
|
|
|
266
|
-
<div className="absolute top-
|
|
267
|
-
{
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
<
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
297
|
+
<div className="absolute top-3 right-3 flex flex-row items-center gap-1">
|
|
298
|
+
{isAIModified && <AIModifiedIndicator />}
|
|
299
|
+
{isPropertyInferred && <>
|
|
300
|
+
<Tooltip title={"Inferred property"} asChild={true}>
|
|
301
|
+
<IconButton size="smallest" disabled>
|
|
302
|
+
<FindInPageIcon size="smallest" />
|
|
303
|
+
</IconButton>
|
|
304
|
+
</Tooltip>
|
|
305
|
+
{onPropertyRemove && <Tooltip title={"Remove inferred property"}
|
|
306
|
+
asChild={true}>
|
|
307
|
+
<IconButton size="smallest"
|
|
308
|
+
color="inherit"
|
|
309
|
+
onClick={(e) => {
|
|
310
|
+
e.stopPropagation();
|
|
311
|
+
onPropertyRemove(propertyKey, namespace);
|
|
312
|
+
}}>
|
|
313
|
+
<DeleteIcon size={"smallest"} />
|
|
314
|
+
</IconButton>
|
|
315
|
+
</Tooltip>}
|
|
316
|
+
</>}
|
|
317
|
+
|
|
318
|
+
<Menu
|
|
319
|
+
trigger={
|
|
320
|
+
<IconButton
|
|
321
|
+
size="smallest"
|
|
322
|
+
>
|
|
323
|
+
<MoreVertIcon size={"smallest"} />
|
|
324
|
+
</IconButton>
|
|
325
|
+
}
|
|
326
|
+
>
|
|
327
|
+
<MenuItem
|
|
328
|
+
dense
|
|
329
|
+
onClick={() => {
|
|
330
|
+
const currentIndex = propertiesOrder.indexOf(propertyKey);
|
|
331
|
+
if (currentIndex > 0) {
|
|
332
|
+
const newOrder = propertiesOrder.filter(k => k !== propertyKey);
|
|
333
|
+
newOrder.unshift(propertyKey);
|
|
334
|
+
onPropertyMove?.(newOrder, namespace);
|
|
335
|
+
}
|
|
336
|
+
}}
|
|
337
|
+
>
|
|
338
|
+
<VerticalAlignTopIcon size="smallest" />
|
|
339
|
+
Move to top
|
|
340
|
+
</MenuItem>
|
|
341
|
+
<MenuItem
|
|
342
|
+
dense
|
|
343
|
+
onClick={() => {
|
|
344
|
+
const currentIndex = propertiesOrder.indexOf(propertyKey);
|
|
345
|
+
if (currentIndex < propertiesOrder.length - 1) {
|
|
346
|
+
const newOrder = propertiesOrder.filter(k => k !== propertyKey);
|
|
347
|
+
newOrder.push(propertyKey);
|
|
348
|
+
onPropertyMove?.(newOrder, namespace);
|
|
349
|
+
}
|
|
350
|
+
}}
|
|
351
|
+
>
|
|
352
|
+
<VerticalAlignBottomIcon size="smallest" />
|
|
353
|
+
Move to bottom
|
|
354
|
+
</MenuItem>
|
|
355
|
+
<MenuItem
|
|
356
|
+
dense
|
|
357
|
+
onClick={() => onPropertyRemove?.(propertyKey, namespace)}
|
|
287
358
|
>
|
|
288
|
-
<
|
|
289
|
-
|
|
290
|
-
|
|
359
|
+
<DeleteIcon size="smallest" />
|
|
360
|
+
Delete
|
|
361
|
+
</MenuItem>
|
|
362
|
+
</Menu>
|
|
291
363
|
|
|
292
364
|
</div>
|
|
293
365
|
|