slice-machine-ui 1.23.2-beta.1 → 1.23.2-beta.10

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 (122) hide show
  1. package/.depcheckrc +3 -0
  2. package/components/DeleteSliceModal/index.tsx +34 -24
  3. package/components/DeleteVariationModal/index.tsx +1 -0
  4. package/components/Forms/CreateCustomTypeModal/CreateCustomTypeModal.tsx +61 -38
  5. package/components/Forms/RenameCustomTypeModal/RenameCustomTypeModal.tsx +2 -2
  6. package/components/Forms/RenameSliceModal/RenameSliceModal.tsx +33 -21
  7. package/components/Forms/RenameVariationModal/RenameVariationModal.tsx +0 -1
  8. package/components/ModalFormCard/index.tsx +0 -1
  9. package/components/Navigation/ChangesListItem.tsx +14 -32
  10. package/components/Navigation/index.tsx +29 -12
  11. package/components/ReviewModal/ReviewForm.tsx +0 -1
  12. package/lib/builders/common/EditModal/Form.jsx +0 -1
  13. package/lib/builders/common/Zone/Card/components/NewField.tsx +0 -1
  14. package/lib/models/common/widgets/StructuredText/index.ts +1 -1
  15. package/out/404.html +1 -1
  16. package/out/_next/static/Dz7wwTNVdXvoAjySXz7mE/_buildManifest.js +1 -0
  17. package/out/_next/static/chunks/18539003-5f78714a35fde4a1.js +97 -0
  18. package/out/_next/static/chunks/25-01f422cea8066349.js +1 -0
  19. package/out/_next/static/chunks/318-99b5914b60bf1d17.js +1 -0
  20. package/out/_next/static/chunks/727-f8fefdd3e50cab2a.js +1 -0
  21. package/out/_next/static/chunks/777-8c5507e3b119b5dc.js +8 -0
  22. package/out/_next/static/chunks/799-b616401fe0dafdeb.js +1 -0
  23. package/out/_next/static/chunks/904-4653b7a849f4db94.js +1 -0
  24. package/out/_next/static/chunks/pages/_app-5ec41fc53c1f6405.js +434 -0
  25. package/out/_next/static/chunks/pages/{changelog-afd18276fe018b24.js → changelog-02cd80dad6f40878.js} +1 -1
  26. package/out/_next/static/chunks/pages/changes-8e9da8fbb809aad3.js +1 -0
  27. package/out/_next/static/chunks/pages/custom-types/{[customTypeId]-3f862ad6111a1fc0.js → [customTypeId]-97ab3b90b85d645d.js} +1 -1
  28. package/out/_next/static/chunks/pages/{custom-types-94b8f8dbf7727412.js → custom-types-3c8e721ec6802127.js} +1 -1
  29. package/out/_next/static/chunks/pages/index-cf93d16e9c63b6db.js +1 -0
  30. package/out/_next/static/chunks/pages/{labs-ee206005948f8e87.js → labs-39b50541a4c370bf.js} +1 -1
  31. package/out/_next/static/chunks/pages/page-types/{[pageTypeId]-d1ffca11c42f2603.js → [pageTypeId]-84a22c5e480d3fa9.js} +1 -1
  32. package/out/_next/static/chunks/pages/settings-879686e3a8759dc3.js +1 -0
  33. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]/{simulator-897ca93c114a1435.js → simulator-c498e9c80cae8cce.js} +1 -1
  34. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-9b893c62b2f2fe4a.js +1 -0
  35. package/out/_next/static/chunks/pages/slices-4522d604117d8c66.js +1 -0
  36. package/out/_next/static/css/3c26dbbbd8f4be12.css +1 -0
  37. package/out/_next/static/css/{37153180c3b0dd66.css → 838fd8bb5a7c32b0.css} +1 -1
  38. package/out/_next/static/css/ca32882a5d2d8d88.css +1 -0
  39. package/out/changelog.html +1 -1
  40. package/out/changes.html +1 -1
  41. package/out/custom-types/[customTypeId].html +1 -1
  42. package/out/custom-types.html +1 -1
  43. package/out/index.html +1 -1
  44. package/out/labs.html +1 -1
  45. package/out/page-types/[pageTypeId].html +1 -1
  46. package/out/settings.html +1 -0
  47. package/out/slices/[lib]/[sliceName]/[variation]/simulator.html +1 -1
  48. package/out/slices/[lib]/[sliceName]/[variation].html +1 -1
  49. package/out/slices.html +1 -1
  50. package/package.json +9 -6
  51. package/pages/settings.tsx +1 -0
  52. package/pages/slices.tsx +20 -8
  53. package/postcss.config.js +10 -0
  54. package/src/apiClient.ts +1 -22
  55. package/src/components/FieldSet/FieldSet.stories.tsx +20 -11
  56. package/src/components/RelativeTime/RelativeTime.stories.tsx +25 -0
  57. package/src/components/RelativeTime/RelativeTime.tsx +40 -0
  58. package/src/components/RelativeTime/index.ts +1 -0
  59. package/src/domain/__tests__/customType.test.ts +205 -19
  60. package/src/domain/customType.ts +132 -7
  61. package/src/domain/slice.ts +38 -0
  62. package/src/features/customTypes/PageTypeOnboarding.tsx +21 -26
  63. package/src/features/customTypes/actions/convertCustomToPageType.ts +14 -10
  64. package/src/features/customTypes/actions/createCustomType.ts +69 -0
  65. package/src/features/customTypes/actions/deleteCustomType.ts +13 -3
  66. package/src/features/customTypes/actions/renameCustomType.ts +10 -4
  67. package/src/features/customTypes/customTypesBuilder/CustomTypesBuilderPage.tsx +3 -1
  68. package/src/features/customTypes/customTypesTable/CustomTypesTable.tsx +8 -8
  69. package/src/features/customTypes/customTypesTable/CustomTypesTablePage.tsx +18 -17
  70. package/src/features/environments/actions/setEnvironment.ts +2 -2
  71. package/src/features/settings/SettingsPage.tsx +47 -0
  72. package/src/features/settings/git/ConnectGitRepository.tsx +126 -0
  73. package/src/features/settings/git/ConnectGitRepositoryBlankSlate.tsx +33 -0
  74. package/src/features/settings/git/GitOwnerSelect.tsx +71 -0
  75. package/src/features/settings/git/GitProvider.ts +40 -0
  76. package/src/features/settings/git/GitProviderConnectButtons.tsx +63 -0
  77. package/src/features/settings/git/GitRepositoriesList.tsx +76 -0
  78. package/src/features/settings/git/GitRepositoriesSearch.tsx +69 -0
  79. package/src/features/settings/git/GitRepositoryConnectDialog.tsx +85 -0
  80. package/src/features/settings/git/GitRepositoryDisconnectDialog.tsx +60 -0
  81. package/src/features/settings/git/useGitIntegrationExperiment.ts +8 -0
  82. package/src/features/settings/git/useGitOwners.ts +12 -0
  83. package/src/features/settings/git/useGitRepos.ts +24 -0
  84. package/src/features/settings/git/useLinkedGitRepos.ts +41 -0
  85. package/src/features/settings/git/useWriteAPIToken.ts +23 -0
  86. package/src/features/slices/actions/createSlice.ts +5 -29
  87. package/src/features/slices/actions/deleteSlice.ts +33 -0
  88. package/src/features/slices/actions/renameSlice.ts +37 -0
  89. package/src/features/slices/convertLegacySlice/ConvertLegacySliceAsNewSliceDialog.tsx +0 -1
  90. package/src/features/slices/convertLegacySlice/ConvertLegacySliceAsNewVariationDialog.tsx +0 -1
  91. package/src/features/slices/convertLegacySlice/ConvertLegacySliceMergeWithIdenticalDialog.tsx +0 -1
  92. package/src/hooks/useUser.ts +14 -0
  93. package/src/icons/SettingsIcon.tsx +19 -0
  94. package/src/modules/availableCustomTypes/index.ts +29 -135
  95. package/src/modules/loading/types.ts +0 -5
  96. package/src/modules/modal/types.ts +0 -3
  97. package/src/modules/slices/index.ts +27 -193
  98. package/src/modules/slices/selector.ts +0 -14
  99. package/src/modules/useSliceMachineActions.ts +70 -89
  100. package/src/modules/userContext/index.ts +3 -3
  101. package/src/redux/saga.ts +0 -4
  102. package/test/src/modules/__fixtures__/serverState.ts +1 -2
  103. package/test/src/modules/availableCustomTypes/index.test.ts +2 -243
  104. package/test/src/modules/slices.test.ts +1 -267
  105. package/out/_next/static/chunks/18539003-5cc559566b738915.js +0 -97
  106. package/out/_next/static/chunks/25-37d6fa7f064be04b.js +0 -1
  107. package/out/_next/static/chunks/318-ce7e74f18f2d5b22.js +0 -1
  108. package/out/_next/static/chunks/376-7e784d6069e01654.js +0 -8
  109. package/out/_next/static/chunks/727-3a3bc32518778317.js +0 -1
  110. package/out/_next/static/chunks/731-501990ebe6a71b32.js +0 -1
  111. package/out/_next/static/chunks/904-9a4c1264727ae89a.js +0 -1
  112. package/out/_next/static/chunks/pages/_app-cd9d4c76a4abc11a.js +0 -432
  113. package/out/_next/static/chunks/pages/changes-2a976f9efeb719aa.js +0 -1
  114. package/out/_next/static/chunks/pages/index-64cfb8b0948ba8ef.js +0 -1
  115. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-b2a9d773ce5d7739.js +0 -1
  116. package/out/_next/static/chunks/pages/slices-e9c70c082ca3e3f9.js +0 -1
  117. package/out/_next/static/css/200244e3e0463c39.css +0 -1
  118. package/out/_next/static/m6psnC5u1xT7Y6osWHKjp/_buildManifest.js +0 -1
  119. package/src/features/customTypes/__tests__/createCustomType.test.ts +0 -159
  120. package/src/features/customTypes/customTypesTable/createCustomType.ts +0 -107
  121. package/test/components/CreateCustomTypeModal.test.tsx +0 -73
  122. /package/out/_next/static/{m6psnC5u1xT7Y6osWHKjp → Dz7wwTNVdXvoAjySXz7mE}/_ssgManifest.js +0 -0
@@ -0,0 +1,69 @@
1
+ import type { GitOwner } from "@slicemachine/manager";
2
+ import { type FC, Suspense, useState } from "react";
3
+
4
+ import { FieldSetContent, FieldSetHeader } from "@src/components/FieldSet";
5
+ import { ConnectGitRepositoryBlankSlate } from "@src/features/settings/git/ConnectGitRepositoryBlankSlate";
6
+ import { GitOwnerSelect } from "@src/features/settings/git/GitOwnerSelect";
7
+ import {
8
+ GitRepositoriesList,
9
+ GitRepositoriesListSkeleton,
10
+ } from "@src/features/settings/git/GitRepositoriesList";
11
+ import { useGitRepos } from "@src/features/settings/git/useGitRepos";
12
+
13
+ type GitRepositoriesSearchProps = { owners: GitOwner[] };
14
+
15
+ export const GitRepositoriesSearch: FC<GitRepositoriesSearchProps> = ({
16
+ owners,
17
+ }) => {
18
+ const [selectedOwner, setSelectedOwner] = useState(owners[0]);
19
+ return (
20
+ <>
21
+ <FieldSetHeader>
22
+ <GitOwnerSelect
23
+ owners={owners}
24
+ selectedOwner={selectedOwner}
25
+ onSelectedOwnerChange={setSelectedOwner}
26
+ sx={{ width: "calc(50% - 8px)" }}
27
+ />
28
+ </FieldSetHeader>
29
+ <Suspense
30
+ fallback={<GitRepositoriesSearchSkeleton gitOwnerSelect={false} />}
31
+ >
32
+ <GitRepositoriesSearchResults owner={selectedOwner} />
33
+ </Suspense>
34
+ </>
35
+ );
36
+ };
37
+
38
+ type GitRepositoriesSearchResultsProps = { owner: GitOwner };
39
+
40
+ const GitRepositoriesSearchResults: FC<GitRepositoriesSearchResultsProps> = ({
41
+ owner,
42
+ }) => {
43
+ const repos = useGitRepos({ provider: owner.provider, owner: owner.name });
44
+ return repos.length > 0 ? (
45
+ <GitRepositoriesList mode="link" repos={repos} />
46
+ ) : (
47
+ <FieldSetContent>
48
+ <ConnectGitRepositoryBlankSlate
49
+ title="No Results Found"
50
+ description="Try selecting a different Git account or organization on the top left."
51
+ />
52
+ </FieldSetContent>
53
+ );
54
+ };
55
+
56
+ type GitRepositoriesSearchSkeletonProps = { gitOwnerSelect: boolean };
57
+
58
+ export const GitRepositoriesSearchSkeleton: FC<
59
+ GitRepositoriesSearchSkeletonProps
60
+ > = ({ gitOwnerSelect }) => (
61
+ <>
62
+ {gitOwnerSelect ? (
63
+ <FieldSetHeader>
64
+ <GitOwnerSelect disabled sx={{ width: "calc(50% - 8px)" }} />
65
+ </FieldSetHeader>
66
+ ) : undefined}
67
+ <GitRepositoriesListSkeleton />
68
+ </>
69
+ );
@@ -0,0 +1,85 @@
1
+ import {
2
+ Box,
3
+ Dialog,
4
+ DialogActions,
5
+ DialogContent,
6
+ DialogHeader,
7
+ FormInput,
8
+ Text,
9
+ } from "@prismicio/editor-ui";
10
+ import type { GitRepo, GitRepoSpecifier } from "@slicemachine/manager";
11
+ import { Formik } from "formik";
12
+ import type { FC, ReactNode } from "react";
13
+ import { toast } from "react-toastify";
14
+
15
+ import { gitProviderToConfig } from "@src/features/settings/git/GitProvider";
16
+ import { useWriteAPIToken } from "@src/features/settings/git/useWriteAPIToken";
17
+
18
+ type GitRepositoryConnectDialogProps = {
19
+ linkRepo: (repo: GitRepoSpecifier) => Promise<void>;
20
+ repo: GitRepo;
21
+ trigger: ReactNode;
22
+ };
23
+
24
+ export const GitRepositoryConnectDialog: FC<
25
+ GitRepositoryConnectDialogProps
26
+ > = ({ linkRepo, repo, trigger }) => {
27
+ const providerConfig = gitProviderToConfig[repo.provider];
28
+ const { updateToken } = useWriteAPIToken({ git: repo });
29
+ return (
30
+ <Dialog size={{ width: 448, height: "auto" }} trigger={trigger}>
31
+ <DialogHeader title="Prismic Write API token required" />
32
+ <DialogContent>
33
+ <Formik
34
+ initialValues={{ writeAPIToken: "" }}
35
+ validate={(values) => {
36
+ if (values.writeAPIToken.length === 0) {
37
+ return { writeAPIToken: "Cannot be empty" };
38
+ }
39
+ }}
40
+ onSubmit={async (values) => {
41
+ try {
42
+ await linkRepo(repo);
43
+ await updateToken(values.writeAPIToken);
44
+ } catch (error) {
45
+ const message = `Could not connect to ${repo.name}`;
46
+ console.error(message, error);
47
+ toast.error(message);
48
+ }
49
+ }}
50
+ >
51
+ {(formikProps) => (
52
+ <form onSubmit={formikProps.handleSubmit}>
53
+ <Box flexDirection="column" gap={4} padding={16}>
54
+ <FormInput
55
+ disabled={formikProps.isSubmitting}
56
+ error={typeof formikProps.errors.writeAPIToken === "string"}
57
+ label="Paste your Write API token"
58
+ onValueChange={(value) => {
59
+ void formikProps.setFieldValue("writeAPIToken", value);
60
+ }}
61
+ placeholder="Write API token"
62
+ size="large"
63
+ value={formikProps.values.writeAPIToken}
64
+ />
65
+ <Text color="grey11">
66
+ Required to sync models from {providerConfig.name} to Prismic.
67
+ </Text>
68
+ </Box>
69
+ <DialogActions
70
+ cancel={{ text: "Cancel" }}
71
+ ok={{
72
+ disabled: !formikProps.isValid,
73
+ loading: formikProps.isSubmitting,
74
+ onClick: () => void formikProps.submitForm(),
75
+ text: "Save Token",
76
+ }}
77
+ size="medium"
78
+ />
79
+ </form>
80
+ )}
81
+ </Formik>
82
+ </DialogContent>
83
+ </Dialog>
84
+ );
85
+ };
@@ -0,0 +1,60 @@
1
+ import {
2
+ Box,
3
+ Dialog,
4
+ DialogActions,
5
+ DialogContent,
6
+ DialogHeader,
7
+ Text,
8
+ } from "@prismicio/editor-ui";
9
+ import type { GitRepoSpecifier } from "@slicemachine/manager";
10
+ import { type FC, type ReactNode, useState } from "react";
11
+ import { toast } from "react-toastify";
12
+
13
+ type GitRepositoryDisconnectDialogProps = {
14
+ repo: GitRepoSpecifier;
15
+ trigger: ReactNode;
16
+ unlinkRepo: (repo: GitRepoSpecifier) => Promise<void>;
17
+ };
18
+
19
+ export const GitRepositoryDisconnectDialog: FC<
20
+ GitRepositoryDisconnectDialogProps
21
+ > = ({ repo, trigger, unlinkRepo }) => {
22
+ const [loading, setLoading] = useState(false);
23
+ return (
24
+ <Dialog size={{ width: 448, height: "auto" }} trigger={trigger}>
25
+ <DialogHeader title="Remove Git Connection" />
26
+ <DialogContent>
27
+ <Box flexDirection="column" padding={16}>
28
+ <Text>
29
+ You will not be able to push your code alongside your models
30
+ anymore. Note that you can reconnect your Git repository at any
31
+ time. Are you sure you want to continue?
32
+ </Text>
33
+ </Box>
34
+ </DialogContent>
35
+ <DialogActions
36
+ asFooter
37
+ cancel={{ text: "Cancel" }}
38
+ ok={{
39
+ color: "tomato",
40
+ loading,
41
+ onClick: () => {
42
+ void (async () => {
43
+ setLoading(true);
44
+ try {
45
+ await unlinkRepo(repo);
46
+ } catch (error) {
47
+ const message = `Could not disconnect from ${repo.name}`;
48
+ console.error(message, error);
49
+ toast.error(message);
50
+ }
51
+ setLoading(false);
52
+ })();
53
+ },
54
+ text: "Disconnect",
55
+ }}
56
+ size="medium"
57
+ />
58
+ </Dialog>
59
+ );
60
+ };
@@ -0,0 +1,8 @@
1
+ import { useExperimentVariant } from "@src/hooks/useExperimentVariant";
2
+
3
+ type UseGitIntegrationExperimentReturnType = { eligible: boolean };
4
+
5
+ export function useGitIntegrationExperiment(): UseGitIntegrationExperimentReturnType {
6
+ const variant = useExperimentVariant("slicemachine-git-integration");
7
+ return { eligible: variant?.value === "on" };
8
+ }
@@ -0,0 +1,12 @@
1
+ import { useRequest } from "@prismicio/editor-support/Suspense";
2
+ import type { GitOwner } from "@slicemachine/manager";
3
+
4
+ import { managerClient } from "@src/managerClient";
5
+
6
+ export function useGitOwners(): GitOwner[] {
7
+ return useRequest(getGitOwners, []);
8
+ }
9
+
10
+ async function getGitOwners(): Promise<GitOwner[]> {
11
+ return await managerClient.git.fetchOwners();
12
+ }
@@ -0,0 +1,24 @@
1
+ import { useRequest } from "@prismicio/editor-support/Suspense";
2
+ import type { GitRepo } from "@slicemachine/manager";
3
+
4
+ import { managerClient } from "@src/managerClient";
5
+
6
+ type UseGitReposArgs = Parameters<typeof managerClient.git.fetchRepos>[0];
7
+
8
+ export function useGitRepos(args: UseGitReposArgs): GitRepo[] {
9
+ return useRequest(getGitRepos, [
10
+ args.provider,
11
+ args.owner,
12
+ args.query,
13
+ args.page,
14
+ ]);
15
+ }
16
+
17
+ async function getGitRepos(
18
+ provider: "gitHub",
19
+ owner: string,
20
+ query?: string,
21
+ page?: number,
22
+ ): Promise<GitRepo[]> {
23
+ return await managerClient.git.fetchRepos({ provider, owner, query, page });
24
+ }
@@ -0,0 +1,41 @@
1
+ import { revalidateData, useRequest } from "@prismicio/editor-support/Suspense";
2
+ import type { GitRepoSpecifier } from "@slicemachine/manager";
3
+
4
+ import { useSliceMachineConfig } from "@src/hooks/useSliceMachineConfig";
5
+ import { managerClient } from "@src/managerClient";
6
+
7
+ type UseLinkedGitReposReturnType = {
8
+ linkedGitRepos: GitRepoSpecifier[];
9
+ linkRepo: (git: GitRepoSpecifier) => Promise<void>;
10
+ unlinkRepo: (git: GitRepoSpecifier) => Promise<void>;
11
+ };
12
+
13
+ export function useLinkedGitRepos(): UseLinkedGitReposReturnType {
14
+ const [config] = useSliceMachineConfig();
15
+ const linkedGitRepos = useRequest(getLinkedGitRepos, [config.repositoryName]);
16
+ return {
17
+ linkedGitRepos,
18
+ linkRepo: async (git) => {
19
+ await managerClient.git.linkRepo({
20
+ prismic: { domain: config.repositoryName },
21
+ git,
22
+ });
23
+ await revalidateData(getLinkedGitRepos, [config.repositoryName]);
24
+ },
25
+ unlinkRepo: async (git) => {
26
+ await managerClient.git.unlinkRepo({
27
+ prismic: { domain: config.repositoryName },
28
+ git,
29
+ });
30
+ await revalidateData(getLinkedGitRepos, [config.repositoryName]);
31
+ },
32
+ };
33
+ }
34
+
35
+ async function getLinkedGitRepos(
36
+ prismicDomain: string,
37
+ ): Promise<GitRepoSpecifier[]> {
38
+ return await managerClient.git.fetchLinkedRepos({
39
+ prismic: { domain: prismicDomain },
40
+ });
41
+ }
@@ -0,0 +1,23 @@
1
+ import type { GitRepoSpecifier } from "@slicemachine/manager";
2
+
3
+ import { useSliceMachineConfig } from "@src/hooks/useSliceMachineConfig";
4
+ import { managerClient } from "@src/managerClient";
5
+
6
+ type UseWriteAPITokenReturnType = {
7
+ updateToken: (token: string) => Promise<void>;
8
+ };
9
+
10
+ export function useWriteAPIToken(args: {
11
+ git: GitRepoSpecifier;
12
+ }): UseWriteAPITokenReturnType {
13
+ const [config] = useSliceMachineConfig();
14
+ return {
15
+ updateToken: async (token) => {
16
+ await managerClient.git.updateWriteAPIToken({
17
+ prismic: { domain: config.repositoryName },
18
+ git: args.git,
19
+ token,
20
+ });
21
+ },
22
+ };
23
+ }
@@ -1,9 +1,10 @@
1
1
  import { toast } from "react-toastify";
2
2
  import { SharedSlice } from "@prismicio/types-internal/lib/customtypes";
3
3
 
4
- import { pascalize, snakelize } from "@lib/utils/str";
4
+ import { pascalize } from "@lib/utils/str";
5
5
  import { managerClient } from "@src/managerClient";
6
6
  import { telemetry } from "@src/apiClient";
7
+ import { buildEmptySliceModel } from "@src/domain/slice";
7
8
 
8
9
  type CreateSliceArgs = {
9
10
  sliceName: string;
@@ -12,8 +13,9 @@ type CreateSliceArgs = {
12
13
  };
13
14
 
14
15
  export async function createSlice(args: CreateSliceArgs) {
16
+ const { sliceName, libraryName, onSuccess } = args;
17
+
15
18
  try {
16
- const { sliceName, libraryName, onSuccess } = args;
17
19
  const newSlice = buildEmptySliceModel(sliceName);
18
20
  const { errors } = await managerClient.slices.createSlice({
19
21
  libraryID: libraryName,
@@ -33,34 +35,8 @@ export async function createSlice(args: CreateSliceArgs) {
33
35
 
34
36
  await onSuccess(newSlice);
35
37
  } catch (e) {
36
- const errorMessage = "Internal Error: Slice not created";
38
+ const errorMessage = `An unexpected error happened while creating slice ${sliceName}.`;
37
39
  console.error(errorMessage, e);
38
40
  toast.error(errorMessage);
39
41
  }
40
42
  }
41
-
42
- const DEFAULT_VARIATION_ID = "default";
43
-
44
- function buildEmptySliceModel(sliceName: string): SharedSlice {
45
- return {
46
- id: snakelize(sliceName),
47
- type: "SharedSlice",
48
- name: sliceName,
49
- description: sliceName,
50
- variations: [
51
- {
52
- id: DEFAULT_VARIATION_ID,
53
- name: pascalize(DEFAULT_VARIATION_ID),
54
- // Property not used yet. Fallback to "...".
55
- docURL: "...",
56
- // "initial" is fine here as default value.
57
- version: "initial",
58
- description: pascalize(DEFAULT_VARIATION_ID),
59
- // Empty string is fine, we don't want to save imageUrl.
60
- // We don't want to compare local and remote image with imageUrl.
61
- // It will be striped anyway when doing the comparison.
62
- imageUrl: "",
63
- },
64
- ],
65
- };
66
- }
@@ -0,0 +1,33 @@
1
+ import { toast } from "react-toastify";
2
+
3
+ import { managerClient } from "@src/managerClient";
4
+
5
+ type DeleteSliceArgs = {
6
+ libraryID: string;
7
+ sliceID: string;
8
+ sliceName: string;
9
+ onSuccess: () => void;
10
+ };
11
+
12
+ export async function deleteSlice(args: DeleteSliceArgs) {
13
+ const { sliceName, sliceID, libraryID, onSuccess } = args;
14
+
15
+ try {
16
+ const { errors } = await managerClient.slices.deleteSlice({
17
+ libraryID,
18
+ sliceID,
19
+ });
20
+
21
+ if (errors.length > 0) {
22
+ throw errors;
23
+ }
24
+
25
+ onSuccess();
26
+
27
+ toast.success(`Successfully deleted slice “${sliceName}”`);
28
+ } catch (e) {
29
+ const errorMessage = `An unexpected error happened while deleting slice “${sliceName}”.`;
30
+ console.error(errorMessage, e);
31
+ toast.error(errorMessage);
32
+ }
33
+ }
@@ -0,0 +1,37 @@
1
+ import { toast } from "react-toastify";
2
+
3
+ import { managerClient } from "@src/managerClient";
4
+ import { ComponentUI } from "@lib/models/common/ComponentUI";
5
+ import { rename } from "@src/domain/slice";
6
+ import { Slices } from "@lib/models/common/Slice";
7
+
8
+ type DeleteSliceArgs = {
9
+ newSliceName: string;
10
+ slice: ComponentUI;
11
+ onSuccess: (renamedSlice: ComponentUI) => void;
12
+ };
13
+
14
+ export async function renameSlice(args: DeleteSliceArgs) {
15
+ const { slice, newSliceName, onSuccess } = args;
16
+
17
+ try {
18
+ const renamedSlice = rename(slice, newSliceName);
19
+
20
+ const { errors } = await managerClient.slices.renameSlice({
21
+ libraryID: slice.from,
22
+ model: Slices.fromSM(renamedSlice.model),
23
+ });
24
+
25
+ if (errors.length > 0) {
26
+ throw errors;
27
+ }
28
+
29
+ onSuccess(renamedSlice);
30
+
31
+ toast.success("Slice name updated");
32
+ } catch (e) {
33
+ const errorMessage = `An unexpected error happened while renaming “${slice.model.name}”.`;
34
+ console.error(errorMessage, e);
35
+ toast.error(errorMessage);
36
+ }
37
+ }
@@ -43,7 +43,6 @@ export const ConvertLegacySliceAsNewSliceDialog: FC<DialogProps> = ({
43
43
  <DialogHeader title="Upgrade slice" />
44
44
  <DialogContent>
45
45
  <Formik
46
- validateOnChange
47
46
  validateOnMount
48
47
  initialValues={{
49
48
  from: libraries[0]?.name,
@@ -47,7 +47,6 @@ export const ConvertLegacySliceAsNewVariationDialog: FC<DialogProps> = ({
47
47
  <DialogHeader title="Convert to slice variation" />
48
48
  <DialogContent>
49
49
  <Formik
50
- validateOnChange
51
50
  initialValues={{
52
51
  libraryID: localSharedSlices[0]?.from,
53
52
  sliceID: localSharedSlices[0]?.model.id,
@@ -31,7 +31,6 @@ export const ConvertLegacySliceMergeWithIdenticalDialog: FC<DialogProps> = ({
31
31
  <DialogHeader title="Merge with an existing slice" />
32
32
  <DialogContent>
33
33
  <Formik
34
- validateOnChange
35
34
  initialValues={{
36
35
  path: identicalSlices[0]?.path ?? "",
37
36
  }}
@@ -0,0 +1,14 @@
1
+ import { useRequest } from "@prismicio/editor-support/Suspense";
2
+
3
+ import { managerClient } from "@src/managerClient";
4
+
5
+ type User = { isLoggedIn: boolean };
6
+
7
+ export function useUser(): User {
8
+ return useRequest(getUser, []);
9
+ }
10
+
11
+ async function getUser(): Promise<User> {
12
+ const isLoggedIn = await managerClient.user.checkIsLoggedIn();
13
+ return { isLoggedIn };
14
+ }
@@ -0,0 +1,19 @@
1
+ import type { FC, SVGProps } from "react";
2
+
3
+ export const SettingsIcon: FC<SVGProps<SVGSVGElement>> = (props) => (
4
+ <svg
5
+ width="32"
6
+ height="32"
7
+ viewBox="0 0 32 32"
8
+ fill="none"
9
+ xmlns="http://www.w3.org/2000/svg"
10
+ {...props}
11
+ >
12
+ <path
13
+ fillRule="evenodd"
14
+ clipRule="evenodd"
15
+ d="M16 12C16 13.1046 15.1046 14 14 14C12.8954 14 12 13.1046 12 12C12 10.8954 12.8954 10 14 10C15.1046 10 16 10.8954 16 12ZM14 9C15.4865 9 16.7205 10.0811 16.9585 11.5H23.5C23.7761 11.5 24 11.7239 24 12C24 12.2761 23.7761 12.5 23.5 12.5H16.9585C16.7205 13.9189 15.4865 15 14 15C12.5135 15 11.2795 13.9189 11.0415 12.5H8.5C8.22386 12.5 8 12.2761 8 12C8 11.7239 8.22386 11.5 8.5 11.5H11.0415C11.2795 10.0811 12.5135 9 14 9ZM21 20C21 21.1046 20.1046 22 19 22C17.8954 22 17 21.1046 17 20C17 18.8954 17.8954 18 19 18C20.1046 18 21 18.8954 21 20ZM16.0415 20.5C16.2795 21.9189 17.5135 23 19 23C20.4865 23 21.7205 21.9189 21.9585 20.5H23.5C23.7761 20.5 24 20.2761 24 20C24 19.7239 23.7761 19.5 23.5 19.5H21.9585C21.7205 18.0811 20.4865 17 19 17C17.5135 17 16.2795 18.0811 16.0415 19.5H8.5C8.22386 19.5 8 19.7239 8 20C8 20.2761 8.22386 20.5 8.5 20.5H16.0415Z"
16
+ fill="currentColor"
17
+ />
18
+ </svg>
19
+ );