slice-machine-ui 1.15.1-dev-next-release.1 → 1.15.1-dev-next-release.3
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/components/ChangesItems/ChangesItems.tsx +16 -25
- package/components/CustomTypeTable/changesPage.tsx +4 -6
- package/components/Forms/CreateCustomTypeModal/CreateCustomTypeModal.tsx +3 -0
- package/lib/builders/CustomTypeBuilder/SliceZone/List.tsx +26 -32
- package/lib/builders/CustomTypeBuilder/SliceZone/SlicesTemplatesModal.tsx +1 -0
- package/lib/builders/CustomTypeBuilder/SliceZone/UpdateSliceZoneModal.tsx +1 -0
- package/lib/builders/CustomTypeBuilder/SliceZone/UpdateSliceZoneModalList.tsx +23 -76
- package/next.config.mjs +1 -0
- package/out/404.html +1 -1
- package/out/[lib]/[sliceName]/[variation]/screenshot.html +1 -1
- package/out/[lib]/[sliceName]/[variation]/simulator.html +1 -1
- package/out/[lib]/[sliceName]/[variation].html +1 -1
- package/out/_next/static/chunks/14-90eaa126dcf1b635.js +1 -0
- package/out/_next/static/chunks/{377-3caacee3c3ffdc25.js → 377-467ca51a57342a23.js} +1 -1
- package/out/_next/static/chunks/{573-e92018662d1f6c26.js → 573-8678a91b09707f5d.js} +1 -1
- package/out/_next/static/chunks/590-d9046f10fcc34a4d.js +1 -0
- package/out/_next/static/chunks/840-d84a2655185995ce.js +1 -0
- package/out/_next/static/chunks/{97-f6188ebe22eb21da.js → 97-ee2fa6c3e6bf7b71.js} +1 -1
- package/out/_next/static/chunks/pages/[lib]/[sliceName]/[variation]/{simulator-c608e0470a8f6099.js → simulator-47ba090193469e3f.js} +1 -1
- package/out/_next/static/chunks/pages/[lib]/[sliceName]/[variation]-89838e684fcaaf5d.js +1 -0
- package/out/_next/static/chunks/pages/{_app-50e4bd906b82c68e.js → _app-f7e14ddd3e363991.js} +9 -9
- package/out/_next/static/chunks/pages/changes-c62c4ac5de9a1a09.js +1 -0
- package/out/_next/static/chunks/pages/custom-types/{[customTypeId]-9ba8a3f68a048222.js → [customTypeId]-1baa6af0ddf0ab6b.js} +1 -1
- package/out/_next/static/chunks/pages/custom-types-78e57821222c9603.js +1 -0
- package/out/_next/static/chunks/pages/index-d3da65c8b508c26e.js +1 -0
- package/out/_next/static/chunks/pages/page-types/{[pageTypeId]-3144fdf0c6f9af94.js → [pageTypeId]-708b782db680b804.js} +1 -1
- package/out/_next/static/chunks/pages/slices-15b69ac3611efbfe.js +1 -0
- package/out/_next/static/css/22d69420bda374a7.css +1 -0
- package/out/_next/static/css/{b6bfe1e0ef76c2b1.css → 9ddd0cb7fff63603.css} +1 -1
- package/out/_next/static/css/f585032018f6024b.css +1 -0
- package/out/_next/static/pA_sw-x2_QsAanOp1Lx0c/_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/page-types/[pageTypeId].html +1 -1
- package/out/slices.html +1 -1
- package/package.json +4 -4
- package/pages/_app.tsx +37 -5
- package/pages/index.tsx +8 -0
- package/pages/slices.tsx +25 -42
- package/src/domain/slice.ts +38 -0
- package/src/features/changes/StatusBadge.tsx +107 -0
- package/src/features/customTypes/PageTypeOnboarding.tsx +60 -0
- package/src/features/customTypes/customTypesBuilder/SliceZoneBlankSlate.tsx +2 -2
- package/src/features/slices/sliceCards/NonSharedSliceViewCard.tsx +39 -0
- package/src/features/slices/sliceCards/SharedSliceSelectionCard.tsx +80 -0
- package/src/features/slices/sliceCards/SharedSliceViewCard.tsx +147 -0
- package/src/hooks/useIsEmptyProject.ts +24 -0
- package/src/icons/BlankPageIcon.tsx +58 -0
- package/src/icons/SliceMachinePrinterIcon.tsx +69 -0
- package/src/modules/pushChangesSaga/trackPushChangesSuccess.ts +1 -1
- package/test/components/CreateCustomTypeModal.test.tsx +1 -0
- package/test/pages/custom-types.test.tsx +1 -1
- package/test/pages/slices.test.tsx +2 -2
- package/components/KebabMenuDropdown/KebabMenuList.tsx +0 -71
- package/components/KebabMenuDropdown/index.tsx +0 -64
- package/components/StatusBadge/index.tsx +0 -139
- package/lib/models/ui/Link.ts +0 -23
- package/lib/models/ui/Slice/LegacySliceTooltip.module.css +0 -10
- package/lib/models/ui/Slice/index.tsx +0 -424
- package/lib/models/ui/Slice/wrappers.tsx +0 -49
- package/lib/models/ui/Store.ts +0 -10
- package/out/_next/static/chunks/323-9843d325f7ff6913.js +0 -1
- package/out/_next/static/chunks/482-93d7a0d3a0353f59.js +0 -1
- package/out/_next/static/chunks/906-9224feb63b5e36f3.js +0 -1
- package/out/_next/static/chunks/pages/[lib]/[sliceName]/[variation]-36ba0bde8415ad8b.js +0 -1
- package/out/_next/static/chunks/pages/changes-8338c9d0723a7033.js +0 -1
- package/out/_next/static/chunks/pages/custom-types-abb8c8c92880120e.js +0 -1
- package/out/_next/static/chunks/pages/index-f382c8090bd21628.js +0 -1
- package/out/_next/static/chunks/pages/slices-afa4b34df8f8e1c3.js +0 -1
- package/out/_next/static/css/6b6c11ed1fffd3e0.css +0 -1
- package/out/_next/static/css/e855bef88bb5345b.css +0 -1
- package/out/_next/static/l5qzy_xQjzd7ei5tL_M1r/_buildManifest.js +0 -1
- package/src/icons/LightningIcon3D.tsx +0 -49
- package/src/models/ApiError.ts +0 -6
- package/src/models/SyncError.ts +0 -3
- package/src/utils/screenshots/missing.ts +0 -4
- package/test/src/utils/screenshots/missing.test.ts +0 -51
- /package/out/_next/static/{l5qzy_xQjzd7ei5tL_M1r → pA_sw-x2_QsAanOp1Lx0c}/_ssgManifest.js +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slice-machine-ui",
|
|
3
|
-
"version": "1.15.1-dev-next-release.
|
|
3
|
+
"version": "1.15.1-dev-next-release.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "A visual builder for your Slice Models with all the tools you need to generate data models and mock CMS content locally.",
|
|
6
6
|
"repository": {
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"start-slicemachine": "./bin/start-slicemachine.cjs"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@slicemachine/manager": "^0.12.1-dev-next-release.
|
|
35
|
-
"start-slicemachine": "^0.11.9-dev-next-release.
|
|
34
|
+
"@slicemachine/manager": "^0.12.1-dev-next-release.3",
|
|
35
|
+
"start-slicemachine": "^0.11.9-dev-next-release.3"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@emotion/react": "11.11.1",
|
|
@@ -130,5 +130,5 @@
|
|
|
130
130
|
"vitest": "0.32.0",
|
|
131
131
|
"yup": "0.32.11"
|
|
132
132
|
},
|
|
133
|
-
"gitHead": "
|
|
133
|
+
"gitHead": "a1e4151a6086f7b177bcd25e6aa674fcb0af5c7c"
|
|
134
134
|
}
|
package/pages/_app.tsx
CHANGED
|
@@ -14,19 +14,27 @@ import "@src/styles/starry-night.css";
|
|
|
14
14
|
import "@src/styles/tabs.css";
|
|
15
15
|
import "@src/styles/toaster.css";
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
Box,
|
|
19
|
+
DefaultErrorMessage,
|
|
20
|
+
ErrorBoundary,
|
|
21
|
+
ThemeProvider,
|
|
22
|
+
TooltipProvider,
|
|
23
|
+
} from "@prismicio/editor-ui";
|
|
18
24
|
import { ConnectedRouter } from "connected-next-router";
|
|
19
25
|
import type { NextPage } from "next";
|
|
20
26
|
import App, { type AppContext, type AppInitialProps } from "next/app";
|
|
21
27
|
import Head from "next/head";
|
|
22
28
|
import Router from "next/router";
|
|
23
|
-
import { type FC, type ReactNode, useEffect, useState } from "react";
|
|
29
|
+
import { type FC, type ReactNode, useEffect, useState, Suspense } from "react";
|
|
24
30
|
import { Provider } from "react-redux";
|
|
25
31
|
import type { Store } from "redux";
|
|
26
32
|
import type { Persistor } from "redux-persist/es/types";
|
|
27
33
|
import { PersistGate } from "redux-persist/integration/react";
|
|
28
34
|
import { ThemeProvider as ThemeUIThemeProvider, useThemeUI } from "theme-ui";
|
|
29
35
|
|
|
36
|
+
import { AppLayout, AppLayoutContent } from "@components/AppLayout";
|
|
37
|
+
|
|
30
38
|
import SliceMachineApp from "../components/App";
|
|
31
39
|
import LoadingPage from "../components/LoadingPage";
|
|
32
40
|
import ToastContainer from "../components/ToasterContainer";
|
|
@@ -122,9 +130,33 @@ function MyApp({
|
|
|
122
130
|
<ConnectedRouter Router={Router}>
|
|
123
131
|
<PersistGate loading={null} persistor={smStore.persistor}>
|
|
124
132
|
<RouteChangeProvider>
|
|
125
|
-
<
|
|
126
|
-
|
|
127
|
-
|
|
133
|
+
<ErrorBoundary
|
|
134
|
+
renderError={(error) => {
|
|
135
|
+
console.error(error);
|
|
136
|
+
|
|
137
|
+
return (
|
|
138
|
+
<AppLayout>
|
|
139
|
+
<AppLayoutContent>
|
|
140
|
+
<Box
|
|
141
|
+
alignItems="center"
|
|
142
|
+
justifyContent="center"
|
|
143
|
+
>
|
|
144
|
+
<DefaultErrorMessage
|
|
145
|
+
title="Error"
|
|
146
|
+
description="An error occurred while rendering the app."
|
|
147
|
+
/>
|
|
148
|
+
</Box>
|
|
149
|
+
</AppLayoutContent>
|
|
150
|
+
</AppLayout>
|
|
151
|
+
);
|
|
152
|
+
}}
|
|
153
|
+
>
|
|
154
|
+
<Suspense fallback={<LoadingPage />}>
|
|
155
|
+
<ComponentLayout>
|
|
156
|
+
<Component {...pageProps} />
|
|
157
|
+
</ComponentLayout>
|
|
158
|
+
</Suspense>
|
|
159
|
+
</ErrorBoundary>
|
|
128
160
|
</RouteChangeProvider>
|
|
129
161
|
</PersistGate>
|
|
130
162
|
</ConnectedRouter>
|
package/pages/index.tsx
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import { type FC } from "react";
|
|
2
2
|
|
|
3
3
|
import { CustomTypesTablePage as CustomTypesTablePageTemplate } from "@src/features/customTypes/customTypesTable/CustomTypesTablePage";
|
|
4
|
+
import { PageTypeOnboarding } from "@src/features/customTypes/PageTypeOnboarding";
|
|
5
|
+
import { useIsEmptyProject } from "@src/hooks/useIsEmptyProject";
|
|
4
6
|
|
|
5
7
|
const PageTypesTablePage: FC = () => {
|
|
8
|
+
const isEmptyProject = useIsEmptyProject();
|
|
9
|
+
|
|
10
|
+
if (isEmptyProject) {
|
|
11
|
+
return <PageTypeOnboarding />;
|
|
12
|
+
}
|
|
13
|
+
|
|
6
14
|
return <CustomTypesTablePageTemplate format="page" />;
|
|
7
15
|
};
|
|
8
16
|
|
package/pages/slices.tsx
CHANGED
|
@@ -9,7 +9,6 @@ import { SharedSlice as SharedSliceType } from "@prismicio/types-internal/lib/cu
|
|
|
9
9
|
|
|
10
10
|
import { ComponentUI } from "@lib/models/common/ComponentUI";
|
|
11
11
|
import { LibraryUI } from "@lib/models/common/LibraryUI";
|
|
12
|
-
import { SharedSlice } from "@lib/models/ui/Slice";
|
|
13
12
|
import { VIDEO_WHAT_ARE_SLICES } from "@lib/consts";
|
|
14
13
|
import {
|
|
15
14
|
AppLayout,
|
|
@@ -26,13 +25,9 @@ import { RenameSliceModal } from "@components/Forms/RenameSliceModal";
|
|
|
26
25
|
import { DeleteSliceModal } from "@components/DeleteSliceModal";
|
|
27
26
|
import { SliceMachineStoreType } from "@src/redux/type";
|
|
28
27
|
import useSliceMachineActions from "@src/modules/useSliceMachineActions";
|
|
29
|
-
import {
|
|
30
|
-
getFrontendSlices,
|
|
31
|
-
getLibraries,
|
|
32
|
-
getRemoteSlices,
|
|
33
|
-
} from "@src/modules/slices";
|
|
34
|
-
import { useModelStatus } from "@src/hooks/useModelStatus";
|
|
28
|
+
import { getLibraries, getRemoteSlices } from "@src/modules/slices";
|
|
35
29
|
import { useScreenshotChangesModal } from "@src/hooks/useScreenshotChangesModal";
|
|
30
|
+
import { SharedSliceViewCard } from "@src/features/slices/sliceCards/SharedSliceViewCard";
|
|
36
31
|
import { SLICES_CONFIG } from "@src/features/slices/slicesConfig";
|
|
37
32
|
import { SliceToastMessage } from "@components/ToasterContainer";
|
|
38
33
|
|
|
@@ -45,11 +40,10 @@ const SlicesIndex: React.FunctionComponent = () => {
|
|
|
45
40
|
|
|
46
41
|
const { sliceFilterFn, defaultVariationSelector } = modalPayload;
|
|
47
42
|
|
|
48
|
-
const { remoteSlices, libraries
|
|
43
|
+
const { remoteSlices, libraries } = useSelector(
|
|
49
44
|
(store: SliceMachineStoreType) => ({
|
|
50
45
|
remoteSlices: getRemoteSlices(store),
|
|
51
46
|
libraries: getLibraries(store),
|
|
52
|
-
frontendSlices: getFrontendSlices(store),
|
|
53
47
|
})
|
|
54
48
|
);
|
|
55
49
|
const [isCreateSliceModalOpen, setIsCreateSliceModalOpen] = useState(false);
|
|
@@ -65,10 +59,6 @@ const SlicesIndex: React.FunctionComponent = () => {
|
|
|
65
59
|
return library;
|
|
66
60
|
});
|
|
67
61
|
|
|
68
|
-
const { modelsStatuses, authStatus, isOnline } = useModelStatus({
|
|
69
|
-
slices: frontendSlices,
|
|
70
|
-
});
|
|
71
|
-
|
|
72
62
|
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
73
63
|
const slices = (libraries || []).map((l) => l.components).flat();
|
|
74
64
|
const sliceCount = slices.length;
|
|
@@ -179,39 +169,32 @@ const SlicesIndex: React.FunctionComponent = () => {
|
|
|
179
169
|
</Flex>
|
|
180
170
|
<Grid
|
|
181
171
|
elems={components}
|
|
182
|
-
defineElementKey={(slice
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
StatusOrCustom: {
|
|
189
|
-
status: modelsStatuses.slices[slice.model.id],
|
|
190
|
-
authStatus,
|
|
191
|
-
isOnline,
|
|
192
|
-
},
|
|
193
|
-
actions: {
|
|
194
|
-
onUpdateScreenshot: (e: React.MouseEvent) => {
|
|
195
|
-
e.preventDefault();
|
|
196
|
-
onOpenModal({
|
|
197
|
-
sliceFilterFn: (s: ComponentUI[]) =>
|
|
198
|
-
s.filter(
|
|
199
|
-
(e) => e.model.id === slice.model.id
|
|
200
|
-
),
|
|
201
|
-
});
|
|
202
|
-
},
|
|
203
|
-
openRenameModal: (slice: ComponentUI) => {
|
|
172
|
+
defineElementKey={(slice) => slice.model.name}
|
|
173
|
+
renderElem={(slice) => (
|
|
174
|
+
<SharedSliceViewCard
|
|
175
|
+
action={{
|
|
176
|
+
type: "menu",
|
|
177
|
+
onRemove: () => {
|
|
204
178
|
setSliceForEdit(slice);
|
|
205
|
-
|
|
179
|
+
openDeleteSliceModal();
|
|
206
180
|
},
|
|
207
|
-
|
|
181
|
+
onRename: () => {
|
|
208
182
|
setSliceForEdit(slice);
|
|
209
|
-
|
|
183
|
+
openRenameSliceModal();
|
|
210
184
|
},
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
185
|
+
}}
|
|
186
|
+
isDeletedSlice={false}
|
|
187
|
+
onUpdateScreenshot={() => {
|
|
188
|
+
onOpenModal({
|
|
189
|
+
sliceFilterFn: (s) =>
|
|
190
|
+
s.filter(
|
|
191
|
+
(e) => e.model.id === slice.model.id
|
|
192
|
+
),
|
|
193
|
+
});
|
|
194
|
+
}}
|
|
195
|
+
slice={slice}
|
|
196
|
+
/>
|
|
197
|
+
)}
|
|
215
198
|
gridGap="32px 16px"
|
|
216
199
|
/>
|
|
217
200
|
</Flex>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CompositeSlice,
|
|
3
|
+
LegacySlice,
|
|
4
|
+
} from "@prismicio/types-internal/lib/customtypes/widgets/slices";
|
|
5
|
+
|
|
6
|
+
import type { ComponentUI } from "@lib/models/common/ComponentUI";
|
|
7
|
+
import type { VariationSM } from "@lib/models/common/Slice";
|
|
8
|
+
|
|
9
|
+
export type NonSharedSlice = CompositeSlice | LegacySlice;
|
|
10
|
+
|
|
11
|
+
export const NON_SHARED_SLICE_LIBRARY_NAME = "Default";
|
|
12
|
+
|
|
13
|
+
export function countMissingScreenshots(slice: ComponentUI): number {
|
|
14
|
+
return slice.model.variations.length - Object.keys(slice.screenshots).length;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function getNonSharedSliceLabel(slice: NonSharedSlice): string {
|
|
18
|
+
return (
|
|
19
|
+
slice.config?.label ??
|
|
20
|
+
(slice.type === "Group" ||
|
|
21
|
+
slice.type === "Slice" ||
|
|
22
|
+
(slice.type !== "Boolean" && slice.type !== "Separator")
|
|
23
|
+
? slice.fieldset
|
|
24
|
+
: undefined) ??
|
|
25
|
+
slice.type
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function getScreenshotUrl(
|
|
30
|
+
slice: ComponentUI,
|
|
31
|
+
variation: VariationSM
|
|
32
|
+
): string | undefined {
|
|
33
|
+
return slice.screenshots[variation.id]?.url;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function getSharedSliceLibraryName(slice: ComponentUI): string {
|
|
37
|
+
return slice.from.length > 0 ? slice.from : "Default";
|
|
38
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Badge, Tooltip } from "@prismicio/editor-ui";
|
|
2
|
+
import type { ComponentProps, FC } from "react";
|
|
3
|
+
|
|
4
|
+
import { ModelStatus } from "@lib/models/common/ModelStatus";
|
|
5
|
+
import { AuthStatus } from "@src/modules/userContext/types";
|
|
6
|
+
|
|
7
|
+
export type StatusBadgeProps = GetStatusBadgeContentArgs;
|
|
8
|
+
|
|
9
|
+
export const StatusBadge: FC<StatusBadgeProps> = (props) => {
|
|
10
|
+
const { badgeColor, badgeTitle, tooltipContent } =
|
|
11
|
+
getStatusBadgeContent(props);
|
|
12
|
+
return (
|
|
13
|
+
<Tooltip content={tooltipContent} side="bottom">
|
|
14
|
+
<Badge color={badgeColor} title={badgeTitle} />
|
|
15
|
+
</Tooltip>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type GetStatusBadgeContentArgs = {
|
|
20
|
+
authStatus: AuthStatus;
|
|
21
|
+
isOnline: boolean;
|
|
22
|
+
modelStatus: ModelStatus;
|
|
23
|
+
modelType: ModelType;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
type ModelType = "CustomType" | "Slice";
|
|
27
|
+
|
|
28
|
+
type StatusBadgeContent = {
|
|
29
|
+
badgeColor: ComponentProps<typeof Badge>["color"];
|
|
30
|
+
badgeTitle: string;
|
|
31
|
+
tooltipContent: string;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
function getStatusBadgeContent(
|
|
35
|
+
args: GetStatusBadgeContentArgs
|
|
36
|
+
): StatusBadgeContent {
|
|
37
|
+
const modelTypeLabel = modelTypeLabels[args.modelType];
|
|
38
|
+
switch (args.modelStatus) {
|
|
39
|
+
case ModelStatus.New: {
|
|
40
|
+
return {
|
|
41
|
+
badgeColor: "green",
|
|
42
|
+
badgeTitle: "New",
|
|
43
|
+
tooltipContent: `This ${modelTypeLabel} exists only locally. Upon sync, it will be pushed to your remote repository.`,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
case ModelStatus.Modified: {
|
|
47
|
+
return {
|
|
48
|
+
badgeColor: "amber",
|
|
49
|
+
badgeTitle: "Modified",
|
|
50
|
+
tooltipContent: `This ${modelTypeLabel} has been modified locally. Upon sync, changes will be pushed to your remote repository.`,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
case ModelStatus.Synced: {
|
|
54
|
+
return {
|
|
55
|
+
badgeColor: "purple",
|
|
56
|
+
badgeTitle: "Synced",
|
|
57
|
+
tooltipContent: `This ${modelTypeLabel} is in sync with the remote repository.`,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
case ModelStatus.Deleted: {
|
|
61
|
+
return {
|
|
62
|
+
badgeColor: "tomato",
|
|
63
|
+
badgeTitle: "Deleted",
|
|
64
|
+
tooltipContent: `This ${modelTypeLabel} has been deleted locally.`,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
case ModelStatus.Unknown: {
|
|
68
|
+
if (!args.isOnline) {
|
|
69
|
+
return {
|
|
70
|
+
badgeColor: "grey",
|
|
71
|
+
badgeTitle: "Unknown",
|
|
72
|
+
tooltipContent:
|
|
73
|
+
"Data from the remote repository could not be fetched (no internet connection).",
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
if (args.authStatus === AuthStatus.UNAUTHORIZED) {
|
|
77
|
+
return {
|
|
78
|
+
badgeColor: "grey",
|
|
79
|
+
badgeTitle: "Unknown",
|
|
80
|
+
tooltipContent:
|
|
81
|
+
"Data from the remote repository could not be fetched (not connected to Prismic).",
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
if (args.authStatus === AuthStatus.FORBIDDEN) {
|
|
85
|
+
return {
|
|
86
|
+
badgeColor: "grey",
|
|
87
|
+
badgeTitle: "Unknown",
|
|
88
|
+
tooltipContent:
|
|
89
|
+
"Data from the remote repository could not be fetched (you don't have access to the repository).",
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
default: {
|
|
94
|
+
return {
|
|
95
|
+
badgeColor: "grey",
|
|
96
|
+
badgeTitle: "Unknown",
|
|
97
|
+
tooltipContent:
|
|
98
|
+
"Data from the remote repository could not be fetched (unknown error).",
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const modelTypeLabels: Record<ModelType, string> = {
|
|
105
|
+
CustomType: "type",
|
|
106
|
+
Slice: "slice",
|
|
107
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { useSelector } from "react-redux";
|
|
3
|
+
import { Box, Button, Text } from "@prismicio/editor-ui";
|
|
4
|
+
|
|
5
|
+
import { CreateCustomTypeModal } from "@components/Forms/CreateCustomTypeModal";
|
|
6
|
+
import { SliceMachineStoreType } from "@src/redux/type";
|
|
7
|
+
import useSliceMachineActions from "@src/modules/useSliceMachineActions";
|
|
8
|
+
import { LoadingKeysEnum } from "@src/modules/loading/types";
|
|
9
|
+
import { isLoading } from "@src/modules/loading";
|
|
10
|
+
import { BlankPageIcon } from "@src/icons/BlankPageIcon";
|
|
11
|
+
|
|
12
|
+
export function PageTypeOnboarding() {
|
|
13
|
+
const { openCreateCustomTypeModal } = useSliceMachineActions();
|
|
14
|
+
const { isCreatingCustomType } = useSelector(
|
|
15
|
+
(store: SliceMachineStoreType) => ({
|
|
16
|
+
isCreatingCustomType: isLoading(
|
|
17
|
+
store,
|
|
18
|
+
LoadingKeysEnum.CREATE_CUSTOM_TYPE
|
|
19
|
+
),
|
|
20
|
+
})
|
|
21
|
+
);
|
|
22
|
+
// State to ensure button loader is still visible while redirecting
|
|
23
|
+
const [isButtonLoading, setIsButtonLoading] = useState(false);
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (isCreatingCustomType) {
|
|
27
|
+
setIsButtonLoading(true);
|
|
28
|
+
}
|
|
29
|
+
}, [isCreatingCustomType]);
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<Box
|
|
33
|
+
display="flex"
|
|
34
|
+
justifyContent="center"
|
|
35
|
+
height="100vh"
|
|
36
|
+
alignItems="center"
|
|
37
|
+
backgroundColor="grey2"
|
|
38
|
+
>
|
|
39
|
+
<Box
|
|
40
|
+
display="flex"
|
|
41
|
+
flexDirection="column"
|
|
42
|
+
alignItems="center"
|
|
43
|
+
width={384}
|
|
44
|
+
>
|
|
45
|
+
<BlankPageIcon />
|
|
46
|
+
<Text variant="h3" align="center" sx={{ marginTop: 16 }}>
|
|
47
|
+
Blank page
|
|
48
|
+
</Text>
|
|
49
|
+
<Text color="grey11" align="center" sx={{ marginBottom: 16 }}>
|
|
50
|
+
Welcome to Slice Machine. Your journey starts with your first page
|
|
51
|
+
type — the model that you will use to create pages for your website.
|
|
52
|
+
</Text>
|
|
53
|
+
<Button onClick={openCreateCustomTypeModal} loading={isButtonLoading}>
|
|
54
|
+
Create a page type
|
|
55
|
+
</Button>
|
|
56
|
+
<CreateCustomTypeModal format="page" origin="onboarding" />
|
|
57
|
+
</Box>
|
|
58
|
+
</Box>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
BlankSlateDescription,
|
|
9
9
|
BlankSlateTitle,
|
|
10
10
|
} from "@src/components/BlankSlate";
|
|
11
|
-
import {
|
|
11
|
+
import { SliceMachinePrinterIcon } from "@src/icons/SliceMachinePrinterIcon";
|
|
12
12
|
|
|
13
13
|
export type SliceZoneBlankSlateProps = {
|
|
14
14
|
openUpdateSliceZoneModal: () => void;
|
|
@@ -30,7 +30,7 @@ export const SliceZoneBlankSlate: FC<SliceZoneBlankSlateProps> = ({
|
|
|
30
30
|
<BlankSlate backgroundImage="/blank-slate-slice-zone.png">
|
|
31
31
|
<BlankSlateContent>
|
|
32
32
|
<Box justifyContent="center" padding={{ bottom: 16 }}>
|
|
33
|
-
<
|
|
33
|
+
<SliceMachinePrinterIcon />
|
|
34
34
|
</Box>
|
|
35
35
|
<BlankSlateTitle>Add slices</BlankSlateTitle>
|
|
36
36
|
<BlankSlateDescription>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Badge, Box, Text, Tooltip } from "@prismicio/editor-ui";
|
|
2
|
+
import type { FC } from "react";
|
|
3
|
+
|
|
4
|
+
import { Card, CardActions, CardFooter, CardMedia } from "@src/components/Card";
|
|
5
|
+
import {
|
|
6
|
+
getNonSharedSliceLabel,
|
|
7
|
+
NON_SHARED_SLICE_LIBRARY_NAME,
|
|
8
|
+
type NonSharedSlice,
|
|
9
|
+
} from "@src/domain/slice";
|
|
10
|
+
|
|
11
|
+
type NonSharedSliceViewCardProps = {
|
|
12
|
+
slice: NonSharedSlice;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const NonSharedSliceViewCard: FC<NonSharedSliceViewCardProps> = ({
|
|
16
|
+
slice,
|
|
17
|
+
}) => (
|
|
18
|
+
<Card>
|
|
19
|
+
<CardMedia component="div">
|
|
20
|
+
<Box alignItems="center" justifyContent="center">
|
|
21
|
+
<Text color="grey11" component="span">
|
|
22
|
+
No screenshot available
|
|
23
|
+
</Text>
|
|
24
|
+
</Box>
|
|
25
|
+
</CardMedia>
|
|
26
|
+
<CardActions>
|
|
27
|
+
<Tooltip
|
|
28
|
+
content="This Slice was created with the Legacy Builder, and is incompatible with Slice Machine. You cannot edit, push, or delete it in Slice Machine. In order to proceed, manually remove the Slice from your type model. Then create a new Slice with the same fields using Slice Machine."
|
|
29
|
+
side="bottom"
|
|
30
|
+
>
|
|
31
|
+
<Badge color="purple" title="Legacy Slice" />
|
|
32
|
+
</Tooltip>
|
|
33
|
+
</CardActions>
|
|
34
|
+
<CardFooter
|
|
35
|
+
subtitle={NON_SHARED_SLICE_LIBRARY_NAME}
|
|
36
|
+
title={getNonSharedSliceLabel(slice)}
|
|
37
|
+
/>
|
|
38
|
+
</Card>
|
|
39
|
+
);
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Box, Checkbox, Text } from "@prismicio/editor-ui";
|
|
2
|
+
import type { FC } from "react";
|
|
3
|
+
|
|
4
|
+
import { ComponentUI } from "@lib/models/common/ComponentUI";
|
|
5
|
+
import { Card, CardFooter, CardMedia } from "@src/components/Card";
|
|
6
|
+
import { getScreenshotUrl, getSharedSliceLibraryName } from "@src/domain/slice";
|
|
7
|
+
|
|
8
|
+
type SharedSliceSelectionCardProps = {
|
|
9
|
+
isComingSoon: boolean;
|
|
10
|
+
isSliceTemplate: boolean;
|
|
11
|
+
onSelectedChange: (selected: boolean) => void;
|
|
12
|
+
selected: boolean;
|
|
13
|
+
slice: ComponentUI;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const SharedSliceSelectionCard: FC<SharedSliceSelectionCardProps> = ({
|
|
17
|
+
isComingSoon,
|
|
18
|
+
isSliceTemplate,
|
|
19
|
+
onSelectedChange,
|
|
20
|
+
selected,
|
|
21
|
+
slice,
|
|
22
|
+
}) => {
|
|
23
|
+
const defaultVariation = ComponentUI.variation(slice);
|
|
24
|
+
if (!defaultVariation) return null;
|
|
25
|
+
const src = getScreenshotUrl(slice, defaultVariation);
|
|
26
|
+
return (
|
|
27
|
+
<Card
|
|
28
|
+
checked={selected}
|
|
29
|
+
data-cy={`shared-slice-selection-card-${slice.model.id}`}
|
|
30
|
+
data-testid="shared-slice-selection-card"
|
|
31
|
+
disabled={isComingSoon}
|
|
32
|
+
interactive
|
|
33
|
+
onClick={() => {
|
|
34
|
+
onSelectedChange(!selected);
|
|
35
|
+
}}
|
|
36
|
+
size="small"
|
|
37
|
+
variant="outlined"
|
|
38
|
+
>
|
|
39
|
+
{src !== undefined ? (
|
|
40
|
+
<CardMedia src={src} />
|
|
41
|
+
) : (
|
|
42
|
+
<CardMedia component="div">
|
|
43
|
+
<Box alignItems="center" justifyContent="center">
|
|
44
|
+
<Text color="grey11" component="span">
|
|
45
|
+
No screenshot available
|
|
46
|
+
</Text>
|
|
47
|
+
</Box>
|
|
48
|
+
</CardMedia>
|
|
49
|
+
)}
|
|
50
|
+
<CardFooter
|
|
51
|
+
action={
|
|
52
|
+
// TODO(DT-1661): `findFocusableAncestor` should find Radix UI's `Checkbox`.
|
|
53
|
+
<div onClick={(event) => event.stopPropagation()}>
|
|
54
|
+
<Checkbox
|
|
55
|
+
checked={selected}
|
|
56
|
+
disabled={isComingSoon}
|
|
57
|
+
onCheckedChange={onSelectedChange}
|
|
58
|
+
/>
|
|
59
|
+
</div>
|
|
60
|
+
}
|
|
61
|
+
subtitle={
|
|
62
|
+
<>
|
|
63
|
+
{isSliceTemplate
|
|
64
|
+
? `${slice.model.variations.length} variation${
|
|
65
|
+
slice.model.variations.length > 1 ? "s" : ""
|
|
66
|
+
}`
|
|
67
|
+
: getSharedSliceLibraryName(slice)}
|
|
68
|
+
{isComingSoon ? (
|
|
69
|
+
<Text color="purple11" component="span" variant="small">
|
|
70
|
+
{" "}
|
|
71
|
+
• (coming soon)
|
|
72
|
+
</Text>
|
|
73
|
+
) : undefined}
|
|
74
|
+
</>
|
|
75
|
+
}
|
|
76
|
+
title={slice.model.name}
|
|
77
|
+
/>
|
|
78
|
+
</Card>
|
|
79
|
+
);
|
|
80
|
+
};
|