slice-machine-ui 1.14.1-dev-upgrade-legacy.2 → 1.14.2-dev-next-release.0

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 (52) hide show
  1. package/components/ChangesItems/ChangesItems.tsx +1 -1
  2. package/lib/builders/CustomTypeBuilder/SliceZone/List.tsx +4 -12
  3. package/lib/builders/CustomTypeBuilder/SliceZone/UpdateSliceZoneModalList.tsx +1 -1
  4. package/lib/builders/CustomTypeBuilder/SliceZone/index.tsx +0 -8
  5. package/lib/models/ui/Slice/index.tsx +26 -52
  6. package/out/404.html +1 -1
  7. package/out/[lib]/[sliceName]/[variation]/screenshot.html +1 -1
  8. package/out/[lib]/[sliceName]/[variation]/simulator.html +1 -1
  9. package/out/[lib]/[sliceName]/[variation].html +1 -1
  10. package/out/_next/static/33MKeR6JI2GQc4QAaCn2K/_buildManifest.js +1 -0
  11. package/out/_next/static/chunks/482-a4c1c3721ca38516.js +1 -0
  12. package/out/_next/static/chunks/573-aaae870d20e5f86c.js +1 -0
  13. package/out/_next/static/chunks/{969-bcfa23e8fd4773e7.js → 740-d0642219804fa9f0.js} +1 -1
  14. package/out/_next/static/chunks/799-5ea3393033a9f617.js +1 -0
  15. package/out/_next/static/chunks/906-9224feb63b5e36f3.js +1 -0
  16. package/out/_next/static/chunks/97-f6188ebe22eb21da.js +1 -0
  17. package/out/_next/static/chunks/970-a6a3a5a5b9f896ab.js +1 -0
  18. package/out/_next/static/chunks/pages/[lib]/[sliceName]/[variation]-9fff494255e34c39.js +1 -0
  19. package/out/_next/static/chunks/pages/{_app-fea3c7cfb3b5c1b5.js → _app-e113bc13f8b34f6e.js} +7 -7
  20. package/out/_next/static/chunks/pages/changes-6a039e823313b41c.js +1 -0
  21. package/out/_next/static/chunks/pages/custom-types/{[customTypeId]-94ffa7cbfab2ef0f.js → [customTypeId]-f8e48a51edbb5e1c.js} +1 -1
  22. package/out/_next/static/chunks/pages/{custom-types-8d55eca5790c0406.js → custom-types-abb8c8c92880120e.js} +1 -1
  23. package/out/_next/static/chunks/pages/{index-203d9ef99d22841a.js → index-f382c8090bd21628.js} +1 -1
  24. package/out/_next/static/chunks/pages/page-types/{[pageTypeId]-81e1a6a78dd46d0f.js → [pageTypeId]-ddc8d057c3e251d1.js} +1 -1
  25. package/out/_next/static/chunks/pages/slices-24d2714462334469.js +1 -0
  26. package/out/changelog.html +1 -1
  27. package/out/changes.html +1 -1
  28. package/out/custom-types/[customTypeId].html +1 -1
  29. package/out/custom-types.html +1 -1
  30. package/out/index.html +1 -1
  31. package/out/page-types/[pageTypeId].html +1 -1
  32. package/out/slices.html +1 -1
  33. package/package.json +6 -6
  34. package/pages/slices.tsx +1 -1
  35. package/components/Forms/ConvertLegacySliceModal/ConvertLegacySliceModal.css.ts +0 -35
  36. package/components/Forms/ConvertLegacySliceModal/ConvertLegacySliceModal.tsx +0 -287
  37. package/components/Forms/ConvertLegacySliceModal/FormAsNewSlice.tsx +0 -153
  38. package/components/Forms/ConvertLegacySliceModal/FormAsNewVariation.tsx +0 -234
  39. package/components/Forms/ConvertLegacySliceModal/FormMergeWithIdentical.tsx +0 -104
  40. package/components/Forms/ConvertLegacySliceModal/index.tsx +0 -1
  41. package/components/Forms/ConvertLegacySliceModal/types.ts +0 -47
  42. package/out/_next/static/M1R8KztYSsGkogo8JNvDL/_buildManifest.js +0 -1
  43. package/out/_next/static/chunks/130-5b1dc0c67078c48b.js +0 -1
  44. package/out/_next/static/chunks/4-11b3d83d878be4e2.js +0 -1
  45. package/out/_next/static/chunks/799-00944cdde5b22566.js +0 -1
  46. package/out/_next/static/chunks/80-dce703180b269337.js +0 -1
  47. package/out/_next/static/chunks/934-7e172f9ea1128015.js +0 -1
  48. package/out/_next/static/chunks/970-d63bac52b8b2439a.js +0 -1
  49. package/out/_next/static/chunks/pages/[lib]/[sliceName]/[variation]-fc545d9beb1bb757.js +0 -1
  50. package/out/_next/static/chunks/pages/changes-eb708af5609cc7d2.js +0 -1
  51. package/out/_next/static/chunks/pages/slices-3ecbaeec98bc9eab.js +0 -1
  52. /package/out/_next/static/{M1R8KztYSsGkogo8JNvDL → 33MKeR6JI2GQc4QAaCn2K}/_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
- };