slice-machine-ui 2.18.1-alpha.jp-unauthorized-error-improvement.2 → 2.18.1-alpha.lg-remove-changes-tooltip.1

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 (82) hide show
  1. package/out/404.html +1 -1
  2. package/out/_next/static/VmMYRhIVl72a4_hcPUaVI/_buildManifest.js +1 -0
  3. package/out/_next/static/chunks/157-fa8b348c960c8283.js +3 -0
  4. package/out/_next/static/chunks/248-43faecb386a16518.js +1 -0
  5. package/out/_next/static/chunks/256-07f768a2b19b0a0e.js +4 -0
  6. package/out/_next/static/chunks/34-8d9d9b2944824750.js +1 -0
  7. package/out/_next/static/chunks/344-fdb3008f4bb3b0c1.js +1 -0
  8. package/out/_next/static/chunks/484-3e011e79c41f0342.js +1 -0
  9. package/out/_next/static/chunks/489-234ed5471aa694b3.js +1 -0
  10. package/out/_next/static/chunks/500-d3989390f5e8da53.js +1 -0
  11. package/out/_next/static/chunks/52d4c156-89c6ec6efca0a0bb.js +1 -0
  12. package/out/_next/static/chunks/630-bb6e3db525588f16.js +1 -0
  13. package/out/_next/static/chunks/pages/{_app-9c512373cecee09f.js → _app-f618a7f60ab6c871.js} +105 -105
  14. package/out/_next/static/chunks/pages/{changelog-3901f2fc937d9648.js → changelog-ba55ed247c20dc21.js} +1 -1
  15. package/out/_next/static/chunks/pages/changes-4c23263cdc8e59c6.js +1 -0
  16. package/out/_next/static/chunks/pages/custom-types/{[customTypeId]-816acb31b652239b.js → [customTypeId]-af9376721beb489e.js} +1 -1
  17. package/out/_next/static/chunks/pages/labs-78ac01d97ab02cd7.js +1 -0
  18. package/out/_next/static/chunks/pages/page-types/{[pageTypeId]-669d5479e81b638b.js → [pageTypeId]-a24665e91b882169.js} +1 -1
  19. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]/simulator-b127d948a17968d3.js +1 -0
  20. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-da423aa0da7bc11e.js +1 -0
  21. package/out/_next/static/chunks/pages/slices-59b857edc9f72d5f.js +1 -0
  22. package/out/_next/static/css/{303dad78be1eb854.css → bc89f2cd4e4781f5.css} +1 -1
  23. package/out/_next/static/css/e8e03c0d4003d1eb.css +1 -0
  24. package/out/changelog.html +1 -1
  25. package/out/changes.html +1 -1
  26. package/out/custom-types/[customTypeId].html +1 -1
  27. package/out/custom-types.html +1 -1
  28. package/out/index.html +1 -1
  29. package/out/labs.html +1 -1
  30. package/out/page-types/[pageTypeId].html +1 -1
  31. package/out/slices/[lib]/[sliceName]/[variation]/simulator.html +1 -1
  32. package/out/slices/[lib]/[sliceName]/[variation].html +1 -1
  33. package/out/slices.html +1 -1
  34. package/package.json +3 -3
  35. package/src/ErrorBoundary.tsx +47 -0
  36. package/src/features/auth/LogoutButton.tsx +36 -42
  37. package/src/features/builder/fields/contentRelationship/ContentRelationshipFieldPicker.tsx +3 -3
  38. package/src/features/changes/StatusBadge.tsx +9 -1
  39. package/src/features/customTypes/customTypesBuilder/PageSnippetDialog/PageSnippetDialog.tsx +3 -3
  40. package/src/features/customTypes/customTypesTable/CustomTypesTablePage.tsx +3 -3
  41. package/src/features/environments/actions/setEnvironment.ts +18 -0
  42. package/src/features/environments/useActiveEnvironment.ts +9 -17
  43. package/src/features/environments/useEnvironments.ts +8 -11
  44. package/src/features/labs/labsList/LabsPage.tsx +3 -3
  45. package/src/features/navigation/Navigation.tsx +8 -7
  46. package/src/features/navigation/RepositoryInfo.tsx +24 -18
  47. package/src/features/slices/sliceBuilder/FloatingBackButton.tsx +3 -3
  48. package/src/features/sync/getUnSyncChanges.ts +3 -1
  49. package/src/legacy/components/AppLayout/index.tsx +85 -10
  50. package/src/legacy/components/ChangesEmptyState/AuthErrorPage.tsx +44 -0
  51. package/src/legacy/components/ChangesEmptyState/index.ts +1 -1
  52. package/src/legacy/components/ChangesItems/ChangesItems.tsx +3 -3
  53. package/src/legacy/components/LoginModal/index.tsx +5 -13
  54. package/src/legacy/components/Navigation/ChangesItem.tsx +48 -96
  55. package/src/legacy/components/Navigation/Environment.tsx +7 -2
  56. package/src/legacy/components/Navigation/SideNavEnvironmentSelector/SideNavEnvironmentSelector.tsx +8 -3
  57. package/src/legacy/components/Simulator/index.tsx +3 -3
  58. package/src/legacy/lib/builders/CustomTypeBuilder/TabZone/index.tsx +3 -3
  59. package/src/modules/userContext/index.ts +3 -6
  60. package/src/modules/userContext/types.ts +1 -1
  61. package/src/pages/_app.tsx +95 -88
  62. package/src/pages/changes.tsx +5 -4
  63. package/test/__testutils__/index.tsx +10 -13
  64. package/out/_next/static/SfM6wNmXllax54gbRXb7m/_buildManifest.js +0 -1
  65. package/out/_next/static/chunks/248-bcf03aa3c62e7dfb.js +0 -1
  66. package/out/_next/static/chunks/34-50c64778da33cff6.js +0 -1
  67. package/out/_next/static/chunks/349-7118116b93278f73.js +0 -4
  68. package/out/_next/static/chunks/429-1137c819c2bf6b66.js +0 -3
  69. package/out/_next/static/chunks/489-77d1fe67b6d0f0f8.js +0 -1
  70. package/out/_next/static/chunks/50-586dc7ab5e584e76.js +0 -1
  71. package/out/_next/static/chunks/630-c34de0401b8a0375.js +0 -1
  72. package/out/_next/static/chunks/pages/changes-62d4e18795217cba.js +0 -1
  73. package/out/_next/static/chunks/pages/labs-5f5c63fb1f7d4b92.js +0 -1
  74. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]/simulator-eca10940c9083d4c.js +0 -1
  75. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-b4700a6332ea828c.js +0 -1
  76. package/out/_next/static/chunks/pages/slices-bf63f937b184b470.js +0 -1
  77. package/out/_next/static/css/cdee5b195444f185.css +0 -1
  78. package/src/errorBoundaries.tsx +0 -150
  79. package/src/features/environments/actions/useSetEnvironment.ts +0 -22
  80. package/src/legacy/components/ChangesEmptyState/UnauthenticatedView.tsx +0 -31
  81. package/src/queryClient.tsx +0 -24
  82. /package/out/_next/static/{SfM6wNmXllax54gbRXb7m → VmMYRhIVl72a4_hcPUaVI}/_ssgManifest.js +0 -0
@@ -9,7 +9,7 @@ import { useRouter } from "next/router";
9
9
  import { Suspense } from "react";
10
10
 
11
11
  import { telemetry } from "@/apiClient";
12
- import { DefaultErrorBoundary } from "@/errorBoundaries";
12
+ import { ErrorBoundary } from "@/ErrorBoundary";
13
13
  import { CUSTOM_TYPES_CONFIG } from "@/features/customTypes/customTypesConfig";
14
14
  import { CUSTOM_TYPES_MESSAGES } from "@/features/customTypes/customTypesMessages";
15
15
  import { RepositoryInfo } from "@/features/navigation/RepositoryInfo";
@@ -86,20 +86,21 @@ export function Navigation() {
86
86
  />
87
87
  </ActionList>
88
88
 
89
- <DefaultErrorBoundary>
89
+ <ErrorBoundary>
90
90
  <Suspense>
91
91
  <UpdateInfo />
92
92
  </Suspense>
93
- </DefaultErrorBoundary>
93
+ </ErrorBoundary>
94
94
  </Box>
95
95
 
96
96
  <Box flexDirection="column">
97
97
  <ActionList variant="compact">
98
- <DefaultErrorBoundary>
98
+ <ErrorBoundary>
99
99
  <Suspense>
100
100
  <OnboardingGuide />
101
101
  </Suspense>
102
- </DefaultErrorBoundary>
102
+ </ErrorBoundary>
103
+
103
104
  <NavigationItem
104
105
  title="Documentation"
105
106
  href={documentationLink}
@@ -135,11 +136,11 @@ export function Navigation() {
135
136
  Icon={LightningIcon}
136
137
  active={router.asPath.startsWith("/changelog")}
137
138
  RightElement={
138
- <DefaultErrorBoundary>
139
+ <ErrorBoundary>
139
140
  <Suspense fallback={<Skeleton height={16} />}>
140
141
  <SliceMachineVersion />
141
142
  </Suspense>
142
- </DefaultErrorBoundary>
143
+ </ErrorBoundary>
143
144
  }
144
145
  />
145
146
  </ActionList>
@@ -14,27 +14,33 @@ export function RepositoryInfo() {
14
14
  const isCollapsed = useMediaQuery({ max: "medium" });
15
15
 
16
16
  return (
17
- <Box justifyContent="center" height={48}>
18
- {!isCollapsed && (
19
- <Box flexGrow={1} flexDirection="column" gap={2} maxWidth="100%">
20
- <Text noWrap component="h1" variant="h3">
17
+ <Box flexDirection="column" gap={2}>
18
+ <Box
19
+ justifyContent={isCollapsed ? "center" : "space-between"}
20
+ alignItems="center"
21
+ gap={2}
22
+ >
23
+ {!isCollapsed && (
24
+ <Text noWrap variant="h3">
21
25
  {repositoryName}
22
26
  </Text>
23
-
24
- <Text noWrap component="h2" variant="small" color="grey11">
25
- {repositoryDomain}
26
- </Text>
27
- </Box>
27
+ )}
28
+ <Tooltip content="Open Prismic repository" side="right">
29
+ <IconButton
30
+ data-testid="prismic-repository-link"
31
+ sx={{ flexShrink: 0 }}
32
+ icon="openInNew"
33
+ onClick={() => {
34
+ window.open(repositoryUrl, "_blank");
35
+ }}
36
+ />
37
+ </Tooltip>
38
+ </Box>
39
+ {!isCollapsed && (
40
+ <Text noWrap variant="small" color="grey11">
41
+ {repositoryDomain}
42
+ </Text>
28
43
  )}
29
- <Tooltip content="Open Prismic repository" side="right">
30
- <IconButton
31
- data-testid="prismic-repository-link"
32
- icon="openInNew"
33
- onClick={() => {
34
- window.open(repositoryUrl, "_blank");
35
- }}
36
- />
37
- </Tooltip>
38
44
  </Box>
39
45
  );
40
46
  }
@@ -2,7 +2,7 @@ import { Box, Button, ButtonGroup } from "@prismicio/editor-ui";
2
2
  import { useRouter } from "next/router";
3
3
  import { type FC, Suspense, useState } from "react";
4
4
 
5
- import { DefaultErrorBoundary } from "@/errorBoundaries";
5
+ import { ErrorBoundary } from "@/ErrorBoundary";
6
6
  import { useCustomType } from "@/features/customTypes/customTypesBuilder/useCustomType";
7
7
  import {
8
8
  CUSTOM_TYPES_CONFIG,
@@ -17,7 +17,7 @@ export const FloatingBackButton: FC = () => {
17
17
  const { source } = useRouteChange();
18
18
  const sourceCustomTypeId = getSourceCustomTypeId(source);
19
19
  return sourceCustomTypeId !== undefined ? (
20
- <DefaultErrorBoundary>
20
+ <ErrorBoundary>
21
21
  <Suspense>
22
22
  <Box
23
23
  bottom={32}
@@ -29,7 +29,7 @@ export const FloatingBackButton: FC = () => {
29
29
  <BackButton sourceCustomTypeId={sourceCustomTypeId} />
30
30
  </Box>
31
31
  </Suspense>
32
- </DefaultErrorBoundary>
32
+ </ErrorBoundary>
33
33
  ) : null;
34
34
  };
35
35
 
@@ -149,7 +149,9 @@ export const getModelStatus = (args: GetModelStatusArgs): ModelsStatuses => {
149
149
  const { slices, customTypes, isOnline, authStatus } = args;
150
150
 
151
151
  const userHasAccessToModels =
152
- isOnline && authStatus === AuthStatus.AUTHORIZED;
152
+ isOnline &&
153
+ authStatus != AuthStatus.FORBIDDEN &&
154
+ authStatus != AuthStatus.UNAUTHORIZED;
153
155
 
154
156
  const modelsStatuses = {
155
157
  slices: computeStatuses(slices, userHasAccessToModels),
@@ -1,6 +1,16 @@
1
- import { Box, Button, ButtonGroup } from "@prismicio/editor-ui";
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";
2
12
  import { useRouter } from "next/router";
3
- import { FC, PropsWithChildren, Suspense } from "react";
13
+ import { FC, PropsWithChildren, Suspense, useState } from "react";
4
14
 
5
15
  import { Breadcrumb } from "@/components/Breadcrumb";
6
16
  import {
@@ -9,6 +19,8 @@ import {
9
19
  PageLayoutHeader,
10
20
  PageLayoutPane,
11
21
  } from "@/components/PageLayout";
22
+ import { ErrorBoundary } from "@/ErrorBoundary";
23
+ import { LogoutButton } from "@/features/auth/LogoutButton";
12
24
  import { useActiveEnvironment } from "@/features/environments/useActiveEnvironment";
13
25
  import { Navigation } from "@/features/navigation/Navigation";
14
26
 
@@ -17,17 +29,80 @@ export const AppLayout: FC<PropsWithChildren> = ({
17
29
  ...otherProps
18
30
  }) => {
19
31
  return (
20
- <Suspense>
21
- <PageLayoutWithActiveEnvironment {...otherProps}>
22
- <PageLayoutPane>
23
- <Navigation />
24
- </PageLayoutPane>
25
- {children}
26
- </PageLayoutWithActiveEnvironment>
27
- </Suspense>
32
+ <ErrorBoundary
33
+ renderError={(error) => {
34
+ return (
35
+ <Box
36
+ position="absolute"
37
+ top={64}
38
+ width="100%"
39
+ justifyContent="center"
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>
28
66
  );
29
67
  };
30
68
 
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
+
31
106
  const environmentTopBorderColorMap = {
32
107
  prod: "purple",
33
108
  stage: "indigo",
@@ -0,0 +1,44 @@
1
+ import { Box, Button, Text } from "@prismicio/editor-ui";
2
+ import React, { FC } from "react";
3
+
4
+ import { AuthStatus } from "@/modules/userContext/types";
5
+ import useSliceMachineActions from "@/modules/useSliceMachineActions";
6
+
7
+ export type AuthErrorPageProps = {
8
+ authStatus: AuthStatus.FORBIDDEN;
9
+ };
10
+
11
+ export const AuthErrorPage: FC<AuthErrorPageProps> = (props) => {
12
+ const { authStatus } = props;
13
+ const { openLoginModal } = useSliceMachineActions();
14
+
15
+ return (
16
+ <Box
17
+ flexDirection="column"
18
+ height="100%"
19
+ alignItems="center"
20
+ justifyContent="center"
21
+ gap={8}
22
+ >
23
+ {authStatus === AuthStatus.FORBIDDEN && (
24
+ <>
25
+ <Text variant="h3" align="center">
26
+ It seems like you are logged out
27
+ </Text>
28
+ <Text align="center">Log in to connect to your repository.</Text>
29
+ </>
30
+ )}
31
+ <Text align="center">
32
+ If that doesn't work, it's possible that Slice Machine is having trouble
33
+ accessing Prismic's servers.{" "}
34
+ <Text href="https://community.prismic.io/">
35
+ Contact our support team
36
+ </Text>
37
+ .
38
+ </Text>
39
+ {authStatus === AuthStatus.FORBIDDEN && (
40
+ <Button onClick={() => openLoginModal()}>Log in to Prismic</Button>
41
+ )}
42
+ </Box>
43
+ );
44
+ };
@@ -1,2 +1,2 @@
1
+ export { AuthErrorPage } from "./AuthErrorPage";
1
2
  export { OfflinePage } from "./OfflinePage";
2
- export { UnauthenticatedView } from "./UnauthenticatedView";
@@ -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 { DefaultErrorBoundary } from "@/errorBoundaries";
6
+ import { ErrorBoundary } from "@/ErrorBoundary";
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
- <DefaultErrorBoundary>
149
+ <ErrorBoundary>
150
150
  <Suspense>
151
151
  <DevCollaborationExperiment />
152
152
  </Suspense>
153
- </DefaultErrorBoundary>
153
+ </ErrorBoundary>
154
154
  </Box>
155
155
  </>
156
156
  );
@@ -1,4 +1,3 @@
1
- import { useQueryClient } from "@tanstack/react-query";
2
1
  import React from "react";
3
2
  import Modal from "react-modal";
4
3
  import { useSelector } from "react-redux";
@@ -16,8 +15,8 @@ import {
16
15
 
17
16
  import { checkAuthStatus, clearAuth, getState } from "@/apiClient";
18
17
  import { getActiveEnvironment } from "@/features/environments/actions/getActiveEnvironment";
19
- import { GetActiveEnvironmentQueryKey } from "@/features/environments/useActiveEnvironment";
20
- import { GetEnvironmentsQueryKey } from "@/features/environments/useEnvironments";
18
+ import { invalidateActiveEnvironmentData } from "@/features/environments/useActiveEnvironment";
19
+ import { invalidateEnvironmentsData } from "@/features/environments/useEnvironments";
21
20
  import { useAutoSync } from "@/features/sync/AutoSyncProvider";
22
21
  import { getUnSyncedChanges } from "@/features/sync/getUnSyncChanges";
23
22
  import SliceMachineModal from "@/legacy/components/SliceMachineModal";
@@ -55,7 +54,6 @@ const LoginModal: React.FunctionComponent = () => {
55
54
  const { syncChanges } = useAutoSync();
56
55
  const { closeModals, startLoadingLogin, stopLoadingLogin, refreshState } =
57
56
  useSliceMachineActions();
58
- const queryClient = useQueryClient();
59
57
 
60
58
  const prismicBase = preferWroomBase(env.manifest.apiEndpoint);
61
59
  const loginRedirectUrl = `${
@@ -81,14 +79,8 @@ const LoginModal: React.FunctionComponent = () => {
81
79
  );
82
80
 
83
81
  // refresh queries to update the UI
84
- await Promise.all([
85
- queryClient.invalidateQueries({
86
- queryKey: GetEnvironmentsQueryKey,
87
- }),
88
- queryClient.invalidateQueries({
89
- queryKey: GetActiveEnvironmentQueryKey,
90
- }),
91
- ]);
82
+ invalidateEnvironmentsData();
83
+ invalidateActiveEnvironmentData();
92
84
 
93
85
  toast.success("Logged in");
94
86
  stopLoadingLogin();
@@ -135,7 +127,7 @@ const LoginModal: React.FunctionComponent = () => {
135
127
 
136
128
  return (
137
129
  <SliceMachineModal
138
- isOpen={isLoginLoading || isOpen}
130
+ isOpen={isOpen}
139
131
  shouldCloseOnOverlayClick
140
132
  onRequestClose={closeModals}
141
133
  contentLabel={"login_modal"}
@@ -9,13 +9,6 @@ import {
9
9
  import { useRouter } from "next/router";
10
10
  import { type FC } from "react";
11
11
 
12
- import {
13
- HoverCard,
14
- HoverCardCloseButton,
15
- HoverCardDescription,
16
- HoverCardMedia,
17
- HoverCardTitle,
18
- } from "@/components/HoverCard";
19
12
  import { useAutoSync } from "@/features/sync/AutoSyncProvider";
20
13
  import { AutoSyncStatusIndicator } from "@/features/sync/components/AutoSyncStatusIndicator";
21
14
  import { useUnSyncChanges } from "@/features/sync/useUnSyncChanges";
@@ -23,87 +16,59 @@ import { useAuthStatus } from "@/hooks/useAuthStatus";
23
16
  import { useNetwork } from "@/hooks/useNetwork";
24
17
  import { ChangesIcon } from "@/icons/ChangesIcon";
25
18
  import { AuthStatus } from "@/modules/userContext/types";
26
- import useSliceMachineActions from "@/modules/useSliceMachineActions";
27
19
 
28
20
  export const ChangesItem: FC = () => {
29
- const { setSeenChangesToolTip } = useSliceMachineActions();
30
- const open = useOpenChangesHoverCard();
31
21
  const router = useRouter();
32
22
  const { autoSyncStatus } = useAutoSync();
33
23
  const collapsed = useMediaQuery({ max: "medium" });
34
24
 
35
- const onClose = () => {
36
- setSeenChangesToolTip();
37
- };
38
-
39
25
  return (
40
- <HoverCard
41
- align="start"
42
- open={open}
43
- openDelay={3000}
44
- onClose={onClose}
45
- side="right"
46
- sideOffset={24}
47
- trigger={
48
- <Box
49
- alignItems={collapsed ? "center" : undefined}
50
- flexDirection="column"
51
- >
52
- {autoSyncStatus === "failed" ||
53
- autoSyncStatus === "synced" ||
54
- autoSyncStatus === "syncing" ? (
55
- <AutoSyncStatusIndicator autoSyncStatus={autoSyncStatus} />
56
- ) : collapsed ? (
57
- <Tooltip content="Review changes" side="right">
58
- <Box position="relative">
59
- {/*
60
- * TODO(DT-1942): This should be an IconButton with a link
61
- * component for accessibility
62
- */}
63
- <IconButton
64
- icon={<ChangesIcon />}
65
- onClick={() => {
66
- void router.push("/changes");
67
- }}
68
- variant="solid"
69
- />
70
- <Box
71
- left="100%"
72
- position="absolute"
73
- top={0}
74
- transform="translate(-50%, -50%)"
75
- >
76
- <ChangesCount color="purple" />
77
- </Box>
78
- </Box>
79
- </Tooltip>
80
- ) : (
81
- // TODO(DT-1942): This should be a Button with a link component for
82
- // accessibility
83
- <Button
84
- color="grey"
26
+ <Box alignItems={collapsed ? "center" : undefined} flexDirection="column">
27
+ {autoSyncStatus === "failed" ||
28
+ autoSyncStatus === "synced" ||
29
+ autoSyncStatus === "syncing" ? (
30
+ <AutoSyncStatusIndicator autoSyncStatus={autoSyncStatus} />
31
+ ) : collapsed ? (
32
+ <Tooltip content="Review changes" side="right">
33
+ <Box position="relative">
34
+ {/*
35
+ * TODO(DT-1942): This should be an IconButton with a link
36
+ * component for accessibility
37
+ */}
38
+ <IconButton
39
+ icon={<ChangesIcon />}
85
40
  onClick={() => {
86
41
  void router.push("/changes");
87
42
  }}
88
- sx={{ width: "100%" }}
43
+ variant="solid"
44
+ />
45
+ <Box
46
+ left="100%"
47
+ position="absolute"
48
+ top={0}
49
+ transform="translate(-50%, -50%)"
89
50
  >
90
- <Box alignItems="center" gap={4}>
91
- <Text variant="bold">Review changes</Text>{" "}
92
- <ChangesCount color="grey" />
93
- </Box>
94
- </Button>
95
- )}
96
- </Box>
97
- }
98
- >
99
- <HoverCardTitle>Push your changes</HoverCardTitle>
100
- <HoverCardMedia component="image" src="/push.png" />
101
- <HoverCardDescription>
102
- When you click Save, your changes are saved locally. Then, you can push
103
- your models to Prismic from the Changes page.
104
- </HoverCardDescription>
105
- <HoverCardCloseButton>Got it</HoverCardCloseButton>
106
- </HoverCard>
51
+ <ChangesCount color="purple" />
52
+ </Box>
53
+ </Box>
54
+ </Tooltip>
55
+ ) : (
56
+ // TODO(DT-1942): This should be a Button with a link component for
57
+ // accessibility
58
+ <Button
59
+ color="grey"
60
+ onClick={() => {
61
+ void router.push("/changes");
62
+ }}
63
+ sx={{ width: "100%" }}
64
+ >
65
+ <Box alignItems="center" gap={4}>
66
+ <Text variant="bold">Review changes</Text>{" "}
67
+ <ChangesCount color="grey" />
68
+ </Box>
69
+ </Button>
70
+ )}
71
+ </Box>
107
72
  );
108
73
  };
109
74
 
@@ -117,12 +82,16 @@ export const ChangesCount: FC<ChangesCountProps> = ({ color }) => {
117
82
 
118
83
  if (
119
84
  !isOnline ||
120
- authStatus !== AuthStatus.AUTHORIZED ||
121
- numberOfChanges === 0
85
+ authStatus === AuthStatus.UNAUTHORIZED ||
86
+ authStatus === AuthStatus.FORBIDDEN
122
87
  ) {
123
88
  return null;
124
89
  }
125
90
 
91
+ if (numberOfChanges === 0) {
92
+ return null;
93
+ }
94
+
126
95
  const formattedNumberOfChanges = numberOfChanges > 9 ? "+9" : numberOfChanges;
127
96
 
128
97
  return (
@@ -137,20 +106,3 @@ export const ChangesCount: FC<ChangesCountProps> = ({ color }) => {
137
106
  </Box>
138
107
  );
139
108
  };
140
-
141
- // TODO(DT-1925): Reactivate this feature
142
- const useOpenChangesHoverCard = () => {
143
- // const { hasSeenChangesToolTip, hasSeenSimulatorToolTip } = useSelector(
144
- // (store: SliceMachineStoreType) => ({
145
- // hasSeenChangesToolTip: userHasSeenChangesToolTip(store),
146
- // hasSeenSimulatorToolTip: userHasSeenSimulatorToolTip(store),
147
- // }),
148
- // );
149
-
150
- // return (
151
- // !hasSeenChangesToolTip &&
152
- // hasSeenSimulatorToolTip
153
- // );
154
-
155
- return false;
156
- };
@@ -5,7 +5,7 @@ import {
5
5
  import { useState } from "react";
6
6
 
7
7
  import { getState, telemetry } from "@/apiClient";
8
- import { useSetEnvironment } from "@/features/environments/actions/useSetEnvironment";
8
+ import { setEnvironment } from "@/features/environments/actions/setEnvironment";
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,7 +28,6 @@ export function Environment() {
28
28
  const authStatus = useAuthStatus();
29
29
  const [isSwitchingEnv, setIsSwitchingEnv] = useState(false);
30
30
  const { autoSyncStatus } = useAutoSync();
31
- const setEnvironment = useSetEnvironment();
32
31
 
33
32
  async function onSelect(environment: EnvironmentType) {
34
33
  if (activeEnvironment?.name === environment.name) {
@@ -106,4 +105,10 @@ export function Environment() {
106
105
  />
107
106
  );
108
107
  }
108
+
109
+ if (useEnvironmentsError !== undefined) {
110
+ throw useEnvironmentsError;
111
+ }
112
+
113
+ throw activeEnvironmentError;
109
114
  }
@@ -17,8 +17,9 @@ 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";
20
21
 
21
- import { EnvironmentLogoutButton } from "@/features/auth/LogoutButton";
22
+ import { LogoutButton } from "@/features/auth/LogoutButton";
22
23
  import { LoginIcon } from "@/icons/LoginIcon";
23
24
  import { LogoIcon } from "@/icons/LogoIcon";
24
25
 
@@ -29,7 +30,7 @@ type SideNavEnvironmentSelectorProps = {
29
30
  disabled?: boolean;
30
31
  environments?: Environment[];
31
32
  loading?: boolean;
32
- variant?: "default" | "offline" | "unauthenticated";
33
+ variant?: "default" | "offline" | "unauthorized" | "unauthenticated";
33
34
  onLogInClick?: () => void;
34
35
  onSelect?: (environment: Environment) => void | Promise<void>;
35
36
  };
@@ -140,7 +141,11 @@ export const SideNavEnvironmentSelector: FC<SideNavEnvironmentSelectorProps> = (
140
141
  />
141
142
  ) : undefined}
142
143
 
143
- {variant === "default" && <EnvironmentLogoutButton />}
144
+ {variant === "default" && (
145
+ <LogoutButton
146
+ onLogoutSuccess={() => toast.success("Logged out")}
147
+ />
148
+ )}
144
149
  </Box>
145
150
  </>
146
151
  )}
@@ -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 { DefaultErrorBoundary } from "@/errorBoundaries";
20
+ import { ErrorBoundary } from "@/ErrorBoundary";
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
- <DefaultErrorBoundary
290
+ <ErrorBoundary
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
- </DefaultErrorBoundary>
318
+ </ErrorBoundary>
319
319
  </Flex>
320
320
  ) : null}
321
321
  </Flex>