slice-machine-ui 1.23.2-beta.9 → 1.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.depcheckrc +3 -0
- package/components/ChangesEmptyState/OfflinePage.tsx +1 -1
- package/components/ChangesItems/ChangesItems.tsx +6 -2
- package/components/CustomTypeTable/changesPage.tsx +12 -7
- package/components/DeleteSliceModal/index.tsx +3 -0
- package/components/DeleteVariationModal/index.tsx +1 -0
- package/components/Forms/CreateCustomTypeModal/CreateCustomTypeModal.tsx +4 -0
- package/components/Forms/CreateSliceModal/CreateSliceModal.tsx +3 -1
- package/components/Forms/RenameCustomTypeModal/RenameCustomTypeModal.tsx +6 -1
- package/components/Forms/RenameSliceModal/RenameSliceModal.tsx +3 -0
- package/components/Forms/RenameVariationModal/RenameVariationModal.tsx +0 -1
- package/components/LoginModal/index.tsx +40 -2
- package/components/ModalFormCard/index.tsx +0 -1
- package/components/Navigation/ChangesItem.tsx +117 -0
- package/components/Navigation/Environment.tsx +51 -4
- package/components/Navigation/index.css.ts +1 -2
- package/components/Navigation/index.test.tsx +5 -85
- package/components/Navigation/index.tsx +32 -20
- package/components/ReviewModal/ReviewForm.tsx +0 -1
- package/lib/builders/SliceBuilder/index.tsx +3 -3
- package/lib/builders/common/EditModal/Form.jsx +0 -1
- package/lib/builders/common/Zone/Card/components/NewField.tsx +0 -1
- package/lib/models/common/ModelStatus/index.ts +25 -0
- package/out/404.html +1 -1
- package/out/_next/static/chunks/18539003-5f78714a35fde4a1.js +97 -0
- package/out/_next/static/chunks/25-3aa4d4b24167d340.js +1 -0
- package/out/_next/static/chunks/318-19dbcae10cdb6408.js +1 -0
- package/out/_next/static/chunks/727-de03055e40815a3a.js +1 -0
- package/out/_next/static/chunks/777-8c5507e3b119b5dc.js +8 -0
- package/out/_next/static/chunks/799-0af1215eb2b3c17e.js +1 -0
- package/out/_next/static/chunks/904-40686b0426716111.js +1 -0
- package/out/_next/static/chunks/pages/_app-bca191df4ac7078e.js +434 -0
- package/out/_next/static/chunks/pages/{changelog-afd18276fe018b24.js → changelog-cb1df3a70b20f1b8.js} +1 -1
- package/out/_next/static/chunks/pages/changes-ccfd715c2bdc4f83.js +1 -0
- package/out/_next/static/chunks/pages/{labs-ee206005948f8e87.js → labs-2adfb5127f9c4081.js} +1 -1
- package/out/_next/static/chunks/pages/settings-94bcd7422e8b237d.js +1 -0
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]/{simulator-52c3e1f9d14160b8.js → simulator-aaf65fbec8f5839c.js} +1 -1
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-90bb2ea76d2abf42.js +1 -0
- package/out/_next/static/chunks/pages/slices-e0ce615c38e8338d.js +1 -0
- package/out/_next/static/css/39e089aad1742a3a.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/eNujlD43QIdmra7ggcNtK/_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 +10 -8
- package/pages/_app.tsx +34 -32
- package/pages/changes.tsx +27 -41
- 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/components/SideNav/SideNav.css.ts +1 -1
- package/src/components/SideNav/SideNav.tsx +9 -5
- package/src/components/SideNav/SideNavEnvironmentSelector.tsx +31 -11
- package/src/features/autoSave/AutoSaveStatusIndicator.tsx +4 -4
- package/src/features/customTypes/customTypesBuilder/CustomTypeProvider.tsx +11 -10
- package/src/features/customTypes/customTypesBuilder/CustomTypesBuilderPage.tsx +3 -3
- package/src/features/environments/actions/setEnvironment.ts +4 -4
- package/src/features/settings/SettingsPage.tsx +47 -0
- package/src/features/settings/git/ConnectGitRepository.tsx +126 -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 +85 -0
- package/src/features/settings/git/GitRepositoryDisconnectDialog.tsx +60 -0
- package/src/features/settings/git/useGitIntegrationExperiment.ts +8 -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 +23 -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/features/slices/sliceBuilder/SliceBuilderProvider.tsx +12 -10
- package/src/features/sync/AutoSyncProvider.tsx +252 -0
- package/src/features/sync/components/AutoSyncStatusIndicator.module.css +17 -0
- package/src/features/sync/components/AutoSyncStatusIndicator.module.css.d.ts +5 -0
- package/src/features/sync/components/AutoSyncStatusIndicator.tsx +58 -0
- package/src/features/sync/fetchUnSyncChanges.ts +40 -0
- package/src/features/sync/getUnSyncChanges.ts +144 -0
- package/src/features/sync/useUnSyncChanges.ts +32 -0
- package/src/hooks/useActionQueue.tsx +177 -0
- package/src/hooks/useAuthStatus.ts +12 -0
- package/src/hooks/useUser.ts +14 -0
- package/src/icons/SettingsIcon.tsx +19 -0
- package/src/icons/SyncFailed.tsx +30 -0
- package/src/icons/Synced.tsx +19 -0
- package/src/icons/Syncing.tsx +23 -0
- package/test/__testutils__/index.tsx +8 -5
- package/test/src/modules/__fixtures__/serverState.ts +1 -2
- package/components/Navigation/ChangesListItem.tsx +0 -74
- package/components/Navigation/ChangesRightElement.tsx +0 -33
- package/out/_next/static/chunks/18539003-5cc559566b738915.js +0 -97
- package/out/_next/static/chunks/25-01f422cea8066349.js +0 -1
- package/out/_next/static/chunks/318-387e3f23d717c53d.js +0 -1
- package/out/_next/static/chunks/376-7e784d6069e01654.js +0 -8
- package/out/_next/static/chunks/727-358d7fae68a880b3.js +0 -1
- package/out/_next/static/chunks/799-9928a9413d9f0730.js +0 -1
- package/out/_next/static/chunks/904-1ff7519adece2b55.js +0 -1
- package/out/_next/static/chunks/pages/_app-9448839a9d20924d.js +0 -432
- package/out/_next/static/chunks/pages/changes-92c84f6cac0285fd.js +0 -1
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-fecb771f91e70853.js +0 -1
- package/out/_next/static/chunks/pages/slices-b0b58192a87df822.js +0 -1
- package/out/_next/static/css/200244e3e0463c39.css +0 -1
- package/out/_next/static/sysU54bHKiGDh8pmVpi41/_buildManifest.js +0 -1
- package/src/features/autoSave/useAutoSave.tsx +0 -177
- package/src/features/legacyState/actions/getLegacySliceMachineState.ts +0 -53
- package/src/features/legacyState/useLegacySliceMachineState.ts +0 -7
- package/src/hooks/useModelStatus.ts +0 -78
- package/src/hooks/useUnSyncChanges.ts +0 -88
- package/test/components/LoginModal.test.tsx +0 -67
- package/test/src/hooks/useModelStatus.test.ts +0 -115
- /package/out/_next/static/{sysU54bHKiGDh8pmVpi41 → eNujlD43QIdmra7ggcNtK}/_ssgManifest.js +0 -0
- /package/src/features/{changes → sync}/actions/pushChanges.ts +0 -0
- /package/src/features/{changes → sync}/actions/trackPushChangesSuccess.ts +0 -0
|
@@ -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,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
|
+
}
|
|
@@ -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,
|
|
@@ -9,18 +9,16 @@ import {
|
|
|
9
9
|
import { useStableCallback } from "@prismicio/editor-support/React";
|
|
10
10
|
import { useRouter } from "next/router";
|
|
11
11
|
|
|
12
|
-
import {
|
|
13
|
-
AutoSaveStatus,
|
|
14
|
-
useAutoSave,
|
|
15
|
-
} from "@src/features/autoSave/useAutoSave";
|
|
16
12
|
import { ComponentUI } from "@lib/models/common/ComponentUI";
|
|
17
13
|
import { readSliceMocks, updateSlice } from "@src/apiClient";
|
|
18
14
|
import useSliceMachineActions from "@src/modules/useSliceMachineActions";
|
|
19
15
|
import { VariationSM } from "@lib/models/common/Slice";
|
|
16
|
+
import { useAutoSync } from "@src/features/sync/AutoSyncProvider";
|
|
17
|
+
import { ActionQueueStatus, useActionQueue } from "@src/hooks/useActionQueue";
|
|
20
18
|
|
|
21
19
|
type SliceContext = {
|
|
22
20
|
slice: ComponentUI;
|
|
23
|
-
|
|
21
|
+
actionQueueStatus: ActionQueueStatus;
|
|
24
22
|
setSlice: (slice: ComponentUI) => void;
|
|
25
23
|
variation: VariationSM;
|
|
26
24
|
};
|
|
@@ -37,12 +35,13 @@ export function SliceBuilderProvider(props: SliceBuilderProviderProps) {
|
|
|
37
35
|
|
|
38
36
|
const router = useRouter();
|
|
39
37
|
const [slice, setSliceState] = useState(initialSlice);
|
|
40
|
-
const {
|
|
38
|
+
const { actionQueueStatus, setNextAction } = useActionQueue({
|
|
41
39
|
errorMessage:
|
|
42
40
|
"Failed to save slice. Check your browser's console for more information.",
|
|
43
41
|
});
|
|
44
42
|
const { saveSliceSuccess } = useSliceMachineActions();
|
|
45
43
|
const stableSaveSliceSuccess = useStableCallback(saveSliceSuccess);
|
|
44
|
+
const { syncChanges } = useAutoSync();
|
|
46
45
|
|
|
47
46
|
const variation = useMemo(() => {
|
|
48
47
|
const variationName = router.query.variation;
|
|
@@ -60,7 +59,7 @@ export function SliceBuilderProvider(props: SliceBuilderProviderProps) {
|
|
|
60
59
|
const setSlice = useCallback(
|
|
61
60
|
(slice: ComponentUI) => {
|
|
62
61
|
setSliceState(slice);
|
|
63
|
-
|
|
62
|
+
setNextAction(async () => {
|
|
64
63
|
const { errors: updateSliceErrors } = await updateSlice(slice);
|
|
65
64
|
|
|
66
65
|
if (updateSliceErrors.length > 0) {
|
|
@@ -76,20 +75,23 @@ export function SliceBuilderProvider(props: SliceBuilderProviderProps) {
|
|
|
76
75
|
throw readSliceMockErrors;
|
|
77
76
|
}
|
|
78
77
|
|
|
78
|
+
// Update slices store with new slice
|
|
79
79
|
stableSaveSliceSuccess({ ...slice, mocks });
|
|
80
|
+
|
|
81
|
+
syncChanges();
|
|
80
82
|
});
|
|
81
83
|
},
|
|
82
|
-
[
|
|
84
|
+
[setNextAction, stableSaveSliceSuccess, syncChanges],
|
|
83
85
|
);
|
|
84
86
|
|
|
85
87
|
const contextValue: SliceContext = useMemo(
|
|
86
88
|
() => ({
|
|
87
|
-
|
|
89
|
+
actionQueueStatus,
|
|
88
90
|
slice,
|
|
89
91
|
setSlice,
|
|
90
92
|
variation,
|
|
91
93
|
}),
|
|
92
|
-
[
|
|
94
|
+
[actionQueueStatus, slice, setSlice, variation],
|
|
93
95
|
);
|
|
94
96
|
|
|
95
97
|
return (
|