slice-machine-ui 1.23.2-alpha.bmo-fix-tsc-error.1 → 1.23.2-alpha.bmo-add-github-settings-page.2

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 (76) hide show
  1. package/.depcheckrc +3 -0
  2. package/components/DeleteVariationModal/index.tsx +1 -0
  3. package/components/Forms/RenameVariationModal/RenameVariationModal.tsx +0 -1
  4. package/components/ModalFormCard/index.tsx +0 -1
  5. package/components/Navigation/index.tsx +25 -12
  6. package/components/ReviewModal/ReviewForm.tsx +0 -1
  7. package/lib/builders/common/EditModal/Form.jsx +0 -1
  8. package/lib/builders/common/Zone/Card/components/NewField.tsx +0 -1
  9. package/out/404.html +1 -1
  10. package/out/_next/static/chunks/18539003-5f78714a35fde4a1.js +97 -0
  11. package/out/_next/static/chunks/318-bd030cc1725e23b5.js +1 -0
  12. package/out/_next/static/chunks/{727-3a3bc32518778317.js → 727-2235967a881f9035.js} +1 -1
  13. package/out/_next/static/chunks/731-a9b66ccdc3fae2c2.js +1 -0
  14. package/out/_next/static/chunks/777-8c5507e3b119b5dc.js +8 -0
  15. package/out/_next/static/chunks/904-6d6937d53ea2761e.js +1 -0
  16. package/out/_next/static/chunks/pages/_app-b6719b931ebc00c6.js +434 -0
  17. package/out/_next/static/chunks/pages/{changelog-afd18276fe018b24.js → changelog-02cd80dad6f40878.js} +1 -1
  18. package/out/_next/static/chunks/pages/{changes-2a976f9efeb719aa.js → changes-8de69920dfb5a48f.js} +1 -1
  19. package/out/_next/static/chunks/pages/{labs-ee206005948f8e87.js → labs-39b50541a4c370bf.js} +1 -1
  20. package/out/_next/static/chunks/pages/settings-386e0971d78f7d57.js +1 -0
  21. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]/{simulator-897ca93c114a1435.js → simulator-b12346e58ac9abea.js} +1 -1
  22. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-62b55bae7f1b3793.js +1 -0
  23. package/out/_next/static/chunks/pages/slices-81e382c3374273df.js +1 -0
  24. package/out/_next/static/css/3c26dbbbd8f4be12.css +1 -0
  25. package/out/_next/static/css/{37153180c3b0dd66.css → 838fd8bb5a7c32b0.css} +1 -1
  26. package/out/_next/static/css/ca32882a5d2d8d88.css +1 -0
  27. package/out/_next/static/u0edTA9rplsCk652gdVmA/_buildManifest.js +1 -0
  28. package/out/changelog.html +1 -1
  29. package/out/changes.html +1 -1
  30. package/out/custom-types/[customTypeId].html +1 -1
  31. package/out/custom-types.html +1 -1
  32. package/out/index.html +1 -1
  33. package/out/labs.html +1 -1
  34. package/out/page-types/[pageTypeId].html +1 -1
  35. package/out/settings.html +1 -0
  36. package/out/slices/[lib]/[sliceName]/[variation]/simulator.html +1 -1
  37. package/out/slices/[lib]/[sliceName]/[variation].html +1 -1
  38. package/out/slices.html +1 -1
  39. package/package.json +9 -6
  40. package/pages/settings.tsx +1 -0
  41. package/postcss.config.js +10 -0
  42. package/src/components/FieldSet/FieldSet.stories.tsx +20 -11
  43. package/src/components/RelativeTime/RelativeTime.stories.tsx +25 -0
  44. package/src/components/RelativeTime/RelativeTime.tsx +40 -0
  45. package/src/components/RelativeTime/index.ts +1 -0
  46. package/src/features/environments/actions/setEnvironment.ts +2 -2
  47. package/src/features/settings/SettingsPage.tsx +29 -0
  48. package/src/features/settings/git/ConnectGitRepository.tsx +97 -0
  49. package/src/features/settings/git/ConnectGitRepositoryBlankSlate.tsx +33 -0
  50. package/src/features/settings/git/GitOwnerSelect.tsx +71 -0
  51. package/src/features/settings/git/GitProvider.ts +40 -0
  52. package/src/features/settings/git/GitProviderConnectButtons.tsx +63 -0
  53. package/src/features/settings/git/GitRepositoriesList.tsx +76 -0
  54. package/src/features/settings/git/GitRepositoriesSearch.tsx +69 -0
  55. package/src/features/settings/git/GitRepositoryConnectDialog.tsx +86 -0
  56. package/src/features/settings/git/GitRepositoryDisconnectDialog.tsx +64 -0
  57. package/src/features/settings/git/useGitOwners.ts +12 -0
  58. package/src/features/settings/git/useGitRepos.ts +24 -0
  59. package/src/features/settings/git/useLinkedGitRepos.ts +41 -0
  60. package/src/features/settings/git/useWriteAPIToken.ts +30 -0
  61. package/src/features/slices/convertLegacySlice/ConvertLegacySliceAsNewSliceDialog.tsx +0 -1
  62. package/src/features/slices/convertLegacySlice/ConvertLegacySliceAsNewVariationDialog.tsx +0 -1
  63. package/src/features/slices/convertLegacySlice/ConvertLegacySliceMergeWithIdenticalDialog.tsx +0 -1
  64. package/src/hooks/useUser.ts +14 -0
  65. package/src/icons/SettingsIcon.tsx +19 -0
  66. package/out/_next/static/chunks/18539003-5cc559566b738915.js +0 -97
  67. package/out/_next/static/chunks/318-ce7e74f18f2d5b22.js +0 -1
  68. package/out/_next/static/chunks/376-7e784d6069e01654.js +0 -8
  69. package/out/_next/static/chunks/731-501990ebe6a71b32.js +0 -1
  70. package/out/_next/static/chunks/904-9a4c1264727ae89a.js +0 -1
  71. package/out/_next/static/chunks/pages/_app-e20a274bd5f065bd.js +0 -432
  72. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-b2a9d773ce5d7739.js +0 -1
  73. package/out/_next/static/chunks/pages/slices-e9c70c082ca3e3f9.js +0 -1
  74. package/out/_next/static/css/200244e3e0463c39.css +0 -1
  75. package/out/_next/static/oUce2teKPsKU-VjaTxYsp/_buildManifest.js +0 -1
  76. /package/out/_next/static/{oUce2teKPsKU-VjaTxYsp → u0edTA9rplsCk652gdVmA}/_ssgManifest.js +0 -0
@@ -0,0 +1,71 @@
1
+ import { Select, SelectItem, tokens } from "@prismicio/editor-ui";
2
+ import type { GitOwner } from "@slicemachine/manager";
3
+ import type { ComponentProps, FC } from "react";
4
+
5
+ import { gitProviderToConfig } from "@src/features/settings/git/GitProvider";
6
+
7
+ type GitOwnerSelectProps = {
8
+ disabled?: boolean;
9
+ owners?: GitOwner[];
10
+ selectedOwner?: GitOwner;
11
+ onSelectedOwnerChange?: (selectedOwner: GitOwner) => void;
12
+ sx?: SX;
13
+ };
14
+
15
+ export const GitOwnerSelect: FC<GitOwnerSelectProps> = ({
16
+ disabled,
17
+ owners = [],
18
+ selectedOwner,
19
+ onSelectedOwnerChange,
20
+ sx,
21
+ }) => (
22
+ <Select
23
+ color="grey"
24
+ constrainContentWidth
25
+ disabled={disabled}
26
+ flexContent
27
+ onValueChange={(value) => {
28
+ const [provider, id] = parseGitOwnerKey(value);
29
+ const selectedOwner = owners.find(
30
+ (owner) => owner.provider === provider && owner.id === id,
31
+ );
32
+ if (selectedOwner) {
33
+ onSelectedOwnerChange?.(selectedOwner);
34
+ }
35
+ }}
36
+ placeholder="Owner"
37
+ renderStartIcon={() => <GitOwnerIcon owner={selectedOwner} />}
38
+ size="large"
39
+ sx={sx}
40
+ value={selectedOwner ? formatGitOwnerKey(selectedOwner) : undefined}
41
+ >
42
+ {owners.map((owner) => (
43
+ <SelectItem
44
+ key={formatGitOwnerKey(owner)}
45
+ renderStartIcon={() => <GitOwnerIcon owner={owner} />}
46
+ size="large"
47
+ value={formatGitOwnerKey(owner)}
48
+ >
49
+ {owner.name}
50
+ </SelectItem>
51
+ ))}
52
+ </Select>
53
+ );
54
+
55
+ type GitOwnerIconProps = { owner: GitOwner | undefined };
56
+
57
+ const GitOwnerIcon: FC<GitOwnerIconProps> = ({ owner }) => {
58
+ const { Icon } = gitProviderToConfig[owner?.provider ?? "gitHub"];
59
+ return <Icon color={tokens.color.greyLight11} />;
60
+ };
61
+
62
+ function formatGitOwnerKey(owner: GitOwner): string {
63
+ return `${owner.provider}@${owner.id}`;
64
+ }
65
+
66
+ function parseGitOwnerKey(key: string): string[] {
67
+ return key.split("@");
68
+ }
69
+
70
+ // TODO(DT-1928): export the `SX` type from `@prismicio/editor-ui`.
71
+ type SX = ComponentProps<typeof Select>["sx"];
@@ -0,0 +1,40 @@
1
+ import { BitbucketIcon } from "@src/icons/BitbucketIcon";
2
+ import { GitHubIcon } from "@src/icons/GitHubIcon";
3
+ import { GitLabIcon } from "@src/icons/GitLabIcon";
4
+ import { managerClient } from "@src/managerClient";
5
+
6
+ export type GitProvider = keyof typeof gitProviderToConfig;
7
+
8
+ const GITHUB_APP_SLUG = "prismic-prod-internal-test";
9
+
10
+ export const gitProviderToConfig = {
11
+ gitHub: {
12
+ connect: async () => {
13
+ const state = await managerClient.git.createGitHubAuthState();
14
+ const url = new URL(
15
+ `https://github.com/apps/${GITHUB_APP_SLUG}/installations/new`,
16
+ );
17
+ url.searchParams.set("state", state.key);
18
+ window.open(url, "git-hub-app-installation");
19
+ },
20
+ Icon: GitHubIcon,
21
+ name: "GitHub",
22
+ supported: true,
23
+ },
24
+ bitbucket: {
25
+ connect: () => {
26
+ throw new Error("Not implemented.");
27
+ },
28
+ Icon: BitbucketIcon,
29
+ name: "Bitbucket",
30
+ supported: false,
31
+ },
32
+ gitLab: {
33
+ connect: () => {
34
+ throw new Error("Not implemented.");
35
+ },
36
+ Icon: GitLabIcon,
37
+ name: "GitLab",
38
+ supported: false,
39
+ },
40
+ };
@@ -0,0 +1,63 @@
1
+ import { keys } from "@prismicio/editor-support/Object";
2
+ import { Button, ButtonGroup, Text, tokens } from "@prismicio/editor-ui";
3
+ import { type ComponentProps, type FC, useState } from "react";
4
+ import { toast } from "react-toastify";
5
+
6
+ import {
7
+ type GitProvider,
8
+ gitProviderToConfig,
9
+ } from "@src/features/settings/git/GitProvider";
10
+
11
+ export const GitProviderConnectButtons: FC = () => (
12
+ <ButtonGroup>
13
+ {keys(gitProviderToConfig).map((provider) => (
14
+ <GitProviderConnectButton
15
+ key={provider}
16
+ provider={provider}
17
+ sx={{ flexBasis: 0, flexGrow: 1 }}
18
+ />
19
+ ))}
20
+ </ButtonGroup>
21
+ );
22
+
23
+ type GitProviderConnectButtonProps = { provider: GitProvider; sx?: SX };
24
+
25
+ const GitProviderConnectButton: FC<GitProviderConnectButtonProps> = ({
26
+ provider,
27
+ sx,
28
+ }) => {
29
+ const { connect, Icon, name, supported } = gitProviderToConfig[provider];
30
+ const [loading, setLoading] = useState(false);
31
+ return (
32
+ <Button
33
+ color="grey"
34
+ disabled={!supported}
35
+ loading={loading}
36
+ onClick={() => {
37
+ void (async () => {
38
+ setLoading(true);
39
+ try {
40
+ await connect();
41
+ } catch (error) {
42
+ const message = `Could not connect to ${name}`;
43
+ console.error(message, error);
44
+ toast.error(message);
45
+ setLoading(false);
46
+ }
47
+ })();
48
+ }}
49
+ renderStartIcon={() => <Icon color={tokens.color.greyLight11} />}
50
+ sx={sx}
51
+ >
52
+ {name}
53
+ {supported ? undefined : (
54
+ <Text color="inherit" variant="small">
55
+ {" soon"}
56
+ </Text>
57
+ )}
58
+ </Button>
59
+ );
60
+ };
61
+
62
+ // TODO(DT-1928): export the `SX` type from `@prismicio/editor-ui`.
63
+ type SX = ComponentProps<typeof Button>["sx"];
@@ -0,0 +1,76 @@
1
+ import { Button, Skeleton, Text } from "@prismicio/editor-ui";
2
+ import type { GitRepo, GitRepoSpecifier } from "@slicemachine/manager";
3
+ import type { FC } from "react";
4
+
5
+ import { FieldSetList, FieldSetListItem } from "@src/components/FieldSet";
6
+ import { RelativeTime } from "@src/components/RelativeTime";
7
+ import { GitRepositoryConnectDialog } from "@src/features/settings/git/GitRepositoryConnectDialog";
8
+ import { GitRepositoryDisconnectDialog } from "@src/features/settings/git/GitRepositoryDisconnectDialog";
9
+ import { useLinkedGitRepos } from "@src/features/settings/git/useLinkedGitRepos";
10
+
11
+ type GitRepositoriesListProps =
12
+ | { mode: "link"; repos: GitRepo[] }
13
+ | { mode: "unlink"; repos: GitRepoSpecifier[] };
14
+
15
+ export const GitRepositoriesList: FC<GitRepositoriesListProps> = ({
16
+ mode,
17
+ repos,
18
+ }) => {
19
+ const { linkRepo, unlinkRepo } = useLinkedGitRepos();
20
+ return (
21
+ <FieldSetList>
22
+ {mode === "link"
23
+ ? repos.map((repo) => (
24
+ <FieldSetListItem
25
+ action={
26
+ <GitRepositoryConnectDialog
27
+ linkRepo={linkRepo}
28
+ repo={repo}
29
+ trigger={<Button color="grey">Connect</Button>}
30
+ />
31
+ }
32
+ key={`${repo.provider}@${repo.id}`}
33
+ >
34
+ {repo.name}
35
+ <Text color="grey11">
36
+ {" • "}
37
+ <RelativeTime date={repo.pushedAt} />
38
+ </Text>
39
+ </FieldSetListItem>
40
+ ))
41
+ : repos.map((repo) => (
42
+ <FieldSetListItem
43
+ action={
44
+ <GitRepositoryDisconnectDialog
45
+ repo={repo}
46
+ trigger={<Button color="grey">Disconnect</Button>}
47
+ unlinkRepo={unlinkRepo}
48
+ />
49
+ }
50
+ key={`${repo.provider}@${repo.owner}/${repo.name}`}
51
+ >
52
+ {repo.name}
53
+ </FieldSetListItem>
54
+ ))}
55
+ </FieldSetList>
56
+ );
57
+ };
58
+
59
+ export const GitRepositoriesListSkeleton: FC = () => (
60
+ <FieldSetList>
61
+ {[...Array(4).keys()].map((index) => (
62
+ <FieldSetListItem
63
+ action={<Skeleton height={32} width={67.59} />}
64
+ key={index}
65
+ >
66
+ <Skeleton
67
+ height={24}
68
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
69
+ // @ts-ignore TODO(DT-1918): add `verticalAlign: "middle"` to the `sx` prop.
70
+ sx={{ verticalAlign: "middle" }}
71
+ width={129.92}
72
+ />
73
+ </FieldSetListItem>
74
+ ))}
75
+ </FieldSetList>
76
+ );
@@ -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,86 @@
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 updateToken(values.writeAPIToken);
43
+ await linkRepo(repo);
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 update your Prismic repository with{" "}
67
+ {providerConfig.name}.
68
+ </Text>
69
+ </Box>
70
+ <DialogActions
71
+ cancel={{ text: "Cancel" }}
72
+ ok={{
73
+ disabled: !formikProps.isValid,
74
+ loading: formikProps.isSubmitting,
75
+ onClick: () => void formikProps.submitForm(),
76
+ text: "Save Token",
77
+ }}
78
+ size="medium"
79
+ />
80
+ </form>
81
+ )}
82
+ </Formik>
83
+ </DialogContent>
84
+ </Dialog>
85
+ );
86
+ };
@@ -0,0 +1,64 @@
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
+ import { useWriteAPIToken } from "@src/features/settings/git/useWriteAPIToken";
14
+
15
+ type GitRepositoryDisconnectDialogProps = {
16
+ repo: GitRepoSpecifier;
17
+ trigger: ReactNode;
18
+ unlinkRepo: (repo: GitRepoSpecifier) => Promise<void>;
19
+ };
20
+
21
+ export const GitRepositoryDisconnectDialog: FC<
22
+ GitRepositoryDisconnectDialogProps
23
+ > = ({ repo, trigger, unlinkRepo }) => {
24
+ const { deleteToken } = useWriteAPIToken({ git: repo });
25
+ const [loading, setLoading] = useState(false);
26
+ return (
27
+ <Dialog size={{ width: 448, height: "auto" }} trigger={trigger}>
28
+ <DialogHeader title="Remove Git Connection" />
29
+ <DialogContent>
30
+ <Box flexDirection="column" padding={16}>
31
+ <Text>
32
+ You will not be able to push your code alongside your models
33
+ anymore. Note that you can reconnect your git repository at any
34
+ time. Are you sure you want to continue?
35
+ </Text>
36
+ </Box>
37
+ </DialogContent>
38
+ <DialogActions
39
+ asFooter
40
+ cancel={{ text: "Cancel" }}
41
+ ok={{
42
+ color: "tomato",
43
+ loading,
44
+ onClick: () => {
45
+ void (async () => {
46
+ setLoading(true);
47
+ try {
48
+ await unlinkRepo(repo);
49
+ await deleteToken();
50
+ } catch (error) {
51
+ const message = `Could not disconnect from ${repo.name}`;
52
+ console.error(message, error);
53
+ toast.error(message);
54
+ }
55
+ setLoading(false);
56
+ })();
57
+ },
58
+ text: "Continue",
59
+ }}
60
+ size="medium"
61
+ />
62
+ </Dialog>
63
+ );
64
+ };
@@ -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,30 @@
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
+ deleteToken: () => Promise<void>;
9
+ };
10
+
11
+ export function useWriteAPIToken(args: {
12
+ git: GitRepoSpecifier;
13
+ }): UseWriteAPITokenReturnType {
14
+ const [config] = useSliceMachineConfig();
15
+ return {
16
+ updateToken: async (token) => {
17
+ await managerClient.git.updateWriteAPIToken({
18
+ prismic: { domain: config.repositoryName },
19
+ git: args.git,
20
+ token,
21
+ });
22
+ },
23
+ deleteToken: async () => {
24
+ await managerClient.git.deleteWriteAPIToken({
25
+ prismic: { domain: config.repositoryName },
26
+ git: args.git,
27
+ });
28
+ },
29
+ };
30
+ }
@@ -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
+ );