slice-machine-ui 2.18.1-alpha.jp-unauthorized-error.3 → 2.18.1-alpha.jp-unauthorized-error-improvement.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.
- package/out/404.html +1 -1
- package/out/_next/static/{6PcBvU_g2QBnuMafU4iYu → bWd9YPY0k1NsrjJCNbscH}/_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-2fd7ba7c1a132cb4.js → _app-d298cdfd4509fb06.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/{6PcBvU_g2QBnuMafU4iYu → bWd9YPY0k1NsrjJCNbscH}/_ssgManifest.js +0 -0
package/src/pages/_app.tsx
CHANGED
|
@@ -13,34 +13,33 @@ import "@/styles/starry-night.css";
|
|
|
13
13
|
import "@/styles/tabs.css";
|
|
14
14
|
import "@/styles/toaster.css";
|
|
15
15
|
|
|
16
|
+
import { ThemeProvider, TooltipProvider } from "@prismicio/editor-ui";
|
|
16
17
|
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
} from "
|
|
22
|
-
import { ConnectedRouter } from "connected-next-router";
|
|
18
|
+
isInvalidActiveEnvironmentError,
|
|
19
|
+
isUnauthorizedError,
|
|
20
|
+
} from "@slicemachine/manager/client";
|
|
21
|
+
import { useSuspenseQuery } from "@tanstack/react-query";
|
|
22
|
+
import { ConnectedRouter as StoreConnectedRouter } from "connected-next-router";
|
|
23
23
|
import type { NextPage } from "next";
|
|
24
24
|
import type { AppContext, AppInitialProps } from "next/app";
|
|
25
25
|
import dynamic from "next/dynamic";
|
|
26
26
|
import Head from "next/head";
|
|
27
27
|
import Router from "next/router";
|
|
28
|
-
import { type FC, type ReactNode, Suspense, useEffect
|
|
28
|
+
import { type FC, type ReactNode, Suspense, useEffect } from "react";
|
|
29
29
|
import { Provider } from "react-redux";
|
|
30
|
-
import type { Store } from "redux";
|
|
31
|
-
import type { Persistor } from "redux-persist/es/types";
|
|
32
30
|
import { PersistGate } from "redux-persist/integration/react";
|
|
33
31
|
import { ThemeProvider as ThemeUIThemeProvider, useThemeUI } from "theme-ui";
|
|
34
32
|
|
|
35
33
|
import { getState } from "@/apiClient";
|
|
36
|
-
import {
|
|
34
|
+
import { AppStateErrorBoundary } from "@/errorBoundaries";
|
|
35
|
+
import { useActiveEnvironment } from "@/features/environments/useActiveEnvironment";
|
|
37
36
|
import { AutoSyncProvider } from "@/features/sync/AutoSyncProvider";
|
|
38
37
|
import { RouteChangeProvider } from "@/hooks/useRouteChange";
|
|
39
38
|
import SliceMachineApp from "@/legacy/components/App";
|
|
40
39
|
import LoadingPage from "@/legacy/components/LoadingPage";
|
|
41
40
|
import ToastContainer from "@/legacy/components/ToasterContainer";
|
|
42
41
|
import { normalizeFrontendCustomTypes } from "@/legacy/lib/models/common/normalizers/customType";
|
|
43
|
-
import
|
|
42
|
+
import { QueryClientProvider } from "@/queryClient";
|
|
44
43
|
import configureStore from "@/redux/store";
|
|
45
44
|
import theme from "@/theme";
|
|
46
45
|
|
|
@@ -68,50 +67,11 @@ const RemoveDarkMode: FC<RemoveDarkModeProps> = ({ children }) => {
|
|
|
68
67
|
return <>{children}</>;
|
|
69
68
|
};
|
|
70
69
|
|
|
71
|
-
function App({
|
|
72
|
-
|
|
73
|
-
pageProps
|
|
74
|
-
}: AppContextWithComponentLayout & AppInitialProps) {
|
|
75
|
-
const [serverState, setServerState] = useState<ServerState | null>(null);
|
|
76
|
-
const [smStore, setSMStore] = useState<{
|
|
77
|
-
store: Store;
|
|
78
|
-
persistor: Persistor;
|
|
79
|
-
} | null>(null);
|
|
70
|
+
function App(props: AppContextWithComponentLayout & AppInitialProps) {
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
72
|
+
const { Component, pageProps } = props;
|
|
80
73
|
|
|
81
|
-
|
|
82
|
-
async function getInitialState() {
|
|
83
|
-
const serverState = await getState();
|
|
84
|
-
setServerState(serverState);
|
|
85
|
-
}
|
|
86
|
-
void getInitialState();
|
|
87
|
-
}, []);
|
|
88
|
-
|
|
89
|
-
useEffect(() => {
|
|
90
|
-
if (!serverState || smStore) {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const normalizedCustomTypes = normalizeFrontendCustomTypes(
|
|
95
|
-
serverState.customTypes,
|
|
96
|
-
serverState.remoteCustomTypes,
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
const { store, persistor } = configureStore({
|
|
100
|
-
environment: serverState.env,
|
|
101
|
-
availableCustomTypes: {
|
|
102
|
-
...normalizedCustomTypes,
|
|
103
|
-
},
|
|
104
|
-
slices: {
|
|
105
|
-
libraries: serverState.libraries,
|
|
106
|
-
remoteSlices: serverState.remoteSlices,
|
|
107
|
-
},
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
setSMStore({ store, persistor });
|
|
111
|
-
}, [serverState, smStore]);
|
|
112
|
-
|
|
113
|
-
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
114
|
-
const ComponentLayout = Component.CustomLayout || SliceMachineApp;
|
|
74
|
+
const ComponentLayout = Component.CustomLayout ?? SliceMachineApp;
|
|
115
75
|
|
|
116
76
|
return (
|
|
117
77
|
<>
|
|
@@ -119,50 +79,83 @@ function App({
|
|
|
119
79
|
<title>Slice Machine</title>
|
|
120
80
|
</Head>
|
|
121
81
|
<ThemeUIThemeProvider theme={theme}>
|
|
122
|
-
<
|
|
123
|
-
<
|
|
124
|
-
<
|
|
125
|
-
|
|
126
|
-
<
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
>
|
|
145
|
-
<Suspense fallback={<LoadingPage />}>
|
|
146
|
-
<AutoSyncProvider>
|
|
147
|
-
<RouteChangeProvider>
|
|
148
|
-
<ComponentLayout>
|
|
149
|
-
<Component {...pageProps} />
|
|
150
|
-
</ComponentLayout>
|
|
151
|
-
</RouteChangeProvider>
|
|
152
|
-
</AutoSyncProvider>
|
|
153
|
-
</Suspense>
|
|
154
|
-
</ErrorBoundary>
|
|
155
|
-
</PersistGate>
|
|
156
|
-
</ConnectedRouter>
|
|
157
|
-
<ToastContainer />
|
|
158
|
-
</Provider>
|
|
159
|
-
)}
|
|
160
|
-
</TooltipProvider>
|
|
161
|
-
</ThemeProvider>
|
|
162
|
-
</RemoveDarkMode>
|
|
82
|
+
<QueryClientProvider>
|
|
83
|
+
<RemoveDarkMode>
|
|
84
|
+
<ThemeProvider mode="light">
|
|
85
|
+
<TooltipProvider>
|
|
86
|
+
<AppStateErrorBoundary>
|
|
87
|
+
<Suspense fallback={<LoadingPage />}>
|
|
88
|
+
<AppStateValidator>
|
|
89
|
+
<AppStateWrapper>
|
|
90
|
+
<AutoSyncProvider>
|
|
91
|
+
<ComponentLayout>
|
|
92
|
+
<Component {...pageProps} />
|
|
93
|
+
</ComponentLayout>
|
|
94
|
+
</AutoSyncProvider>
|
|
95
|
+
</AppStateWrapper>
|
|
96
|
+
</AppStateValidator>
|
|
97
|
+
</Suspense>
|
|
98
|
+
</AppStateErrorBoundary>
|
|
99
|
+
<ToastContainer />
|
|
100
|
+
</TooltipProvider>
|
|
101
|
+
</ThemeProvider>
|
|
102
|
+
</RemoveDarkMode>
|
|
103
|
+
</QueryClientProvider>
|
|
163
104
|
</ThemeUIThemeProvider>
|
|
164
105
|
</>
|
|
165
106
|
);
|
|
166
107
|
}
|
|
167
108
|
|
|
109
|
+
/** This is where we should check for unwanted states that should prevent the
|
|
110
|
+
* user from using the app, and trigger the {@link AppStateErrorBoundary} to
|
|
111
|
+
* display something explaining why. */
|
|
112
|
+
function AppStateValidator(props: { children: ReactNode }) {
|
|
113
|
+
const activeEnvironment = useActiveEnvironment({ suspense: true });
|
|
114
|
+
|
|
115
|
+
if (
|
|
116
|
+
isUnauthorizedError(activeEnvironment.error) ||
|
|
117
|
+
isInvalidActiveEnvironmentError(activeEnvironment.error)
|
|
118
|
+
) {
|
|
119
|
+
throw activeEnvironment.error;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return <>{props.children}</>;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function AppStateWrapper({ children }: { children: ReactNode }) {
|
|
126
|
+
const { data: state } = useSuspenseQuery({
|
|
127
|
+
queryKey: ["getInitialState"],
|
|
128
|
+
queryFn: async () => {
|
|
129
|
+
const serverState = await getState();
|
|
130
|
+
const { store, persistor } = configureStore({
|
|
131
|
+
environment: serverState.env,
|
|
132
|
+
availableCustomTypes: {
|
|
133
|
+
...normalizeFrontendCustomTypes(
|
|
134
|
+
serverState.customTypes,
|
|
135
|
+
serverState.remoteCustomTypes,
|
|
136
|
+
),
|
|
137
|
+
},
|
|
138
|
+
slices: {
|
|
139
|
+
libraries: serverState.libraries,
|
|
140
|
+
remoteSlices: serverState.remoteSlices,
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
return { serverState, store, persistor };
|
|
145
|
+
},
|
|
146
|
+
staleTime: Infinity,
|
|
147
|
+
gcTime: Infinity,
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
return (
|
|
151
|
+
<Provider store={state.store}>
|
|
152
|
+
<StoreConnectedRouter Router={Router}>
|
|
153
|
+
<PersistGate loading={null} persistor={state.persistor}>
|
|
154
|
+
<RouteChangeProvider>{children}</RouteChangeProvider>
|
|
155
|
+
</PersistGate>
|
|
156
|
+
</StoreConnectedRouter>
|
|
157
|
+
</Provider>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
168
161
|
export default dynamic(() => Promise.resolve(App), { ssr: false });
|
package/src/pages/changes.tsx
CHANGED
|
@@ -25,8 +25,8 @@ import {
|
|
|
25
25
|
AppLayoutHeader,
|
|
26
26
|
} from "@/legacy/components/AppLayout";
|
|
27
27
|
import {
|
|
28
|
-
AuthErrorPage,
|
|
29
28
|
OfflinePage,
|
|
29
|
+
UnauthenticatedView,
|
|
30
30
|
} from "@/legacy/components/ChangesEmptyState";
|
|
31
31
|
import { ChangesItems } from "@/legacy/components/ChangesItems";
|
|
32
32
|
import {
|
|
@@ -114,8 +114,8 @@ const Changes: React.FunctionComponent = () => {
|
|
|
114
114
|
if (!isOnline) {
|
|
115
115
|
return <OfflinePage />;
|
|
116
116
|
}
|
|
117
|
-
if (authStatus === AuthStatus.
|
|
118
|
-
return <
|
|
117
|
+
if (authStatus === AuthStatus.UNAUTHENTICATED) {
|
|
118
|
+
return <UnauthenticatedView />;
|
|
119
119
|
}
|
|
120
120
|
if (numberOfChanges === 0) {
|
|
121
121
|
return (
|
|
@@ -160,8 +160,7 @@ const Changes: React.FunctionComponent = () => {
|
|
|
160
160
|
disabled={
|
|
161
161
|
numberOfChanges === 0 ||
|
|
162
162
|
!isOnline ||
|
|
163
|
-
authStatus
|
|
164
|
-
authStatus === AuthStatus.FORBIDDEN ||
|
|
163
|
+
authStatus !== AuthStatus.AUTHORIZED ||
|
|
165
164
|
isSyncing
|
|
166
165
|
}
|
|
167
166
|
loading={isSyncing}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
QueryClient,
|
|
3
|
+
QueryClientProvider as RCQueryClientProvider,
|
|
4
|
+
} from "@tanstack/react-query";
|
|
5
|
+
import { ReactNode } from "react";
|
|
6
|
+
|
|
7
|
+
export const queryClient = new QueryClient({
|
|
8
|
+
defaultOptions: {
|
|
9
|
+
queries: {
|
|
10
|
+
staleTime: 5 * 60 * 1000,
|
|
11
|
+
gcTime: 10 * 60 * 1000,
|
|
12
|
+
retry: false,
|
|
13
|
+
refetchOnWindowFocus: "always",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export function QueryClientProvider(props: { children: ReactNode }) {
|
|
19
|
+
return (
|
|
20
|
+
<RCQueryClientProvider client={queryClient}>
|
|
21
|
+
{props.children}
|
|
22
|
+
</RCQueryClientProvider>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
@@ -5,7 +5,8 @@ import { Provider } from "react-redux";
|
|
|
5
5
|
import { AnyAction, Store } from "redux";
|
|
6
6
|
import { BaseStyles, ThemeProvider as ThemeUIThemeProvider } from "theme-ui";
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { DefaultErrorBoundary } from "@/errorBoundaries";
|
|
9
|
+
import { QueryClientProvider } from "@/queryClient";
|
|
9
10
|
|
|
10
11
|
import configureStore from "../../src/redux/store";
|
|
11
12
|
import type { SliceMachineStoreType } from "../../src/redux/type";
|
|
@@ -44,15 +45,17 @@ function render(
|
|
|
44
45
|
children: any;
|
|
45
46
|
}) {
|
|
46
47
|
return (
|
|
47
|
-
<
|
|
48
|
-
<
|
|
49
|
-
<
|
|
50
|
-
<
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
48
|
+
<QueryClientProvider>
|
|
49
|
+
<ThemeUIThemeProvider theme={theme}>
|
|
50
|
+
<TooltipProvider>
|
|
51
|
+
<BaseStyles>
|
|
52
|
+
<Provider store={store}>
|
|
53
|
+
<DefaultErrorBoundary>{children}</DefaultErrorBoundary>
|
|
54
|
+
</Provider>
|
|
55
|
+
</BaseStyles>
|
|
56
|
+
</TooltipProvider>
|
|
57
|
+
</ThemeUIThemeProvider>
|
|
58
|
+
</QueryClientProvider>
|
|
56
59
|
);
|
|
57
60
|
}
|
|
58
61
|
return {
|