@firecms/collection_editor 3.0.1 → 3.1.0-canary.02232f4

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 (119) hide show
  1. package/dist/ConfigControllerProvider.d.ts +6 -0
  2. package/dist/api/generateCollectionApi.d.ts +71 -0
  3. package/dist/api/index.d.ts +1 -0
  4. package/dist/index.d.ts +5 -1
  5. package/dist/index.es.js +15260 -8173
  6. package/dist/index.es.js.map +1 -1
  7. package/dist/index.umd.js +15257 -8170
  8. package/dist/index.umd.js.map +1 -1
  9. package/dist/locales/de.d.ts +120 -0
  10. package/dist/locales/en.d.ts +120 -0
  11. package/dist/locales/es.d.ts +120 -0
  12. package/dist/locales/fr.d.ts +120 -0
  13. package/dist/locales/hi.d.ts +120 -0
  14. package/dist/locales/it.d.ts +120 -0
  15. package/dist/locales/pt.d.ts +120 -0
  16. package/dist/types/collection_editor_controller.d.ts +14 -0
  17. package/dist/types/collection_inference.d.ts +8 -2
  18. package/dist/types/config_controller.d.ts +23 -2
  19. package/dist/ui/AddKanbanColumnAction.d.ts +11 -0
  20. package/dist/ui/KanbanSetupAction.d.ts +10 -0
  21. package/dist/ui/collection_editor/AICollectionGeneratorPopover.d.ts +37 -0
  22. package/dist/ui/collection_editor/AIModifiedPathsContext.d.ts +20 -0
  23. package/dist/ui/collection_editor/CollectionDetailsForm.d.ts +2 -3
  24. package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +24 -0
  25. package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +4 -1
  26. package/dist/ui/collection_editor/CollectionJsonImportDialog.d.ts +7 -0
  27. package/dist/ui/collection_editor/CollectionYupValidation.d.ts +9 -13
  28. package/dist/ui/collection_editor/DisplaySettingsForm.d.ts +3 -0
  29. package/dist/ui/collection_editor/EntityActionsEditTab.d.ts +2 -1
  30. package/dist/ui/collection_editor/ExtendSettingsForm.d.ts +14 -0
  31. package/dist/ui/collection_editor/GeneralSettingsForm.d.ts +7 -0
  32. package/dist/ui/collection_editor/KanbanConfigSection.d.ts +4 -0
  33. package/dist/ui/collection_editor/PropertyEditView.d.ts +6 -1
  34. package/dist/ui/collection_editor/PropertyTree.d.ts +2 -1
  35. package/dist/ui/collection_editor/SubcollectionsEditTab.d.ts +2 -1
  36. package/dist/ui/collection_editor/ViewModeSwitch.d.ts +6 -0
  37. package/dist/ui/collection_editor/properties/EnumPropertyField.d.ts +2 -1
  38. package/dist/ui/collection_editor/properties/conditions/ConditionsEditor.d.ts +10 -0
  39. package/dist/ui/collection_editor/properties/conditions/ConditionsPanel.d.ts +2 -0
  40. package/dist/ui/collection_editor/properties/conditions/EnumConditionsEditor.d.ts +6 -0
  41. package/dist/ui/collection_editor/properties/conditions/index.d.ts +6 -0
  42. package/dist/ui/collection_editor/properties/conditions/property_paths.d.ts +19 -0
  43. package/dist/useCollectionEditorPlugin.d.ts +7 -1
  44. package/dist/utils/validateCollectionJson.d.ts +22 -0
  45. package/package.json +15 -15
  46. package/src/ConfigControllerProvider.tsx +82 -47
  47. package/src/api/generateCollectionApi.ts +119 -0
  48. package/src/api/index.ts +1 -0
  49. package/src/index.ts +28 -1
  50. package/src/locales/de.ts +125 -0
  51. package/src/locales/en.ts +145 -0
  52. package/src/locales/es.ts +125 -0
  53. package/src/locales/fr.ts +125 -0
  54. package/src/locales/hi.ts +125 -0
  55. package/src/locales/it.ts +125 -0
  56. package/src/locales/pt.ts +125 -0
  57. package/src/types/collection_editor_controller.tsx +16 -3
  58. package/src/types/collection_inference.ts +15 -2
  59. package/src/types/config_controller.tsx +27 -2
  60. package/src/ui/AddKanbanColumnAction.tsx +203 -0
  61. package/src/ui/EditorCollectionAction.tsx +3 -3
  62. package/src/ui/EditorCollectionActionStart.tsx +1 -2
  63. package/src/ui/EditorEntityAction.tsx +3 -2
  64. package/src/ui/HomePageEditorCollectionAction.tsx +41 -13
  65. package/src/ui/KanbanSetupAction.tsx +38 -0
  66. package/src/ui/MissingReferenceWidget.tsx +1 -1
  67. package/src/ui/NewCollectionButton.tsx +4 -2
  68. package/src/ui/NewCollectionCard.tsx +7 -4
  69. package/src/ui/PropertyAddColumnComponent.tsx +4 -3
  70. package/src/ui/collection_editor/AICollectionGeneratorPopover.tsx +243 -0
  71. package/src/ui/collection_editor/AIModifiedPathsContext.tsx +88 -0
  72. package/src/ui/collection_editor/CollectionDetailsForm.tsx +222 -267
  73. package/src/ui/collection_editor/CollectionEditorDialog.tsx +270 -198
  74. package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +138 -71
  75. package/src/ui/collection_editor/CollectionJsonImportDialog.tsx +171 -0
  76. package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +202 -101
  77. package/src/ui/collection_editor/DisplaySettingsForm.tsx +335 -0
  78. package/src/ui/collection_editor/EntityActionsEditTab.tsx +106 -97
  79. package/src/ui/collection_editor/EntityActionsSelectDialog.tsx +8 -10
  80. package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +5 -7
  81. package/src/ui/collection_editor/EnumForm.tsx +153 -102
  82. package/src/ui/collection_editor/ExtendSettingsForm.tsx +94 -0
  83. package/src/ui/collection_editor/GeneralSettingsForm.tsx +335 -0
  84. package/src/ui/collection_editor/GetCodeDialog.tsx +63 -41
  85. package/src/ui/collection_editor/KanbanConfigSection.tsx +209 -0
  86. package/src/ui/collection_editor/LayoutModeSwitch.tsx +27 -43
  87. package/src/ui/collection_editor/PropertyEditView.tsx +272 -199
  88. package/src/ui/collection_editor/PropertyFieldPreview.tsx +1 -1
  89. package/src/ui/collection_editor/PropertyTree.tsx +130 -58
  90. package/src/ui/collection_editor/SubcollectionsEditTab.tsx +169 -163
  91. package/src/ui/collection_editor/UnsavedChangesDialog.tsx +0 -2
  92. package/src/ui/collection_editor/ViewModeSwitch.tsx +43 -0
  93. package/src/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +6 -3
  94. package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +5 -2
  95. package/src/ui/collection_editor/properties/BlockPropertyField.tsx +0 -2
  96. package/src/ui/collection_editor/properties/BooleanPropertyField.tsx +4 -1
  97. package/src/ui/collection_editor/properties/CommonPropertyFields.tsx +6 -4
  98. package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +126 -42
  99. package/src/ui/collection_editor/properties/EnumPropertyField.tsx +32 -24
  100. package/src/ui/collection_editor/properties/MapPropertyField.tsx +8 -9
  101. package/src/ui/collection_editor/properties/MarkdownPropertyField.tsx +128 -53
  102. package/src/ui/collection_editor/properties/NumberPropertyField.tsx +3 -1
  103. package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +5 -4
  104. package/src/ui/collection_editor/properties/StoragePropertyField.tsx +47 -52
  105. package/src/ui/collection_editor/properties/StringPropertyField.tsx +3 -1
  106. package/src/ui/collection_editor/properties/UrlPropertyField.tsx +12 -10
  107. package/src/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +23 -4
  108. package/src/ui/collection_editor/properties/conditions/ConditionsEditor.tsx +866 -0
  109. package/src/ui/collection_editor/properties/conditions/ConditionsPanel.tsx +28 -0
  110. package/src/ui/collection_editor/properties/conditions/EnumConditionsEditor.tsx +599 -0
  111. package/src/ui/collection_editor/properties/conditions/index.ts +6 -0
  112. package/src/ui/collection_editor/properties/conditions/property_paths.ts +92 -0
  113. package/src/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +5 -2
  114. package/src/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +7 -5
  115. package/src/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +10 -7
  116. package/src/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +11 -9
  117. package/src/ui/collection_editor/properties/validation/ValidationPanel.tsx +5 -2
  118. package/src/useCollectionEditorPlugin.tsx +53 -22
  119. package/src/utils/validateCollectionJson.ts +380 -0
@@ -0,0 +1,209 @@
1
+ import React, { useMemo, useRef, useState } from "react";
2
+ import {
3
+ EntityCollection,
4
+ FieldCaption,
5
+ getFieldConfig,
6
+ Property,
7
+ PropertyConfigBadge,
8
+ resolveCollection,
9
+ unslugify,
10
+ useAuthController,
11
+ useCustomizationController,
12
+ useTranslation
13
+ } from "@firecms/core";
14
+ import {
15
+ CloseIcon,
16
+ IconButton,
17
+ Select,
18
+ SelectItem,
19
+ Typography
20
+ } from "@firecms/ui";
21
+ import { useFormex } from "@firecms/formex";
22
+ import { PropertyFormDialog } from "./PropertyEditView";
23
+
24
+ export function KanbanConfigSection({
25
+ className,
26
+ forceExpanded
27
+ }: {
28
+ className?: string;
29
+ forceExpanded?: boolean;
30
+ }) {
31
+ const authController = useAuthController();
32
+ const customizationController = useCustomizationController();
33
+ const { values, setFieldValue } = useFormex<EntityCollection>();
34
+ const { t } = useTranslation();
35
+ const panelRef = useRef<HTMLDivElement>(null);
36
+ const [columnPropertyDialogOpen, setColumnPropertyDialogOpen] = useState(false);
37
+
38
+ // Resolve collection to get properties
39
+ const resolvedCollection = useMemo(() => resolveCollection({
40
+ collection: values,
41
+ path: values.path,
42
+ propertyConfigs: customizationController.propertyConfigs,
43
+ authController
44
+ }), [values, customizationController.propertyConfigs, authController]);
45
+
46
+ // Get enum string properties (for columnProperty)
47
+ const enumStringProperties = useMemo(() => {
48
+ const result: { key: string; label: string; property: Property }[] = [];
49
+ if (!resolvedCollection.properties) return result;
50
+
51
+ Object.entries(resolvedCollection.properties).forEach(([key, prop]) => {
52
+ if (prop && 'dataType' in prop && prop.dataType === 'string' && prop.enumValues) {
53
+ result.push({
54
+ key,
55
+ label: (prop as Property).name || key,
56
+ property: prop as Property
57
+ });
58
+ }
59
+ });
60
+ return result;
61
+ }, [resolvedCollection.properties]);
62
+
63
+ const kanbanConfig = values.kanban;
64
+
65
+ // Check if columnProperty references a non-existent property
66
+ const columnPropertyMissing = Boolean(kanbanConfig?.columnProperty) &&
67
+ !enumStringProperties.some(p => p.key === kanbanConfig?.columnProperty);
68
+
69
+ // Scroll to section when forceExpanded
70
+ React.useEffect(() => {
71
+ if (forceExpanded && panelRef.current) {
72
+ setTimeout(() => {
73
+ panelRef.current?.scrollIntoView({ behavior: "smooth", block: "center" });
74
+ }, 100);
75
+ }
76
+ }, [forceExpanded]);
77
+
78
+ const showCreateButton = !kanbanConfig?.columnProperty || columnPropertyMissing;
79
+ const dialogPropertyKey = columnPropertyMissing && kanbanConfig?.columnProperty
80
+ ? kanbanConfig.columnProperty
81
+ : "status";
82
+ const dialogPropertyName = columnPropertyMissing && kanbanConfig?.columnProperty
83
+ ? unslugify(kanbanConfig.columnProperty)
84
+ : "Status";
85
+
86
+ return (
87
+ <div className={className} ref={panelRef}>
88
+ <Typography variant={"label"} color={"secondary"} className={"ml-3.5"}>{t("kanban_column_property")}</Typography>
89
+ <Select
90
+ key={`column-select-${enumStringProperties.length}`}
91
+ name="kanban.columnProperty"
92
+ size={"large"}
93
+ fullWidth={true}
94
+ position={"item-aligned"}
95
+ disabled={enumStringProperties.length === 0}
96
+ error={columnPropertyMissing}
97
+ value={kanbanConfig?.columnProperty ?? ""}
98
+ onValueChange={(v) => {
99
+ if (v) {
100
+ setFieldValue("kanban", {
101
+ ...kanbanConfig,
102
+ columnProperty: v
103
+ });
104
+ } else {
105
+ setFieldValue("kanban", undefined);
106
+ }
107
+ }}
108
+ renderValue={(value) => {
109
+ if (columnPropertyMissing) {
110
+ return <span className="text-red-500">{value} ({t("not_found_suffix")})</span>;
111
+ }
112
+ const prop = enumStringProperties.find(p => p.key === value);
113
+ if (!prop) return t("select_a_property");
114
+ const fieldConfig = getFieldConfig(prop.property, customizationController.propertyConfigs);
115
+ return (
116
+ <div className="flex items-center gap-2">
117
+ <PropertyConfigBadge propertyConfig={fieldConfig} />
118
+ <span>{prop.label}</span>
119
+ </div>
120
+ );
121
+ }}
122
+ endAdornment={kanbanConfig?.columnProperty ? (
123
+ <IconButton
124
+ size="small"
125
+ onClick={(e) => {
126
+ e.stopPropagation();
127
+ setFieldValue("kanban", undefined);
128
+ }}
129
+ >
130
+ <CloseIcon size="small" />
131
+ </IconButton>
132
+ ) : undefined}
133
+ >
134
+ {enumStringProperties.map((prop) => {
135
+ const fieldConfig = getFieldConfig(prop.property, customizationController.propertyConfigs);
136
+ return (
137
+ <SelectItem key={prop.key} value={prop.key}>
138
+ <div className="flex items-center gap-3">
139
+ <PropertyConfigBadge propertyConfig={fieldConfig} />
140
+ <div>
141
+ <div>{prop.label}</div>
142
+ <Typography variant="caption" color="secondary">
143
+ {fieldConfig?.name || "enum"}
144
+ </Typography>
145
+ </div>
146
+ </div>
147
+ </SelectItem>
148
+ );
149
+ })}
150
+ </Select>
151
+ <FieldCaption error={columnPropertyMissing}>
152
+ {columnPropertyMissing
153
+ ? t("kanban_property_not_found", { property: kanbanConfig?.columnProperty ?? "" })
154
+ : enumStringProperties.length === 0
155
+ ? t("no_enum_string_properties")
156
+ : t("kanban_column_description")
157
+ }
158
+ </FieldCaption>
159
+
160
+ {showCreateButton && (
161
+ <>
162
+ <button
163
+ type="button"
164
+ className="ml-3.5 text-sm text-primary hover:text-primary-dark mt-2"
165
+ onClick={() => setColumnPropertyDialogOpen(true)}
166
+ >
167
+ {t("create_property", { property: dialogPropertyKey })}
168
+ </button>
169
+ <PropertyFormDialog
170
+ open={columnPropertyDialogOpen}
171
+ onCancel={() => setColumnPropertyDialogOpen(false)}
172
+ property={{
173
+ dataType: "string",
174
+ name: dialogPropertyName,
175
+ enumValues: [
176
+ { id: "todo", label: "To Do" },
177
+ { id: "in_progress", label: "In Progress" },
178
+ { id: "done", label: "Done" }
179
+ ]
180
+ }}
181
+ propertyKey={dialogPropertyKey}
182
+ existingProperty={false}
183
+ autoOpenTypeSelect={false}
184
+ autoUpdateId={false}
185
+ inArray={false}
186
+ allowDataInference={false}
187
+ propertyConfigs={customizationController.propertyConfigs}
188
+ collectionEditable={true}
189
+ existingPropertyKeys={Object.keys(values.properties ?? {})}
190
+ onPropertyChanged={({ id, property }) => {
191
+ const newProperties = {
192
+ ...values.properties,
193
+ [id!]: property
194
+ };
195
+ const newPropertiesOrder = [...(values.propertiesOrder ?? Object.keys(values.properties ?? {})), id];
196
+ setFieldValue("properties", newProperties);
197
+ setFieldValue("propertiesOrder", newPropertiesOrder);
198
+ setFieldValue("kanban", {
199
+ ...kanbanConfig,
200
+ columnProperty: id
201
+ });
202
+ setColumnPropertyDialogOpen(false);
203
+ }}
204
+ />
205
+ </>
206
+ )}
207
+ </div>
208
+ );
209
+ }
@@ -1,54 +1,38 @@
1
- import { Card, cls, SquareIcon, Tooltip, Typography, VerticalSplitIcon } from "@firecms/ui";
1
+ import { cls, SquareIcon, ToggleButtonGroup, Typography, VerticalSplitIcon } from "@firecms/ui";
2
+ import { useTranslation } from "@firecms/core";
2
3
 
3
4
  export function LayoutModeSwitch({
4
- value,
5
- onChange,
6
- className
7
- }: {
5
+ value,
6
+ onChange,
7
+ className
8
+ }: {
8
9
  value: "side_panel" | "full_screen";
9
10
  onChange: (value: "side_panel" | "full_screen") => void;
10
11
  className?: string;
11
12
  }) {
12
13
 
13
- return <div className={cls(className)}>
14
- <Typography variant={"label"} color={"secondary"} className={"ml-3.5"}>Document view</Typography>
15
- <div className={cls("flex flex-row gap-4")}>
16
-
17
- <Tooltip title={"Documents are open in a side panel"}>
18
- <Card
19
- onClick={() => onChange("side_panel")}
20
- className={cls(
21
- "my-2 rounded-md mx-0 p-4 focus:outline-none transition ease-in-out duration-150 flex flex-row gap-4 items-center",
22
- "text-surface-700 dark:text-surface-accent-300",
23
- "hover:text-primary-dark dark:hover:text-primary focus:ring-primary hover:ring-1 hover:ring-primary",
24
- value === "side_panel" ? "border-primary dark:border-primary" : "border-surface-400 dark:border-surface-600",
25
- )}
26
- >
27
- <VerticalSplitIcon/>
28
- <Typography variant={"label"}>
29
- Side panel
30
- </Typography>
31
- </Card>
32
- </Tooltip>
33
-
34
- <Tooltip title={"Documents are open full-screen"}>
35
- <Card
36
- onClick={() => onChange("full_screen")}
37
- className={cls(
38
- "my-2 rounded-md mx-0 p-4 focus:outline-none transition ease-in-out duration-150 flex flex-row gap-4 items-center",
39
- "text-surface-700 dark:text-surface-accent-300",
40
- "hover:text-primary-dark dark:hover:text-primary focus:ring-primary hover:ring-1 hover:ring-primary",
41
- value === "full_screen" ? "border-primary dark:border-primary" : "border-surface-400 dark:border-surface-600",
42
- )}
43
- >
44
- <SquareIcon/>
45
- <Typography variant={"label"}>
46
- Full screen
47
- </Typography>
48
- </Card>
49
- </Tooltip>
14
+ const { t } = useTranslation();
50
15
 
16
+ return <div className={cls(className)}>
17
+ <Typography variant={"label"} color={"secondary"} className={"ml-3.5"}>{t("document_view")}</Typography>
18
+ <div className={"my-2"}>
19
+ <ToggleButtonGroup
20
+ value={value}
21
+ onValueChange={onChange}
22
+ options={[
23
+ {
24
+ value: "side_panel",
25
+ label: t("side_panel"),
26
+ icon: <VerticalSplitIcon />
27
+ },
28
+ {
29
+ value: "full_screen",
30
+ label: t("full_screen"),
31
+ icon: <SquareIcon />
32
+ }
33
+ ]}
34
+ />
51
35
  </div>
52
- <Typography variant={"caption"} color={"secondary"} className={"ml-3.5"}>Should documents be opened full screen or in an inline side dialog</Typography>
36
+ <Typography variant={"caption"} color={"secondary"} className={"ml-3.5"}>{t("should_documents_opened_full_screen")}</Typography>
53
37
  </div>
54
38
  }