slice-machine-ui 2.18.1-alpha.jp-unauthorized-error.4 → 2.18.1-alpha.jp-unauthorized-error-improvement.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/out/404.html +1 -1
- package/out/_next/static/{eWxsTVqoYTTRkUB_nHhoh → SfM6wNmXllax54gbRXb7m}/_buildManifest.js +1 -1
- package/out/_next/static/chunks/{248-bdbfde18c5a04eae.js → 248-bcf03aa3c62e7dfb.js} +1 -1
- package/out/_next/static/chunks/34-50c64778da33cff6.js +1 -0
- package/out/_next/static/chunks/422-c9192a1dbdd2ae0e.js +1 -0
- package/out/_next/static/chunks/429-1137c819c2bf6b66.js +3 -0
- package/out/_next/static/chunks/{489-6edb99e269996dd1.js → 489-77d1fe67b6d0f0f8.js} +1 -1
- package/out/_next/static/chunks/630-c34de0401b8a0375.js +1 -0
- package/out/_next/static/chunks/pages/{_app-d1098ab653091b72.js → _app-9c512373cecee09f.js} +40 -40
- package/out/_next/static/chunks/pages/changelog-3901f2fc937d9648.js +1 -0
- package/out/_next/static/chunks/pages/changes-62d4e18795217cba.js +1 -0
- package/out/_next/static/chunks/pages/custom-types/{[customTypeId]-7102c23f96cd1768.js → [customTypeId]-816acb31b652239b.js} +1 -1
- package/out/_next/static/chunks/pages/{labs-d79597003a1ff74e.js → labs-5f5c63fb1f7d4b92.js} +1 -1
- package/out/_next/static/chunks/pages/page-types/{[pageTypeId]-d4bc920a5efffa0a.js → [pageTypeId]-669d5479e81b638b.js} +1 -1
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]/simulator-eca10940c9083d4c.js +1 -0
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-b4700a6332ea828c.js +1 -0
- package/out/_next/static/chunks/pages/slices-bf63f937b184b470.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/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 +3 -6
- package/src/errorBoundaries.tsx +150 -0
- package/src/features/auth/LogoutButton.tsx +42 -36
- package/src/features/builder/fields/contentRelationship/ContentRelationshipFieldPicker.tsx +3 -3
- package/src/features/changes/StatusBadge.tsx +1 -9
- package/src/features/customTypes/customTypesBuilder/PageSnippetDialog/PageSnippetDialog.tsx +3 -3
- package/src/features/customTypes/customTypesTable/CustomTypesTablePage.tsx +3 -3
- package/src/features/environments/actions/useSetEnvironment.ts +22 -0
- package/src/features/environments/useActiveEnvironment.ts +17 -9
- package/src/features/environments/useEnvironments.ts +11 -8
- package/src/features/labs/labsList/LabsPage.tsx +3 -3
- package/src/features/navigation/Navigation.tsx +31 -8
- package/src/features/navigation/NavigationItem.tsx +9 -3
- package/src/features/navigation/SliceMachineVersion.tsx +1 -6
- package/src/features/slices/sliceBuilder/FloatingBackButton.tsx +3 -3
- package/src/features/slices/sliceBuilder/McpPromoLink.tsx +29 -0
- package/src/features/sync/actions/pushChanges.ts +1 -0
- package/src/features/sync/getUnSyncChanges.ts +23 -7
- package/src/legacy/components/AppLayout/index.tsx +10 -85
- package/src/legacy/components/ChangesEmptyState/UnauthenticatedView.tsx +31 -0
- package/src/legacy/components/ChangesEmptyState/index.ts +1 -1
- package/src/legacy/components/ChangesItems/ChangesItems.tsx +3 -3
- package/src/legacy/components/LoginModal/index.tsx +13 -5
- package/src/legacy/components/Navigation/ChangesItem.tsx +2 -6
- package/src/legacy/components/Navigation/Environment.tsx +2 -7
- package/src/legacy/components/Navigation/SideNavEnvironmentSelector/SideNavEnvironmentSelector.tsx +3 -8
- package/src/legacy/components/Simulator/index.tsx +3 -3
- package/src/legacy/lib/builders/CustomTypeBuilder/TabZone/index.tsx +3 -3
- package/src/legacy/lib/builders/SliceBuilder/index.tsx +2 -0
- package/src/legacy/lib/models/common/ModelStatus/index.ts +6 -1
- package/src/modules/userContext/index.ts +6 -3
- package/src/modules/userContext/types.ts +1 -1
- package/src/pages/_app.tsx +88 -95
- package/src/pages/changes.tsx +4 -5
- package/src/queryClient.tsx +24 -0
- package/test/__testutils__/index.tsx +13 -10
- package/out/_next/static/chunks/157-54b8336d20b41933.js +0 -3
- package/out/_next/static/chunks/34-8d9d9b2944824750.js +0 -1
- package/out/_next/static/chunks/385-b949173dfa03dd3e.js +0 -1
- package/out/_next/static/chunks/630-bb6e3db525588f16.js +0 -1
- package/out/_next/static/chunks/pages/changelog-21b960abba5abf71.js +0 -1
- package/out/_next/static/chunks/pages/changes-7919746009a45ad8.js +0 -1
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]/simulator-b127d948a17968d3.js +0 -1
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-98f85d5fb8d5c704.js +0 -1
- package/out/_next/static/chunks/pages/slices-046e5e978ffc3a42.js +0 -1
- package/src/ErrorBoundary.tsx +0 -47
- package/src/features/environments/actions/setEnvironment.ts +0 -18
- package/src/legacy/components/ChangesEmptyState/AuthErrorPage.tsx +0 -44
- /package/out/_next/static/{eWxsTVqoYTTRkUB_nHhoh → SfM6wNmXllax54gbRXb7m}/_ssgManifest.js +0 -0
|
@@ -3,6 +3,7 @@ import { LibraryUI } from "@/legacy/lib/models/common/LibraryUI";
|
|
|
3
3
|
import {
|
|
4
4
|
getModelId,
|
|
5
5
|
hasLocal,
|
|
6
|
+
hasRemote,
|
|
6
7
|
isRemoteOnly,
|
|
7
8
|
LocalOrRemoteCustomType,
|
|
8
9
|
LocalOrRemoteSlice,
|
|
@@ -76,11 +77,23 @@ export function getUnSyncedChanges(
|
|
|
76
77
|
);
|
|
77
78
|
|
|
78
79
|
const changedSlices = unSyncedSlices
|
|
79
|
-
.map((
|
|
80
|
-
slice
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
.map((slice) => {
|
|
81
|
+
const status = modelsStatuses.slices[slice.model.id];
|
|
82
|
+
|
|
83
|
+
const imageUrlMap = findRemoteSlice(
|
|
84
|
+
slices,
|
|
85
|
+
slice.model.id,
|
|
86
|
+
)?.variations.reduce<Record<string, string>>((result, variation) => {
|
|
87
|
+
const { imageUrl } = variation;
|
|
88
|
+
if (imageUrl === undefined || imageUrl === "") return result;
|
|
89
|
+
result[variation.id] = imageUrl;
|
|
90
|
+
return result;
|
|
91
|
+
}, {});
|
|
92
|
+
|
|
93
|
+
return { status, slice, variationImageUrlMap: imageUrlMap ?? {} };
|
|
94
|
+
})
|
|
83
95
|
.filter((s): s is ChangedSlice => unSyncStatuses.includes(s.status));
|
|
96
|
+
|
|
84
97
|
const changedCustomTypes = unSyncedCustomTypes
|
|
85
98
|
.map((model) => (hasLocal(model) ? model.local : model.remote))
|
|
86
99
|
.map((ct) => ({
|
|
@@ -98,6 +111,11 @@ export function getUnSyncedChanges(
|
|
|
98
111
|
};
|
|
99
112
|
}
|
|
100
113
|
|
|
114
|
+
function findRemoteSlice(slices: LocalOrRemoteSlice[], sliceId: string) {
|
|
115
|
+
const slice = slices.find((s) => hasRemote(s) && s.remote.id === sliceId);
|
|
116
|
+
return slice && hasRemote(slice) ? slice.remote : undefined;
|
|
117
|
+
}
|
|
118
|
+
|
|
101
119
|
// ComponentUI are manipulated on all the relevant pages
|
|
102
120
|
// But the data is not available for remote only slices
|
|
103
121
|
// which have been deleted locally
|
|
@@ -131,9 +149,7 @@ export const getModelStatus = (args: GetModelStatusArgs): ModelsStatuses => {
|
|
|
131
149
|
const { slices, customTypes, isOnline, authStatus } = args;
|
|
132
150
|
|
|
133
151
|
const userHasAccessToModels =
|
|
134
|
-
isOnline &&
|
|
135
|
-
authStatus != AuthStatus.FORBIDDEN &&
|
|
136
|
-
authStatus != AuthStatus.UNAUTHORIZED;
|
|
152
|
+
isOnline && authStatus === AuthStatus.AUTHORIZED;
|
|
137
153
|
|
|
138
154
|
const modelsStatuses = {
|
|
139
155
|
slices: computeStatuses(slices, userHasAccessToModels),
|
|
@@ -1,16 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BlankSlate,
|
|
3
|
-
BlankSlateDescription,
|
|
4
|
-
BlankSlateIcon,
|
|
5
|
-
BlankSlateTitle,
|
|
6
|
-
Box,
|
|
7
|
-
Button,
|
|
8
|
-
ButtonGroup,
|
|
9
|
-
Text,
|
|
10
|
-
} from "@prismicio/editor-ui";
|
|
11
|
-
import { isUnauthorizedError } from "@slicemachine/manager/client";
|
|
1
|
+
import { Box, Button, ButtonGroup } from "@prismicio/editor-ui";
|
|
12
2
|
import { useRouter } from "next/router";
|
|
13
|
-
import { FC, PropsWithChildren, Suspense
|
|
3
|
+
import { FC, PropsWithChildren, Suspense } from "react";
|
|
14
4
|
|
|
15
5
|
import { Breadcrumb } from "@/components/Breadcrumb";
|
|
16
6
|
import {
|
|
@@ -19,8 +9,6 @@ import {
|
|
|
19
9
|
PageLayoutHeader,
|
|
20
10
|
PageLayoutPane,
|
|
21
11
|
} from "@/components/PageLayout";
|
|
22
|
-
import { ErrorBoundary } from "@/ErrorBoundary";
|
|
23
|
-
import { LogoutButton } from "@/features/auth/LogoutButton";
|
|
24
12
|
import { useActiveEnvironment } from "@/features/environments/useActiveEnvironment";
|
|
25
13
|
import { Navigation } from "@/features/navigation/Navigation";
|
|
26
14
|
|
|
@@ -29,80 +17,17 @@ export const AppLayout: FC<PropsWithChildren> = ({
|
|
|
29
17
|
...otherProps
|
|
30
18
|
}) => {
|
|
31
19
|
return (
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
flexDirection="column"
|
|
41
|
-
>
|
|
42
|
-
<BlankSlate>
|
|
43
|
-
<BlankSlateIcon
|
|
44
|
-
lineColor="tomato11"
|
|
45
|
-
backgroundColor="tomato3"
|
|
46
|
-
name="alert"
|
|
47
|
-
/>
|
|
48
|
-
<BlankSlateTitle>Failed to load Slice Machine</BlankSlateTitle>
|
|
49
|
-
<BlankSlateDescription>
|
|
50
|
-
<RenderError error={error} />
|
|
51
|
-
</BlankSlateDescription>
|
|
52
|
-
</BlankSlate>
|
|
53
|
-
</Box>
|
|
54
|
-
);
|
|
55
|
-
}}
|
|
56
|
-
>
|
|
57
|
-
<Suspense>
|
|
58
|
-
<PageLayoutWithActiveEnvironment {...otherProps}>
|
|
59
|
-
<PageLayoutPane>
|
|
60
|
-
<Navigation />
|
|
61
|
-
</PageLayoutPane>
|
|
62
|
-
{children}
|
|
63
|
-
</PageLayoutWithActiveEnvironment>
|
|
64
|
-
</Suspense>
|
|
65
|
-
</ErrorBoundary>
|
|
20
|
+
<Suspense>
|
|
21
|
+
<PageLayoutWithActiveEnvironment {...otherProps}>
|
|
22
|
+
<PageLayoutPane>
|
|
23
|
+
<Navigation />
|
|
24
|
+
</PageLayoutPane>
|
|
25
|
+
{children}
|
|
26
|
+
</PageLayoutWithActiveEnvironment>
|
|
27
|
+
</Suspense>
|
|
66
28
|
);
|
|
67
29
|
};
|
|
68
30
|
|
|
69
|
-
function RenderError(args: { error: unknown }) {
|
|
70
|
-
const { error } = args;
|
|
71
|
-
|
|
72
|
-
if (isUnauthorizedError(error)) {
|
|
73
|
-
return <UnauthorizedErrorView />;
|
|
74
|
-
}
|
|
75
|
-
return <>{JSON.stringify(error)}</>;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function UnauthorizedErrorView() {
|
|
79
|
-
const [isLoggingOut, setIsLoggingOut] = useState(false);
|
|
80
|
-
|
|
81
|
-
return (
|
|
82
|
-
<Box flexDirection="column" gap={16} margin={{ top: 8 }}>
|
|
83
|
-
<Box flexDirection="column" gap={8} alignItems="center">
|
|
84
|
-
<Text variant="h3" align="center">
|
|
85
|
-
It seems like you don't have access to this repository
|
|
86
|
-
</Text>
|
|
87
|
-
<Text align="center">
|
|
88
|
-
Check that the repository name is correct, then contact your
|
|
89
|
-
repository administrator.
|
|
90
|
-
</Text>
|
|
91
|
-
</Box>
|
|
92
|
-
<LogoutButton
|
|
93
|
-
isLoading={isLoggingOut}
|
|
94
|
-
onLogoutSuccess={() => {
|
|
95
|
-
setIsLoggingOut(true);
|
|
96
|
-
window.location.reload();
|
|
97
|
-
}}
|
|
98
|
-
sx={{ alignSelf: "center" }}
|
|
99
|
-
>
|
|
100
|
-
Log out
|
|
101
|
-
</LogoutButton>
|
|
102
|
-
</Box>
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
31
|
const environmentTopBorderColorMap = {
|
|
107
32
|
prod: "purple",
|
|
108
33
|
stage: "indigo",
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Box, Button, Text } from "@prismicio/editor-ui";
|
|
2
|
+
|
|
3
|
+
import useSliceMachineActions from "@/modules/useSliceMachineActions";
|
|
4
|
+
|
|
5
|
+
export const UnauthenticatedView = () => {
|
|
6
|
+
const { openLoginModal } = useSliceMachineActions();
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<Box
|
|
10
|
+
flexDirection="column"
|
|
11
|
+
height="100%"
|
|
12
|
+
alignItems="center"
|
|
13
|
+
justifyContent="center"
|
|
14
|
+
gap={8}
|
|
15
|
+
>
|
|
16
|
+
<Text variant="h3" align="center">
|
|
17
|
+
It seems like you are logged out
|
|
18
|
+
</Text>
|
|
19
|
+
<Text align="center">Log in to connect to your repository.</Text>
|
|
20
|
+
<Text align="center">
|
|
21
|
+
If that doesn't work, it's possible that Slice Machine is having trouble
|
|
22
|
+
accessing Prismic's servers.{" "}
|
|
23
|
+
<Text href="https://community.prismic.io/">
|
|
24
|
+
Contact our support team
|
|
25
|
+
</Text>
|
|
26
|
+
.
|
|
27
|
+
</Text>
|
|
28
|
+
<Button onClick={() => openLoginModal()}>Log in to Prismic</Button>
|
|
29
|
+
</Box>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
@@ -3,7 +3,7 @@ import React, { Suspense } from "react";
|
|
|
3
3
|
import { AiOutlineExclamationCircle } from "react-icons/ai";
|
|
4
4
|
|
|
5
5
|
import { countMissingScreenshots } from "@/domain/slice";
|
|
6
|
-
import {
|
|
6
|
+
import { DefaultErrorBoundary } from "@/errorBoundaries";
|
|
7
7
|
import { SharedSliceCard } from "@/features/slices/sliceCards/SharedSliceCard";
|
|
8
8
|
import { ModelsStatuses } from "@/features/sync/getUnSyncChanges";
|
|
9
9
|
import { useScreenshotChangesModal } from "@/hooks/useScreenshotChangesModal";
|
|
@@ -146,11 +146,11 @@ export const ChangesItems: React.FC<ChangesItemsProps> = ({
|
|
|
146
146
|
)}
|
|
147
147
|
</Box>
|
|
148
148
|
|
|
149
|
-
<
|
|
149
|
+
<DefaultErrorBoundary>
|
|
150
150
|
<Suspense>
|
|
151
151
|
<DevCollaborationExperiment />
|
|
152
152
|
</Suspense>
|
|
153
|
-
</
|
|
153
|
+
</DefaultErrorBoundary>
|
|
154
154
|
</Box>
|
|
155
155
|
</>
|
|
156
156
|
);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useQueryClient } from "@tanstack/react-query";
|
|
1
2
|
import React from "react";
|
|
2
3
|
import Modal from "react-modal";
|
|
3
4
|
import { useSelector } from "react-redux";
|
|
@@ -15,8 +16,8 @@ import {
|
|
|
15
16
|
|
|
16
17
|
import { checkAuthStatus, clearAuth, getState } from "@/apiClient";
|
|
17
18
|
import { getActiveEnvironment } from "@/features/environments/actions/getActiveEnvironment";
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
19
|
+
import { GetActiveEnvironmentQueryKey } from "@/features/environments/useActiveEnvironment";
|
|
20
|
+
import { GetEnvironmentsQueryKey } from "@/features/environments/useEnvironments";
|
|
20
21
|
import { useAutoSync } from "@/features/sync/AutoSyncProvider";
|
|
21
22
|
import { getUnSyncedChanges } from "@/features/sync/getUnSyncChanges";
|
|
22
23
|
import SliceMachineModal from "@/legacy/components/SliceMachineModal";
|
|
@@ -54,6 +55,7 @@ const LoginModal: React.FunctionComponent = () => {
|
|
|
54
55
|
const { syncChanges } = useAutoSync();
|
|
55
56
|
const { closeModals, startLoadingLogin, stopLoadingLogin, refreshState } =
|
|
56
57
|
useSliceMachineActions();
|
|
58
|
+
const queryClient = useQueryClient();
|
|
57
59
|
|
|
58
60
|
const prismicBase = preferWroomBase(env.manifest.apiEndpoint);
|
|
59
61
|
const loginRedirectUrl = `${
|
|
@@ -79,8 +81,14 @@ const LoginModal: React.FunctionComponent = () => {
|
|
|
79
81
|
);
|
|
80
82
|
|
|
81
83
|
// refresh queries to update the UI
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
await Promise.all([
|
|
85
|
+
queryClient.invalidateQueries({
|
|
86
|
+
queryKey: GetEnvironmentsQueryKey,
|
|
87
|
+
}),
|
|
88
|
+
queryClient.invalidateQueries({
|
|
89
|
+
queryKey: GetActiveEnvironmentQueryKey,
|
|
90
|
+
}),
|
|
91
|
+
]);
|
|
84
92
|
|
|
85
93
|
toast.success("Logged in");
|
|
86
94
|
stopLoadingLogin();
|
|
@@ -127,7 +135,7 @@ const LoginModal: React.FunctionComponent = () => {
|
|
|
127
135
|
|
|
128
136
|
return (
|
|
129
137
|
<SliceMachineModal
|
|
130
|
-
isOpen={isOpen}
|
|
138
|
+
isOpen={isLoginLoading || isOpen}
|
|
131
139
|
shouldCloseOnOverlayClick
|
|
132
140
|
onRequestClose={closeModals}
|
|
133
141
|
contentLabel={"login_modal"}
|
|
@@ -117,16 +117,12 @@ export const ChangesCount: FC<ChangesCountProps> = ({ color }) => {
|
|
|
117
117
|
|
|
118
118
|
if (
|
|
119
119
|
!isOnline ||
|
|
120
|
-
authStatus
|
|
121
|
-
|
|
120
|
+
authStatus !== AuthStatus.AUTHORIZED ||
|
|
121
|
+
numberOfChanges === 0
|
|
122
122
|
) {
|
|
123
123
|
return null;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
if (numberOfChanges === 0) {
|
|
127
|
-
return null;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
126
|
const formattedNumberOfChanges = numberOfChanges > 9 ? "+9" : numberOfChanges;
|
|
131
127
|
|
|
132
128
|
return (
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import { useState } from "react";
|
|
6
6
|
|
|
7
7
|
import { getState, telemetry } from "@/apiClient";
|
|
8
|
-
import {
|
|
8
|
+
import { useSetEnvironment } from "@/features/environments/actions/useSetEnvironment";
|
|
9
9
|
import { useActiveEnvironment } from "@/features/environments/useActiveEnvironment";
|
|
10
10
|
import { useEnvironments } from "@/features/environments/useEnvironments";
|
|
11
11
|
import { useAutoSync } from "@/features/sync/AutoSyncProvider";
|
|
@@ -28,6 +28,7 @@ export function Environment() {
|
|
|
28
28
|
const authStatus = useAuthStatus();
|
|
29
29
|
const [isSwitchingEnv, setIsSwitchingEnv] = useState(false);
|
|
30
30
|
const { autoSyncStatus } = useAutoSync();
|
|
31
|
+
const setEnvironment = useSetEnvironment();
|
|
31
32
|
|
|
32
33
|
async function onSelect(environment: EnvironmentType) {
|
|
33
34
|
if (activeEnvironment?.name === environment.name) {
|
|
@@ -105,10 +106,4 @@ export function Environment() {
|
|
|
105
106
|
/>
|
|
106
107
|
);
|
|
107
108
|
}
|
|
108
|
-
|
|
109
|
-
if (useEnvironmentsError !== undefined) {
|
|
110
|
-
throw useEnvironmentsError;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
throw activeEnvironmentError;
|
|
114
109
|
}
|
package/src/legacy/components/Navigation/SideNavEnvironmentSelector/SideNavEnvironmentSelector.tsx
CHANGED
|
@@ -17,9 +17,8 @@ import * as VisuallyHidden from "@radix-ui/react-visually-hidden";
|
|
|
17
17
|
import type { Environment } from "@slicemachine/manager/client";
|
|
18
18
|
import { clsx } from "clsx";
|
|
19
19
|
import type { FC, ReactNode } from "react";
|
|
20
|
-
import { toast } from "react-toastify";
|
|
21
20
|
|
|
22
|
-
import {
|
|
21
|
+
import { EnvironmentLogoutButton } from "@/features/auth/LogoutButton";
|
|
23
22
|
import { LoginIcon } from "@/icons/LoginIcon";
|
|
24
23
|
import { LogoIcon } from "@/icons/LogoIcon";
|
|
25
24
|
|
|
@@ -30,7 +29,7 @@ type SideNavEnvironmentSelectorProps = {
|
|
|
30
29
|
disabled?: boolean;
|
|
31
30
|
environments?: Environment[];
|
|
32
31
|
loading?: boolean;
|
|
33
|
-
variant?: "default" | "offline" | "
|
|
32
|
+
variant?: "default" | "offline" | "unauthenticated";
|
|
34
33
|
onLogInClick?: () => void;
|
|
35
34
|
onSelect?: (environment: Environment) => void | Promise<void>;
|
|
36
35
|
};
|
|
@@ -141,11 +140,7 @@ export const SideNavEnvironmentSelector: FC<SideNavEnvironmentSelectorProps> = (
|
|
|
141
140
|
/>
|
|
142
141
|
) : undefined}
|
|
143
142
|
|
|
144
|
-
{variant === "default" &&
|
|
145
|
-
<LogoutButton
|
|
146
|
-
onLogoutSuccess={() => toast.success("Logged out")}
|
|
147
|
-
/>
|
|
148
|
-
)}
|
|
143
|
+
{variant === "default" && <EnvironmentLogoutButton />}
|
|
149
144
|
</Box>
|
|
150
145
|
</>
|
|
151
146
|
)}
|
|
@@ -17,7 +17,7 @@ import { toast } from "react-toastify";
|
|
|
17
17
|
import { BaseStyles, Box, Flex, Spinner } from "theme-ui";
|
|
18
18
|
|
|
19
19
|
import { saveSliceMock, telemetry } from "@/apiClient";
|
|
20
|
-
import {
|
|
20
|
+
import { DefaultErrorBoundary } from "@/errorBoundaries";
|
|
21
21
|
import useThrottle from "@/hooks/useThrottle";
|
|
22
22
|
import ScreenshotPreviewModal from "@/legacy/components/ScreenshotPreviewModal";
|
|
23
23
|
import { ComponentUI } from "@/legacy/lib/models/common/ComponentUI";
|
|
@@ -287,7 +287,7 @@ const Simulator: FC<SimulatorProps> = ({ slice, variation }) => {
|
|
|
287
287
|
overflowY: "auto",
|
|
288
288
|
}}
|
|
289
289
|
>
|
|
290
|
-
<
|
|
290
|
+
<DefaultErrorBoundary
|
|
291
291
|
renderError={() => (
|
|
292
292
|
<DefaultErrorMessage
|
|
293
293
|
title="Editor error"
|
|
@@ -315,7 +315,7 @@ const Simulator: FC<SimulatorProps> = ({ slice, variation }) => {
|
|
|
315
315
|
/>
|
|
316
316
|
</QueryClientProvider>
|
|
317
317
|
</Suspense>
|
|
318
|
-
</
|
|
318
|
+
</DefaultErrorBoundary>
|
|
319
319
|
</Flex>
|
|
320
320
|
) : null}
|
|
321
321
|
</Flex>
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
reorderField,
|
|
21
21
|
updateField,
|
|
22
22
|
} from "@/domain/customType";
|
|
23
|
-
import {
|
|
23
|
+
import { DefaultErrorBoundary } from "@/errorBoundaries";
|
|
24
24
|
import { useCustomTypeState } from "@/features/customTypes/customTypesBuilder/CustomTypeProvider";
|
|
25
25
|
import {
|
|
26
26
|
CustomTypes,
|
|
@@ -246,7 +246,7 @@ const TabZone: FC<TabZoneProps> = ({ tabId }) => {
|
|
|
246
246
|
};
|
|
247
247
|
|
|
248
248
|
return (
|
|
249
|
-
<
|
|
249
|
+
<DefaultErrorBoundary>
|
|
250
250
|
<Suspense
|
|
251
251
|
fallback={
|
|
252
252
|
<Box padding={32}>
|
|
@@ -297,7 +297,7 @@ const TabZone: FC<TabZoneProps> = ({ tabId }) => {
|
|
|
297
297
|
/>
|
|
298
298
|
</List>
|
|
299
299
|
</Suspense>
|
|
300
|
-
</
|
|
300
|
+
</DefaultErrorBoundary>
|
|
301
301
|
);
|
|
302
302
|
};
|
|
303
303
|
|
|
@@ -4,6 +4,7 @@ import { type FC } from "react";
|
|
|
4
4
|
import { BreadcrumbItem } from "@/components/Breadcrumb";
|
|
5
5
|
import { AutoSaveStatusIndicator } from "@/features/autoSave/AutoSaveStatusIndicator";
|
|
6
6
|
import { FloatingBackButton } from "@/features/slices/sliceBuilder/FloatingBackButton";
|
|
7
|
+
import { McpPromoLink } from "@/features/slices/sliceBuilder/McpPromoLink";
|
|
7
8
|
import { useSliceState } from "@/features/slices/sliceBuilder/SliceBuilderProvider";
|
|
8
9
|
import {
|
|
9
10
|
AppLayout,
|
|
@@ -35,6 +36,7 @@ export const SliceBuilder: FC = () => {
|
|
|
35
36
|
<BreadcrumbItem active>{slice.model.name}</BreadcrumbItem>
|
|
36
37
|
</AppLayoutBreadcrumb>
|
|
37
38
|
<AppLayoutActions>
|
|
39
|
+
<McpPromoLink />
|
|
38
40
|
<AutoSaveStatusIndicator status={actionQueueStatus} />
|
|
39
41
|
<SimulatorButton disabled={actionQueueStatus !== "done"} />
|
|
40
42
|
</AppLayoutActions>
|
|
@@ -30,7 +30,12 @@ export type ChangesStatus =
|
|
|
30
30
|
| ModelStatus.New
|
|
31
31
|
| ModelStatus.Modified;
|
|
32
32
|
|
|
33
|
-
export type ChangedSlice = {
|
|
33
|
+
export type ChangedSlice = {
|
|
34
|
+
status: ChangesStatus;
|
|
35
|
+
slice: ComponentUI;
|
|
36
|
+
/** A map of variation IDs to remote screenshot URLs. */
|
|
37
|
+
variationImageUrlMap: Record<string, string>;
|
|
38
|
+
};
|
|
34
39
|
export type ChangedCustomType = {
|
|
35
40
|
status: ChangesStatus;
|
|
36
41
|
customType: CustomTypeSM;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { UnauthenticatedError } from "@slicemachine/manager/client";
|
|
1
2
|
import { Reducer } from "redux";
|
|
2
3
|
import { ActionType, createAction, getType } from "typesafe-actions";
|
|
3
4
|
|
|
@@ -92,10 +93,12 @@ const getAuthStatus = (
|
|
|
92
93
|
case undefined: {
|
|
93
94
|
return AuthStatus.AUTHORIZED;
|
|
94
95
|
}
|
|
95
|
-
case 403: {
|
|
96
|
-
return AuthStatus.UNAUTHORIZED;
|
|
97
|
-
}
|
|
98
96
|
case 401: {
|
|
97
|
+
if (clientError.name === new UnauthenticatedError().name) {
|
|
98
|
+
return AuthStatus.UNAUTHENTICATED;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
case 403: {
|
|
99
102
|
return AuthStatus.FORBIDDEN;
|
|
100
103
|
}
|
|
101
104
|
default: {
|