@firecms/collection_editor 3.0.0-alpha.5 → 3.0.0-alpha.51

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 (140) hide show
  1. package/dist/ConfigControllerProvider.d.ts +36 -0
  2. package/dist/index.d.ts +11 -0
  3. package/dist/index.es.js +6995 -0
  4. package/dist/index.es.js.map +1 -0
  5. package/dist/index.umd.js +4 -0
  6. package/dist/index.umd.js.map +1 -0
  7. package/dist/types/collection_editor_controller.d.ts +35 -0
  8. package/dist/types/collection_inference.d.ts +2 -0
  9. package/dist/types/config_controller.d.ts +41 -0
  10. package/dist/types/config_permissions.d.ts +19 -0
  11. package/dist/types/persisted_collection.d.ts +6 -0
  12. package/dist/ui/CollectionViewHeaderAction.d.ts +10 -0
  13. package/dist/ui/EditorCollectionAction.d.ts +2 -0
  14. package/dist/ui/HomePageEditorCollectionAction.d.ts +2 -0
  15. package/dist/ui/MissingReferenceWidget.d.ts +3 -0
  16. package/dist/ui/NewCollectionCard.d.ts +2 -0
  17. package/dist/ui/PropertyAddColumnComponent.d.ts +6 -0
  18. package/dist/ui/RootCollectionSuggestions.d.ts +1 -0
  19. package/dist/ui/collection_editor/CollectionDetailsForm.d.ts +9 -0
  20. package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +38 -0
  21. package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +15 -0
  22. package/dist/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +20 -0
  23. package/dist/ui/collection_editor/CollectionYupValidation.d.ts +14 -0
  24. package/dist/ui/collection_editor/EntityCustomViewsSelectDialog.d.ts +4 -0
  25. package/dist/ui/collection_editor/EnumForm.d.ts +13 -0
  26. package/dist/ui/collection_editor/GetCodeDialog.d.ts +5 -0
  27. package/dist/ui/collection_editor/PropertyEditView.d.ts +40 -0
  28. package/dist/ui/collection_editor/PropertyFieldPreview.d.ts +15 -0
  29. package/dist/ui/collection_editor/PropertySelectItem.d.ts +8 -0
  30. package/dist/ui/collection_editor/PropertyTree.d.ts +32 -0
  31. package/dist/ui/collection_editor/SelectIcons.d.ts +6 -0
  32. package/dist/ui/collection_editor/SubcollectionsEditTab.d.ts +12 -0
  33. package/dist/ui/collection_editor/UnsavedChangesDialog.d.ts +9 -0
  34. package/dist/ui/collection_editor/import/CollectionEditorImportDataPreview.d.ts +7 -0
  35. package/dist/ui/collection_editor/import/CollectionEditorImportMapping.d.ts +7 -0
  36. package/dist/ui/collection_editor/import/clean_import_data.d.ts +7 -0
  37. package/dist/ui/collection_editor/properties/BlockPropertyField.d.ts +8 -0
  38. package/dist/ui/collection_editor/properties/BooleanPropertyField.d.ts +3 -0
  39. package/dist/ui/collection_editor/properties/CommonPropertyFields.d.ts +10 -0
  40. package/dist/ui/collection_editor/properties/DateTimePropertyField.d.ts +3 -0
  41. package/dist/ui/collection_editor/properties/EnumPropertyField.d.ts +8 -0
  42. package/dist/ui/collection_editor/properties/FieldHelperView.d.ts +4 -0
  43. package/dist/ui/collection_editor/properties/KeyValuePropertyField.d.ts +3 -0
  44. package/dist/ui/collection_editor/properties/MapPropertyField.d.ts +8 -0
  45. package/dist/ui/collection_editor/properties/NumberPropertyField.d.ts +3 -0
  46. package/dist/ui/collection_editor/properties/ReferencePropertyField.d.ts +13 -0
  47. package/dist/ui/collection_editor/properties/RepeatPropertyField.d.ts +10 -0
  48. package/dist/ui/collection_editor/properties/StoragePropertyField.d.ts +5 -0
  49. package/dist/ui/collection_editor/properties/StringPropertyField.d.ts +5 -0
  50. package/dist/ui/collection_editor/properties/UrlPropertyField.d.ts +4 -0
  51. package/dist/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.d.ts +3 -0
  52. package/dist/ui/collection_editor/properties/validation/ArrayPropertyValidation.d.ts +5 -0
  53. package/dist/ui/collection_editor/properties/validation/GeneralPropertyValidation.d.ts +4 -0
  54. package/dist/ui/collection_editor/properties/validation/NumberPropertyValidation.d.ts +3 -0
  55. package/dist/ui/collection_editor/properties/validation/StringPropertyValidation.d.ts +11 -0
  56. package/dist/ui/collection_editor/properties/validation/ValidationPanel.d.ts +2 -0
  57. package/dist/ui/collection_editor/templates/blog_template.d.ts +2 -0
  58. package/dist/ui/collection_editor/templates/products_template.d.ts +2 -0
  59. package/dist/ui/collection_editor/templates/users_template.d.ts +2 -0
  60. package/dist/ui/collection_editor/util.d.ts +4 -0
  61. package/dist/ui/collection_editor/utils/strings.d.ts +1 -0
  62. package/dist/ui/collection_editor/utils/supported_fields.d.ts +3 -0
  63. package/dist/ui/collection_editor/utils/update_property_for_widget.d.ts +2 -0
  64. package/dist/ui/collection_editor/utils/useTraceUpdate.d.ts +1 -0
  65. package/dist/useCollectionEditorController.d.ts +6 -0
  66. package/dist/useCollectionEditorPlugin.d.ts +45 -0
  67. package/dist/useCollectionsConfigController.d.ts +6 -0
  68. package/dist/utils/arrays.d.ts +1 -0
  69. package/dist/utils/entities.d.ts +3 -0
  70. package/dist/utils/icons.d.ts +1 -0
  71. package/dist/utils/synonyms.d.ts +1951 -0
  72. package/package.json +26 -23
  73. package/src/ConfigControllerProvider.tsx +321 -0
  74. package/src/index.ts +35 -0
  75. package/src/types/collection_editor_controller.tsx +42 -0
  76. package/src/types/collection_inference.ts +3 -0
  77. package/src/types/config_controller.tsx +50 -0
  78. package/src/types/config_permissions.ts +20 -0
  79. package/src/types/persisted_collection.ts +9 -0
  80. package/src/ui/CollectionViewHeaderAction.tsx +42 -0
  81. package/src/ui/EditorCollectionAction.tsx +95 -0
  82. package/src/ui/HomePageEditorCollectionAction.tsx +88 -0
  83. package/src/ui/MissingReferenceWidget.tsx +34 -0
  84. package/src/ui/NewCollectionCard.tsx +46 -0
  85. package/src/ui/PropertyAddColumnComponent.tsx +41 -0
  86. package/src/ui/RootCollectionSuggestions.tsx +62 -0
  87. package/src/ui/collection_editor/CollectionDetailsForm.tsx +353 -0
  88. package/src/ui/collection_editor/CollectionEditorDialog.tsx +744 -0
  89. package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +212 -0
  90. package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +480 -0
  91. package/src/ui/collection_editor/CollectionYupValidation.tsx +7 -0
  92. package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +36 -0
  93. package/src/ui/collection_editor/EnumForm.tsx +356 -0
  94. package/src/ui/collection_editor/GetCodeDialog.tsx +118 -0
  95. package/src/ui/collection_editor/PropertyEditView.tsx +565 -0
  96. package/src/ui/collection_editor/PropertyFieldPreview.tsx +201 -0
  97. package/src/ui/collection_editor/PropertySelectItem.tsx +31 -0
  98. package/src/ui/collection_editor/PropertyTree.tsx +238 -0
  99. package/src/ui/collection_editor/SelectIcons.tsx +72 -0
  100. package/src/ui/collection_editor/SubcollectionsEditTab.tsx +252 -0
  101. package/src/ui/collection_editor/UnsavedChangesDialog.tsx +47 -0
  102. package/src/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +37 -0
  103. package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +275 -0
  104. package/src/ui/collection_editor/import/clean_import_data.ts +53 -0
  105. package/src/ui/collection_editor/properties/BlockPropertyField.tsx +134 -0
  106. package/src/ui/collection_editor/properties/BooleanPropertyField.tsx +36 -0
  107. package/src/ui/collection_editor/properties/CommonPropertyFields.tsx +111 -0
  108. package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +86 -0
  109. package/src/ui/collection_editor/properties/EnumPropertyField.tsx +116 -0
  110. package/src/ui/collection_editor/properties/FieldHelperView.tsx +13 -0
  111. package/src/ui/collection_editor/properties/KeyValuePropertyField.tsx +20 -0
  112. package/src/ui/collection_editor/properties/MapPropertyField.tsx +157 -0
  113. package/src/ui/collection_editor/properties/NumberPropertyField.tsx +38 -0
  114. package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +184 -0
  115. package/src/ui/collection_editor/properties/RepeatPropertyField.tsx +107 -0
  116. package/src/ui/collection_editor/properties/StoragePropertyField.tsx +194 -0
  117. package/src/ui/collection_editor/properties/StringPropertyField.tsx +79 -0
  118. package/src/ui/collection_editor/properties/UrlPropertyField.tsx +89 -0
  119. package/src/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +36 -0
  120. package/src/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +50 -0
  121. package/src/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +49 -0
  122. package/src/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +99 -0
  123. package/src/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +131 -0
  124. package/src/ui/collection_editor/properties/validation/ValidationPanel.tsx +28 -0
  125. package/src/ui/collection_editor/templates/blog_template.ts +115 -0
  126. package/src/ui/collection_editor/templates/products_template.ts +88 -0
  127. package/src/ui/collection_editor/templates/users_template.ts +34 -0
  128. package/src/ui/collection_editor/util.ts +21 -0
  129. package/src/ui/collection_editor/utils/strings.ts +8 -0
  130. package/src/ui/collection_editor/utils/supported_fields.tsx +29 -0
  131. package/src/ui/collection_editor/utils/update_property_for_widget.ts +271 -0
  132. package/src/ui/collection_editor/utils/useTraceUpdate.tsx +23 -0
  133. package/src/useCollectionEditorController.tsx +9 -0
  134. package/src/useCollectionEditorPlugin.tsx +128 -0
  135. package/src/useCollectionsConfigController.tsx +9 -0
  136. package/src/utils/arrays.ts +3 -0
  137. package/src/utils/entities.ts +38 -0
  138. package/src/utils/icons.ts +17 -0
  139. package/src/utils/synonyms.ts +1952 -0
  140. package/src/vite-env.d.ts +1 -0
@@ -0,0 +1,201 @@
1
+ import {
2
+ cardClickableMixin,
3
+ cardMixin,
4
+ cardSelectedMixin,
5
+ cn,
6
+ ErrorBoundary,
7
+ FieldConfigBadge,
8
+ FunctionsIcon,
9
+ getFieldConfig,
10
+ isPropertyBuilder,
11
+ Paper,
12
+ Property,
13
+ PropertyOrBuilder,
14
+ RemoveCircleIcon,
15
+ Typography,
16
+ useFireCMSContext
17
+ } from "@firecms/core";
18
+
19
+ import { editableProperty } from "../../utils/entities";
20
+
21
+ export function PropertyFieldPreview({
22
+ property,
23
+ onClick,
24
+ hasError,
25
+ includeName,
26
+ includeEditButton,
27
+ selected
28
+ }: {
29
+ property: Property,
30
+ hasError?: boolean,
31
+ selected?: boolean,
32
+ includeName?: boolean,
33
+ includeEditButton?: boolean;
34
+ onClick?: () => void
35
+ }) {
36
+
37
+ const { propertyConfigs } = useFireCMSContext();
38
+
39
+ const propertyConfig = getFieldConfig(property, propertyConfigs);
40
+ const disabled = !editableProperty(property);
41
+
42
+ const borderColorClass = hasError
43
+ ? "border-red-500"
44
+ : (selected ? "border-blue-500" : "border-transparent");
45
+
46
+ return <ErrorBoundary>
47
+ <div
48
+ onClick={onClick}
49
+ className="flex flex-row w-full cursor-pointer">
50
+ <div className={"m-4"}>
51
+ <FieldConfigBadge propertyConfig={propertyConfig}/>
52
+ </div>
53
+ <Paper
54
+ className={cn(
55
+ "pl-2 w-full flex flex-row gap-4 items-center",
56
+ cardMixin,
57
+ onClick ? cardClickableMixin : "",
58
+ selected ? cardSelectedMixin : "",
59
+ "flex-grow p-4 border transition-colors duration-200",
60
+ borderColorClass
61
+ )}
62
+ >
63
+
64
+ <div className="w-full flex flex-col">
65
+
66
+ {includeName &&
67
+ <ErrorBoundary>
68
+ <Typography variant="body1"
69
+ component="span"
70
+ className="flex-grow pr-2">
71
+ {property.name
72
+ ? property.name
73
+ : "\u00a0"
74
+ }
75
+ </Typography>
76
+ </ErrorBoundary>}
77
+
78
+ <div className="flex flex-row items-center">
79
+ <ErrorBoundary>
80
+ <Typography className="flex-grow pr-2"
81
+ variant={includeName ? "body2" : "subtitle1"}
82
+ component="span"
83
+ color="secondary">
84
+ {propertyConfig?.name}
85
+ </Typography>
86
+ </ErrorBoundary>
87
+ <ErrorBoundary>
88
+ <Typography variant="body2"
89
+ component="span"
90
+ color="disabled">
91
+ {property.dataType}
92
+ </Typography>
93
+ </ErrorBoundary>
94
+
95
+ </div>
96
+ </div>
97
+
98
+ {includeEditButton && <Typography variant={"button"}>
99
+ EDIT
100
+ </Typography>}
101
+
102
+ </Paper>
103
+ </div>
104
+ </ErrorBoundary>
105
+ }
106
+
107
+ export function NonEditablePropertyPreview({
108
+ name,
109
+ selected,
110
+ onClick,
111
+ property
112
+ }: {
113
+ name: string,
114
+ selected: boolean,
115
+ onClick?: () => void,
116
+ property?: PropertyOrBuilder
117
+ }) {
118
+
119
+ const { propertyConfigs } = useFireCMSContext();
120
+
121
+ const propertyConfig = !isPropertyBuilder(property) && property ? getFieldConfig(property, propertyConfigs) : undefined;
122
+
123
+ return (
124
+ <div
125
+ onClick={onClick}
126
+ className="flex flex-row w-full cursor-pointer">
127
+ <div className={"relative m-4"}>
128
+ {propertyConfig && <FieldConfigBadge propertyConfig={propertyConfig}/>}
129
+ {!propertyConfig && <div
130
+ className={"h-8 w-8 p-1 rounded-full shadow text-white bg-gray-500"}>
131
+ <FunctionsIcon color={"inherit"} size={"medium"}/>
132
+ </div>}
133
+ <RemoveCircleIcon color={"disabled"} size={"small"} className={"absolute -right-2 -top-2"}/>
134
+ </div>
135
+ <Paper
136
+ className={cn(
137
+ "pl-2 w-full flex flex-row gap-4 items-center",
138
+ cardMixin,
139
+ onClick ? cardClickableMixin : "",
140
+ selected ? cardSelectedMixin : "",
141
+ "flex-grow p-4 border transition-colors duration-200",
142
+ selected ? "border-blue-500" : "border-transparent")}
143
+ >
144
+
145
+ <div className="w-full flex flex-col">
146
+ <Typography variant="body1"
147
+ component="span"
148
+ className="flex-grow pr-2">
149
+ {property?.name
150
+ ? property.name
151
+ : name
152
+ }
153
+ </Typography>
154
+
155
+ <div className="flex flex-row items-center">
156
+ {propertyConfig && <Typography className="flex-grow pr-2"
157
+ variant={"body2"}
158
+ component="span"
159
+ color="secondary">
160
+ {propertyConfig?.name}
161
+ </Typography>}
162
+
163
+ {property && !isPropertyBuilder(property) && <ErrorBoundary>
164
+ <Typography variant="body2"
165
+ component="span"
166
+ color="disabled">
167
+ {property.dataType}
168
+ </Typography>
169
+ </ErrorBoundary>}
170
+
171
+ {property && isPropertyBuilder(property) && <ErrorBoundary>
172
+ <Typography variant="body2"
173
+ component="span"
174
+ color="disabled">
175
+ This property is defined as a property builder in code
176
+ </Typography>
177
+ </ErrorBoundary>}
178
+
179
+ {!property && <ErrorBoundary>
180
+ <Typography variant="body2"
181
+ component="span"
182
+ color="disabled">
183
+ This field is defined as an additional field in code
184
+ </Typography>
185
+ </ErrorBoundary>}
186
+
187
+ </div>
188
+
189
+ {/*<div className="flex flex-row text-xs">*/}
190
+ {/* <Typography className="flex-grow pr-2"*/}
191
+ {/* variant="body2"*/}
192
+ {/* component="span"*/}
193
+ {/* color="secondary">*/}
194
+ {/* This field can only be edited in code*/}
195
+ {/* </Typography>*/}
196
+ {/*</div>*/}
197
+ </div>
198
+
199
+ </Paper>
200
+ </div>)
201
+ }
@@ -0,0 +1,31 @@
1
+ import { cn, FieldConfigBadge, PropertyConfig, SelectItem, Typography } from "@firecms/core";
2
+
3
+ export interface PropertySelectItemProps {
4
+ value: string;
5
+ optionDisabled: boolean;
6
+ propertyConfig: PropertyConfig;
7
+ existing: boolean;
8
+ }
9
+
10
+ export function PropertySelectItem({ value, optionDisabled, propertyConfig, existing }: PropertySelectItemProps) {
11
+ return <SelectItem value={value}
12
+ disabled={optionDisabled}
13
+ className={"flex flex-row items-center"}>
14
+ <div
15
+ className={cn(
16
+ "flex flex-row items-center text-base min-h-[52px]",
17
+ optionDisabled ? "w-full" : "")}>
18
+ <div className={"mr-8"}>
19
+ <FieldConfigBadge propertyConfig={propertyConfig}/>
20
+ </div>
21
+ <div>
22
+ <div>{propertyConfig.name}</div>
23
+ <Typography variant={"caption"}
24
+ color={"disabled"}
25
+ className={"max-w-sm"}>
26
+ {existing && optionDisabled ? "You can only switch to widgets that use the same data type" : propertyConfig.description}
27
+ </Typography>
28
+ </div>
29
+ </div>
30
+ </SelectItem>
31
+ }
@@ -0,0 +1,238 @@
1
+ import {
2
+ AdditionalFieldDelegate,
3
+ AutoAwesomeIcon,
4
+ CMSType,
5
+ defaultBorderMixin,
6
+ DragHandleIcon,
7
+ ErrorBoundary,
8
+ IconButton,
9
+ isPropertyBuilder,
10
+ PropertiesOrBuilders,
11
+ PropertyOrBuilder,
12
+ RemoveIcon,
13
+ Tooltip
14
+ } from "@firecms/core";
15
+ import { NonEditablePropertyPreview, PropertyFieldPreview } from "./PropertyFieldPreview";
16
+ import { DragDropContext, Draggable, DraggableProvided, Droppable } from "@hello-pangea/dnd";
17
+ import { getFullId, idToPropertiesPath } from "./util";
18
+ import { getIn } from "formik";
19
+ import { editableProperty } from "../../utils/entities";
20
+ import { useCallback } from "react";
21
+
22
+ export function PropertyTree<M extends {
23
+ [Key: string]: CMSType
24
+ }>({
25
+ namespace,
26
+ selectedPropertyKey,
27
+ onPropertyClick,
28
+ properties,
29
+ propertiesOrder: propertiesOrderProp,
30
+ additionalFields,
31
+ errors,
32
+ onPropertyMove,
33
+ onPropertyRemove,
34
+ className,
35
+ inferredPropertyKeys,
36
+ collectionEditable,
37
+ }: {
38
+ namespace?: string;
39
+ selectedPropertyKey?: string;
40
+ onPropertyClick?: (propertyKey: string, namespace?: string) => void;
41
+ properties: PropertiesOrBuilders<M>;
42
+ propertiesOrder?: string[];
43
+ additionalFields?: AdditionalFieldDelegate<M>[];
44
+ errors: Record<string, any>;
45
+ onPropertyMove?: (propertiesOrder: string[], namespace?: string) => void;
46
+ onPropertyRemove?: (propertyKey: string, namespace?: string) => void;
47
+ className?: string;
48
+ inferredPropertyKeys?: string[];
49
+ collectionEditable: boolean;
50
+ }) {
51
+
52
+ const propertiesOrder = propertiesOrderProp ?? Object.keys(properties);
53
+
54
+ const onDragEnd = useCallback((result: any) => {
55
+ // dropped outside the list
56
+ if (!result.destination) {
57
+ return;
58
+ }
59
+ const startIndex = result.source.index;
60
+ const endIndex = result.destination.index;
61
+
62
+ const newPropertiesOrder = Array.from(propertiesOrder);
63
+ const [removed] = newPropertiesOrder.splice(startIndex, 1);
64
+ newPropertiesOrder.splice(endIndex, 0, removed);
65
+ if (onPropertyMove)
66
+ onPropertyMove(newPropertiesOrder, namespace);
67
+ }, [namespace, onPropertyMove, propertiesOrder])
68
+
69
+ return (
70
+ <>
71
+
72
+ <DragDropContext onDragEnd={onDragEnd}>
73
+ <Droppable droppableId={`droppable_${namespace}`}>
74
+ {(droppableProvided, droppableSnapshot) => (
75
+ <div
76
+ {...droppableProvided.droppableProps}
77
+ ref={droppableProvided.innerRef}
78
+ className={className}>
79
+ {propertiesOrder && propertiesOrder
80
+ // .filter((propertyKey) => Boolean(properties[propertyKey]))
81
+ .map((propertyKey: string, index: number) => {
82
+ const property = properties[propertyKey] as PropertyOrBuilder;
83
+ const additionalField = additionalFields?.find(field => field.key === propertyKey);
84
+
85
+ if (!property && !additionalField) {
86
+ console.warn(`Property ${propertyKey} not found in properties or additionalFields`);
87
+ return null;
88
+ }
89
+ return (
90
+ <Draggable
91
+ key={`array_field_${namespace}_${propertyKey}}`}
92
+ draggableId={`array_field_${namespace}_${propertyKey}}`}
93
+ index={index}>
94
+ {(provided, snapshot) => {
95
+ return (
96
+ <ErrorBoundary>
97
+ <PropertyTreeEntry
98
+ propertyKey={propertyKey as string}
99
+ propertyOrBuilder={property}
100
+ additionalField={additionalField}
101
+ provided={provided}
102
+ errors={errors}
103
+ namespace={namespace}
104
+ inferredPropertyKeys={inferredPropertyKeys}
105
+ onPropertyMove={onPropertyMove}
106
+ onPropertyRemove={onPropertyRemove}
107
+ onPropertyClick={snapshot.isDragging ? undefined : onPropertyClick}
108
+ selectedPropertyKey={selectedPropertyKey}
109
+ collectionEditable={collectionEditable}
110
+ />
111
+ </ErrorBoundary>
112
+ );
113
+ }}
114
+ </Draggable>);
115
+ }).filter(Boolean)}
116
+
117
+ {droppableProvided.placeholder}
118
+
119
+ </div>
120
+ )}
121
+ </Droppable>
122
+ </DragDropContext>
123
+
124
+ </>
125
+ );
126
+ }
127
+
128
+ export function PropertyTreeEntry({
129
+ propertyKey,
130
+ namespace,
131
+ propertyOrBuilder,
132
+ additionalField,
133
+ provided,
134
+ selectedPropertyKey,
135
+ errors,
136
+ onPropertyClick,
137
+ onPropertyMove,
138
+ onPropertyRemove,
139
+ inferredPropertyKeys,
140
+ collectionEditable,
141
+ }: {
142
+ propertyKey: string;
143
+ namespace?: string;
144
+ propertyOrBuilder: PropertyOrBuilder;
145
+ additionalField?: AdditionalFieldDelegate<any>;
146
+ selectedPropertyKey?: string;
147
+ provided: DraggableProvided;
148
+ errors: Record<string, any>;
149
+ onPropertyClick?: (propertyKey: string, namespace?: string) => void;
150
+ onPropertyMove?: (propertiesOrder: string[], namespace?: string) => void;
151
+ onPropertyRemove?: (propertyKey: string, namespace?: string) => void;
152
+ inferredPropertyKeys?: string[];
153
+ collectionEditable: boolean;
154
+ }) {
155
+
156
+ const isPropertyInferred = inferredPropertyKeys?.includes(namespace ? `${namespace}.${propertyKey}` : propertyKey);
157
+
158
+ const fullId = getFullId(propertyKey, namespace);
159
+
160
+ let subtree;
161
+ if (typeof propertyOrBuilder === "object") {
162
+ const property = propertyOrBuilder;
163
+ if (property.dataType === "map" && property.properties) {
164
+ subtree = <PropertyTree
165
+ selectedPropertyKey={selectedPropertyKey}
166
+ namespace={fullId}
167
+ properties={property.properties}
168
+ propertiesOrder={property.propertiesOrder}
169
+ errors={errors}
170
+ onPropertyClick={onPropertyClick}
171
+ onPropertyMove={onPropertyMove}
172
+ onPropertyRemove={onPropertyRemove}
173
+ collectionEditable={collectionEditable}
174
+ />
175
+ }
176
+ }
177
+
178
+ const hasError = fullId ? getIn(errors, idToPropertiesPath(fullId)) : false;
179
+ const selected = selectedPropertyKey === fullId;
180
+ const editable = propertyOrBuilder && ((collectionEditable && !isPropertyBuilder(propertyOrBuilder)) || editableProperty(propertyOrBuilder));
181
+
182
+ return (
183
+ <div
184
+ ref={provided.innerRef}
185
+ {...provided.draggableProps}
186
+ {...provided.dragHandleProps}
187
+ className="relative -ml-8"
188
+ >
189
+ {subtree && <div
190
+ className={"absolute border-l " + defaultBorderMixin}
191
+ style={{
192
+ left: "32px",
193
+ top: "64px",
194
+ bottom: "16px"
195
+ }}/>}
196
+
197
+ {!isPropertyBuilder(propertyOrBuilder) && !additionalField && editable
198
+ ? <PropertyFieldPreview
199
+ property={propertyOrBuilder}
200
+ onClick={onPropertyClick ? () => onPropertyClick(propertyKey, namespace) : undefined}
201
+ includeName={true}
202
+ selected={selected}
203
+ hasError={hasError}/>
204
+ : <NonEditablePropertyPreview name={propertyKey}
205
+ property={propertyOrBuilder}
206
+ onClick={onPropertyClick ? () => onPropertyClick(propertyKey, namespace) : undefined}
207
+ selected={selected}/>}
208
+
209
+ <div className="absolute top-2 right-2 flex flex-row ">
210
+
211
+ {isPropertyInferred && <Tooltip title={"Inferred property"}>
212
+ <AutoAwesomeIcon size="small" className={"p-2"}/>
213
+ </Tooltip>}
214
+
215
+ {onPropertyRemove && <Tooltip title={"Remove"}>
216
+ <IconButton size="small"
217
+ color="inherit"
218
+ onClick={() => onPropertyRemove(propertyKey, namespace)}>
219
+ <RemoveIcon size={"small"}/>
220
+ </IconButton>
221
+ </Tooltip>}
222
+
223
+ {onPropertyMove && <Tooltip title={"Move"}>
224
+ <IconButton
225
+ component={"span"}
226
+ size="small"
227
+ >
228
+ <DragHandleIcon size={"small"}/>
229
+ </IconButton>
230
+ </Tooltip>}
231
+ </div>
232
+
233
+
234
+ {subtree && <div className={"ml-16"}>{subtree}</div>}
235
+ </div>
236
+ );
237
+
238
+ }
@@ -0,0 +1,72 @@
1
+ import * as React from "react";
2
+ import synonyms from "../../utils/synonyms";
3
+ import { iconsSearch } from "../../utils/icons";
4
+ import { coolIconKeys, debounce, Icon, IconButton, iconKeys, SearchBar, Tooltip } from "@firecms/core";
5
+
6
+ const UPDATE_SEARCH_INDEX_WAIT_MS = 220;
7
+
8
+ if (process.env.NODE_ENV !== "production") {
9
+ Object.keys(synonyms).forEach((icon: string) => {
10
+ if (!iconKeys.includes(icon)) {
11
+ console.warn(`The icon ${icon} no longer exists. Remove it from \`synonyms\``);
12
+ }
13
+ });
14
+ }
15
+
16
+ interface SearchIconsProps {
17
+ selectedIcon?: string;
18
+ onIconSelected: (icon: string) => void;
19
+ }
20
+
21
+ export function SearchIcons({ selectedIcon = "", onIconSelected }: SearchIconsProps) {
22
+ const [keys, setKeys] = React.useState<string[] | null>(null);
23
+ const [query, setQuery] = React.useState<string>("");
24
+
25
+ const updateSearchResults = React.useMemo(() =>
26
+ debounce((value: string) => {
27
+ if (!value || value === "") {
28
+ setKeys(null);
29
+ } else {
30
+ const searchResult = iconsSearch.search(value);
31
+ setKeys(searchResult.map((e:any) => e.key));
32
+ }
33
+ }, UPDATE_SEARCH_INDEX_WAIT_MS), []
34
+ );
35
+
36
+ React.useEffect(() => {
37
+ updateSearchResults(query);
38
+ return () => {
39
+ updateSearchResults.clear();
40
+ };
41
+ }, [query, updateSearchResults]);
42
+
43
+ const icons = keys === null ? coolIconKeys : keys;
44
+
45
+ return (
46
+ <>
47
+ <SearchBar
48
+ autoFocus
49
+ className={"w-full sticky top-0 z-10"}
50
+ onTextSearch={(value?: string) => setQuery(value ?? "")}
51
+ placeholder="Search for more icons…"
52
+ />
53
+
54
+ <div className={"flex max-w-full flex-wrap mt-4"}>
55
+ {icons.map((icon: string) => {
56
+ return (
57
+ <Tooltip title={icon} key={icon}>
58
+ <IconButton
59
+ shape={"square"}
60
+ toggled={selectedIcon === icon}
61
+ onClick={() => onIconSelected(icon)}
62
+ className="box-content m-1"
63
+ >
64
+ <Icon iconKey={icon} size={24} />
65
+ </IconButton>
66
+ </Tooltip>
67
+ );
68
+ })}
69
+ </div>
70
+ </>
71
+ );
72
+ }