@firecms/collection_editor 3.0.0-alpha.27 → 3.0.0-alpha.29

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 (43) hide show
  1. package/dist/components/CollectionViewHeaderAction.d.ts +3 -1
  2. package/dist/components/PropertyAddColumnComponent.d.ts +2 -2
  3. package/dist/components/collection_editor/CollectionPropertiesEditorForm.d.ts +5 -4
  4. package/dist/components/collection_editor/PropertyEditView.d.ts +4 -3
  5. package/dist/components/collection_editor/PropertySelectItem.d.ts +3 -3
  6. package/dist/components/collection_editor/PropertyTree.d.ts +4 -2
  7. package/dist/components/collection_editor/import/CollectionEditorImportMapping.d.ts +4 -3
  8. package/dist/components/collection_editor/properties/BlockPropertyField.d.ts +4 -3
  9. package/dist/components/collection_editor/properties/MapPropertyField.d.ts +4 -3
  10. package/dist/components/collection_editor/properties/RepeatPropertyField.d.ts +4 -3
  11. package/dist/components/collection_editor/templates/blog_template.d.ts +1 -1
  12. package/dist/components/collection_editor/templates/products_template.d.ts +1 -1
  13. package/dist/components/collection_editor/templates/users_template.d.ts +1 -1
  14. package/dist/components/collection_editor/utils/supported_fields.d.ts +1 -1
  15. package/dist/components/collection_editor/utils/update_property_for_widget.d.ts +2 -2
  16. package/dist/index.es.js +1967 -1914
  17. package/dist/index.es.js.map +1 -1
  18. package/dist/index.umd.js +1 -1
  19. package/dist/index.umd.js.map +1 -1
  20. package/dist/types/collection_editor_controller.d.ts +4 -2
  21. package/dist/types/config_controller.d.ts +8 -0
  22. package/dist/types/persisted_collection.d.ts +2 -1
  23. package/dist/useCollectionEditorPlugin.d.ts +1 -1
  24. package/package.json +4 -4
  25. package/src/ConfigControllerProvider.tsx +38 -5
  26. package/src/components/CollectionViewHeaderAction.tsx +7 -3
  27. package/src/components/PropertyAddColumnComponent.tsx +4 -2
  28. package/src/components/collection_editor/CollectionEditorDialog.tsx +7 -3
  29. package/src/components/collection_editor/CollectionPropertiesEditorForm.tsx +10 -4
  30. package/src/components/collection_editor/EnumForm.tsx +8 -6
  31. package/src/components/collection_editor/PropertyEditView.tsx +26 -15
  32. package/src/components/collection_editor/PropertyFieldPreview.tsx +8 -8
  33. package/src/components/collection_editor/PropertySelectItem.tsx +6 -6
  34. package/src/components/collection_editor/PropertyTree.tsx +15 -6
  35. package/src/components/collection_editor/import/CollectionEditorImportMapping.tsx +9 -6
  36. package/src/components/collection_editor/properties/BlockPropertyField.tsx +6 -3
  37. package/src/components/collection_editor/properties/MapPropertyField.tsx +6 -3
  38. package/src/components/collection_editor/properties/RepeatPropertyField.tsx +6 -3
  39. package/src/components/collection_editor/utils/update_property_for_widget.ts +23 -23
  40. package/src/types/collection_editor_controller.tsx +4 -2
  41. package/src/types/config_controller.tsx +9 -0
  42. package/src/types/persisted_collection.ts +3 -2
  43. package/src/useCollectionEditorPlugin.tsx +3 -8
@@ -1,5 +1,6 @@
1
1
  import { CollectionEditorPermissionsBuilder } from "./config_permissions";
2
2
  import { EntityCollection, Property } from "@firecms/core";
3
+ import { PersistedCollection } from "./persisted_collection";
3
4
  /**
4
5
  * Controller to open the collection editor dialog.
5
6
  * @category Hooks and utilities
@@ -9,7 +10,7 @@ export interface CollectionEditorController {
9
10
  path?: string;
10
11
  fullPath?: string;
11
12
  parentPathSegments: string[];
12
- parentCollection?: EntityCollection<any, any, any>;
13
+ parentCollection?: EntityCollection;
13
14
  }) => void;
14
15
  createCollection: (props: {
15
16
  initialValues?: {
@@ -18,7 +19,7 @@ export interface CollectionEditorController {
18
19
  name?: string;
19
20
  };
20
21
  parentPathSegments: string[];
21
- parentCollection?: EntityCollection<any, any, any>;
22
+ parentCollection?: PersistedCollection;
22
23
  redirect: boolean;
23
24
  }) => void;
24
25
  editProperty: (props: {
@@ -27,6 +28,7 @@ export interface CollectionEditorController {
27
28
  currentPropertiesOrder?: string[];
28
29
  editedCollectionPath: string;
29
30
  parentPathSegments: string[];
31
+ collection: PersistedCollection;
30
32
  }) => void;
31
33
  configPermissions: CollectionEditorPermissionsBuilder;
32
34
  rootPathSuggestions?: string[];
@@ -11,6 +11,7 @@ export interface CollectionsConfigController {
11
11
  [Key: string]: CMSType;
12
12
  }>(params: SaveCollectionParams<M>) => Promise<void>;
13
13
  saveProperty: (params: SavePropertyParams) => Promise<void>;
14
+ deleteProperty: (params: DeletePropertyParams) => Promise<void>;
14
15
  deleteCollection: (props: DeleteCollectionParams) => Promise<void>;
15
16
  }
16
17
  export type SaveCollectionParams<M extends Record<string, any>> = {
@@ -27,6 +28,13 @@ export type SavePropertyParams = {
27
28
  property: Property;
28
29
  parentPathSegments?: string[];
29
30
  };
31
+ export type DeletePropertyParams = {
32
+ path: string;
33
+ propertyKey: string;
34
+ namespace?: string;
35
+ newPropertiesOrder?: string[];
36
+ parentPathSegments?: string[];
37
+ };
30
38
  export type DeleteCollectionParams = {
31
39
  path: string;
32
40
  parentPathSegments?: string[];
@@ -1,6 +1,7 @@
1
1
  import { EntityCollection, Properties, User } from "@firecms/core";
2
- export type PersistedCollection<M extends Record<string, any> = any, AdditionalKey extends string = string, UserType extends User = User> = Omit<EntityCollection<M, AdditionalKey, UserType>, "properties" | "subcollections"> & {
2
+ export type PersistedCollection<M extends Record<string, any> = any, UserType extends User = User> = Omit<EntityCollection<M, UserType>, "properties" | "subcollections"> & {
3
3
  properties: Properties<M>;
4
4
  ownerId: string;
5
5
  subcollections?: PersistedCollection<any, any>[];
6
+ editable?: boolean;
6
7
  };
@@ -41,4 +41,4 @@ export interface CollectionConfigControllerProps<EC extends PersistedCollection
41
41
  * @param getUser
42
42
  * @param collectionInference
43
43
  */
44
- export declare function useCollectionEditorPlugin<EC extends PersistedCollection = PersistedCollection, UserType extends User = User>({ collectionConfigController, configPermissions, reservedGroups, extraView, pathSuggestions, getUser, collectionInference, getData }: CollectionConfigControllerProps<EC, UserType>): FireCMSPlugin;
44
+ export declare function useCollectionEditorPlugin<EC extends PersistedCollection = PersistedCollection, UserType extends User = User>({ collectionConfigController, configPermissions, reservedGroups, extraView, pathSuggestions, getUser, collectionInference, getData }: CollectionConfigControllerProps<EC, UserType>): FireCMSPlugin<any, any, PersistedCollection>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firecms/collection_editor",
3
- "version": "3.0.0-alpha.27",
3
+ "version": "3.0.0-alpha.29",
4
4
  "main": "./dist/index.umd.js",
5
5
  "module": "./dist/index.es.js",
6
6
  "types": "dist/index.d.ts",
@@ -14,8 +14,8 @@
14
14
  "./package.json": "./package.json"
15
15
  },
16
16
  "dependencies": {
17
- "@firecms/data_import": "^3.0.0-alpha.27",
18
- "@firecms/schema_inference": "^3.0.0-alpha.27"
17
+ "@firecms/data_import": "^3.0.0-alpha.29",
18
+ "@firecms/schema_inference": "^3.0.0-alpha.29"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "react": "^18.2.0",
@@ -76,5 +76,5 @@
76
76
  "publishConfig": {
77
77
  "access": "public"
78
78
  },
79
- "gitHead": "deb0ef4491986b9a599919a2cd581f40ac6920c1"
79
+ "gitHead": "65c1ea189696ea89b29b2416680a1dc541da0b36"
80
80
  }
@@ -16,6 +16,7 @@ import { CollectionEditorController } from "./types/collection_editor_controller
16
16
  import { CollectionEditorPermissionsBuilder } from "./types/config_permissions";
17
17
  import { CollectionInference } from "./types/collection_inference";
18
18
  import { PropertyFormDialog } from "./components/collection_editor/PropertyEditView";
19
+ import { PersistedCollection } from "./types/persisted_collection";
19
20
 
20
21
  export const ConfigControllerContext = React.createContext<CollectionsConfigController>({} as any);
21
22
  export const CollectionEditorContext = React.createContext<CollectionEditorController>({} as any);
@@ -111,8 +112,11 @@ export const ConfigControllerProvider = React.memo(
111
112
  editedCollectionPath: string,
112
113
  fullPath?: string,
113
114
  parentPathSegments: string[],
115
+ collectionEditable: boolean;
114
116
  }>();
115
117
 
118
+ console.log("currentPropertyDialog", currentPropertyDialog);
119
+
116
120
  const defaultConfigPermissions: CollectionEditorPermissionsBuilder = useCallback(() => ({
117
121
  createCollections: true,
118
122
  editCollections: true,
@@ -146,14 +150,14 @@ export const ConfigControllerProvider = React.memo(
146
150
  editedCollectionPath,
147
151
  currentPropertiesOrder,
148
152
  parentPathSegments,
149
- parentCollection
153
+ collection
150
154
  }: {
151
155
  propertyKey?: string,
152
156
  property?: Property,
153
157
  currentPropertiesOrder?: string[],
154
158
  editedCollectionPath: string,
155
159
  parentPathSegments: string[],
156
- parentCollection?: EntityCollection
160
+ collection: PersistedCollection,
157
161
  }) => {
158
162
  // namespace is all the path until the last dot
159
163
  const namespace = propertyKey && propertyKey.includes(".")
@@ -162,6 +166,7 @@ export const ConfigControllerProvider = React.memo(
162
166
  const propertyKeyWithoutNamespace = propertyKey && propertyKey.includes(".")
163
167
  ? propertyKey.substring(propertyKey.lastIndexOf(".") + 1)
164
168
  : propertyKey;
169
+ console.log("edit property", propertyKeyWithoutNamespace, collection)
165
170
  setCurrentPropertyDialog({
166
171
  propertyKey: propertyKeyWithoutNamespace,
167
172
  property,
@@ -169,7 +174,7 @@ export const ConfigControllerProvider = React.memo(
169
174
  currentPropertiesOrder,
170
175
  editedCollectionPath,
171
176
  parentPathSegments,
172
- parentCollection
177
+ collectionEditable: collection?.editable ?? false
173
178
  });
174
179
  }, []);
175
180
 
@@ -180,7 +185,7 @@ export const ConfigControllerProvider = React.memo(
180
185
  redirect
181
186
  }: {
182
187
  parentPathSegments: string[],
183
- parentCollection?: EntityCollection<any, any, any>
188
+ parentCollection?: EntityCollection
184
189
  initialValues?: {
185
190
  group?: string,
186
191
  path?: string,
@@ -207,6 +212,9 @@ export const ConfigControllerProvider = React.memo(
207
212
  }
208
213
  }
209
214
 
215
+ console.log("aaa", getData, currentPropertyDialog?.editedCollectionPath);
216
+ console.log(currentPropertyDialog)
217
+
210
218
  return (
211
219
  <ConfigControllerContext.Provider value={collectionConfigController}>
212
220
  <CollectionEditorContext.Provider
@@ -249,7 +257,13 @@ export const ConfigControllerProvider = React.memo(
249
257
  autoUpdateId={!currentPropertyDialog ? false : !currentPropertyDialog?.propertyKey}
250
258
  autoOpenTypeSelect={!currentPropertyDialog ? false : !currentPropertyDialog?.propertyKey}
251
259
  inArray={false}
252
- getData={getData && currentDialog?.fullPath ? () => getData(currentDialog.fullPath!) : undefined}
260
+ collectionEditable={currentPropertyDialog?.collectionEditable ?? false}
261
+ getData={getData && currentPropertyDialog?.editedCollectionPath
262
+ ? () => {
263
+ const resolvedPath = navigation.resolveAliasesFrom(currentPropertyDialog.editedCollectionPath!)
264
+ return getData(resolvedPath);
265
+ }
266
+ : undefined}
253
267
  onPropertyChanged={({
254
268
  id,
255
269
  property
@@ -276,6 +290,25 @@ export const ConfigControllerProvider = React.memo(
276
290
  }}
277
291
  onPropertyChangedImmediate={false}
278
292
  onDelete={() => {
293
+ if (!currentPropertyDialog?.propertyKey) return;
294
+ const newPropertiesOrder = currentPropertyDialog?.currentPropertiesOrder?.filter(p => p !== currentPropertyDialog?.propertyKey);
295
+ return collectionConfigController.deleteProperty({
296
+ path: currentPropertyDialog?.editedCollectionPath,
297
+ propertyKey: currentPropertyDialog?.propertyKey,
298
+ namespace: currentPropertyDialog?.namespace,
299
+ newPropertiesOrder,
300
+ parentPathSegments: currentPropertyDialog?.parentPathSegments
301
+ })
302
+ .then(() => {
303
+ setCurrentPropertyDialog(undefined);
304
+ }).catch((e) => {
305
+ console.error(e);
306
+ snackbarController.open({
307
+ type: "error",
308
+ message: "Error deleting property: " + (e.message ?? "Details in the console")
309
+ });
310
+ return false;
311
+ });
279
312
  }}
280
313
  onError={() => {
281
314
  }}
@@ -1,19 +1,22 @@
1
- import { IconButton, ResolvedProperty, SettingsIcon, Tooltip } from "@firecms/core";
1
+ import { EntityCollection, IconButton, ResolvedProperty, SettingsIcon, Tooltip } from "@firecms/core";
2
2
  import React from "react";
3
3
  import { useCollectionEditorController } from "../useCollectionEditorController";
4
+ import { PersistedCollection } from "../types/persisted_collection";
4
5
 
5
6
  export function CollectionViewHeaderAction({
6
7
  propertyKey,
7
8
  onHover,
8
9
  property,
9
10
  fullPath,
10
- parentPathSegments
11
+ parentPathSegments,
12
+ collection
11
13
  }: {
12
14
  property: ResolvedProperty,
13
15
  propertyKey: string,
14
16
  onHover: boolean,
15
17
  fullPath: string,
16
18
  parentPathSegments: string[],
19
+ collection: PersistedCollection;
17
20
  }) {
18
21
 
19
22
  const collectionEditorController = useCollectionEditorController();
@@ -27,7 +30,8 @@ export function CollectionViewHeaderAction({
27
30
  propertyKey,
28
31
  property,
29
32
  editedCollectionPath: fullPath,
30
- parentPathSegments
33
+ parentPathSegments,
34
+ collection
31
35
  });
32
36
  }}
33
37
  size={"small"}>
@@ -1,5 +1,6 @@
1
1
  import { AddIcon, EntityCollection, getDefaultPropertiesOrder, Tooltip, useAuthController } from "@firecms/core";
2
2
  import { useCollectionEditorController } from "../useCollectionEditorController";
3
+ import { PersistedCollection } from "../types/persisted_collection";
3
4
 
4
5
  export function PropertyAddColumnComponent({
5
6
  fullPath,
@@ -8,7 +9,7 @@ export function PropertyAddColumnComponent({
8
9
  }: {
9
10
  fullPath: string,
10
11
  parentPathSegments: string[],
11
- collection: EntityCollection;
12
+ collection: PersistedCollection;
12
13
  }) {
13
14
 
14
15
  const authController = useAuthController();
@@ -29,7 +30,8 @@ export function PropertyAddColumnComponent({
29
30
  collectionEditorController.editProperty({
30
31
  editedCollectionPath: fullPath,
31
32
  parentPathSegments,
32
- currentPropertiesOrder: getDefaultPropertiesOrder(collection)
33
+ currentPropertiesOrder: getDefaultPropertiesOrder(collection),
34
+ collection
33
35
  });
34
36
  }}>
35
37
  <AddIcon color={"inherit"}/>
@@ -285,11 +285,11 @@ export function CollectionEditorDialogInternal<M extends {
285
285
 
286
286
  if (Object.keys(inferredCollection.properties ?? {}).length > 0) {
287
287
  values.properties = inferredCollection.properties as Properties<M>;
288
- values.propertiesOrder = inferredCollection.propertiesOrder
288
+ values.propertiesOrder = inferredCollection.propertiesOrder as Extract<keyof M, string>[];
289
289
  }
290
290
 
291
291
  if (!values.propertiesOrder) {
292
- values.propertiesOrder = Object.keys(values.properties);
292
+ values.propertiesOrder = Object.keys(values.properties) as Extract<keyof M, string>[];
293
293
  return values;
294
294
  }
295
295
 
@@ -392,7 +392,8 @@ export function CollectionEditorDialogInternal<M extends {
392
392
 
393
393
  const path = values.path ?? editedCollectionPath;
394
394
  const updatedFullPath = fullPath?.includes("/") ? fullPath?.split("/").slice(0, -1).join("/") + "/" + path : path;
395
- const getDataWithPath = updatedFullPath && getData ? () => getData(updatedFullPath) : undefined;
395
+ const resolvedPath = navigation.resolveAliasesFrom(updatedFullPath);
396
+ const getDataWithPath = resolvedPath && getData ? () => getData(resolvedPath) : undefined;
396
397
 
397
398
  // eslint-disable-next-line react-hooks/rules-of-hooks
398
399
  useEffect(() => {
@@ -430,6 +431,7 @@ export function CollectionEditorDialogInternal<M extends {
430
431
  })
431
432
  };
432
433
 
434
+ const collectionEditable = collection?.editable || isNewCollection;
433
435
  return (
434
436
  <>
435
437
  {!isNewCollection && <Tabs value={currentView}
@@ -476,6 +478,7 @@ export function CollectionEditorDialogInternal<M extends {
476
478
 
477
479
  {currentView === "import_data_mapping" && importConfig &&
478
480
  <CollectionEditorImportMapping importConfig={importConfig}
481
+ collectionEditable={collectionEditable}
479
482
  customFields={customFields}/>}
480
483
 
481
484
  {currentView === "import_data_preview" && importConfig &&
@@ -527,6 +530,7 @@ export function CollectionEditorDialogInternal<M extends {
527
530
  getData={getDataWithPath}
528
531
  doCollectionInference={doCollectionInference}
529
532
  customFields={customFields}
533
+ collectionEditable={collectionEditable}
530
534
  extraIcon={extraView?.icon &&
531
535
  <IconButton
532
536
  color={"primary"}
@@ -11,7 +11,7 @@ import {
11
11
  defaultBorderMixin,
12
12
  EntityCollection,
13
13
  ErrorBoundary,
14
- FieldConfig,
14
+ PropertyConfig,
15
15
  isPropertyBuilder,
16
16
  makePropertiesEditable,
17
17
  Paper,
@@ -40,8 +40,9 @@ type CollectionEditorFormProps = {
40
40
  extraIcon: React.ReactNode;
41
41
  getUser: (uid: string) => User | null;
42
42
  getData?: () => Promise<object[]>;
43
- doCollectionInference: (collection: PersistedCollection<any, string>) => Promise<EntityCollection | null> | undefined;
44
- customFields: Record<string, FieldConfig>;
43
+ doCollectionInference: (collection: PersistedCollection) => Promise<EntityCollection | null> | undefined;
44
+ customFields: Record<string, PropertyConfig>;
45
+ collectionEditable: boolean;
45
46
  };
46
47
 
47
48
  export function CollectionPropertiesEditorForm({
@@ -55,7 +56,8 @@ export function CollectionPropertiesEditorForm({
55
56
  getUser,
56
57
  getData,
57
58
  doCollectionInference,
58
- customFields
59
+ customFields,
60
+ collectionEditable
59
61
  }: CollectionEditorFormProps) {
60
62
 
61
63
  const {
@@ -354,6 +356,7 @@ export function CollectionPropertiesEditorForm({
354
356
  propertiesOrder={usedPropertiesOrder}
355
357
  onPropertyMove={onPropertyMove}
356
358
  onPropertyRemove={isNewCollection ? deleteProperty : undefined}
359
+ collectionEditable={collectionEditable}
357
360
  errors={showErrors ? errors : {}}/>
358
361
  </ErrorBoundary>
359
362
 
@@ -392,6 +395,7 @@ export function CollectionPropertiesEditorForm({
392
395
  initialErrors={initialErrors}
393
396
  getData={getData}
394
397
  customFields={customFields}
398
+ collectionEditable={collectionEditable}
395
399
  />}
396
400
 
397
401
  {!selectedProperty &&
@@ -426,6 +430,7 @@ export function CollectionPropertiesEditorForm({
426
430
  initialErrors={initialErrors}
427
431
  getData={getData}
428
432
  customFields={customFields}
433
+ collectionEditable={collectionEditable}
429
434
  onOkClicked={asDialog
430
435
  ? closePropertyDialog
431
436
  : undefined
@@ -450,6 +455,7 @@ export function CollectionPropertiesEditorForm({
450
455
  getData={getData}
451
456
  allowDataInference={!isNewCollection}
452
457
  customFields={customFields}
458
+ collectionEditable={collectionEditable}
453
459
  existingPropertyKeys={values.propertiesOrder as string[]}/>
454
460
 
455
461
  </>
@@ -14,7 +14,6 @@ import {
14
14
  FormikArrayContainer,
15
15
  IconButton,
16
16
  ListIcon,
17
- LoadingButton,
18
17
  Paper,
19
18
  SettingsIcon,
20
19
  Typography
@@ -132,7 +131,8 @@ function EnumFormFields({
132
131
  };
133
132
 
134
133
  const inferValues = async () => {
135
-
134
+ if (!getData)
135
+ return;
136
136
  setInferring(true);
137
137
  getData?.().then((data) => {
138
138
  if (!data)
@@ -169,12 +169,14 @@ function EnumFormFields({
169
169
  Values
170
170
  </Typography>
171
171
  {allowDataInference &&
172
- <LoadingButton loading={inferring}
173
- disabled={disabled || inferring}
174
- variant={"text"} size={"small"} onClick={inferValues}>
172
+ <Button loading={inferring}
173
+ disabled={disabled || inferring}
174
+ variant={"text"}
175
+ size={"small"}
176
+ onClick={inferValues}>
175
177
  {inferring ? <CircularProgress size={"small"}/> : <AutoAwesomeIcon/>}
176
178
  Infer values from data
177
- </LoadingButton>}
179
+ </Button>}
178
180
  </div>
179
181
 
180
182
  <Paper className="p-4 m-1">
@@ -11,7 +11,6 @@ import {
11
11
  Dialog,
12
12
  DialogActions,
13
13
  DialogContent,
14
- FieldConfig,
15
14
  FieldConfigBadge,
16
15
  FieldConfigId,
17
16
  getFieldConfig,
@@ -21,6 +20,7 @@ import {
21
20
  isPropertyBuilder,
22
21
  mergeDeep,
23
22
  Property,
23
+ PropertyConfig, PropertyOrBuilder,
24
24
  Select,
25
25
  toSnakeCase,
26
26
  Typography
@@ -72,7 +72,8 @@ export type PropertyFormProps = {
72
72
  allowDataInference: boolean;
73
73
  getData?: () => Promise<object[]>;
74
74
  getHelpers?: (formikProps: FormikProps<PropertyWithId>) => void;
75
- customFields: Record<string, FieldConfig>;
75
+ customFields: Record<string, PropertyConfig>;
76
+ collectionEditable: boolean;
76
77
  };
77
78
 
78
79
  export const PropertyForm = React.memo(
@@ -95,7 +96,8 @@ export const PropertyForm = React.memo(
95
96
  allowDataInference,
96
97
  getHelpers,
97
98
  getData,
98
- customFields
99
+ customFields,
100
+ collectionEditable
99
101
  }: PropertyFormProps) {
100
102
 
101
103
  const initialValue: PropertyWithId = {
@@ -103,7 +105,8 @@ export const PropertyForm = React.memo(
103
105
  name: ""
104
106
  } as PropertyWithId;
105
107
 
106
- const disabled = (property && !editableProperty(property)) ?? false;
108
+ const disabled = (Boolean(property && !editableProperty(property)) && !collectionEditable);
109
+ console.log("PropertyForm disabled", disabled)
107
110
 
108
111
  const lastSubmittedProperty = useRef<OnPropertyChangedParams | undefined>(property ? {
109
112
  id: propertyKey,
@@ -139,7 +142,7 @@ export const PropertyForm = React.memo(
139
142
  } = newPropertyWithId;
140
143
  doOnPropertyChanged({
141
144
  id,
142
- property
145
+ property: { ...property, editable: property.editable ?? true }
143
146
  });
144
147
  if (!existingProperty)
145
148
  helpers.resetForm({ values: initialValue });
@@ -182,6 +185,7 @@ export const PropertyForm = React.memo(
182
185
  getData={getData}
183
186
  allowDataInference={allowDataInference}
184
187
  customFields={customFields}
188
+ collectionEditable={collectionEditable}
185
189
  {...props}/>;
186
190
 
187
191
  }}
@@ -201,6 +205,7 @@ export function PropertyFormDialog({
201
205
  onOkClicked,
202
206
  onPropertyChanged,
203
207
  getData,
208
+ collectionEditable,
204
209
  ...formProps
205
210
  }: PropertyFormProps & {
206
211
  open?: boolean;
@@ -224,6 +229,7 @@ export function PropertyFormDialog({
224
229
  onPropertyChanged?.(params);
225
230
  onOkClicked?.();
226
231
  }}
232
+ collectionEditable={collectionEditable}
227
233
  onPropertyChangedImmediate={false}
228
234
  getHelpers={getHelpers}
229
235
  getData={getData}
@@ -271,7 +277,8 @@ function PropertyEditView({
271
277
  existingPropertyKeys,
272
278
  getData,
273
279
  allowDataInference,
274
- customFields
280
+ customFields,
281
+ collectionEditable
275
282
  }: {
276
283
  includeIdAndTitle?: boolean;
277
284
  existing: boolean;
@@ -287,7 +294,8 @@ function PropertyEditView({
287
294
  existingPropertyKeys?: string[];
288
295
  getData?: () => Promise<object[]>;
289
296
  allowDataInference: boolean;
290
- customFields: Record<string, FieldConfig>;
297
+ customFields: Record<string, PropertyConfig>;
298
+ collectionEditable: boolean;
291
299
  } & FormikProps<PropertyWithId>) {
292
300
 
293
301
  const [selectOpen, setSelectOpen] = useState(autoOpenTypeSelect);
@@ -297,7 +305,7 @@ function PropertyEditView({
297
305
  const allSupportedFields = Object.entries(DEFAULT_FIELD_CONFIGS).concat(Object.entries(customFields));
298
306
 
299
307
  const displayedWidgets = inArray
300
- ? allSupportedFields.filter(([_, fieldConfig]) => !isPropertyBuilder(fieldConfig.property) && fieldConfig.property?.dataType !== "array")
308
+ ? allSupportedFields.filter(([_, propertyConfig]) => !isPropertyBuilder(propertyConfig.property) && propertyConfig.property?.dataType !== "array")
301
309
  : allSupportedFields;
302
310
 
303
311
  const deferredValues = useDeferredValue(values);
@@ -395,10 +403,12 @@ function PropertyEditView({
395
403
  } else if (selectedFieldConfigId === "group") {
396
404
  childComponent =
397
405
  <MapPropertyField disabled={disabled} getData={getData} allowDataInference={allowDataInference}
406
+ collectionEditable={collectionEditable}
398
407
  customFields={customFields}/>;
399
408
  } else if (selectedFieldConfigId === "block") {
400
409
  childComponent =
401
410
  <BlockPropertyField disabled={disabled} getData={getData} allowDataInference={allowDataInference}
411
+ collectionEditable={collectionEditable}
402
412
  customFields={customFields}/>;
403
413
  } else if (selectedFieldConfigId === "reference") {
404
414
  childComponent =
@@ -421,6 +431,7 @@ function PropertyEditView({
421
431
  getData={getData}
422
432
  allowDataInference={allowDataInference}
423
433
  disabled={disabled}
434
+ collectionEditable={collectionEditable}
424
435
  customFields={customFields}/>;
425
436
  } else if (selectedFieldConfigId === "key_value") {
426
437
  childComponent =
@@ -456,11 +467,11 @@ function PropertyEditView({
456
467
  widget</em>;
457
468
  }
458
469
  const key = value as FieldConfigId;
459
- const fieldConfig = DEFAULT_FIELD_CONFIGS[key] ?? customFields[key];
460
- const baseProperty = fieldConfig.property;
470
+ const propertyConfig = DEFAULT_FIELD_CONFIGS[key] ?? customFields[key];
471
+ const baseProperty = propertyConfig.property;
461
472
  const baseFieldConfig = baseProperty && !isPropertyBuilder(baseProperty) ? getFieldConfig(baseProperty, customFields) : undefined;
462
473
  const optionDisabled = isPropertyBuilder(baseProperty) || (existing && baseProperty.dataType !== values?.dataType);
463
- const computedFieldConfig = baseFieldConfig ? mergeDeep(baseFieldConfig, fieldConfig) : fieldConfig;
474
+ const computedFieldConfig = baseFieldConfig ? mergeDeep(baseFieldConfig, propertyConfig) : propertyConfig;
464
475
  return <div
465
476
  onClick={(e) => {
466
477
  if (optionDisabled) {
@@ -472,7 +483,7 @@ function PropertyEditView({
472
483
  "flex items-center",
473
484
  optionDisabled ? "w-full pointer-events-none opacity-50" : "")}>
474
485
  <div className={"mr-8"}>
475
- <FieldConfigBadge fieldConfig={computedFieldConfig}/>
486
+ <FieldConfigBadge propertyConfig={computedFieldConfig}/>
476
487
  </div>
477
488
  <div className={"flex flex-col items-start text-base text-left"}>
478
489
  <div>{computedFieldConfig.name}</div>
@@ -486,14 +497,14 @@ function PropertyEditView({
486
497
  onValueChange={(value) => {
487
498
  onWidgetSelectChanged(value as FieldConfigId);
488
499
  }}>
489
- {displayedWidgets.map(([key, fieldConfig]) => {
490
- const baseProperty = fieldConfig.property;
500
+ {displayedWidgets.map(([key, propertyConfig]) => {
501
+ const baseProperty = propertyConfig.property;
491
502
  const optionDisabled = existing && !isPropertyBuilder(baseProperty) && baseProperty.dataType !== values?.dataType;
492
503
  return <PropertySelectItem
493
504
  key={key}
494
505
  value={key}
495
506
  optionDisabled={optionDisabled}
496
- fieldConfig={fieldConfig}
507
+ propertyConfig={propertyConfig}
497
508
  existing={existing}/>;
498
509
  })}
499
510
  </Select>
@@ -36,7 +36,7 @@ export function PropertyFieldPreview({
36
36
 
37
37
  const { fields } = useFireCMSContext();
38
38
 
39
- const fieldConfig = getFieldConfig(property, fields);
39
+ const propertyConfig = getFieldConfig(property, fields);
40
40
  const disabled = !editableProperty(property);
41
41
 
42
42
  const borderColorClass = hasError
@@ -48,7 +48,7 @@ export function PropertyFieldPreview({
48
48
  onClick={onClick}
49
49
  className="flex flex-row w-full cursor-pointer">
50
50
  <div className={"m-4"}>
51
- <FieldConfigBadge fieldConfig={fieldConfig}/>
51
+ <FieldConfigBadge propertyConfig={propertyConfig}/>
52
52
  </div>
53
53
  <Paper
54
54
  className={cn(
@@ -81,7 +81,7 @@ export function PropertyFieldPreview({
81
81
  variant={includeName ? "body2" : "subtitle1"}
82
82
  component="span"
83
83
  color="secondary">
84
- {fieldConfig?.name}
84
+ {propertyConfig?.name}
85
85
  </Typography>
86
86
  </ErrorBoundary>
87
87
  <ErrorBoundary>
@@ -122,15 +122,15 @@ export function NonEditablePropertyPreview({
122
122
 
123
123
  const { fields } = useFireCMSContext();
124
124
 
125
- const fieldConfig = !isPropertyBuilder(property) && property ? getFieldConfig(property, fields) : undefined;
125
+ const propertyConfig = !isPropertyBuilder(property) && property ? getFieldConfig(property, fields) : undefined;
126
126
 
127
127
  return (
128
128
  <div
129
129
  onClick={onClick}
130
130
  className="flex flex-row w-full cursor-pointer">
131
131
  <div className={"relative m-4"}>
132
- {fieldConfig && <FieldConfigBadge fieldConfig={fieldConfig}/>}
133
- {!fieldConfig && <div
132
+ {propertyConfig && <FieldConfigBadge propertyConfig={propertyConfig}/>}
133
+ {!propertyConfig && <div
134
134
  className={"h-8 w-8 p-1 rounded-full shadow text-white bg-gray-500"}>
135
135
  <FunctionsIcon color={"inherit"} size={"medium"}/>
136
136
  </div>}
@@ -157,11 +157,11 @@ export function NonEditablePropertyPreview({
157
157
  </Typography>
158
158
 
159
159
  <div className="flex flex-row items-center">
160
- {fieldConfig && <Typography className="flex-grow pr-2"
160
+ {propertyConfig && <Typography className="flex-grow pr-2"
161
161
  variant={"body2"}
162
162
  component="span"
163
163
  color="secondary">
164
- {fieldConfig?.name}
164
+ {propertyConfig?.name}
165
165
  </Typography>}
166
166
 
167
167
  {property && !isPropertyBuilder(property) && <ErrorBoundary>