slice-machine-ui 2.16.2-alpha.jp-cr-empty-customtypes.1 → 2.16.2-alpha.jp-cr-ui-fix-invalid-fields-checked.1
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/out/404.html +1 -1
- package/out/_next/static/{xnrtmfRZsORP9Q_a5DySO → -b_7ATSiEFTCqrUK1sPZq}/_buildManifest.js +1 -1
- package/out/_next/static/chunks/630-ffb67177d6d9784c.js +1 -0
- package/out/_next/static/chunks/pages/{_app-a27cc92bf2c85218.js → _app-d387cf057dfd4f7f.js} +1 -1
- package/out/changelog.html +1 -1
- package/out/changes.html +1 -1
- package/out/custom-types/[customTypeId].html +1 -1
- package/out/custom-types.html +1 -1
- package/out/index.html +1 -1
- package/out/labs.html +1 -1
- package/out/page-types/[pageTypeId].html +1 -1
- package/out/settings.html +1 -1
- package/out/slices/[lib]/[sliceName]/[variation]/simulator.html +1 -1
- package/out/slices/[lib]/[sliceName]/[variation].html +1 -1
- package/out/slices.html +1 -1
- package/package.json +3 -3
- package/src/features/builder/fields/contentRelationship/ContentRelationshipFieldPicker.tsx +287 -127
- package/src/features/builder/fields/contentRelationship/__tests__/ContentRelationshipFieldPicker.test.ts +1086 -168
- package/src/legacy/lib/models/common/widgets/ContentRelationship/index.ts +1 -2
- package/src/utils/tracking/getLinkTrackingProperties.ts +3 -1
- package/out/_next/static/chunks/630-fdfc5e7140814b4c.js +0 -1
- /package/out/_next/static/{xnrtmfRZsORP9Q_a5DySO → -b_7ATSiEFTCqrUK1sPZq}/_ssgManifest.js +0 -0
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
} from "@prismicio/editor-ui";
|
|
23
23
|
import {
|
|
24
24
|
CustomType,
|
|
25
|
+
DynamicWidget,
|
|
25
26
|
Group,
|
|
26
27
|
Link,
|
|
27
28
|
LinkConfig,
|
|
@@ -260,20 +261,13 @@ export function ContentRelationshipFieldPicker(
|
|
|
260
261
|
function ContentRelationshipFieldPickerContent(
|
|
261
262
|
props: ContentRelationshipFieldPickerProps,
|
|
262
263
|
) {
|
|
263
|
-
const { value, onChange } = props;
|
|
264
|
-
const { allCustomTypes, pickedCustomTypes } = useCustomTypes(
|
|
264
|
+
const { value: linkCustomtypes, onChange } = props;
|
|
265
|
+
const { allCustomTypes, pickedCustomTypes } = useCustomTypes(linkCustomtypes);
|
|
265
266
|
|
|
266
|
-
const fieldCheckMap =
|
|
267
|
-
? convertLinkCustomtypesToFieldCheckMap(
|
|
267
|
+
const fieldCheckMap = linkCustomtypes
|
|
268
|
+
? convertLinkCustomtypesToFieldCheckMap({ linkCustomtypes, allCustomTypes })
|
|
268
269
|
: {};
|
|
269
270
|
|
|
270
|
-
useEffect(() => {
|
|
271
|
-
// Make sure the field has a customtypes property. We did not create it
|
|
272
|
-
// before for new Content Relationship fields, but now we do, and we want to
|
|
273
|
-
// correct most of the cases where it's missing.
|
|
274
|
-
if (!value) onChange([]);
|
|
275
|
-
}, [value]);
|
|
276
|
-
|
|
277
271
|
function onCustomTypesChange(id: string, newCustomType: PickerCustomType) {
|
|
278
272
|
// The picker does not handle strings (custom type ids), as it's only meant
|
|
279
273
|
// to pick fields from custom types (objects). So we need to merge it with
|
|
@@ -281,22 +275,24 @@ function ContentRelationshipFieldPickerContent(
|
|
|
281
275
|
// represent new types added without any picked fields.
|
|
282
276
|
onChange(
|
|
283
277
|
mergeAndConvertCheckMapToLinkCustomtypes({
|
|
284
|
-
|
|
285
|
-
previousPickerCustomtypes: fieldCheckMap,
|
|
286
|
-
customTypeId: id,
|
|
278
|
+
fieldCheckMap,
|
|
287
279
|
newCustomType,
|
|
280
|
+
linkCustomtypes,
|
|
281
|
+
customTypeId: id,
|
|
288
282
|
}),
|
|
289
283
|
);
|
|
290
284
|
}
|
|
291
285
|
|
|
292
286
|
function addCustomType(id: string) {
|
|
293
|
-
const newFields =
|
|
287
|
+
const newFields = linkCustomtypes ? [...linkCustomtypes, id] : [id];
|
|
294
288
|
onChange(newFields);
|
|
295
289
|
}
|
|
296
290
|
|
|
297
291
|
function removeCustomType(id: string) {
|
|
298
|
-
if (
|
|
299
|
-
onChange(
|
|
292
|
+
if (linkCustomtypes) {
|
|
293
|
+
onChange(
|
|
294
|
+
linkCustomtypes.filter((existingCt) => getId(existingCt) !== id),
|
|
295
|
+
);
|
|
300
296
|
}
|
|
301
297
|
}
|
|
302
298
|
|
|
@@ -416,8 +412,9 @@ function ContentRelationshipFieldPickerContent(
|
|
|
416
412
|
rel="noopener noreferrer"
|
|
417
413
|
style={{ color: "inherit", textDecoration: "underline" }}
|
|
418
414
|
>
|
|
419
|
-
Please provide your feedback here
|
|
415
|
+
Please provide your feedback here
|
|
420
416
|
</a>
|
|
417
|
+
.
|
|
421
418
|
</Text>
|
|
422
419
|
</Box>
|
|
423
420
|
</Box>
|
|
@@ -470,20 +467,20 @@ function AddTypeButton(props: AddTypeButtonProps) {
|
|
|
470
467
|
</Button>
|
|
471
468
|
);
|
|
472
469
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
<
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
470
|
+
if (allCustomTypes.length === 0) {
|
|
471
|
+
return (
|
|
472
|
+
<Box>
|
|
473
|
+
<Tooltip
|
|
474
|
+
content="No type available"
|
|
475
|
+
side="bottom"
|
|
476
|
+
align="start"
|
|
477
|
+
disableHoverableContent
|
|
478
|
+
>
|
|
479
|
+
{triggerButton}
|
|
480
|
+
</Tooltip>
|
|
481
|
+
</Box>
|
|
482
|
+
);
|
|
483
|
+
}
|
|
487
484
|
|
|
488
485
|
return (
|
|
489
486
|
<Box>
|
|
@@ -908,7 +905,7 @@ function getTypeFormatLabel(format: CustomType["format"]) {
|
|
|
908
905
|
}
|
|
909
906
|
|
|
910
907
|
/** Retrieves all existing page & custom types. */
|
|
911
|
-
function useCustomTypes(
|
|
908
|
+
function useCustomTypes(linkCustomtypes: LinkCustomtypes | undefined): {
|
|
912
909
|
/** Every existing custom type, used to discover nested custom types down the tree and the add type dropdown. */
|
|
913
910
|
allCustomTypes: CustomType[];
|
|
914
911
|
/** The custom types that are already picked. */
|
|
@@ -920,14 +917,14 @@ function useCustomTypes(value: LinkCustomtypes | undefined): {
|
|
|
920
917
|
void revalidateGetCustomTypes();
|
|
921
918
|
}, []);
|
|
922
919
|
|
|
923
|
-
if (!
|
|
920
|
+
if (!linkCustomtypes) {
|
|
924
921
|
return {
|
|
925
922
|
allCustomTypes,
|
|
926
923
|
pickedCustomTypes: [],
|
|
927
924
|
};
|
|
928
925
|
}
|
|
929
926
|
|
|
930
|
-
const pickedCustomTypes =
|
|
927
|
+
const pickedCustomTypes = linkCustomtypes.flatMap(
|
|
931
928
|
(pickedCt) => allCustomTypes.find((ct) => ct.id === getId(pickedCt)) ?? [],
|
|
932
929
|
);
|
|
933
930
|
|
|
@@ -950,92 +947,212 @@ function resolveContentRelationshipCustomTypes(
|
|
|
950
947
|
* Converts a Link config `customtypes` ({@link LinkCustomtypes}) structure into
|
|
951
948
|
* picker fields check map ({@link PickerCustomTypes}).
|
|
952
949
|
*/
|
|
953
|
-
export function convertLinkCustomtypesToFieldCheckMap(
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
950
|
+
export function convertLinkCustomtypesToFieldCheckMap(args: {
|
|
951
|
+
linkCustomtypes: LinkCustomtypes;
|
|
952
|
+
allCustomTypes?: CustomType[];
|
|
953
|
+
}): PickerCustomTypes {
|
|
954
|
+
const { linkCustomtypes, allCustomTypes } = args;
|
|
955
|
+
|
|
956
|
+
const checkMap = linkCustomtypes.reduce((customTypes, customType) => {
|
|
957
957
|
if (typeof customType === "string") return customTypes;
|
|
958
958
|
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
959
|
+
const existingCt = allCustomTypes?.find((ct) => ct.id === customType.id);
|
|
960
|
+
if (allCustomTypes && !existingCt) return customTypes;
|
|
961
|
+
|
|
962
|
+
const ctFlatFieldMap = getCustomTypeFlatFieldMap(existingCt);
|
|
963
|
+
|
|
964
|
+
const customTypeFields = customType.fields.reduce((fields, field) => {
|
|
965
|
+
// Check if the field exists
|
|
966
|
+
const existingField = ctFlatFieldMap.get(getId(field));
|
|
967
|
+
if (allCustomTypes && !existingField) return fields;
|
|
968
|
+
|
|
969
|
+
// Regular field
|
|
970
|
+
if (typeof field === "string") {
|
|
971
|
+
// Check if the field matched the existing one in the custom type
|
|
972
|
+
if (allCustomTypes && existingField && existingField.type === "Group") {
|
|
973
|
+
return fields;
|
|
971
974
|
}
|
|
972
975
|
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
976
|
+
fields[field] = { type: "checkbox", value: true };
|
|
977
|
+
return fields;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
// Group field
|
|
981
|
+
if ("fields" in field && field.fields !== undefined) {
|
|
982
|
+
// Check if the field matched the existing one in the custom type
|
|
983
|
+
if (allCustomTypes && existingField && existingField.type !== "Group") {
|
|
984
|
+
return fields;
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
const groupFieldCheckMap = createGroupFieldCheckMap({
|
|
988
|
+
group: field,
|
|
989
|
+
allCustomTypes,
|
|
990
|
+
ctFlatFieldMap,
|
|
991
|
+
});
|
|
992
|
+
|
|
993
|
+
if (groupFieldCheckMap) {
|
|
994
|
+
fields[field.id] = groupFieldCheckMap;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
return fields;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
// Content relationship field
|
|
1001
|
+
if ("customtypes" in field && field.customtypes !== undefined) {
|
|
1002
|
+
// Check if the field matched the existing one in the custom type
|
|
1003
|
+
if (
|
|
1004
|
+
allCustomTypes &&
|
|
1005
|
+
existingField &&
|
|
1006
|
+
!isContentRelationshipField(existingField)
|
|
1007
|
+
) {
|
|
1008
|
+
return fields;
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
const crFieldCheckMap = createContentRelationshipFieldCheckMap({
|
|
1012
|
+
field,
|
|
1013
|
+
allCustomTypes,
|
|
1014
|
+
});
|
|
1015
|
+
|
|
1016
|
+
if (crFieldCheckMap) {
|
|
1017
|
+
fields[field.id] = crFieldCheckMap;
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
return fields;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
return fields;
|
|
1024
|
+
}, {} as PickerCustomType);
|
|
1025
|
+
|
|
1026
|
+
if (Object.keys(customTypeFields).length > 0) {
|
|
1027
|
+
customTypes[customType.id] = customTypeFields;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
977
1030
|
return customTypes;
|
|
978
|
-
}, {});
|
|
1031
|
+
}, {} as PickerCustomTypes);
|
|
1032
|
+
|
|
1033
|
+
return checkMap;
|
|
979
1034
|
}
|
|
980
1035
|
|
|
981
|
-
function createGroupFieldCheckMap(
|
|
982
|
-
group: LinkCustomtypesGroupFieldValue
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
(fields, field) => {
|
|
988
|
-
if (typeof field === "string") {
|
|
989
|
-
// Regular field
|
|
990
|
-
fields[field] = { type: "checkbox", value: true };
|
|
991
|
-
} else if ("customtypes" in field && field.customtypes !== undefined) {
|
|
992
|
-
// Content relationship field
|
|
993
|
-
fields[field.id] = createContentRelationshipFieldCheckMap(field);
|
|
994
|
-
}
|
|
1036
|
+
function createGroupFieldCheckMap(args: {
|
|
1037
|
+
group: LinkCustomtypesGroupFieldValue;
|
|
1038
|
+
allCustomTypes?: CustomType[];
|
|
1039
|
+
ctFlatFieldMap: CustomTypeFlatFieldMap;
|
|
1040
|
+
}): PickerFirstLevelGroupField | undefined {
|
|
1041
|
+
const { group, ctFlatFieldMap, allCustomTypes } = args;
|
|
995
1042
|
|
|
1043
|
+
const fieldEntries = group.fields.reduce((fields, field) => {
|
|
1044
|
+
// Check if the field exists
|
|
1045
|
+
const existingField = ctFlatFieldMap.get(`${group.id}.${getId(field)}`);
|
|
1046
|
+
if (allCustomTypes && !existingField) return fields;
|
|
1047
|
+
|
|
1048
|
+
// Regular field
|
|
1049
|
+
if (typeof field === "string") {
|
|
1050
|
+
// Check if the field matched the existing one in the custom type
|
|
1051
|
+
if (allCustomTypes && existingField && existingField.type === "Group") {
|
|
996
1052
|
return fields;
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
fields[field] = { type: "checkbox", value: true };
|
|
1056
|
+
return fields;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
// Content relationship field
|
|
1060
|
+
if ("customtypes" in field && field.customtypes !== undefined) {
|
|
1061
|
+
// Check if the field matched the existing one in the custom type
|
|
1062
|
+
if (
|
|
1063
|
+
allCustomTypes &&
|
|
1064
|
+
existingField &&
|
|
1065
|
+
!isContentRelationshipField(existingField)
|
|
1066
|
+
) {
|
|
1067
|
+
return fields;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
const crFieldCheckMap = createContentRelationshipFieldCheckMap({
|
|
1071
|
+
field,
|
|
1072
|
+
allCustomTypes,
|
|
1073
|
+
});
|
|
1074
|
+
|
|
1075
|
+
if (crFieldCheckMap) {
|
|
1076
|
+
fields[field.id] = crFieldCheckMap;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
return fields;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
return fields;
|
|
1083
|
+
}, {} as PickerFirstLevelGroupFieldValue);
|
|
1084
|
+
|
|
1085
|
+
if (Object.keys(fieldEntries).length === 0) return undefined;
|
|
1086
|
+
|
|
1087
|
+
return {
|
|
1088
|
+
type: "group",
|
|
1089
|
+
value: fieldEntries,
|
|
1000
1090
|
};
|
|
1001
1091
|
}
|
|
1002
1092
|
|
|
1003
|
-
function createContentRelationshipFieldCheckMap(
|
|
1004
|
-
field: LinkCustomtypesContentRelationshipFieldValue
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1093
|
+
function createContentRelationshipFieldCheckMap(args: {
|
|
1094
|
+
field: LinkCustomtypesContentRelationshipFieldValue;
|
|
1095
|
+
allCustomTypes?: CustomType[];
|
|
1096
|
+
}): PickerContentRelationshipField | undefined {
|
|
1097
|
+
const { field, allCustomTypes } = args;
|
|
1098
|
+
|
|
1099
|
+
const fieldEntries = field.customtypes.reduce((customTypes, customType) => {
|
|
1100
|
+
if (typeof customType === "string") return customTypes;
|
|
1011
1101
|
|
|
1012
|
-
|
|
1013
|
-
if (
|
|
1102
|
+
const existingCt = allCustomTypes?.find((ct) => ct.id === customType.id);
|
|
1103
|
+
if (allCustomTypes && !existingCt) return customTypes;
|
|
1014
1104
|
|
|
1015
|
-
|
|
1016
|
-
const customTypeFields = crFieldCustomTypes[customType.id];
|
|
1105
|
+
const ctFlatFieldMap = getCustomTypeFlatFieldMap(existingCt);
|
|
1017
1106
|
|
|
1018
|
-
|
|
1107
|
+
const ctFields = customType.fields.reduce((nestedFields, nestedField) => {
|
|
1108
|
+
// Regular field
|
|
1019
1109
|
if (typeof nestedField === "string") {
|
|
1020
|
-
//
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1110
|
+
// Check if the field matched the existing one in the custom type
|
|
1111
|
+
if (allCustomTypes && !ctFlatFieldMap.has(nestedField)) {
|
|
1112
|
+
return nestedFields;
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
nestedFields[nestedField] = { type: "checkbox", value: true };
|
|
1116
|
+
return nestedFields;
|
|
1117
|
+
}
|
|
1027
1118
|
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1119
|
+
// Group field
|
|
1120
|
+
const groupFields = nestedField.fields.reduce((fields, field) => {
|
|
1121
|
+
// Check if the field matched the existing one in the custom type
|
|
1122
|
+
if (
|
|
1123
|
+
allCustomTypes &&
|
|
1124
|
+
!ctFlatFieldMap.has(`${nestedField.id}.${field}`)
|
|
1125
|
+
) {
|
|
1126
|
+
return fields;
|
|
1033
1127
|
}
|
|
1128
|
+
|
|
1129
|
+
fields[field] = { type: "checkbox", value: true };
|
|
1130
|
+
return fields;
|
|
1131
|
+
}, {} as PickerLeafGroupFieldValue);
|
|
1132
|
+
|
|
1133
|
+
if (Object.keys(groupFields).length > 0) {
|
|
1134
|
+
nestedFields[nestedField.id] = {
|
|
1135
|
+
type: "group",
|
|
1136
|
+
value: groupFields,
|
|
1137
|
+
};
|
|
1034
1138
|
}
|
|
1139
|
+
|
|
1140
|
+
return nestedFields;
|
|
1141
|
+
}, {} as PickerNestedCustomTypeValue);
|
|
1142
|
+
|
|
1143
|
+
if (Object.keys(ctFields).length > 0) {
|
|
1144
|
+
customTypes[customType.id] = ctFields;
|
|
1035
1145
|
}
|
|
1036
|
-
}
|
|
1037
1146
|
|
|
1038
|
-
|
|
1147
|
+
return customTypes;
|
|
1148
|
+
}, {} as PickerContentRelationshipFieldValue);
|
|
1149
|
+
|
|
1150
|
+
if (Object.keys(fieldEntries).length === 0) return undefined;
|
|
1151
|
+
|
|
1152
|
+
return {
|
|
1153
|
+
type: "contentRelationship",
|
|
1154
|
+
value: fieldEntries,
|
|
1155
|
+
};
|
|
1039
1156
|
}
|
|
1040
1157
|
|
|
1041
1158
|
/**
|
|
@@ -1044,27 +1161,22 @@ function createContentRelationshipFieldCheckMap(
|
|
|
1044
1161
|
* made correctly and that the order is preserved.
|
|
1045
1162
|
*/
|
|
1046
1163
|
function mergeAndConvertCheckMapToLinkCustomtypes(args: {
|
|
1047
|
-
|
|
1048
|
-
|
|
1164
|
+
linkCustomtypes: LinkCustomtypes | undefined;
|
|
1165
|
+
fieldCheckMap: PickerCustomTypes;
|
|
1049
1166
|
newCustomType: PickerCustomType;
|
|
1050
1167
|
customTypeId: string;
|
|
1051
1168
|
}): LinkCustomtypes {
|
|
1052
|
-
const {
|
|
1053
|
-
existingLinkCustomtypes,
|
|
1054
|
-
previousPickerCustomtypes,
|
|
1055
|
-
newCustomType,
|
|
1056
|
-
customTypeId,
|
|
1057
|
-
} = args;
|
|
1169
|
+
const { linkCustomtypes, fieldCheckMap, newCustomType, customTypeId } = args;
|
|
1058
1170
|
|
|
1059
1171
|
const result: NonReadonly<LinkCustomtypes> = [];
|
|
1060
1172
|
const pickerLinkCustomtypes = convertFieldCheckMapToLinkCustomtypes({
|
|
1061
|
-
...
|
|
1173
|
+
...fieldCheckMap,
|
|
1062
1174
|
[customTypeId]: newCustomType,
|
|
1063
1175
|
});
|
|
1064
1176
|
|
|
1065
|
-
if (!
|
|
1177
|
+
if (!linkCustomtypes) return pickerLinkCustomtypes;
|
|
1066
1178
|
|
|
1067
|
-
for (const existingLinkCt of
|
|
1179
|
+
for (const existingLinkCt of linkCustomtypes) {
|
|
1068
1180
|
const existingPickerLinkCt = pickerLinkCustomtypes.find((ct) => {
|
|
1069
1181
|
return getId(ct) === getId(existingLinkCt);
|
|
1070
1182
|
});
|
|
@@ -1236,6 +1348,10 @@ export function countPickedFields(
|
|
|
1236
1348
|
);
|
|
1237
1349
|
}
|
|
1238
1350
|
|
|
1351
|
+
function isContentRelationshipField(field: DynamicWidget): field is Link {
|
|
1352
|
+
return field.type === "Link" && field.config?.select === "document";
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1239
1355
|
/**
|
|
1240
1356
|
* Check if the field is a Content Relationship Link with a **single** custom
|
|
1241
1357
|
* type. CRs with multiple custom types are not currently supported (legacy).
|
|
@@ -1244,34 +1360,78 @@ function isContentRelationshipFieldWithSingleCustomtype(
|
|
|
1244
1360
|
field: NestableWidget | Group,
|
|
1245
1361
|
): field is Link {
|
|
1246
1362
|
return !!(
|
|
1247
|
-
field
|
|
1248
|
-
field.config?.select === "document" &&
|
|
1363
|
+
isContentRelationshipField(field) &&
|
|
1249
1364
|
field.config?.customtypes &&
|
|
1250
1365
|
field.config.customtypes.length === 1
|
|
1251
1366
|
);
|
|
1252
1367
|
}
|
|
1253
1368
|
|
|
1369
|
+
type CustomTypeFlatFieldMap = {
|
|
1370
|
+
get: (fieldId: string) => DynamicWidget | undefined;
|
|
1371
|
+
has: (fieldId: string) => boolean;
|
|
1372
|
+
};
|
|
1373
|
+
|
|
1374
|
+
/**
|
|
1375
|
+
* Util that flattens a custom type's fields into a map of field ids to fields and
|
|
1376
|
+
* returns functions to get and check if a field exists by key.
|
|
1377
|
+
* For group fields, the key is separated by a dot (e.g. "group.fieldId").
|
|
1378
|
+
*/
|
|
1379
|
+
function getCustomTypeFlatFieldMap(
|
|
1380
|
+
customType: CustomType | undefined,
|
|
1381
|
+
): CustomTypeFlatFieldMap {
|
|
1382
|
+
if (!customType) return { get: () => undefined, has: () => false };
|
|
1383
|
+
|
|
1384
|
+
const ctFieldMap = Object.values(customType.json).reduce((acc, tabFields) => {
|
|
1385
|
+
for (const [fieldId, field] of Object.entries(tabFields)) {
|
|
1386
|
+
if (!isValidField(fieldId, field)) continue;
|
|
1387
|
+
|
|
1388
|
+
if (field.type === "Group") {
|
|
1389
|
+
acc.set(fieldId, field);
|
|
1390
|
+
|
|
1391
|
+
if (!field.config?.fields) continue;
|
|
1392
|
+
|
|
1393
|
+
for (const [groupId, group] of Object.entries(field.config.fields)) {
|
|
1394
|
+
if (!isValidField(groupId, group)) continue;
|
|
1395
|
+
acc.set(`${fieldId}.${groupId}`, group);
|
|
1396
|
+
}
|
|
1397
|
+
} else {
|
|
1398
|
+
acc.set(fieldId, field);
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
return acc;
|
|
1402
|
+
}, new Map<string, DynamicWidget>());
|
|
1403
|
+
|
|
1404
|
+
return {
|
|
1405
|
+
get: (fieldId) => ctFieldMap.get(fieldId),
|
|
1406
|
+
has: (fieldId) => ctFieldMap.has(fieldId),
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1254
1410
|
function getCustomTypeStaticFields(customType: CustomType) {
|
|
1255
1411
|
return Object.values(customType.json).flatMap((tabFields) => {
|
|
1256
1412
|
return Object.entries(tabFields).flatMap(([fieldId, field]) => {
|
|
1257
|
-
|
|
1258
|
-
field.type !== "Slices" &&
|
|
1259
|
-
field.type !== "Choice" &&
|
|
1260
|
-
// Filter out uid fields because it's a special field returned by the
|
|
1261
|
-
// API and is not part of the data object in the document.
|
|
1262
|
-
// We also filter by key "uid", because (as of the time of writing
|
|
1263
|
-
// this), creating any field with that API id will result in it being
|
|
1264
|
-
// used for metadata.
|
|
1265
|
-
(field.type !== "UID" || fieldId !== "uid")
|
|
1266
|
-
) {
|
|
1267
|
-
return { fieldId, field: field as NestableWidget | Group };
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
|
-
return [];
|
|
1413
|
+
return isValidField(fieldId, field) ? { fieldId, field } : [];
|
|
1271
1414
|
});
|
|
1272
1415
|
});
|
|
1273
1416
|
}
|
|
1274
1417
|
|
|
1418
|
+
function isValidField(
|
|
1419
|
+
fieldId: string,
|
|
1420
|
+
field: DynamicWidget,
|
|
1421
|
+
): field is NestableWidget | Group {
|
|
1422
|
+
return (
|
|
1423
|
+
field.type !== "Slices" &&
|
|
1424
|
+
field.type !== "Choice" &&
|
|
1425
|
+
// We don't display uid fields because they're a special field returned by
|
|
1426
|
+
// the API and they're not included in the document data object.
|
|
1427
|
+
// We also filter by key "uid", because (as of the time of writing this)
|
|
1428
|
+
// creating any field with that API id will result in it being used for
|
|
1429
|
+
// metadata, regardless of its type.
|
|
1430
|
+
field.type !== "UID" &&
|
|
1431
|
+
fieldId !== "uid"
|
|
1432
|
+
);
|
|
1433
|
+
}
|
|
1434
|
+
|
|
1275
1435
|
function getGroupFields(group: Group) {
|
|
1276
1436
|
if (!group.config?.fields) return [];
|
|
1277
1437
|
return Object.entries(group.config.fields).map(([fieldId, field]) => {
|