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.
- package/.depcheckrc +3 -0
- package/components/DeleteVariationModal/index.tsx +1 -0
- package/components/Forms/RenameVariationModal/RenameVariationModal.tsx +0 -1
- package/components/ModalFormCard/index.tsx +0 -1
- package/components/Navigation/index.tsx +25 -12
- package/components/ReviewModal/ReviewForm.tsx +0 -1
- package/lib/builders/common/EditModal/Form.jsx +0 -1
- package/lib/builders/common/Zone/Card/components/NewField.tsx +0 -1
- package/out/404.html +1 -1
- package/out/_next/static/chunks/18539003-5f78714a35fde4a1.js +97 -0
- package/out/_next/static/chunks/318-bd030cc1725e23b5.js +1 -0
- package/out/_next/static/chunks/{727-3a3bc32518778317.js → 727-2235967a881f9035.js} +1 -1
- package/out/_next/static/chunks/731-a9b66ccdc3fae2c2.js +1 -0
- package/out/_next/static/chunks/777-8c5507e3b119b5dc.js +8 -0
- package/out/_next/static/chunks/904-6d6937d53ea2761e.js +1 -0
- package/out/_next/static/chunks/pages/_app-b6719b931ebc00c6.js +434 -0
- package/out/_next/static/chunks/pages/{changelog-afd18276fe018b24.js → changelog-02cd80dad6f40878.js} +1 -1
- package/out/_next/static/chunks/pages/{changes-2a976f9efeb719aa.js → changes-8de69920dfb5a48f.js} +1 -1
- package/out/_next/static/chunks/pages/{labs-ee206005948f8e87.js → labs-39b50541a4c370bf.js} +1 -1
- package/out/_next/static/chunks/pages/settings-386e0971d78f7d57.js +1 -0
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]/{simulator-897ca93c114a1435.js → simulator-b12346e58ac9abea.js} +1 -1
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-62b55bae7f1b3793.js +1 -0
- package/out/_next/static/chunks/pages/slices-81e382c3374273df.js +1 -0
- package/out/_next/static/css/3c26dbbbd8f4be12.css +1 -0
- package/out/_next/static/css/{37153180c3b0dd66.css → 838fd8bb5a7c32b0.css} +1 -1
- package/out/_next/static/css/ca32882a5d2d8d88.css +1 -0
- package/out/_next/static/u0edTA9rplsCk652gdVmA/_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/labs.html +1 -1
- package/out/page-types/[pageTypeId].html +1 -1
- package/out/settings.html +1 -0
- package/out/slices/[lib]/[sliceName]/[variation]/simulator.html +1 -1
- package/out/slices/[lib]/[sliceName]/[variation].html +1 -1
- package/out/slices.html +1 -1
- package/package.json +9 -6
- package/pages/settings.tsx +1 -0
- package/postcss.config.js +10 -0
- package/src/components/FieldSet/FieldSet.stories.tsx +20 -11
- package/src/components/RelativeTime/RelativeTime.stories.tsx +25 -0
- package/src/components/RelativeTime/RelativeTime.tsx +40 -0
- package/src/components/RelativeTime/index.ts +1 -0
- package/src/features/environments/actions/setEnvironment.ts +2 -2
- package/src/features/settings/SettingsPage.tsx +29 -0
- package/src/features/settings/git/ConnectGitRepository.tsx +97 -0
- package/src/features/settings/git/ConnectGitRepositoryBlankSlate.tsx +33 -0
- package/src/features/settings/git/GitOwnerSelect.tsx +71 -0
- package/src/features/settings/git/GitProvider.ts +40 -0
- package/src/features/settings/git/GitProviderConnectButtons.tsx +63 -0
- package/src/features/settings/git/GitRepositoriesList.tsx +76 -0
- package/src/features/settings/git/GitRepositoriesSearch.tsx +69 -0
- package/src/features/settings/git/GitRepositoryConnectDialog.tsx +86 -0
- package/src/features/settings/git/GitRepositoryDisconnectDialog.tsx +64 -0
- package/src/features/settings/git/useGitOwners.ts +12 -0
- package/src/features/settings/git/useGitRepos.ts +24 -0
- package/src/features/settings/git/useLinkedGitRepos.ts +41 -0
- package/src/features/settings/git/useWriteAPIToken.ts +30 -0
- package/src/features/slices/convertLegacySlice/ConvertLegacySliceAsNewSliceDialog.tsx +0 -1
- package/src/features/slices/convertLegacySlice/ConvertLegacySliceAsNewVariationDialog.tsx +0 -1
- package/src/features/slices/convertLegacySlice/ConvertLegacySliceMergeWithIdenticalDialog.tsx +0 -1
- package/src/hooks/useUser.ts +14 -0
- package/src/icons/SettingsIcon.tsx +19 -0
- package/out/_next/static/chunks/18539003-5cc559566b738915.js +0 -97
- package/out/_next/static/chunks/318-ce7e74f18f2d5b22.js +0 -1
- package/out/_next/static/chunks/376-7e784d6069e01654.js +0 -8
- package/out/_next/static/chunks/731-501990ebe6a71b32.js +0 -1
- package/out/_next/static/chunks/904-9a4c1264727ae89a.js +0 -1
- package/out/_next/static/chunks/pages/_app-e20a274bd5f065bd.js +0 -432
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-b2a9d773ce5d7739.js +0 -1
- package/out/_next/static/chunks/pages/slices-e9c70c082ca3e3f9.js +0 -1
- package/out/_next/static/css/200244e3e0463c39.css +0 -1
- package/out/_next/static/oUce2teKPsKU-VjaTxYsp/_buildManifest.js +0 -1
- /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
|
+
}
|
|
@@ -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,
|
|
@@ -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
|
+
);
|