slice-machine-ui 1.15.1-dev-next-release.2 → 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/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/{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-0e270aca89a6033d.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]-868f09f50fd3039a.js → [customTypeId]-1baa6af0ddf0ab6b.js} +1 -1
- package/out/_next/static/chunks/pages/page-types/{[pageTypeId]-b6552cab363f7fbf.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/slices.tsx +25 -42
- package/src/domain/slice.ts +38 -0
- package/src/features/changes/StatusBadge.tsx +107 -0
- 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/modules/pushChangesSaga/trackPushChangesSuccess.ts +1 -1
- 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/809-d1f83d7413864f03.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/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/z-OmqvYWKjvP9W4MN_LBy/_buildManifest.js +0 -1
- 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/{z-OmqvYWKjvP9W4MN_LBy → pA_sw-x2_QsAanOp1Lx0c}/_ssgManifest.js +0 -0
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
|
-
import { BsThreeDotsVertical } from "react-icons/bs";
|
|
3
|
-
import { Popover } from "react-tiny-popover";
|
|
4
|
-
import { Box, Button, useThemeUI } from "theme-ui";
|
|
5
|
-
import { KebabMenuList } from "./KebabMenuList";
|
|
6
|
-
|
|
7
|
-
export type MenuOption = {
|
|
8
|
-
displayName: string;
|
|
9
|
-
onClick: (event: React.MouseEvent<HTMLDivElement>) => void;
|
|
10
|
-
dataCy?: string;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
type KebabMenuDropdownProps = {
|
|
14
|
-
menuOptions: MenuOption[];
|
|
15
|
-
dataCy?: string;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export const KebabMenuDropdown: React.FC<KebabMenuDropdownProps> = ({
|
|
19
|
-
menuOptions,
|
|
20
|
-
dataCy,
|
|
21
|
-
}) => {
|
|
22
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
23
|
-
|
|
24
|
-
const { theme } = useThemeUI();
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<Box>
|
|
28
|
-
<Popover
|
|
29
|
-
align="end"
|
|
30
|
-
isOpen={isOpen}
|
|
31
|
-
onClickOutside={() => setIsOpen(false)}
|
|
32
|
-
positions={["bottom", "top"]}
|
|
33
|
-
padding={2}
|
|
34
|
-
content={() => (
|
|
35
|
-
<KebabMenuList
|
|
36
|
-
menuOptions={menuOptions}
|
|
37
|
-
closeMenu={() => setIsOpen(false)}
|
|
38
|
-
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
39
|
-
dataCy={dataCy && `${dataCy}-dropdown`}
|
|
40
|
-
/>
|
|
41
|
-
)}
|
|
42
|
-
>
|
|
43
|
-
<Button
|
|
44
|
-
variant="dropDownButton"
|
|
45
|
-
sx={{
|
|
46
|
-
p: "5px",
|
|
47
|
-
backgroundColor: "white",
|
|
48
|
-
boxShadow: "0px 1px 0px rgba(0, 0, 0, 0.04)",
|
|
49
|
-
}}
|
|
50
|
-
onClick={(event) => {
|
|
51
|
-
event.preventDefault();
|
|
52
|
-
setIsOpen(!isOpen);
|
|
53
|
-
}}
|
|
54
|
-
data-cy={dataCy}
|
|
55
|
-
>
|
|
56
|
-
<BsThreeDotsVertical
|
|
57
|
-
color={theme.colors?.greyIcon as string}
|
|
58
|
-
size={16}
|
|
59
|
-
/>
|
|
60
|
-
</Button>
|
|
61
|
-
</Popover>
|
|
62
|
-
</Box>
|
|
63
|
-
);
|
|
64
|
-
};
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import ReactTooltip from "react-tooltip";
|
|
2
|
-
import { Badge, Box, Flex, Text } from "theme-ui";
|
|
3
|
-
import { ReactTooltipPortal } from "@components/ReactTooltipPortal";
|
|
4
|
-
import { ModelStatus } from "@lib/models/common/ModelStatus";
|
|
5
|
-
import { AuthStatus } from "@src/modules/userContext/types";
|
|
6
|
-
|
|
7
|
-
interface StatusBadgeProps {
|
|
8
|
-
modelType: "Slice" | "Custom Type";
|
|
9
|
-
modelId: string;
|
|
10
|
-
status: ModelStatus;
|
|
11
|
-
authStatus: AuthStatus;
|
|
12
|
-
isOnline: boolean;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const StatusBadge: React.FC<StatusBadgeProps> = ({
|
|
16
|
-
modelType,
|
|
17
|
-
modelId,
|
|
18
|
-
status,
|
|
19
|
-
authStatus,
|
|
20
|
-
isOnline,
|
|
21
|
-
}) => {
|
|
22
|
-
// Getting information to display depending on status
|
|
23
|
-
const { displayName, tooltipText } = statusDisplayInformation(
|
|
24
|
-
modelType,
|
|
25
|
-
status,
|
|
26
|
-
authStatus,
|
|
27
|
-
isOnline
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
return (
|
|
31
|
-
<Box sx={{ height: 28, display: "flex", alignItems: "center" }}>
|
|
32
|
-
<Text
|
|
33
|
-
data-for={`${modelId}-tooltip`}
|
|
34
|
-
data-tip
|
|
35
|
-
sx={{
|
|
36
|
-
display: "flex",
|
|
37
|
-
height: 24,
|
|
38
|
-
}}
|
|
39
|
-
>
|
|
40
|
-
<Badge
|
|
41
|
-
variant={status}
|
|
42
|
-
sx={{
|
|
43
|
-
padding: "4px 8px;",
|
|
44
|
-
borderRadius: "6px;",
|
|
45
|
-
lineHeight: "16px",
|
|
46
|
-
}}
|
|
47
|
-
>
|
|
48
|
-
{displayName}
|
|
49
|
-
</Badge>
|
|
50
|
-
</Text>
|
|
51
|
-
<ReactTooltipPortal>
|
|
52
|
-
<ReactTooltip
|
|
53
|
-
id={`${modelId}-tooltip`}
|
|
54
|
-
type="dark"
|
|
55
|
-
multiline
|
|
56
|
-
border
|
|
57
|
-
borderColor="black"
|
|
58
|
-
place="bottom"
|
|
59
|
-
effect="solid"
|
|
60
|
-
>
|
|
61
|
-
<Flex
|
|
62
|
-
sx={{
|
|
63
|
-
maxWidth: "196px",
|
|
64
|
-
textAlign: "center",
|
|
65
|
-
margin: "0 -13px",
|
|
66
|
-
}}
|
|
67
|
-
>
|
|
68
|
-
{tooltipText}
|
|
69
|
-
</Flex>
|
|
70
|
-
</ReactTooltip>
|
|
71
|
-
</ReactTooltipPortal>
|
|
72
|
-
</Box>
|
|
73
|
-
);
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
function statusDisplayInformation(
|
|
77
|
-
modelType: StatusBadgeProps["modelType"],
|
|
78
|
-
status: ModelStatus,
|
|
79
|
-
authStatus: AuthStatus,
|
|
80
|
-
isOnline: boolean
|
|
81
|
-
): { displayName: string; tooltipText: string } {
|
|
82
|
-
switch (status) {
|
|
83
|
-
case ModelStatus.New:
|
|
84
|
-
return {
|
|
85
|
-
displayName: "New",
|
|
86
|
-
tooltipText: `This ${modelType} exists only locally. Upon sync, it will be pushed to your remote repository.`,
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
case ModelStatus.Modified:
|
|
90
|
-
return {
|
|
91
|
-
displayName: "Modified",
|
|
92
|
-
tooltipText: `This ${modelType} has been modified locally. Upon sync, changes will be pushed to your remote repository.`,
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
case ModelStatus.Synced:
|
|
96
|
-
return {
|
|
97
|
-
displayName: "Synced",
|
|
98
|
-
tooltipText: `This ${modelType} is in sync with the remote repository.`,
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
case ModelStatus.Deleted:
|
|
102
|
-
return {
|
|
103
|
-
displayName: "Deleted",
|
|
104
|
-
tooltipText: `This ${modelType} has been deleted locally.`,
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
case ModelStatus.Unknown:
|
|
108
|
-
if (!isOnline) {
|
|
109
|
-
return {
|
|
110
|
-
displayName: "Unknown",
|
|
111
|
-
tooltipText:
|
|
112
|
-
"Data from the remote repository could not be fetched (no internet connection).",
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (authStatus === AuthStatus.UNAUTHORIZED) {
|
|
117
|
-
return {
|
|
118
|
-
displayName: "Unknown",
|
|
119
|
-
tooltipText:
|
|
120
|
-
"Data from the remote repository could not be fetched (not connected to Prismic).",
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (authStatus === AuthStatus.FORBIDDEN) {
|
|
125
|
-
return {
|
|
126
|
-
displayName: "Unknown",
|
|
127
|
-
tooltipText:
|
|
128
|
-
"Data from the remote repository could not be fetched (you don't have access to the repository).",
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
default:
|
|
133
|
-
return {
|
|
134
|
-
displayName: "Unknown",
|
|
135
|
-
tooltipText:
|
|
136
|
-
"Data from the remote repository could not be fetched (unknown error).",
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
}
|
package/lib/models/ui/Link.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export const Link = {
|
|
2
|
-
variation(
|
|
3
|
-
lib: string,
|
|
4
|
-
sliceName: string,
|
|
5
|
-
variationId: string,
|
|
6
|
-
options: object = {}
|
|
7
|
-
): {
|
|
8
|
-
href: string;
|
|
9
|
-
as: string;
|
|
10
|
-
options: object;
|
|
11
|
-
all: [string, string, object];
|
|
12
|
-
} {
|
|
13
|
-
const href = "/[lib]/[sliceName]/[variation]";
|
|
14
|
-
const as = `/${lib}/${sliceName}/${variationId}`;
|
|
15
|
-
|
|
16
|
-
return {
|
|
17
|
-
href,
|
|
18
|
-
as,
|
|
19
|
-
options,
|
|
20
|
-
all: [href, as, options],
|
|
21
|
-
};
|
|
22
|
-
},
|
|
23
|
-
};
|
|
@@ -1,424 +0,0 @@
|
|
|
1
|
-
import React, { useCallback } from "react";
|
|
2
|
-
import {
|
|
3
|
-
Text,
|
|
4
|
-
Card as Themecard,
|
|
5
|
-
Flex,
|
|
6
|
-
type ThemeUIStyleObject,
|
|
7
|
-
type ThemeUICSSObject,
|
|
8
|
-
} from "theme-ui";
|
|
9
|
-
import { ComponentUI } from "../../common/ComponentUI";
|
|
10
|
-
import { Link as LinkUtil } from "../Link";
|
|
11
|
-
import { WrapperType, WrapperByType } from "./wrappers";
|
|
12
|
-
import { ReactTooltipPortal } from "@components/ReactTooltipPortal";
|
|
13
|
-
import { TextWithTooltip } from "@components/Tooltip/TextWithTooltip";
|
|
14
|
-
import { ScreenshotPreview } from "@components/ScreenshotPreview";
|
|
15
|
-
import { StatusBadge } from "@components/StatusBadge";
|
|
16
|
-
import { ModelStatus } from "@lib/models/common/ModelStatus";
|
|
17
|
-
import { AuthStatus } from "@src/modules/userContext/types";
|
|
18
|
-
import { AiOutlineCamera, AiOutlineExclamationCircle } from "react-icons/ai";
|
|
19
|
-
import { countMissingScreenshots } from "@src/utils/screenshots/missing";
|
|
20
|
-
import { Button } from "@components/Button";
|
|
21
|
-
import { KebabMenuDropdown } from "@components/KebabMenuDropdown";
|
|
22
|
-
import ReactTooltip from "react-tooltip";
|
|
23
|
-
import style from "./LegacySliceTooltip.module.css";
|
|
24
|
-
|
|
25
|
-
const defaultSx = (sx: ThemeUIStyleObject = {}): ThemeUICSSObject => ({
|
|
26
|
-
bg: "white",
|
|
27
|
-
position: "relative",
|
|
28
|
-
transition: "all 100ms cubic-bezier(0.215,0.60,0.355,1)",
|
|
29
|
-
...sx,
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
const SliceVariations = ({
|
|
33
|
-
numberOfVariations,
|
|
34
|
-
}: {
|
|
35
|
-
numberOfVariations: number;
|
|
36
|
-
}) => {
|
|
37
|
-
return (
|
|
38
|
-
<>
|
|
39
|
-
{numberOfVariations ? (
|
|
40
|
-
<Text
|
|
41
|
-
sx={{
|
|
42
|
-
fontSize: 14,
|
|
43
|
-
color: "textClear",
|
|
44
|
-
flexShrink: 0,
|
|
45
|
-
lineHeight: "24px",
|
|
46
|
-
}}
|
|
47
|
-
>
|
|
48
|
-
{numberOfVariations} variation{numberOfVariations > 1 ? "s" : ""}
|
|
49
|
-
</Text>
|
|
50
|
-
) : null}
|
|
51
|
-
</>
|
|
52
|
-
);
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const SliceCardActions: React.FC<{
|
|
56
|
-
slice: ComponentUI;
|
|
57
|
-
disableActions: boolean;
|
|
58
|
-
actions?: {
|
|
59
|
-
onUpdateScreenshot: (e: React.MouseEvent) => void;
|
|
60
|
-
openRenameModal?: (slice: ComponentUI) => void;
|
|
61
|
-
openDeleteModal?: (slice: ComponentUI) => void;
|
|
62
|
-
};
|
|
63
|
-
}> = ({ actions, slice, disableActions }) => {
|
|
64
|
-
const onRenameClick = useCallback(() => {
|
|
65
|
-
if (actions?.openRenameModal) {
|
|
66
|
-
actions.openRenameModal(slice);
|
|
67
|
-
}
|
|
68
|
-
}, [actions, slice]);
|
|
69
|
-
const onDeleteClick = useCallback(() => {
|
|
70
|
-
if (actions?.openDeleteModal) {
|
|
71
|
-
actions.openDeleteModal(slice);
|
|
72
|
-
}
|
|
73
|
-
}, [actions, slice]);
|
|
74
|
-
|
|
75
|
-
if (!actions) {
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return (
|
|
80
|
-
<Flex
|
|
81
|
-
mt={1}
|
|
82
|
-
sx={{
|
|
83
|
-
alignItems: "center",
|
|
84
|
-
justifyContent: "space-between",
|
|
85
|
-
padding: 3,
|
|
86
|
-
borderBottom: (t) => `1px solid ${t.colors?.borders as string}`,
|
|
87
|
-
mt: 0,
|
|
88
|
-
}}
|
|
89
|
-
>
|
|
90
|
-
<Button
|
|
91
|
-
onClick={actions.onUpdateScreenshot}
|
|
92
|
-
variant="secondarySmall"
|
|
93
|
-
sx={{ fontWeight: "bold" }}
|
|
94
|
-
Icon={AiOutlineCamera}
|
|
95
|
-
label="Update screenshot"
|
|
96
|
-
disabled={disableActions}
|
|
97
|
-
/>
|
|
98
|
-
|
|
99
|
-
{actions.openRenameModal && (
|
|
100
|
-
<KebabMenuDropdown
|
|
101
|
-
dataCy="slice-action-icon"
|
|
102
|
-
menuOptions={[
|
|
103
|
-
{
|
|
104
|
-
displayName: "Rename",
|
|
105
|
-
onClick: onRenameClick,
|
|
106
|
-
dataCy: "slice-action-rename",
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
displayName: "Delete",
|
|
110
|
-
onClick: onDeleteClick,
|
|
111
|
-
},
|
|
112
|
-
]}
|
|
113
|
-
/>
|
|
114
|
-
)}
|
|
115
|
-
</Flex>
|
|
116
|
-
);
|
|
117
|
-
};
|
|
118
|
-
const SliceDescription = ({
|
|
119
|
-
slice,
|
|
120
|
-
StatusOrCustom,
|
|
121
|
-
}: {
|
|
122
|
-
slice: ComponentUI;
|
|
123
|
-
StatusOrCustom:
|
|
124
|
-
| {
|
|
125
|
-
status: ModelStatus;
|
|
126
|
-
authStatus: AuthStatus;
|
|
127
|
-
isOnline: boolean;
|
|
128
|
-
}
|
|
129
|
-
| React.FC<{ slice: ComponentUI }>;
|
|
130
|
-
}) => (
|
|
131
|
-
<Flex
|
|
132
|
-
sx={{
|
|
133
|
-
flexDirection: "column",
|
|
134
|
-
padding: 3,
|
|
135
|
-
}}
|
|
136
|
-
>
|
|
137
|
-
<Flex>
|
|
138
|
-
<TextWithTooltip
|
|
139
|
-
text={slice.model.name}
|
|
140
|
-
as="h6"
|
|
141
|
-
sx={{
|
|
142
|
-
fontWeight: "600 !important",
|
|
143
|
-
maxWidth: "80%",
|
|
144
|
-
lineHeight: "24px !important",
|
|
145
|
-
}}
|
|
146
|
-
/>
|
|
147
|
-
</Flex>
|
|
148
|
-
<Flex
|
|
149
|
-
sx={{
|
|
150
|
-
alignItems: "center",
|
|
151
|
-
justifyContent: "space-between",
|
|
152
|
-
}}
|
|
153
|
-
>
|
|
154
|
-
<SliceVariations numberOfVariations={slice.model.variations.length} />
|
|
155
|
-
<Flex sx={{ alignItems: "center" }}>
|
|
156
|
-
{"status" in StatusOrCustom ? (
|
|
157
|
-
<StatusBadge
|
|
158
|
-
modelType="Slice"
|
|
159
|
-
modelId={slice.model.id}
|
|
160
|
-
status={StatusOrCustom.status}
|
|
161
|
-
authStatus={StatusOrCustom.authStatus}
|
|
162
|
-
isOnline={StatusOrCustom.isOnline}
|
|
163
|
-
/>
|
|
164
|
-
) : (
|
|
165
|
-
<StatusOrCustom slice={slice} />
|
|
166
|
-
)}
|
|
167
|
-
</Flex>
|
|
168
|
-
</Flex>
|
|
169
|
-
</Flex>
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
const ScreenshotMissingBanner: React.FC<{ slice: ComponentUI }> = ({
|
|
173
|
-
slice,
|
|
174
|
-
}) => {
|
|
175
|
-
const missingScreenshots = countMissingScreenshots(slice);
|
|
176
|
-
|
|
177
|
-
if (!missingScreenshots) {
|
|
178
|
-
return null;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return (
|
|
182
|
-
<Flex
|
|
183
|
-
sx={{
|
|
184
|
-
position: "absolute",
|
|
185
|
-
alignItems: "center",
|
|
186
|
-
justifyContent: "center",
|
|
187
|
-
padding: 2,
|
|
188
|
-
bg: "missingScreenshotBanner.bg",
|
|
189
|
-
color: "missingScreenshotBanner.color",
|
|
190
|
-
width: "100%",
|
|
191
|
-
fontSize: "12px",
|
|
192
|
-
lineHeight: "16px",
|
|
193
|
-
fontWeight: "600",
|
|
194
|
-
}}
|
|
195
|
-
>
|
|
196
|
-
<AiOutlineExclamationCircle size={16} style={{ marginRight: "8px" }} />{" "}
|
|
197
|
-
{missingScreenshots}/{slice.model.variations.length} screenshots missing
|
|
198
|
-
</Flex>
|
|
199
|
-
);
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
type Status = {
|
|
203
|
-
status: ModelStatus;
|
|
204
|
-
authStatus: AuthStatus;
|
|
205
|
-
isOnline: boolean;
|
|
206
|
-
};
|
|
207
|
-
type StatusOrCustom = Status | React.FC<{ slice: ComponentUI }>;
|
|
208
|
-
|
|
209
|
-
const isDeleted = (statusOrCustom: StatusOrCustom): boolean =>
|
|
210
|
-
"status" in statusOrCustom && statusOrCustom.status === ModelStatus.Deleted;
|
|
211
|
-
|
|
212
|
-
export const SharedSlice = {
|
|
213
|
-
render({
|
|
214
|
-
showActions,
|
|
215
|
-
slice,
|
|
216
|
-
Wrapper,
|
|
217
|
-
StatusOrCustom,
|
|
218
|
-
wrapperType = WrapperType.clickable,
|
|
219
|
-
actions,
|
|
220
|
-
sx,
|
|
221
|
-
}: {
|
|
222
|
-
showActions?: boolean;
|
|
223
|
-
slice: ComponentUI;
|
|
224
|
-
StatusOrCustom: StatusOrCustom;
|
|
225
|
-
Wrapper?: React.FC<{
|
|
226
|
-
children?: React.ReactNode;
|
|
227
|
-
link?: { as: string };
|
|
228
|
-
slice: ComponentUI;
|
|
229
|
-
sx?: ThemeUIStyleObject;
|
|
230
|
-
}>;
|
|
231
|
-
wrapperType?: WrapperType;
|
|
232
|
-
actions?: {
|
|
233
|
-
onUpdateScreenshot: (e: React.MouseEvent) => void;
|
|
234
|
-
openRenameModal?: (slice: ComponentUI) => void;
|
|
235
|
-
openDeleteModal?: (slice: ComponentUI) => void;
|
|
236
|
-
};
|
|
237
|
-
sx?: ThemeUIStyleObject;
|
|
238
|
-
}) {
|
|
239
|
-
const defaultVariation = ComponentUI.variation(slice);
|
|
240
|
-
if (!defaultVariation) {
|
|
241
|
-
return null;
|
|
242
|
-
}
|
|
243
|
-
const variationId = defaultVariation.id;
|
|
244
|
-
const link = LinkUtil.variation(slice.href, slice.model.name, variationId);
|
|
245
|
-
|
|
246
|
-
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
247
|
-
const CardWrapper = Wrapper || WrapperByType[wrapperType];
|
|
248
|
-
|
|
249
|
-
const screenshotUrl = slice.screenshots?.[variationId]?.url;
|
|
250
|
-
|
|
251
|
-
return (
|
|
252
|
-
<CardWrapper
|
|
253
|
-
link={link}
|
|
254
|
-
slice={slice}
|
|
255
|
-
sx={{
|
|
256
|
-
borderColor: (t) => t.colors?.borders,
|
|
257
|
-
"&:focus": {
|
|
258
|
-
borderColor: "bordersFocused",
|
|
259
|
-
},
|
|
260
|
-
}}
|
|
261
|
-
>
|
|
262
|
-
<Themecard
|
|
263
|
-
role="button"
|
|
264
|
-
aria-pressed="false"
|
|
265
|
-
sx={{
|
|
266
|
-
borderColor: "inherit",
|
|
267
|
-
borderWidth: "1px",
|
|
268
|
-
borderStyle: "solid",
|
|
269
|
-
borderRadius: "6px",
|
|
270
|
-
overflow: "hidden",
|
|
271
|
-
...defaultSx(sx),
|
|
272
|
-
}}
|
|
273
|
-
aria-label={`${slice.model.name} slice card`}
|
|
274
|
-
>
|
|
275
|
-
<Flex
|
|
276
|
-
sx={{
|
|
277
|
-
position: "relative",
|
|
278
|
-
flexDirection: "column",
|
|
279
|
-
}}
|
|
280
|
-
>
|
|
281
|
-
<ScreenshotPreview
|
|
282
|
-
hideMissingWarning={isDeleted(StatusOrCustom)}
|
|
283
|
-
src={screenshotUrl}
|
|
284
|
-
sx={{
|
|
285
|
-
height: "198px",
|
|
286
|
-
borderBottom: (t) => `1px solid ${t.colors?.borders as string}`,
|
|
287
|
-
borderRadius: "4px 4px 0 0",
|
|
288
|
-
}}
|
|
289
|
-
/>
|
|
290
|
-
{/* eslint-disable-next-line @typescript-eslint/strict-boolean-expressions */}
|
|
291
|
-
{showActions && !isDeleted(StatusOrCustom) ? (
|
|
292
|
-
<ScreenshotMissingBanner slice={slice} />
|
|
293
|
-
) : null}
|
|
294
|
-
<Flex
|
|
295
|
-
sx={{
|
|
296
|
-
flexDirection: "column",
|
|
297
|
-
}}
|
|
298
|
-
>
|
|
299
|
-
<SliceCardActions
|
|
300
|
-
slice={slice}
|
|
301
|
-
disableActions={isDeleted(StatusOrCustom)}
|
|
302
|
-
actions={actions}
|
|
303
|
-
/>
|
|
304
|
-
<SliceDescription slice={slice} StatusOrCustom={StatusOrCustom} />
|
|
305
|
-
</Flex>
|
|
306
|
-
</Flex>
|
|
307
|
-
</Themecard>
|
|
308
|
-
</CardWrapper>
|
|
309
|
-
);
|
|
310
|
-
},
|
|
311
|
-
};
|
|
312
|
-
|
|
313
|
-
export const NonSharedSlice = {
|
|
314
|
-
render({
|
|
315
|
-
slice,
|
|
316
|
-
sx,
|
|
317
|
-
}: {
|
|
318
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
319
|
-
slice: { key: string; value: any };
|
|
320
|
-
sx?: ThemeUIStyleObject;
|
|
321
|
-
}) {
|
|
322
|
-
const Wrapper = WrapperByType[WrapperType.nonClickable];
|
|
323
|
-
|
|
324
|
-
return (
|
|
325
|
-
<Wrapper
|
|
326
|
-
sx={{
|
|
327
|
-
borderColor: (t) => t.colors?.borders,
|
|
328
|
-
"&:focus": {
|
|
329
|
-
borderColor: "bordersFocused",
|
|
330
|
-
},
|
|
331
|
-
}}
|
|
332
|
-
>
|
|
333
|
-
<Themecard
|
|
334
|
-
sx={{
|
|
335
|
-
borderColor: "inherit",
|
|
336
|
-
borderWidth: "1px",
|
|
337
|
-
borderStyle: "solid",
|
|
338
|
-
borderRadius: "6px",
|
|
339
|
-
overflow: "hidden",
|
|
340
|
-
...defaultSx(sx),
|
|
341
|
-
}}
|
|
342
|
-
>
|
|
343
|
-
<Flex
|
|
344
|
-
data-for={`legacy-slice-tooltip-${slice.key}`}
|
|
345
|
-
data-tip
|
|
346
|
-
sx={{
|
|
347
|
-
py: 2,
|
|
348
|
-
flexDirection: "row",
|
|
349
|
-
justifyContent: "center",
|
|
350
|
-
bg: "purple12",
|
|
351
|
-
fontSize: "12px",
|
|
352
|
-
fontWeight: "bold",
|
|
353
|
-
color: "purple08",
|
|
354
|
-
lineHeight: "16px",
|
|
355
|
-
}}
|
|
356
|
-
>
|
|
357
|
-
Legacy Slice
|
|
358
|
-
</Flex>
|
|
359
|
-
<ReactTooltipPortal>
|
|
360
|
-
<ReactTooltip
|
|
361
|
-
id={`legacy-slice-tooltip-${slice.key}`}
|
|
362
|
-
type="dark"
|
|
363
|
-
border
|
|
364
|
-
borderColor="black"
|
|
365
|
-
place="bottom"
|
|
366
|
-
effect="solid"
|
|
367
|
-
clickable
|
|
368
|
-
delayHide={100}
|
|
369
|
-
className={style.legacySliceTooltipContainer}
|
|
370
|
-
>
|
|
371
|
-
<Text
|
|
372
|
-
sx={{
|
|
373
|
-
fontSize: "12px",
|
|
374
|
-
lineHeight: "16px",
|
|
375
|
-
}}
|
|
376
|
-
>
|
|
377
|
-
This Slice was created with the Legacy Builder, and is
|
|
378
|
-
incompatible with Slice Machine. You cannot edit, push, or
|
|
379
|
-
delete it in Slice Machine. In order to proceed, manually remove
|
|
380
|
-
the Slice from your type model. Then create a new Slice with the
|
|
381
|
-
same fields using Slice Machine.
|
|
382
|
-
</Text>
|
|
383
|
-
</ReactTooltip>
|
|
384
|
-
</ReactTooltipPortal>
|
|
385
|
-
<ScreenshotPreview
|
|
386
|
-
hideMissingWarning
|
|
387
|
-
sx={{
|
|
388
|
-
height: "166px",
|
|
389
|
-
borderBottom: (t) => `1px solid ${t.colors?.borders as string}`,
|
|
390
|
-
borderRadius: 0,
|
|
391
|
-
}}
|
|
392
|
-
/>
|
|
393
|
-
<Flex
|
|
394
|
-
p={3}
|
|
395
|
-
sx={{
|
|
396
|
-
flexDirection: "column",
|
|
397
|
-
}}
|
|
398
|
-
>
|
|
399
|
-
<TextWithTooltip
|
|
400
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/strict-boolean-expressions
|
|
401
|
-
text={slice?.value?.fieldset || slice.key}
|
|
402
|
-
as="h6"
|
|
403
|
-
sx={{
|
|
404
|
-
fontWeight: "600 !important",
|
|
405
|
-
maxWidth: "80%",
|
|
406
|
-
lineHeight: "24px !important",
|
|
407
|
-
color: "grey10",
|
|
408
|
-
}}
|
|
409
|
-
/>
|
|
410
|
-
<Flex
|
|
411
|
-
sx={{
|
|
412
|
-
height: "28px",
|
|
413
|
-
justifyContent: "center",
|
|
414
|
-
flexDirection: "column",
|
|
415
|
-
}}
|
|
416
|
-
>
|
|
417
|
-
<SliceVariations numberOfVariations={1} />
|
|
418
|
-
</Flex>
|
|
419
|
-
</Flex>
|
|
420
|
-
</Themecard>
|
|
421
|
-
</Wrapper>
|
|
422
|
-
);
|
|
423
|
-
},
|
|
424
|
-
};
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { Box, Link as ThemeLink, ThemeUIStyleObject } from "theme-ui";
|
|
2
|
-
import Link from "next/link";
|
|
3
|
-
|
|
4
|
-
export const LinkCardWrapper = ({
|
|
5
|
-
link,
|
|
6
|
-
children,
|
|
7
|
-
sx,
|
|
8
|
-
}: {
|
|
9
|
-
link: { as: string } | undefined;
|
|
10
|
-
children: React.ReactNode;
|
|
11
|
-
sx?: ThemeUIStyleObject;
|
|
12
|
-
}) => {
|
|
13
|
-
//TODO: make the redirection through "connected-next-router" so that the router location is synched with redux
|
|
14
|
-
return (
|
|
15
|
-
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/prefer-nullish-coalescing
|
|
16
|
-
<Link passHref href={link?.as || ""}>
|
|
17
|
-
<ThemeLink
|
|
18
|
-
sx={{
|
|
19
|
-
textDecoration: "none",
|
|
20
|
-
color: "inherit",
|
|
21
|
-
...sx,
|
|
22
|
-
}}
|
|
23
|
-
as="a"
|
|
24
|
-
>
|
|
25
|
-
{children}
|
|
26
|
-
</ThemeLink>
|
|
27
|
-
</Link>
|
|
28
|
-
);
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export const NonClickableCardWrapper = ({
|
|
32
|
-
children,
|
|
33
|
-
sx,
|
|
34
|
-
}: {
|
|
35
|
-
children: React.ReactNode;
|
|
36
|
-
sx?: ThemeUIStyleObject;
|
|
37
|
-
}) => {
|
|
38
|
-
return <Box sx={{ cursor: "not-allowed", ...sx }}>{children}</Box>;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export enum WrapperType {
|
|
42
|
-
clickable = "clickable",
|
|
43
|
-
nonClickable = "nonClickable",
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export const WrapperByType = {
|
|
47
|
-
[WrapperType.clickable]: LinkCardWrapper,
|
|
48
|
-
[WrapperType.nonClickable]: NonClickableCardWrapper,
|
|
49
|
-
};
|