slice-machine-ui 1.14.1-dev-upgrade-legacy.2 → 1.14.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/components/ChangesItems/ChangesItems.tsx +1 -1
- package/lib/builders/CustomTypeBuilder/SliceZone/List.tsx +4 -12
- package/lib/builders/CustomTypeBuilder/SliceZone/UpdateSliceZoneModalList.tsx +1 -1
- package/lib/builders/CustomTypeBuilder/SliceZone/index.tsx +0 -8
- package/lib/models/ui/Slice/index.tsx +26 -52
- package/out/404.html +1 -1
- package/out/[lib]/[sliceName]/[variation]/screenshot.html +1 -1
- package/out/[lib]/[sliceName]/[variation]/simulator.html +1 -1
- package/out/[lib]/[sliceName]/[variation].html +1 -1
- package/out/_next/static/chunks/482-a4c1c3721ca38516.js +1 -0
- package/out/_next/static/chunks/573-aaae870d20e5f86c.js +1 -0
- package/out/_next/static/chunks/{969-bcfa23e8fd4773e7.js → 740-d0642219804fa9f0.js} +1 -1
- package/out/_next/static/chunks/799-5ea3393033a9f617.js +1 -0
- package/out/_next/static/chunks/906-9224feb63b5e36f3.js +1 -0
- package/out/_next/static/chunks/97-f6188ebe22eb21da.js +1 -0
- package/out/_next/static/chunks/970-6fb969573ccdf018.js +1 -0
- package/out/_next/static/chunks/pages/[lib]/[sliceName]/[variation]-9fff494255e34c39.js +1 -0
- package/out/_next/static/chunks/pages/{_app-fea3c7cfb3b5c1b5.js → _app-e667eb27c83f2806.js} +7 -7
- package/out/_next/static/chunks/pages/changes-6a039e823313b41c.js +1 -0
- package/out/_next/static/chunks/pages/custom-types/{[customTypeId]-94ffa7cbfab2ef0f.js → [customTypeId]-f8e48a51edbb5e1c.js} +1 -1
- package/out/_next/static/chunks/pages/{custom-types-8d55eca5790c0406.js → custom-types-abb8c8c92880120e.js} +1 -1
- package/out/_next/static/chunks/pages/{index-203d9ef99d22841a.js → index-f382c8090bd21628.js} +1 -1
- package/out/_next/static/chunks/pages/page-types/{[pageTypeId]-81e1a6a78dd46d0f.js → [pageTypeId]-ddc8d057c3e251d1.js} +1 -1
- package/out/_next/static/chunks/pages/slices-24d2714462334469.js +1 -0
- package/out/_next/static/n_JoJA4knO1LXgyjcCqiI/_buildManifest.js +1 -0
- 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/page-types/[pageTypeId].html +1 -1
- package/out/slices.html +1 -1
- package/package.json +6 -6
- package/pages/slices.tsx +1 -1
- package/components/Forms/ConvertLegacySliceModal/ConvertLegacySliceModal.css.ts +0 -35
- package/components/Forms/ConvertLegacySliceModal/ConvertLegacySliceModal.tsx +0 -287
- package/components/Forms/ConvertLegacySliceModal/FormAsNewSlice.tsx +0 -153
- package/components/Forms/ConvertLegacySliceModal/FormAsNewVariation.tsx +0 -234
- package/components/Forms/ConvertLegacySliceModal/FormMergeWithIdentical.tsx +0 -104
- package/components/Forms/ConvertLegacySliceModal/index.tsx +0 -1
- package/components/Forms/ConvertLegacySliceModal/types.ts +0 -47
- package/out/_next/static/M1R8KztYSsGkogo8JNvDL/_buildManifest.js +0 -1
- package/out/_next/static/chunks/130-5b1dc0c67078c48b.js +0 -1
- package/out/_next/static/chunks/4-11b3d83d878be4e2.js +0 -1
- package/out/_next/static/chunks/799-00944cdde5b22566.js +0 -1
- package/out/_next/static/chunks/80-dce703180b269337.js +0 -1
- package/out/_next/static/chunks/934-7e172f9ea1128015.js +0 -1
- package/out/_next/static/chunks/970-d63bac52b8b2439a.js +0 -1
- package/out/_next/static/chunks/pages/[lib]/[sliceName]/[variation]-fc545d9beb1bb757.js +0 -1
- package/out/_next/static/chunks/pages/changes-eb708af5609cc7d2.js +0 -1
- package/out/_next/static/chunks/pages/slices-3ecbaeec98bc9eab.js +0 -1
- /package/out/_next/static/{M1R8KztYSsGkogo8JNvDL → n_JoJA4knO1LXgyjcCqiI}/_ssgManifest.js +0 -0
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { sprinkles } from "@prismicio/editor-ui";
|
|
2
|
-
import { style } from "@vanilla-extract/css";
|
|
3
|
-
|
|
4
|
-
export const form = style([
|
|
5
|
-
sprinkles({
|
|
6
|
-
display: "flex",
|
|
7
|
-
flexDirection: "column",
|
|
8
|
-
}),
|
|
9
|
-
]);
|
|
10
|
-
|
|
11
|
-
export const scrollArea = style([
|
|
12
|
-
sprinkles({
|
|
13
|
-
height: "100%",
|
|
14
|
-
display: "flex",
|
|
15
|
-
gap: 8,
|
|
16
|
-
paddingInline: 16,
|
|
17
|
-
paddingBlock: 16,
|
|
18
|
-
}),
|
|
19
|
-
]);
|
|
20
|
-
|
|
21
|
-
export const field = style([
|
|
22
|
-
sprinkles({
|
|
23
|
-
display: "flex",
|
|
24
|
-
flexDirection: "column",
|
|
25
|
-
gap: 4,
|
|
26
|
-
}),
|
|
27
|
-
]);
|
|
28
|
-
|
|
29
|
-
export const label = style([
|
|
30
|
-
sprinkles({
|
|
31
|
-
display: "inline-flex",
|
|
32
|
-
alignItems: "center",
|
|
33
|
-
gap: 4,
|
|
34
|
-
}),
|
|
35
|
-
]);
|
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
import { useMemo, useState } from "react";
|
|
2
|
-
import { useSelector } from "react-redux";
|
|
3
|
-
import {
|
|
4
|
-
DropdownMenu,
|
|
5
|
-
DropdownMenuContent,
|
|
6
|
-
DropdownMenuItem,
|
|
7
|
-
DropdownMenuTrigger,
|
|
8
|
-
Icon,
|
|
9
|
-
Button,
|
|
10
|
-
} from "@prismicio/editor-ui";
|
|
11
|
-
import { CompositeSlice } from "@prismicio/types-internal/lib/customtypes";
|
|
12
|
-
|
|
13
|
-
import { getLibraries } from "@src/modules/slices";
|
|
14
|
-
import { VariationSM } from "@models/common/Slice";
|
|
15
|
-
import { SliceMachineStoreType } from "@src/redux/type";
|
|
16
|
-
import { managerClient } from "@src/managerClient";
|
|
17
|
-
import { getState, telemetry } from "@src/apiClient";
|
|
18
|
-
import useSliceMachineActions from "@src/modules/useSliceMachineActions";
|
|
19
|
-
import { ToasterType } from "@src/modules/toaster";
|
|
20
|
-
|
|
21
|
-
import { FormAsNewSlice } from "./FormAsNewSlice";
|
|
22
|
-
import { FormAsNewVariation } from "./FormAsNewVariation";
|
|
23
|
-
import { FormMergeWithIdentical } from "./FormMergeWithIdentical";
|
|
24
|
-
import {
|
|
25
|
-
ConvertLegacySliceModalProps,
|
|
26
|
-
ConvertLegacySliceAndTrackArgs,
|
|
27
|
-
IdenticalSlice,
|
|
28
|
-
Type,
|
|
29
|
-
} from "./types";
|
|
30
|
-
|
|
31
|
-
const getFieldMappingFingerprint = (
|
|
32
|
-
slice: CompositeSlice | VariationSM
|
|
33
|
-
): {
|
|
34
|
-
primary: string;
|
|
35
|
-
items: string;
|
|
36
|
-
} => {
|
|
37
|
-
const primary: Record<string, string> = {};
|
|
38
|
-
const items: Record<string, string> = {};
|
|
39
|
-
|
|
40
|
-
if ("type" in slice && slice.type === "Slice") {
|
|
41
|
-
for (const key in slice["non-repeat"]) {
|
|
42
|
-
primary[key] = slice["non-repeat"][key].type;
|
|
43
|
-
}
|
|
44
|
-
for (const key in slice.repeat) {
|
|
45
|
-
items[key] = slice.repeat[key].type;
|
|
46
|
-
}
|
|
47
|
-
} else if ("id" in slice) {
|
|
48
|
-
for (const { key, value } of slice.primary ?? []) {
|
|
49
|
-
primary[key] = value.type;
|
|
50
|
-
}
|
|
51
|
-
for (const { key, value } of slice.items ?? []) {
|
|
52
|
-
items[key] = value.type;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return {
|
|
57
|
-
primary: JSON.stringify(
|
|
58
|
-
Object.keys(primary)
|
|
59
|
-
.sort()
|
|
60
|
-
.map((key) => [key, primary[key]])
|
|
61
|
-
),
|
|
62
|
-
items: JSON.stringify(
|
|
63
|
-
Object.keys(items)
|
|
64
|
-
.sort()
|
|
65
|
-
.map((key) => [key, items[key]])
|
|
66
|
-
),
|
|
67
|
-
};
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
export const ConvertLegacySliceModal: React.FC<
|
|
71
|
-
ConvertLegacySliceModalProps
|
|
72
|
-
> = ({ slice, slices, path }) => {
|
|
73
|
-
const { refreshState, replaceCustomTypeSharedSlice, openToaster } =
|
|
74
|
-
useSliceMachineActions();
|
|
75
|
-
|
|
76
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
77
|
-
const [isModalOpen, setIsModalOpen] = useState<false | Type>(false);
|
|
78
|
-
|
|
79
|
-
const { libraries: allLibraries } = useSelector(
|
|
80
|
-
(store: SliceMachineStoreType) => ({
|
|
81
|
-
libraries: getLibraries(store),
|
|
82
|
-
})
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
const {} = useSliceMachineActions();
|
|
86
|
-
|
|
87
|
-
const sliceName = useMemo(() => {
|
|
88
|
-
return slice.value.type === "Slice"
|
|
89
|
-
? slice.value.fieldset ?? slice.key
|
|
90
|
-
: slice.key;
|
|
91
|
-
}, [slice]);
|
|
92
|
-
const libraries = useMemo(() => {
|
|
93
|
-
return allLibraries.filter((library) => library.isLocal);
|
|
94
|
-
}, [allLibraries]);
|
|
95
|
-
const localSharedSlices = useMemo(() => {
|
|
96
|
-
return libraries.map((library) => library.components).flat();
|
|
97
|
-
}, [libraries]);
|
|
98
|
-
const identicalSlices = useMemo<IdenticalSlice[]>(() => {
|
|
99
|
-
const results: IdenticalSlice[] = [];
|
|
100
|
-
|
|
101
|
-
if (slice.value.type !== "Slice") {
|
|
102
|
-
return results;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const sliceFields = getFieldMappingFingerprint(slice.value);
|
|
106
|
-
|
|
107
|
-
for (const sharedSlice of localSharedSlices) {
|
|
108
|
-
for (const variation of sharedSlice.model.variations) {
|
|
109
|
-
const variationFields = getFieldMappingFingerprint(variation);
|
|
110
|
-
|
|
111
|
-
if (
|
|
112
|
-
sliceFields.primary === variationFields.primary &&
|
|
113
|
-
sliceFields.items === variationFields.items
|
|
114
|
-
) {
|
|
115
|
-
results.push({
|
|
116
|
-
libraryID: sharedSlice.from,
|
|
117
|
-
sliceID: sharedSlice.model.id,
|
|
118
|
-
variationID: variation.id,
|
|
119
|
-
path: `${sharedSlice.from}::${sharedSlice.model.id}::${variation.id}`,
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return results;
|
|
126
|
-
}, [slice, localSharedSlices]);
|
|
127
|
-
|
|
128
|
-
const convertLegacySliceAndTrack = (args: ConvertLegacySliceAndTrackArgs) => {
|
|
129
|
-
if (isModalOpen === false) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
setIsLoading(true);
|
|
134
|
-
void (async () => {
|
|
135
|
-
void telemetry.track({
|
|
136
|
-
event: "legacy-slice:converted",
|
|
137
|
-
id: args.sliceID,
|
|
138
|
-
variation: args.variationID ?? "default",
|
|
139
|
-
library: args.libraryID,
|
|
140
|
-
conversionType: isModalOpen,
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
const { errors } =
|
|
144
|
-
await managerClient.slices.convertLegacySliceToSharedSlice({
|
|
145
|
-
model: slice.value,
|
|
146
|
-
src: {
|
|
147
|
-
...path,
|
|
148
|
-
sliceID: slice.key,
|
|
149
|
-
},
|
|
150
|
-
dest: {
|
|
151
|
-
libraryID: args.libraryID,
|
|
152
|
-
sliceID: args.sliceID,
|
|
153
|
-
variationName: args.variationName ?? "Default",
|
|
154
|
-
variationID: args.variationID ?? "default",
|
|
155
|
-
},
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
if (errors.length) {
|
|
159
|
-
console.error(
|
|
160
|
-
`Errors happened when converting slice \`${sliceName}\``,
|
|
161
|
-
errors
|
|
162
|
-
);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// TODO(DT-1453): Remove the need of the global getState
|
|
166
|
-
const serverState = await getState();
|
|
167
|
-
// Update Redux store
|
|
168
|
-
refreshState(serverState);
|
|
169
|
-
|
|
170
|
-
setIsLoading(false);
|
|
171
|
-
setIsModalOpen(false);
|
|
172
|
-
switch (isModalOpen) {
|
|
173
|
-
case "as_new_slice":
|
|
174
|
-
openToaster(
|
|
175
|
-
`${sliceName} has been upgraded to a new slice ${args.libraryID} > ${args.sliceID}`,
|
|
176
|
-
ToasterType.SUCCESS
|
|
177
|
-
);
|
|
178
|
-
break;
|
|
179
|
-
|
|
180
|
-
case "as_new_variation":
|
|
181
|
-
openToaster(
|
|
182
|
-
`${sliceName} has been converted as a variation of ${args.libraryID} > ${args.sliceID}`,
|
|
183
|
-
ToasterType.SUCCESS
|
|
184
|
-
);
|
|
185
|
-
break;
|
|
186
|
-
|
|
187
|
-
case "merge_with_identical":
|
|
188
|
-
default:
|
|
189
|
-
openToaster(
|
|
190
|
-
`${sliceName} has been merged with ${args.libraryID} > ${args.sliceID}`,
|
|
191
|
-
ToasterType.SUCCESS
|
|
192
|
-
);
|
|
193
|
-
break;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
replaceCustomTypeSharedSlice(
|
|
197
|
-
path.tabID,
|
|
198
|
-
[
|
|
199
|
-
...slices
|
|
200
|
-
.map((slice) => {
|
|
201
|
-
if (
|
|
202
|
-
"model" in slice.payload &&
|
|
203
|
-
slice.payload.model.id !== args.sliceID
|
|
204
|
-
) {
|
|
205
|
-
return slice.payload.model.id;
|
|
206
|
-
}
|
|
207
|
-
return "";
|
|
208
|
-
})
|
|
209
|
-
.filter(Boolean),
|
|
210
|
-
args.sliceID,
|
|
211
|
-
],
|
|
212
|
-
slices
|
|
213
|
-
.map((_slice) => {
|
|
214
|
-
if ("key" in _slice.payload && _slice.payload.key !== slice.key) {
|
|
215
|
-
return _slice.payload.key;
|
|
216
|
-
}
|
|
217
|
-
return "";
|
|
218
|
-
})
|
|
219
|
-
.filter(Boolean)
|
|
220
|
-
);
|
|
221
|
-
})();
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
const formProps = {
|
|
225
|
-
path,
|
|
226
|
-
slice,
|
|
227
|
-
sliceName,
|
|
228
|
-
libraries,
|
|
229
|
-
localSharedSlices,
|
|
230
|
-
identicalSlices,
|
|
231
|
-
close: () => setIsModalOpen(false),
|
|
232
|
-
onSubmit: convertLegacySliceAndTrack,
|
|
233
|
-
isLoading,
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
return (
|
|
237
|
-
<>
|
|
238
|
-
<DropdownMenu>
|
|
239
|
-
<DropdownMenuTrigger>
|
|
240
|
-
<Button
|
|
241
|
-
data-cy="convert-legacy-slice"
|
|
242
|
-
startIcon="refresh"
|
|
243
|
-
endIcon="arrowDropDown"
|
|
244
|
-
size="medium"
|
|
245
|
-
variant="secondary"
|
|
246
|
-
>
|
|
247
|
-
Migrate legacy slice
|
|
248
|
-
</Button>
|
|
249
|
-
</DropdownMenuTrigger>
|
|
250
|
-
<DropdownMenuContent align="start">
|
|
251
|
-
<DropdownMenuItem
|
|
252
|
-
startIcon={<Icon name="folder" size="large" />}
|
|
253
|
-
description="Use it with new types"
|
|
254
|
-
onSelect={() => setIsModalOpen("as_new_slice")}
|
|
255
|
-
>
|
|
256
|
-
Upgrade slice
|
|
257
|
-
</DropdownMenuItem>
|
|
258
|
-
<DropdownMenuItem
|
|
259
|
-
startIcon={<Icon name="viewDay" size="large" />}
|
|
260
|
-
description="Add it to another slice"
|
|
261
|
-
onSelect={() => setIsModalOpen("as_new_variation")}
|
|
262
|
-
disabled={!localSharedSlices.length}
|
|
263
|
-
>
|
|
264
|
-
Convert to slice variation
|
|
265
|
-
</DropdownMenuItem>
|
|
266
|
-
<DropdownMenuItem
|
|
267
|
-
startIcon={<Icon name="driveFileMove" size="large" />}
|
|
268
|
-
description="Combine identical slices"
|
|
269
|
-
onSelect={() => setIsModalOpen("merge_with_identical")}
|
|
270
|
-
disabled={!identicalSlices.length}
|
|
271
|
-
>
|
|
272
|
-
Merge with another slice
|
|
273
|
-
</DropdownMenuItem>
|
|
274
|
-
</DropdownMenuContent>
|
|
275
|
-
</DropdownMenu>
|
|
276
|
-
<FormAsNewSlice {...formProps} isOpen={isModalOpen === "as_new_slice"} />
|
|
277
|
-
<FormAsNewVariation
|
|
278
|
-
{...formProps}
|
|
279
|
-
isOpen={isModalOpen === "as_new_variation"}
|
|
280
|
-
/>
|
|
281
|
-
<FormMergeWithIdentical
|
|
282
|
-
{...formProps}
|
|
283
|
-
isOpen={isModalOpen === "merge_with_identical"}
|
|
284
|
-
/>
|
|
285
|
-
</>
|
|
286
|
-
);
|
|
287
|
-
};
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import { useSelector } from "react-redux";
|
|
2
|
-
import { Formik } from "formik";
|
|
3
|
-
import {
|
|
4
|
-
Dialog,
|
|
5
|
-
DialogActions,
|
|
6
|
-
DialogContent,
|
|
7
|
-
DialogHeader,
|
|
8
|
-
ScrollArea,
|
|
9
|
-
FormInput,
|
|
10
|
-
Text,
|
|
11
|
-
Select,
|
|
12
|
-
SelectItem,
|
|
13
|
-
} from "@prismicio/editor-ui";
|
|
14
|
-
|
|
15
|
-
import { SliceMachineStoreType } from "@src/redux/type";
|
|
16
|
-
import { getRemoteSlices } from "@src/modules/slices";
|
|
17
|
-
import { pascalize } from "@lib/utils/str";
|
|
18
|
-
|
|
19
|
-
import { validateSliceModalValues as validateAsNewSliceValues } from "../formsValidator";
|
|
20
|
-
import * as styles from "./ConvertLegacySliceModal.css";
|
|
21
|
-
import { FormProps } from "./types";
|
|
22
|
-
|
|
23
|
-
export const FormAsNewSlice: React.FC<FormProps> = ({
|
|
24
|
-
isOpen,
|
|
25
|
-
close,
|
|
26
|
-
onSubmit,
|
|
27
|
-
isLoading,
|
|
28
|
-
slice,
|
|
29
|
-
libraries,
|
|
30
|
-
}) => {
|
|
31
|
-
const { remoteSlices } = useSelector((store: SliceMachineStoreType) => ({
|
|
32
|
-
remoteSlices: getRemoteSlices(store),
|
|
33
|
-
}));
|
|
34
|
-
|
|
35
|
-
return (
|
|
36
|
-
<Dialog
|
|
37
|
-
open={isOpen}
|
|
38
|
-
onOpenChange={(open) => !open && close()}
|
|
39
|
-
size={{ width: 448, height: "auto" }}
|
|
40
|
-
>
|
|
41
|
-
<DialogHeader title="Upgrade slice" />
|
|
42
|
-
<DialogContent>
|
|
43
|
-
<Formik
|
|
44
|
-
validateOnChange
|
|
45
|
-
initialValues={{
|
|
46
|
-
_init: false,
|
|
47
|
-
from: libraries[0]?.name,
|
|
48
|
-
sliceName: pascalize(slice.key),
|
|
49
|
-
}}
|
|
50
|
-
validate={(values) => {
|
|
51
|
-
return validateAsNewSliceValues(values, libraries, remoteSlices);
|
|
52
|
-
}}
|
|
53
|
-
onSubmit={(values) => {
|
|
54
|
-
onSubmit({ libraryID: values.from, sliceID: values.sliceName });
|
|
55
|
-
}}
|
|
56
|
-
>
|
|
57
|
-
{(formik) => {
|
|
58
|
-
// Just a hack to trigger validation on init for better UX
|
|
59
|
-
if (!formik.values._init) {
|
|
60
|
-
void formik.setFieldValue("_init", true);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return (
|
|
64
|
-
<form
|
|
65
|
-
id="convert-legacy-slice-modal-as-new-slice"
|
|
66
|
-
data-cy="convert-legacy-slice-modal-as-new-slice"
|
|
67
|
-
className={styles.form}
|
|
68
|
-
>
|
|
69
|
-
<ScrollArea className={styles.scrollArea}>
|
|
70
|
-
<Text variant="normal" color="grey11">
|
|
71
|
-
This will create a new slice with the same fields. The new
|
|
72
|
-
slice will replace the legacy slice in all of your types,
|
|
73
|
-
and the existing slice content will be re-mapped to the new
|
|
74
|
-
slice.
|
|
75
|
-
</Text>
|
|
76
|
-
<Text variant="normal" color="grey11">
|
|
77
|
-
This will not migrate your component. You will need to do
|
|
78
|
-
that manually.
|
|
79
|
-
</Text>
|
|
80
|
-
<div className={styles.field}>
|
|
81
|
-
<label className={styles.label}>
|
|
82
|
-
<Text variant="bold">Display name*</Text>
|
|
83
|
-
{typeof formik.errors.sliceName === "string" ? (
|
|
84
|
-
<Text variant="small" color="tomato10">
|
|
85
|
-
{formik.errors.sliceName}
|
|
86
|
-
</Text>
|
|
87
|
-
) : null}
|
|
88
|
-
</label>
|
|
89
|
-
<FormInput
|
|
90
|
-
placeholder={`Pascalised Slice API ID (e.g. ${pascalize(
|
|
91
|
-
slice.key
|
|
92
|
-
)})`}
|
|
93
|
-
error={typeof formik.errors.sliceName === "string"}
|
|
94
|
-
value={formik.values.sliceName}
|
|
95
|
-
onValueChange={(value) =>
|
|
96
|
-
void formik.setFieldValue(
|
|
97
|
-
"sliceName",
|
|
98
|
-
value.slice(0, 30)
|
|
99
|
-
)
|
|
100
|
-
}
|
|
101
|
-
data-cy="slice-name-input"
|
|
102
|
-
/>
|
|
103
|
-
<Text variant="normal" color="grey11">
|
|
104
|
-
A display name for the slice
|
|
105
|
-
</Text>
|
|
106
|
-
</div>
|
|
107
|
-
<div className={styles.field}>
|
|
108
|
-
<label className={styles.label}>
|
|
109
|
-
<Text variant="bold">Slice library*</Text>
|
|
110
|
-
{typeof formik.errors.from === "string" ? (
|
|
111
|
-
<Text variant="small" color="tomato10">
|
|
112
|
-
{formik.errors.from}
|
|
113
|
-
</Text>
|
|
114
|
-
) : null}
|
|
115
|
-
</label>
|
|
116
|
-
<Select
|
|
117
|
-
size="medium"
|
|
118
|
-
variant="secondary"
|
|
119
|
-
startIcon="folder"
|
|
120
|
-
flexContent={true}
|
|
121
|
-
value={formik.values.from}
|
|
122
|
-
onValueChange={(value) =>
|
|
123
|
-
value ? void formik.setFieldValue("from", value) : null
|
|
124
|
-
}
|
|
125
|
-
>
|
|
126
|
-
{libraries.map((library) => (
|
|
127
|
-
<SelectItem key={library.name} value={library.name}>
|
|
128
|
-
{library.name}
|
|
129
|
-
</SelectItem>
|
|
130
|
-
))}
|
|
131
|
-
</Select>
|
|
132
|
-
<Text variant="normal" color="grey11">
|
|
133
|
-
The library where we'll store your slice
|
|
134
|
-
</Text>
|
|
135
|
-
</div>
|
|
136
|
-
</ScrollArea>
|
|
137
|
-
<DialogActions
|
|
138
|
-
ok={{
|
|
139
|
-
text: "Upgrade",
|
|
140
|
-
onClick: () => void formik.submitForm(),
|
|
141
|
-
loading: isLoading,
|
|
142
|
-
disabled: !formik.isValid,
|
|
143
|
-
}}
|
|
144
|
-
cancel={{ text: "Cancel" }}
|
|
145
|
-
/>
|
|
146
|
-
</form>
|
|
147
|
-
);
|
|
148
|
-
}}
|
|
149
|
-
</Formik>
|
|
150
|
-
</DialogContent>
|
|
151
|
-
</Dialog>
|
|
152
|
-
);
|
|
153
|
-
};
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
|
-
import { Formik } from "formik";
|
|
3
|
-
import {
|
|
4
|
-
Dialog,
|
|
5
|
-
DialogActions,
|
|
6
|
-
DialogContent,
|
|
7
|
-
DialogHeader,
|
|
8
|
-
ScrollArea,
|
|
9
|
-
FormInput,
|
|
10
|
-
Text,
|
|
11
|
-
Select,
|
|
12
|
-
SelectItem,
|
|
13
|
-
} from "@prismicio/editor-ui";
|
|
14
|
-
|
|
15
|
-
import { Variation } from "@models/common/Variation";
|
|
16
|
-
import { LibraryUI } from "@models/common/LibraryUI";
|
|
17
|
-
|
|
18
|
-
import * as styles from "./ConvertLegacySliceModal.css";
|
|
19
|
-
import { FormProps } from "./types";
|
|
20
|
-
|
|
21
|
-
type FormValues = {
|
|
22
|
-
libraryID: string;
|
|
23
|
-
sliceID: string;
|
|
24
|
-
variationID: string;
|
|
25
|
-
variationName: string;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const validateAsNewVariationValues = (
|
|
29
|
-
values: FormValues,
|
|
30
|
-
libraries: readonly LibraryUI[]
|
|
31
|
-
): Partial<Record<keyof FormValues, string>> => {
|
|
32
|
-
const errors: Partial<Record<keyof FormValues, string>> = {};
|
|
33
|
-
|
|
34
|
-
if (!values.libraryID) {
|
|
35
|
-
errors.libraryID = "Cannot be empty.";
|
|
36
|
-
}
|
|
37
|
-
const library = libraries.find(
|
|
38
|
-
(library) => library.path === values.libraryID
|
|
39
|
-
);
|
|
40
|
-
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
41
|
-
if (!errors.libraryID && !library) {
|
|
42
|
-
errors.libraryID = "Does not exists.";
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (!values.sliceID) {
|
|
46
|
-
errors.sliceID = "Cannot be empty.";
|
|
47
|
-
}
|
|
48
|
-
const slice = library?.components.find(
|
|
49
|
-
(component) => component.model.id === values.sliceID
|
|
50
|
-
);
|
|
51
|
-
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
52
|
-
if (!errors.sliceID && !slice) {
|
|
53
|
-
errors.sliceID = "Does not exists.";
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (!values.variationName) {
|
|
57
|
-
errors.variationName = "Cannot be empty.";
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (!values.variationID) {
|
|
61
|
-
errors.variationID = "Cannot be empty.";
|
|
62
|
-
} else {
|
|
63
|
-
const variationIDs =
|
|
64
|
-
slice?.model.variations.map((variation) => variation.id) ?? [];
|
|
65
|
-
|
|
66
|
-
if (variationIDs.includes(values.variationID)) {
|
|
67
|
-
errors.variationID = "Slice variation ID is already taken.";
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return errors;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
export const FormAsNewVariation: React.FC<FormProps> = ({
|
|
75
|
-
isOpen,
|
|
76
|
-
close,
|
|
77
|
-
onSubmit,
|
|
78
|
-
isLoading,
|
|
79
|
-
slice,
|
|
80
|
-
sliceName,
|
|
81
|
-
libraries,
|
|
82
|
-
localSharedSlices,
|
|
83
|
-
}) => {
|
|
84
|
-
const [inferIDFromName, setInferIDFromName] = useState(true);
|
|
85
|
-
|
|
86
|
-
return (
|
|
87
|
-
<Dialog
|
|
88
|
-
open={isOpen}
|
|
89
|
-
onOpenChange={(open) => !open && close()}
|
|
90
|
-
size={{ width: 448, height: "auto" }}
|
|
91
|
-
>
|
|
92
|
-
<DialogHeader title="Convert to slice variation" />
|
|
93
|
-
<DialogContent>
|
|
94
|
-
<Formik
|
|
95
|
-
validateOnChange
|
|
96
|
-
initialValues={{
|
|
97
|
-
libraryID: localSharedSlices[0]?.from,
|
|
98
|
-
sliceID: localSharedSlices[0]?.model.id,
|
|
99
|
-
variationID: Variation.generateId(slice.key),
|
|
100
|
-
variationName: sliceName,
|
|
101
|
-
}}
|
|
102
|
-
validate={(values) => {
|
|
103
|
-
return validateAsNewVariationValues(values, libraries);
|
|
104
|
-
}}
|
|
105
|
-
onSubmit={(values) => {
|
|
106
|
-
onSubmit(values);
|
|
107
|
-
}}
|
|
108
|
-
>
|
|
109
|
-
{(formik) => {
|
|
110
|
-
return (
|
|
111
|
-
<form
|
|
112
|
-
id="convert-legacy-slice-modal-as-new-variation"
|
|
113
|
-
data-cy="convert-legacy-slice-modal-as-new-variation"
|
|
114
|
-
className={styles.form}
|
|
115
|
-
>
|
|
116
|
-
<ScrollArea className={styles.scrollArea}>
|
|
117
|
-
<Text variant="normal" color="grey11">
|
|
118
|
-
If you have multiple slices that are similar, you can
|
|
119
|
-
combine them as variations of the same slice.
|
|
120
|
-
</Text>
|
|
121
|
-
<div className={styles.field}>
|
|
122
|
-
<label className={styles.label}>
|
|
123
|
-
<Text variant="bold">Target slice*</Text>
|
|
124
|
-
{typeof formik.errors.libraryID === "string" ? (
|
|
125
|
-
<Text variant="small" color="tomato10">
|
|
126
|
-
{formik.errors.libraryID}
|
|
127
|
-
</Text>
|
|
128
|
-
) : null}
|
|
129
|
-
{typeof formik.errors.sliceID === "string" ? (
|
|
130
|
-
<Text variant="small" color="tomato10">
|
|
131
|
-
{formik.errors.sliceID}
|
|
132
|
-
</Text>
|
|
133
|
-
) : null}
|
|
134
|
-
</label>
|
|
135
|
-
<Select
|
|
136
|
-
size="medium"
|
|
137
|
-
variant="secondary"
|
|
138
|
-
startIcon="viewDay"
|
|
139
|
-
flexContent={true}
|
|
140
|
-
value={`${formik.values.libraryID}::${formik.values.sliceID}`}
|
|
141
|
-
onValueChange={(value) => {
|
|
142
|
-
if (value) {
|
|
143
|
-
const [libraryID, sliceID] = value.split("::");
|
|
144
|
-
void formik.setFieldValue("libraryID", libraryID);
|
|
145
|
-
void formik.setFieldValue("sliceID", sliceID);
|
|
146
|
-
}
|
|
147
|
-
}}
|
|
148
|
-
>
|
|
149
|
-
{localSharedSlices.map((slice) => (
|
|
150
|
-
<SelectItem
|
|
151
|
-
key={`${slice.from}::${slice.model.id}`}
|
|
152
|
-
value={`${slice.from}::${slice.model.id}`}
|
|
153
|
-
>
|
|
154
|
-
{slice.from} {">"} {slice.model.name} (
|
|
155
|
-
{slice.model.id})
|
|
156
|
-
</SelectItem>
|
|
157
|
-
))}
|
|
158
|
-
</Select>
|
|
159
|
-
<Text variant="normal" color="grey11">
|
|
160
|
-
Choose the slice to which you would like to add this
|
|
161
|
-
variation.
|
|
162
|
-
</Text>
|
|
163
|
-
</div>
|
|
164
|
-
<div className={styles.field}>
|
|
165
|
-
<label className={styles.label}>
|
|
166
|
-
<Text variant="bold">Variation name*</Text>
|
|
167
|
-
{typeof formik.errors.variationName === "string" ? (
|
|
168
|
-
<Text variant="small" color="tomato10">
|
|
169
|
-
{formik.errors.variationName}
|
|
170
|
-
</Text>
|
|
171
|
-
) : null}
|
|
172
|
-
</label>
|
|
173
|
-
<FormInput
|
|
174
|
-
placeholder={sliceName}
|
|
175
|
-
error={typeof formik.errors.variationName === "string"}
|
|
176
|
-
value={formik.values.variationName}
|
|
177
|
-
onValueChange={(value) => {
|
|
178
|
-
const values = {
|
|
179
|
-
...formik.values,
|
|
180
|
-
variationName: value.slice(0, 30),
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
if (inferIDFromName) {
|
|
184
|
-
values.variationID = Variation.generateId(
|
|
185
|
-
values.variationName
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
formik.setValues(values, true);
|
|
190
|
-
}}
|
|
191
|
-
data-cy="variation-name-input"
|
|
192
|
-
/>
|
|
193
|
-
</div>
|
|
194
|
-
<div className={styles.field}>
|
|
195
|
-
<label className={styles.label}>
|
|
196
|
-
<Text variant="bold">ID*</Text>
|
|
197
|
-
{typeof formik.errors.variationID === "string" ? (
|
|
198
|
-
<Text variant="small" color="tomato10">
|
|
199
|
-
{formik.errors.variationID}
|
|
200
|
-
</Text>
|
|
201
|
-
) : null}
|
|
202
|
-
</label>
|
|
203
|
-
<FormInput
|
|
204
|
-
placeholder={Variation.generateId(slice.key)}
|
|
205
|
-
error={typeof formik.errors.variationID === "string"}
|
|
206
|
-
value={formik.values.variationID}
|
|
207
|
-
onValueChange={(value) => {
|
|
208
|
-
setInferIDFromName(false);
|
|
209
|
-
void formik.setFieldValue(
|
|
210
|
-
"variationID",
|
|
211
|
-
Variation.generateId(value.slice(0, 30))
|
|
212
|
-
);
|
|
213
|
-
}}
|
|
214
|
-
data-cy="variation-id-input"
|
|
215
|
-
/>
|
|
216
|
-
</div>
|
|
217
|
-
</ScrollArea>
|
|
218
|
-
<DialogActions
|
|
219
|
-
ok={{
|
|
220
|
-
text: "Convert",
|
|
221
|
-
onClick: () => void formik.submitForm(),
|
|
222
|
-
loading: isLoading,
|
|
223
|
-
disabled: !formik.isValid,
|
|
224
|
-
}}
|
|
225
|
-
cancel={{ text: "Cancel" }}
|
|
226
|
-
/>
|
|
227
|
-
</form>
|
|
228
|
-
);
|
|
229
|
-
}}
|
|
230
|
-
</Formik>
|
|
231
|
-
</DialogContent>
|
|
232
|
-
</Dialog>
|
|
233
|
-
);
|
|
234
|
-
};
|