slice-machine-ui 1.20.0 → 1.20.1-dev-environments.0

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 (62) hide show
  1. package/components/AppLayout/index.tsx +34 -10
  2. package/components/Navigation/Environment.tsx +47 -0
  3. package/components/Navigation/index.css.ts +6 -0
  4. package/components/Navigation/index.tsx +15 -2
  5. package/out/404.html +1 -1
  6. package/out/_next/static/chunks/{482-4db559872e756d8e.js → 482-39cef3a713901788.js} +1 -1
  7. package/out/_next/static/chunks/840-5b485c737b24324b.js +1 -0
  8. package/out/_next/static/chunks/904-6204ab2ad8798857.js +1 -0
  9. package/out/_next/static/chunks/958-c90d60818f1c468a.js +1 -0
  10. package/out/_next/static/chunks/pages/{_app-e3bc35d62b63f7ad.js → _app-ba6984f5be36bff0.js} +7 -7
  11. package/out/_next/static/chunks/pages/{changelog-fa36b9995c26e1d7.js → changelog-4b8369d91d82b28b.js} +1 -1
  12. package/out/_next/static/chunks/pages/changes-db6e8c6be5ae076e.js +1 -0
  13. package/out/_next/static/chunks/pages/labs-2922105ab714d32a.js +1 -0
  14. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-724893d27ffa426c.js +1 -0
  15. package/out/_next/static/chunks/pages/slices-93b7af2624c85b8e.js +1 -0
  16. package/out/_next/static/css/{412af4286eb0b283.css → 009bd7f5ac85fc6a.css} +1 -1
  17. package/out/_next/static/v-bXsgTHaXnMXnXoIqObT/_buildManifest.js +1 -0
  18. package/out/changelog.html +1 -1
  19. package/out/changes.html +1 -1
  20. package/out/custom-types/[customTypeId].html +1 -1
  21. package/out/custom-types.html +1 -1
  22. package/out/index.html +1 -1
  23. package/out/labs.html +1 -1
  24. package/out/page-types/[pageTypeId].html +1 -1
  25. package/out/slices/[lib]/[sliceName]/[variation]/simulator.html +1 -1
  26. package/out/slices/[lib]/[sliceName]/[variation].html +1 -1
  27. package/out/slices.html +1 -1
  28. package/package.json +4 -4
  29. package/pages/slices.tsx +1 -0
  30. package/src/components/Divider/Divider.css.ts +31 -0
  31. package/src/components/Divider/Divider.stories.tsx +27 -0
  32. package/src/components/Divider/Divider.tsx +25 -0
  33. package/src/components/Divider/index.ts +1 -0
  34. package/src/components/PageLayout/PageLayout.css.ts +8 -3
  35. package/src/components/PageLayout/PageLayout.stories.tsx +10 -1
  36. package/src/components/PageLayout/PageLayout.tsx +7 -2
  37. package/src/components/SideNav/SideNav.css.ts +3 -10
  38. package/src/components/SideNav/SideNav.stories.tsx +29 -2
  39. package/src/components/SideNav/SideNav.tsx +5 -1
  40. package/src/components/SideNav/SideNavEnvironmentSelector.css.ts +69 -0
  41. package/src/components/SideNav/SideNavEnvironmentSelector.tsx +163 -0
  42. package/src/components/SideNav/index.ts +1 -0
  43. package/src/features/customTypes/__tests__/CustomTypeBuilderPage.test.tsx +4 -3
  44. package/src/features/environments/actions/getActiveEnvironmentDomain.ts +11 -0
  45. package/src/features/environments/actions/getEnvironments.ts +12 -0
  46. package/src/features/environments/actions/setEnvironment.ts +18 -0
  47. package/src/features/environments/useActiveEnvironment.ts +38 -0
  48. package/src/features/environments/useEnvironments.ts +7 -0
  49. package/src/features/legacyState/actions/getLegacySliceMachineState.ts +53 -0
  50. package/src/features/legacyState/useLegacySliceMachineState.ts +7 -0
  51. package/src/features/slices/sliceBuilder/actions/deleteVariation.ts +4 -1
  52. package/test/pages/slices.test.tsx +4 -8
  53. package/test/src/modules/__fixtures__/serverState.ts +2 -0
  54. package/out/_next/static/HyLqPqqUuTwm5E7j_4GAQ/_buildManifest.js +0 -1
  55. package/out/_next/static/chunks/840-884e41a48b92e5d3.js +0 -1
  56. package/out/_next/static/chunks/904-dd90b9b35742ec39.js +0 -1
  57. package/out/_next/static/chunks/958-fc1d7f74387b37a3.js +0 -1
  58. package/out/_next/static/chunks/pages/changes-e388be4457a43c3a.js +0 -1
  59. package/out/_next/static/chunks/pages/labs-ebce03a4e7a95a4e.js +0 -1
  60. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-7c811c2c79f01a25.js +0 -1
  61. package/out/_next/static/chunks/pages/slices-22db04643850c1d8.js +0 -1
  62. /package/out/_next/static/{HyLqPqqUuTwm5E7j_4GAQ → v-bXsgTHaXnMXnXoIqObT}/_ssgManifest.js +0 -0
@@ -0,0 +1,31 @@
1
+ import { colors, sprinkles } from "@prismicio/editor-ui";
2
+ import { style, styleVariants } from "@vanilla-extract/css";
3
+
4
+ const base = style([
5
+ sprinkles({
6
+ width: "100%",
7
+ borderStyle: "none",
8
+ margin: 0,
9
+ }),
10
+ ]);
11
+
12
+ export const variants = styleVariants({
13
+ dashed: [
14
+ base,
15
+ sprinkles({
16
+ borderColor: colors.currentColor,
17
+ borderTopStyle: "dashed",
18
+ borderWidth: 1,
19
+ }),
20
+ ],
21
+ edgeFaded: [
22
+ base,
23
+ sprinkles({
24
+ height: 1,
25
+ }),
26
+ {
27
+ backgroundImage:
28
+ "linear-gradient(to right, color-mix(in srgb, currentColor 0%, transparent), currentColor, color-mix(in srgb, currentColor 0%, transparent))",
29
+ },
30
+ ],
31
+ });
@@ -0,0 +1,27 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { colors } from "@prismicio/editor-ui";
3
+
4
+ import { Divider } from "./Divider";
5
+ import { variants } from "./Divider.css";
6
+
7
+ type Story = StoryObj<typeof meta>;
8
+
9
+ const meta = {
10
+ component: Divider,
11
+ argTypes: {
12
+ variant: {
13
+ control: { type: "select" },
14
+ options: Object.keys(variants),
15
+ },
16
+ color: {
17
+ control: { type: "select" },
18
+ options: Object.keys(colors),
19
+ },
20
+ },
21
+ } satisfies Meta<typeof Divider>;
22
+
23
+ export default meta;
24
+
25
+ export const Default = {
26
+ args: {},
27
+ } satisfies Story;
@@ -0,0 +1,25 @@
1
+ import { FC } from "react";
2
+ import { colors, sprinkles } from "@prismicio/editor-ui";
3
+ import clsx from "clsx";
4
+
5
+ import * as styles from "./Divider.css";
6
+
7
+ type DividerProps = {
8
+ color?: keyof typeof colors;
9
+ variant?: "dashed" | "edgeFaded";
10
+ className?: string;
11
+ };
12
+
13
+ export const Divider: FC<DividerProps> = (props) => {
14
+ const { variant = "dashed", color = "currentColor", className } = props;
15
+
16
+ return (
17
+ <hr
18
+ className={clsx(
19
+ styles.variants[variant],
20
+ sprinkles({ color: colors[color] }),
21
+ className,
22
+ )}
23
+ />
24
+ );
25
+ };
@@ -0,0 +1 @@
1
+ export { Divider } from "./Divider";
@@ -1,5 +1,5 @@
1
1
  import { colors, sprinkles, vars } from "@prismicio/editor-ui";
2
- import { style } from "@vanilla-extract/css";
2
+ import { style, styleVariants } from "@vanilla-extract/css";
3
3
 
4
4
  const grid = sprinkles({ all: "unset", display: "grid" });
5
5
 
@@ -23,10 +23,9 @@ export const root = style([
23
23
  },
24
24
  ]);
25
25
 
26
- export const borderTop = style([
26
+ const borderTopBase = style([
27
27
  sprinkles({
28
28
  all: "unset",
29
- backgroundColor: colors.purple9,
30
29
  display: "revert",
31
30
  height: 2,
32
31
  position: "fixed",
@@ -35,6 +34,12 @@ export const borderTop = style([
35
34
  { width: "inherit" },
36
35
  ]);
37
36
 
37
+ export const borderTop = styleVariants({
38
+ prod: [borderTopBase, sprinkles({ backgroundColor: colors.purple9 })],
39
+ stage: [borderTopBase, sprinkles({ backgroundColor: colors.indigo10 })],
40
+ dev: [borderTopBase, sprinkles({ backgroundColor: colors.amber10 })],
41
+ });
42
+
38
43
  export const pane = style([
39
44
  grid,
40
45
  sprinkles({
@@ -6,12 +6,21 @@ import {
6
6
  PageLayoutHeader,
7
7
  PageLayoutPane,
8
8
  } from "./PageLayout";
9
+ import { borderTop } from "./PageLayout.css";
9
10
 
10
11
  type Story = StoryObj<typeof meta>;
11
12
 
12
13
  const meta = {
13
14
  component: PageLayout,
14
- argTypes: { children: { control: { disable: true } } },
15
+ argTypes: {
16
+ children: {
17
+ control: { disable: true },
18
+ },
19
+ activeEnvironmentKind: {
20
+ control: { type: "select" },
21
+ options: Object.keys(borderTop),
22
+ },
23
+ },
15
24
  parameters: {
16
25
  docs: { story: { height: 256, inline: false } },
17
26
  layout: "fullscreen",
@@ -2,13 +2,18 @@ import type { FC, PropsWithChildren } from "react";
2
2
 
3
3
  import * as styles from "./PageLayout.css";
4
4
 
5
- export const PageLayout: FC<PropsWithChildren> = ({
5
+ type PageLayoutProps = PropsWithChildren<{
6
+ activeEnvironmentKind?: "prod" | "stage" | "dev";
7
+ }>;
8
+
9
+ export const PageLayout: FC<PageLayoutProps> = ({
10
+ activeEnvironmentKind = "prod",
6
11
  children,
7
12
  ...otherProps
8
13
  }) => (
9
14
  <div {...otherProps} className={styles.root}>
10
15
  {children}
11
- <div className={styles.borderTop} />
16
+ <div className={styles.borderTop[activeEnvironmentKind]} />
12
17
  </div>
13
18
  );
14
19
 
@@ -101,7 +101,6 @@ export const repositoryLinkIcon = style([
101
101
  borderWidth: 1,
102
102
  cursor: "pointer",
103
103
  height: 32,
104
- marginRight: 8,
105
104
  width: 32,
106
105
  color: colors.grey12,
107
106
  backgroundColor: {
@@ -163,15 +162,9 @@ export const listTitle = style([
163
162
  },
164
163
  ]);
165
164
 
166
- export const dashedLine = style([
167
- blockWithDisplayRevert,
168
- sprinkles({
169
- borderColor: colors.grey6,
170
- borderTopStyle: "dashed",
171
- borderWidth: 1,
172
- marginTop: 8,
173
- }),
174
- ]);
165
+ export const separator = sprinkles({
166
+ marginTop: 8,
167
+ });
175
168
 
176
169
  export const link = style([
177
170
  block,
@@ -5,7 +5,6 @@ import { LightningIcon } from "@src/icons/Lightning";
5
5
 
6
6
  import {
7
7
  SideNav,
8
- SideNavLogo,
9
8
  SideNavList,
10
9
  SideNavListItem,
11
10
  SideNavLink,
@@ -15,6 +14,7 @@ import {
15
14
  SideNavRepository,
16
15
  RightElement,
17
16
  } from "./SideNav";
17
+ import { SideNavEnvironmentSelector } from "./SideNavEnvironmentSelector";
18
18
 
19
19
  type Story = StoryObj<typeof meta>;
20
20
 
@@ -33,7 +33,34 @@ export const Default = {
33
33
  args: {
34
34
  children: (
35
35
  <>
36
- <SideNavLogo />
36
+ <SideNavEnvironmentSelector
37
+ environments={[
38
+ {
39
+ name: "Production",
40
+ domain: "example-prismic-repo",
41
+ kind: "prod",
42
+ users: [{ id: "id" }],
43
+ },
44
+ {
45
+ name: "Staging",
46
+ domain: "example-prismic-repo-staging",
47
+ kind: "stage",
48
+ users: [{ id: "id" }],
49
+ },
50
+ {
51
+ name: "Development",
52
+ domain: "example-prismic-repo-development",
53
+ kind: "dev",
54
+ users: [{ id: "id" }],
55
+ },
56
+ ]}
57
+ activeEnvironment={{
58
+ name: "Production",
59
+ domain: "example-prismic-repo",
60
+ kind: "prod",
61
+ users: [{ id: "id" }],
62
+ }}
63
+ />
37
64
 
38
65
  <SideNavRepository
39
66
  repositoryName="really long repository name"
@@ -16,6 +16,8 @@ import type { UrlObject } from "node:url";
16
16
  import LogoIcon from "@src/icons/LogoIcon";
17
17
  import OpenIcon from "@src/icons/OpenIcon";
18
18
 
19
+ import { Divider } from "../Divider";
20
+
19
21
  import * as styles from "./SideNav.css";
20
22
 
21
23
  type SideNavProps = PropsWithChildren<{ style?: CSSProperties }>;
@@ -90,7 +92,9 @@ export const SideNavListTitle: FC<PropsWithChildren> = (props) => (
90
92
  <h3 {...props} className={styles.listTitle} />
91
93
  );
92
94
 
93
- export const SideNavSeparator = () => <hr className={styles.dashedLine} />;
95
+ export const SideNavSeparator = () => (
96
+ <Divider color="grey6" className={styles.separator} />
97
+ );
94
98
 
95
99
  export type SideNavLinkProps = {
96
100
  title: string;
@@ -0,0 +1,69 @@
1
+ import { colors, sprinkles } from "@prismicio/editor-ui";
2
+ import { style, styleVariants } from "@vanilla-extract/css";
3
+
4
+ export const logo = style([
5
+ sprinkles({
6
+ height: 40,
7
+ width: 40,
8
+ }),
9
+ {
10
+ display: "block",
11
+ },
12
+ ]);
13
+
14
+ const environmentDotBase = style([
15
+ sprinkles({
16
+ flexShrink: 0,
17
+ borderRadius: "50%",
18
+ }),
19
+ {
20
+ width: 10,
21
+ height: 10,
22
+ },
23
+ ]);
24
+
25
+ export const environmentDot = styleVariants({
26
+ prod: [environmentDotBase, sprinkles({ backgroundColor: colors.purple10 })],
27
+ stage: [environmentDotBase, sprinkles({ backgroundColor: colors.indigo10 })],
28
+ dev: [environmentDotBase, sprinkles({ backgroundColor: colors.amber10 })],
29
+ });
30
+
31
+ export const menuItemEnvironmentDot = sprinkles({
32
+ marginRight: 2,
33
+ marginLeft: 2,
34
+ });
35
+
36
+ export const activeEnvironmentDot = style([
37
+ sprinkles({
38
+ position: "absolute",
39
+ bottom: 0,
40
+ right: 0,
41
+ outlineWidth: 3,
42
+ outlineColor: colors.grey2,
43
+ outlineStyle: "solid",
44
+ }),
45
+ {
46
+ transform: "translate(50%, 50%)",
47
+ },
48
+ ]);
49
+
50
+ export const activeEnvironmentName = style([
51
+ sprinkles({
52
+ overflow: "hidden",
53
+ textOverflow: "ellipsis",
54
+ whiteSpace: "nowrap",
55
+ }),
56
+ {
57
+ fontWeight: 500,
58
+ lineHeight: "1.25rem",
59
+ },
60
+ ]);
61
+
62
+ export const actionRequiredLabel = style([
63
+ sprinkles({
64
+ color: colors.purple10,
65
+ }),
66
+ {
67
+ fontWeight: 500,
68
+ },
69
+ ]);
@@ -0,0 +1,163 @@
1
+ import {
2
+ Box,
3
+ DropdownMenu,
4
+ DropdownMenuContent,
5
+ DropdownMenuItem,
6
+ DropdownMenuLabel,
7
+ DropdownMenuTrigger,
8
+ Icon,
9
+ IconButton,
10
+ Text,
11
+ } from "@prismicio/editor-ui";
12
+ import { Environment } from "@slicemachine/manager/client";
13
+ import type { FC } from "react";
14
+ import clsx from "clsx";
15
+
16
+ import LogoIcon from "@src/icons/LogoIcon";
17
+
18
+ import * as styles from "./SideNavEnvironmentSelector.css";
19
+
20
+ type SideNavEnvironmentSelectorProps = {
21
+ variant?: "default" | "unauthorized";
22
+ environments?: Environment[];
23
+ activeEnvironment?: Environment;
24
+ onSelect?: (environment: Environment) => void | Promise<void>;
25
+ onLogInClick?: () => void;
26
+ };
27
+
28
+ export const SideNavEnvironmentSelector: FC<SideNavEnvironmentSelectorProps> = (
29
+ props,
30
+ ) => {
31
+ const {
32
+ variant = "default",
33
+ environments = [],
34
+ activeEnvironment,
35
+ onSelect,
36
+ onLogInClick,
37
+ } = props;
38
+
39
+ const isProductionEnvironmentActive = activeEnvironment?.kind === "prod";
40
+
41
+ return (
42
+ <Box alignItems="center" gap={16}>
43
+ <Box position="relative">
44
+ <LogoIcon className={styles.logo} />
45
+ {activeEnvironment !== undefined && (
46
+ <EnvironmentDot
47
+ kind={activeEnvironment.kind}
48
+ className={styles.activeEnvironmentDot}
49
+ />
50
+ )}
51
+ </Box>
52
+ <Box flexGrow={1} flexDirection="column" overflow="hidden">
53
+ <Text component="span" variant="small" color="grey11">
54
+ Environment
55
+ </Text>
56
+ {variant === "unauthorized" ? (
57
+ <Text component="span" className={styles.actionRequiredLabel}>
58
+ Login required
59
+ </Text>
60
+ ) : activeEnvironment === undefined ? (
61
+ <Text component="span" className={styles.actionRequiredLabel}>
62
+ Select environment
63
+ </Text>
64
+ ) : (
65
+ <Text component="span" className={styles.activeEnvironmentName}>
66
+ {isProductionEnvironmentActive
67
+ ? "Production"
68
+ : activeEnvironment?.name}
69
+ </Text>
70
+ )}
71
+ </Box>
72
+ <Box flexShrink={0}>
73
+ {variant === "unauthorized" ? (
74
+ <IconButton icon="arrowForward" onClick={onLogInClick} />
75
+ ) : !activeEnvironment || environments.length > 1 ? (
76
+ <EnvironmentDropdownMenu
77
+ environments={environments}
78
+ activeEnvironment={activeEnvironment}
79
+ onSelect={onSelect}
80
+ />
81
+ ) : null}
82
+ </Box>
83
+ </Box>
84
+ );
85
+ };
86
+
87
+ type EnvironmentDropdownMenuProps = Pick<
88
+ SideNavEnvironmentSelectorProps,
89
+ "environments" | "activeEnvironment" | "onSelect"
90
+ >;
91
+
92
+ const EnvironmentDropdownMenu: FC<EnvironmentDropdownMenuProps> = (props) => {
93
+ const { environments = [], activeEnvironment, onSelect } = props;
94
+
95
+ return (
96
+ <DropdownMenu modal>
97
+ <DropdownMenuTrigger>
98
+ <IconButton icon="unfoldMore" />
99
+ </DropdownMenuTrigger>
100
+ <DropdownMenuContent align="end" minWidth={256}>
101
+ <DropdownMenuLabel>Regular Environments</DropdownMenuLabel>
102
+ {environments.map((environment) =>
103
+ environment.kind !== "dev" ? (
104
+ <EnvironmentDropdownMenuItem
105
+ key={environment.domain}
106
+ environment={environment}
107
+ onSelect={onSelect}
108
+ isActive={environment.domain === activeEnvironment?.domain}
109
+ />
110
+ ) : (
111
+ <>
112
+ <DropdownMenuLabel>Personal Environment</DropdownMenuLabel>
113
+ <EnvironmentDropdownMenuItem
114
+ key={environment.domain}
115
+ environment={environment}
116
+ onSelect={onSelect}
117
+ isActive={environment.domain === activeEnvironment?.domain}
118
+ />
119
+ </>
120
+ ),
121
+ )}
122
+ </DropdownMenuContent>
123
+ </DropdownMenu>
124
+ );
125
+ };
126
+
127
+ type EnvironmentDropdownMenuItemProps = {
128
+ environment: Environment;
129
+ isActive?: boolean;
130
+ } & Pick<SideNavEnvironmentSelectorProps, "onSelect">;
131
+
132
+ const EnvironmentDropdownMenuItem: FC<EnvironmentDropdownMenuItemProps> = (
133
+ props,
134
+ ) => {
135
+ const { environment, onSelect, isActive } = props;
136
+ const isProductionEnvironment = environment.kind === "prod";
137
+
138
+ return (
139
+ <DropdownMenuItem
140
+ startIcon={
141
+ <EnvironmentDot
142
+ kind={environment.kind}
143
+ className={styles.menuItemEnvironmentDot}
144
+ />
145
+ }
146
+ endIcon={Boolean(isActive) ? <Icon name="check" /> : undefined}
147
+ onSelect={() => void onSelect?.(environment)}
148
+ >
149
+ {isProductionEnvironment ? "Production" : environment.name}
150
+ </DropdownMenuItem>
151
+ );
152
+ };
153
+
154
+ type EnvironmentDotProps = {
155
+ kind: Environment["kind"];
156
+ className?: string;
157
+ };
158
+
159
+ const EnvironmentDot: FC<EnvironmentDotProps> = (props) => {
160
+ const { kind, className } = props;
161
+
162
+ return <div className={clsx(styles.environmentDot[kind], className)} />;
163
+ };
@@ -1 +1,2 @@
1
1
  export * from "./SideNav";
2
+ export { SideNavEnvironmentSelector } from "./SideNavEnvironmentSelector";
@@ -178,9 +178,10 @@ async function renderCustomTypesBuilderPage({
178
178
  const renderResults = render(<CustomTypesBuilderPage />, customTypeMockStore);
179
179
 
180
180
  const folder = customType.format === "page" ? "Page types" : "Custom types";
181
- expect(
182
- screen.getByTestId(`breadcrumb-${folder}-${customType.label as string}`),
183
- ).toBeVisible();
181
+ const breadcrumb = await screen.findByTestId(
182
+ `breadcrumb-${folder}-${customType.label as string}`,
183
+ );
184
+ expect(breadcrumb).toBeVisible();
184
185
 
185
186
  return renderResults;
186
187
  }
@@ -0,0 +1,11 @@
1
+ import { managerClient } from "@src/managerClient";
2
+
3
+ export async function getActiveEnvironmentDomain() {
4
+ try {
5
+ const { environment } = await managerClient.project.readEnvironment();
6
+
7
+ return { activeEnvironmentDomain: environment };
8
+ } catch (error) {
9
+ return { error };
10
+ }
11
+ }
@@ -0,0 +1,12 @@
1
+ import { managerClient } from "@src/managerClient";
2
+
3
+ export async function getEnvironments() {
4
+ try {
5
+ const environments =
6
+ await managerClient.prismicRepository.fetchEnvironments();
7
+
8
+ return { environments };
9
+ } catch (error) {
10
+ return { error };
11
+ }
12
+ }
@@ -0,0 +1,18 @@
1
+ import { revalidateData } from "@prismicio/editor-support/Suspense";
2
+ import { Environment } from "@slicemachine/manager/client";
3
+
4
+ import { getLegacySliceMachineState } from "@src/features/legacyState/actions/getLegacySliceMachineState";
5
+ import { managerClient } from "@src/managerClient";
6
+
7
+ import { getActiveEnvironmentDomain } from "./getActiveEnvironmentDomain";
8
+
9
+ export async function setEnvironment(
10
+ environment: Pick<Environment, "domain">,
11
+ ): Promise<void> {
12
+ await managerClient.project.updateEnvironment({
13
+ environment: environment.domain,
14
+ });
15
+
16
+ revalidateData(getActiveEnvironmentDomain, []);
17
+ revalidateData(getLegacySliceMachineState, []);
18
+ }
@@ -0,0 +1,38 @@
1
+ import { useRequest } from "@prismicio/editor-support/Suspense";
2
+
3
+ import { getActiveEnvironmentDomain } from "./actions/getActiveEnvironmentDomain";
4
+ import { useEnvironments } from "./useEnvironments";
5
+
6
+ export function useActiveEnvironment() {
7
+ const { environments, error: useEnvironmentsError } = useEnvironments();
8
+ const { activeEnvironmentDomain, error: getActiveEnvironmentError } =
9
+ useRequest(getActiveEnvironmentDomain, []);
10
+
11
+ if (useEnvironmentsError !== undefined) {
12
+ return { error: useEnvironmentsError };
13
+ }
14
+
15
+ if (getActiveEnvironmentError !== undefined) {
16
+ return { error: getActiveEnvironmentError };
17
+ }
18
+
19
+ const activeEnvironment = environments?.find((environment) => {
20
+ if (activeEnvironmentDomain === undefined) {
21
+ return environment.kind === "prod";
22
+ }
23
+
24
+ return environment.domain === activeEnvironmentDomain;
25
+ });
26
+
27
+ if (!activeEnvironment) {
28
+ return {
29
+ error: new Error(
30
+ `The active environment (${
31
+ activeEnvironmentDomain ?? "Production"
32
+ }) does not match one of the repository's environments.`,
33
+ ),
34
+ };
35
+ }
36
+
37
+ return { activeEnvironment };
38
+ }
@@ -0,0 +1,7 @@
1
+ import { useRequest } from "@prismicio/editor-support/Suspense";
2
+
3
+ import { getEnvironments } from "./actions/getEnvironments";
4
+
5
+ export function useEnvironments() {
6
+ return useRequest(getEnvironments, []);
7
+ }
@@ -0,0 +1,53 @@
1
+ import ServerState from "@models/server/ServerState";
2
+ import { Slices } from "@lib/models/common/Slice";
3
+ import { CustomTypes } from "@lib/models/common/CustomType";
4
+ import { managerClient } from "@src/managerClient";
5
+
6
+ export async function getLegacySliceMachineState() {
7
+ const rawState = await managerClient.getState();
8
+
9
+ // `rawState` from the client contains non-SM-specific models. We need to
10
+ // transform the data to something SM recognizes.
11
+ const state: ServerState = {
12
+ ...rawState,
13
+ libraries: rawState.libraries.map((library) => {
14
+ return {
15
+ ...library,
16
+ components: library.components.map((component) => {
17
+ return {
18
+ ...component,
19
+ model: Slices.toSM(component.model),
20
+
21
+ // Replace screnshot Blobs with URLs.
22
+ screenshots: Object.fromEntries(
23
+ Object.entries(component.screenshots).map(
24
+ ([variationID, screenshot]) => {
25
+ return [
26
+ variationID,
27
+ {
28
+ ...screenshot,
29
+ url: URL.createObjectURL(screenshot.data),
30
+ },
31
+ ];
32
+ },
33
+ ),
34
+ ),
35
+ };
36
+ }),
37
+ };
38
+ }),
39
+ customTypes: rawState.customTypes.map((customTypeModel) => {
40
+ return CustomTypes.toSM(customTypeModel);
41
+ }),
42
+ remoteCustomTypes: rawState.remoteCustomTypes.map(
43
+ (remoteCustomTypeModel) => {
44
+ return CustomTypes.toSM(remoteCustomTypeModel);
45
+ },
46
+ ),
47
+ remoteSlices: rawState.remoteSlices.map((remoteSliceModel) => {
48
+ return Slices.toSM(remoteSliceModel);
49
+ }),
50
+ };
51
+
52
+ return state;
53
+ }
@@ -0,0 +1,7 @@
1
+ import { useRequest } from "@prismicio/editor-support/Suspense";
2
+
3
+ import { getLegacySliceMachineState } from "./actions/getLegacySliceMachineState";
4
+
5
+ export function useLegacySliceMachineState() {
6
+ return useRequest(getLegacySliceMachineState, []);
7
+ }