slice-machine-ui 2.20.4 → 2.20.5-alpha.jp-import-slice-base.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.
Files changed (45) hide show
  1. package/out/404.html +1 -1
  2. package/out/_next/static/chunks/130-e1a16d2f94fb2b64.js +1 -0
  3. package/out/_next/static/chunks/422-c7a16d95b75c9e1c.js +1 -0
  4. package/out/_next/static/chunks/{429-aab52070cad2884b.js → 429-e5d7e39160de9f5e.js} +1 -1
  5. package/out/_next/static/chunks/489-c9535ef34da63d1a.js +1 -0
  6. package/out/_next/static/chunks/585-c89bb2471e85b9f8.js +1 -0
  7. package/out/_next/static/chunks/954-bedaaabf664584a0.js +1 -0
  8. package/out/_next/static/chunks/pages/{_app-0757e69fc5aa12d6.js → _app-058f06cc8ce33c8d.js} +1 -1
  9. package/out/_next/static/chunks/pages/custom-types/{[customTypeId]-6d613b67e6967ae5.js → [customTypeId]-273e9a82c085b596.js} +1 -1
  10. package/out/_next/static/chunks/pages/page-types/{[pageTypeId]-40207b66190e3fcd.js → [pageTypeId]-3fa7667de1a790d9.js} +1 -1
  11. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]/{simulator-faeb6d2f77d97096.js → simulator-8c70298caf51bed0.js} +1 -1
  12. package/out/_next/static/chunks/pages/slices-76679cf064761d2b.js +1 -0
  13. package/out/_next/static/ycaxuLGaColncBF1Sgjjd/_buildManifest.js +1 -0
  14. package/out/changelog.html +1 -1
  15. package/out/changes.html +1 -1
  16. package/out/custom-types/[customTypeId].html +1 -1
  17. package/out/custom-types.html +1 -1
  18. package/out/index.html +1 -1
  19. package/out/labs.html +1 -1
  20. package/out/page-types/[pageTypeId].html +1 -1
  21. package/out/slices/[lib]/[sliceName]/[variation]/simulator.html +1 -1
  22. package/out/slices/[lib]/[sliceName]/[variation].html +1 -1
  23. package/out/slices.html +1 -1
  24. package/package.json +5 -4
  25. package/src/features/customTypes/customTypesBuilder/ImportSlicesFromLibraryModal/ImportSlicesFromLibraryModal.tsx +336 -0
  26. package/src/features/customTypes/customTypesBuilder/ImportSlicesFromLibraryModal/SliceCard.tsx +48 -0
  27. package/src/features/customTypes/customTypesBuilder/ImportSlicesFromLibraryModal/hooks/useImportSlicesFromGithub.ts +91 -0
  28. package/src/features/customTypes/customTypesBuilder/ImportSlicesFromLibraryModal/index.tsx +1 -0
  29. package/src/features/customTypes/customTypesBuilder/ImportSlicesFromLibraryModal/types.ts +28 -0
  30. package/src/features/customTypes/customTypesBuilder/ImportSlicesFromLibraryModal/utils/addSlices.ts +186 -0
  31. package/src/features/customTypes/customTypesBuilder/ImportSlicesFromLibraryModal/utils/github.ts +657 -0
  32. package/src/features/customTypes/customTypesBuilder/ImportSlicesFromLibraryModal/utils/mapWithConcurrency.ts +28 -0
  33. package/src/features/customTypes/customTypesBuilder/ImportSlicesFromLibraryModal/utils/sliceWithoutConflicts.ts +51 -0
  34. package/src/features/customTypes/customTypesBuilder/SliceZoneBlankSlate.tsx +11 -0
  35. package/src/features/customTypes/customTypesBuilder/shared/getSubmitButtonLabel.ts +12 -0
  36. package/src/features/customTypes/customTypesBuilder/shared/useExistingSlices.ts +26 -0
  37. package/src/features/customTypes/customTypesBuilder/sliceCreationOptions.tsx +14 -0
  38. package/src/legacy/lib/builders/CustomTypeBuilder/SliceZone/index.tsx +51 -0
  39. package/src/pages/slices.tsx +30 -0
  40. package/out/_next/static/chunks/422-c9192a1dbdd2ae0e.js +0 -1
  41. package/out/_next/static/chunks/489-32281540712d98bb.js +0 -1
  42. package/out/_next/static/chunks/633-74a9ae6d5200cefc.js +0 -1
  43. package/out/_next/static/chunks/pages/slices-ec56b94b35794675.js +0 -1
  44. package/out/_next/static/rBa8bli71awcMIaTyoop1/_buildManifest.js +0 -1
  45. /package/out/_next/static/{rBa8bli71awcMIaTyoop1 → ycaxuLGaColncBF1Sgjjd}/_ssgManifest.js +0 -0
@@ -0,0 +1,51 @@
1
+ import { SharedSlice } from "@prismicio/types-internal/lib/customtypes";
2
+
3
+ import { NewSlice } from "../types";
4
+
5
+ /**
6
+ * If needed, assigns new ids and names to avoid conflicts with existing slices.
7
+ * Names are compared case-insensitively to avoid conflicts
8
+ * between folder names with different casing.
9
+ */
10
+ export function sliceWithoutConflicts({
11
+ existingSlices,
12
+ newSlices,
13
+ slice,
14
+ }: {
15
+ existingSlices: SharedSlice[];
16
+ newSlices: NewSlice[];
17
+ slice: SharedSlice;
18
+ }): SharedSlice {
19
+ const existingIds = new Set<string>();
20
+ const existingNames = new Set<string>();
21
+
22
+ for (const { id, name } of existingSlices) {
23
+ existingIds.add(id);
24
+ existingNames.add(name.toLowerCase());
25
+ }
26
+
27
+ for (const s of newSlices) {
28
+ existingIds.add(s.model.id);
29
+ existingNames.add(s.model.name.toLowerCase());
30
+ }
31
+
32
+ let id = slice.id;
33
+ let counter = 2;
34
+ while (existingIds.has(id)) {
35
+ id = `${slice.id}_${counter}`;
36
+ counter++;
37
+ }
38
+
39
+ let name = slice.name;
40
+ counter = 2;
41
+ while (existingNames.has(name.toLowerCase())) {
42
+ name = `${slice.name}${counter}`;
43
+ counter++;
44
+ }
45
+
46
+ return {
47
+ ...slice,
48
+ id,
49
+ name,
50
+ };
51
+ }
@@ -16,6 +16,7 @@ export type SliceZoneBlankSlateProps = {
16
16
  openCreateSliceModal: () => void;
17
17
  openCreateSliceFromImageModal: () => void;
18
18
  openSlicesTemplatesModal: () => void;
19
+ openImportSlicesFromLibraryModal: () => void;
19
20
  projectHasAvailableSlices: boolean;
20
21
  isSlicesTemplatesSupported: boolean;
21
22
  };
@@ -24,6 +25,7 @@ export const SliceZoneBlankSlate: FC<SliceZoneBlankSlateProps> = ({
24
25
  openCreateSliceModal,
25
26
  openCreateSliceFromImageModal,
26
27
  openUpdateSliceZoneModal,
28
+ openImportSlicesFromLibraryModal,
27
29
  openSlicesTemplatesModal,
28
30
  projectHasAvailableSlices,
29
31
  isSlicesTemplatesSupported,
@@ -88,6 +90,15 @@ export const SliceZoneBlankSlate: FC<SliceZoneBlankSlateProps> = ({
88
90
  {sliceCreationOptions.fromExisting.title}
89
91
  </ActionListItem>
90
92
  )}
93
+ <ActionListItem
94
+ renderStartIcon={() =>
95
+ sliceCreationOptions.importFromExternal.BackgroundIcon
96
+ }
97
+ onClick={openImportSlicesFromLibraryModal}
98
+ description={sliceCreationOptions.importFromExternal.description}
99
+ >
100
+ {sliceCreationOptions.importFromExternal.title}
101
+ </ActionListItem>
91
102
  </ActionList>
92
103
  </BlankSlateActions>
93
104
  </BlankSlate>
@@ -0,0 +1,12 @@
1
+ export const getSubmitButtonLabel = (
2
+ location: "custom_type" | "page_type" | "slices",
3
+ ) => {
4
+ switch (location) {
5
+ case "custom_type":
6
+ return "Add to type";
7
+ case "page_type":
8
+ return "Add to page";
9
+ case "slices":
10
+ return "Add to slices";
11
+ }
12
+ };
@@ -0,0 +1,26 @@
1
+ import { SharedSlice } from "@prismicio/types-internal/lib/customtypes";
2
+ import { useEffect, useRef } from "react";
3
+
4
+ import { managerClient } from "@/managerClient";
5
+
6
+ /**
7
+ * Keeps track of the existing slices in the project.
8
+ * Re-fetches them when the modal is opened.
9
+ */
10
+ export function useExistingSlices({ open }: { open: boolean }) {
11
+ const ref = useRef<SharedSlice[]>([]);
12
+
13
+ useEffect(() => {
14
+ if (!open) return;
15
+
16
+ ref.current = [];
17
+ managerClient.slices
18
+ .readAllSlices()
19
+ .then((slices) => {
20
+ ref.current = slices.models.map(({ model }) => model);
21
+ })
22
+ .catch(() => null);
23
+ }, [open]);
24
+
25
+ return ref;
26
+ }
@@ -64,5 +64,19 @@ export const getSliceCreationOptions = (args: SliceCreationOptionArgs) => {
64
64
  title: "Reuse an existing slice",
65
65
  description: "Select from your created slices.",
66
66
  },
67
+ importFromExternal: {
68
+ BackgroundIcon: (
69
+ <BackgroundIcon
70
+ name="cloudUpload"
71
+ size={menuType === "ActionList" ? "small" : "extraSmall"}
72
+ iconSize={menuType === "ActionList" ? "medium" : "small"}
73
+ color="white"
74
+ variant="solid"
75
+ radius={6}
76
+ />
77
+ ),
78
+ title: "Add from external library",
79
+ description: "Import slices from a github repository.",
80
+ },
67
81
  };
68
82
  };
@@ -17,6 +17,7 @@ import { telemetry } from "@/apiClient";
17
17
  import { ListHeader } from "@/components/List";
18
18
  import { CreateSliceFromImageModal } from "@/features/customTypes/customTypesBuilder/CreateSliceFromImageModal";
19
19
  import { useCustomTypeState } from "@/features/customTypes/customTypesBuilder/CustomTypeProvider";
20
+ import { ImportSlicesFromLibraryModal } from "@/features/customTypes/customTypesBuilder/ImportSlicesFromLibraryModal";
20
21
  import { getSliceCreationOptions } from "@/features/customTypes/customTypesBuilder/sliceCreationOptions";
21
22
  import { SliceZoneBlankSlate } from "@/features/customTypes/customTypesBuilder/SliceZoneBlankSlate";
22
23
  import { useOnboarding } from "@/features/onboarding/useOnboarding";
@@ -121,6 +122,10 @@ const SliceZone: React.FC<SliceZoneProps> = ({
121
122
  const [isCreateSliceModalOpen, setIsCreateSliceModalOpen] = useState(false);
122
123
  const [isCreateSliceFromImageModalOpen, setIsCreateSliceFromImageModalOpen] =
123
124
  useState(false);
125
+ const [
126
+ isImportSlicesFromLibraryModalOpen,
127
+ setIsImportSlicesFromLibraryModalOpen,
128
+ ] = useState(false);
124
129
  const { remoteSlices, libraries } = useSelector(
125
130
  (store: SliceMachineStoreType) => ({
126
131
  remoteSlices: getRemoteSlices(store),
@@ -197,6 +202,10 @@ const SliceZone: React.FC<SliceZoneProps> = ({
197
202
  });
198
203
  };
199
204
 
205
+ const openImportSlicesFromLibraryModal = () => {
206
+ setIsImportSlicesFromLibraryModalOpen(true);
207
+ };
208
+
200
209
  const closeUpdateSliceZoneModal = () => {
201
210
  setIsUpdateSliceZoneModalOpen(false);
202
211
  };
@@ -213,6 +222,10 @@ const SliceZone: React.FC<SliceZoneProps> = ({
213
222
  setIsSlicesTemplatesModalOpen(false);
214
223
  };
215
224
 
225
+ const closeImportSlicesFromLibraryModal = () => {
226
+ setIsImportSlicesFromLibraryModalOpen(false);
227
+ };
228
+
216
229
  return (
217
230
  <>
218
231
  <ListHeader
@@ -272,6 +285,17 @@ const SliceZone: React.FC<SliceZoneProps> = ({
272
285
  {sliceCreationOptions.fromExisting.title}
273
286
  </DropdownMenuItem>
274
287
  ) : undefined}
288
+ <DropdownMenuItem
289
+ onSelect={openImportSlicesFromLibraryModal}
290
+ renderStartIcon={() =>
291
+ sliceCreationOptions.importFromExternal.BackgroundIcon
292
+ }
293
+ description={
294
+ sliceCreationOptions.importFromExternal.description
295
+ }
296
+ >
297
+ {sliceCreationOptions.importFromExternal.title}
298
+ </DropdownMenuItem>
275
299
  </DropdownMenuContent>
276
300
  </DropdownMenu>
277
301
  ) : undefined
@@ -324,6 +348,9 @@ const SliceZone: React.FC<SliceZoneProps> = ({
324
348
  openCreateSliceFromImageModal={() =>
325
349
  void openCreateSliceFromImageModal()
326
350
  }
351
+ openImportSlicesFromLibraryModal={() =>
352
+ void openImportSlicesFromLibraryModal()
353
+ }
327
354
  openSlicesTemplatesModal={openSlicesTemplatesModal}
328
355
  projectHasAvailableSlices={availableSlicesToAdd.length > 0}
329
356
  isSlicesTemplatesSupported={availableSlicesTemplates.length > 0}
@@ -444,6 +471,30 @@ const SliceZone: React.FC<SliceZoneProps> = ({
444
471
  }}
445
472
  onClose={closeCreateSliceFromImageModal}
446
473
  />
474
+ <ImportSlicesFromLibraryModal
475
+ open={isImportSlicesFromLibraryModalOpen}
476
+ location={`${customType.format}_type`}
477
+ onSuccess={({ slices, library }) => {
478
+ const newCustomType = addSlicesToSliceZone({
479
+ customType,
480
+ tabId,
481
+ slices: slices.map((slice) => slice.model),
482
+ });
483
+ setCustomType({
484
+ customType: CustomTypes.fromSM(newCustomType),
485
+ onSaveCallback: () => {
486
+ toast.success(
487
+ <ToastMessageWithPath
488
+ message="Slice(s) added to slice zone and created at: "
489
+ path={library}
490
+ />,
491
+ );
492
+ },
493
+ });
494
+ closeImportSlicesFromLibraryModal();
495
+ }}
496
+ onClose={closeImportSlicesFromLibraryModal}
497
+ />
447
498
  </>
448
499
  );
449
500
  };
@@ -15,6 +15,7 @@ import { BaseStyles, Flex, Link, Text } from "theme-ui";
15
15
 
16
16
  import { BreadcrumbItem } from "@/components/Breadcrumb";
17
17
  import { CreateSliceFromImageModal } from "@/features/customTypes/customTypesBuilder/CreateSliceFromImageModal";
18
+ import { ImportSlicesFromLibraryModal } from "@/features/customTypes/customTypesBuilder/ImportSlicesFromLibraryModal";
18
19
  import { getSliceCreationOptions } from "@/features/customTypes/customTypesBuilder/sliceCreationOptions";
19
20
  import { SharedSliceCard } from "@/features/slices/sliceCards/SharedSliceCard";
20
21
  import { SLICES_CONFIG } from "@/features/slices/slicesConfig";
@@ -64,6 +65,10 @@ const SlicesIndex: React.FunctionComponent = () => {
64
65
  const [isRenameSliceModalOpen, setIsRenameSliceModalOpen] = useState(false);
65
66
  const [isCreateSliceFromImageModalOpen, setIsCreateSliceFromImageModalOpen] =
66
67
  useState(false);
68
+ const [
69
+ isImportSlicesFromLibraryModalOpen,
70
+ setIsImportSlicesFromLibraryModalOpen,
71
+ ] = useState(false);
67
72
 
68
73
  const localLibraries: LibraryUI[] = libraries.filter(
69
74
  (library) => library.isLocal,
@@ -145,6 +150,17 @@ const SlicesIndex: React.FunctionComponent = () => {
145
150
  >
146
151
  {sliceCreationOptions.fromScratch.title}
147
152
  </DropdownMenuItem>
153
+ <DropdownMenuItem
154
+ renderStartIcon={() =>
155
+ sliceCreationOptions.importFromExternal.BackgroundIcon
156
+ }
157
+ onSelect={() => setIsImportSlicesFromLibraryModalOpen(true)}
158
+ description={
159
+ sliceCreationOptions.importFromExternal.description
160
+ }
161
+ >
162
+ {sliceCreationOptions.importFromExternal.title}
163
+ </DropdownMenuItem>
148
164
  </DropdownMenuContent>
149
165
  </DropdownMenu>
150
166
  ) : undefined}
@@ -340,6 +356,20 @@ const SlicesIndex: React.FunctionComponent = () => {
340
356
  }}
341
357
  onClose={closeCreateSliceFromImageModal}
342
358
  />
359
+ <ImportSlicesFromLibraryModal
360
+ open={isImportSlicesFromLibraryModalOpen}
361
+ location="slices"
362
+ onSuccess={({ library }: { library: string }) => {
363
+ toast.success(
364
+ <ToastMessageWithPath
365
+ message="Slice(s) added to slice zone and created at: "
366
+ path={library}
367
+ />,
368
+ );
369
+ setIsImportSlicesFromLibraryModalOpen(false);
370
+ }}
371
+ onClose={() => setIsImportSlicesFromLibraryModalOpen(false)}
372
+ />
343
373
  </AppLayoutContent>
344
374
  </AppLayout>
345
375
  </>