slice-machine-ui 1.23.2-alpha.xru-auto-sync-provider.3 → 1.23.2-beta.2
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 +2 -6
- package/components/CustomTypeTable/changesPage.tsx +7 -12
- package/components/DeleteSliceModal/index.tsx +24 -37
- package/components/Forms/CreateCustomTypeModal/CreateCustomTypeModal.tsx +38 -65
- package/components/Forms/CreateSliceModal/CreateSliceModal.tsx +1 -3
- package/components/Forms/RenameCustomTypeModal/RenameCustomTypeModal.tsx +2 -7
- package/components/Forms/RenameSliceModal/RenameSliceModal.tsx +21 -36
- package/components/LoginModal/index.tsx +2 -40
- package/components/Navigation/ChangesListItem.tsx +92 -0
- package/components/Navigation/ChangesRightElement.tsx +33 -0
- package/components/Navigation/Environment.tsx +4 -38
- package/components/Navigation/index.test.tsx +85 -5
- package/components/Navigation/index.tsx +8 -3
- package/lib/builders/SliceBuilder/index.tsx +3 -3
- package/lib/models/common/ModelStatus/index.ts +0 -25
- package/out/404.html +1 -1
- package/out/_next/static/{Fwm-rgKzl3GHiphGOBICh → HXkyCNwSfsIXY_W6wsobB}/_buildManifest.js +1 -1
- package/out/_next/static/chunks/25-37d6fa7f064be04b.js +1 -0
- package/out/_next/static/chunks/{318-454bf8a965950ade.js → 318-ce7e74f18f2d5b22.js} +1 -1
- package/out/_next/static/chunks/727-3a3bc32518778317.js +1 -0
- package/out/_next/static/chunks/731-501990ebe6a71b32.js +1 -0
- package/out/_next/static/chunks/904-9a4c1264727ae89a.js +1 -0
- package/out/_next/static/chunks/pages/{_app-49689700be9746a4.js → _app-a6fbbdc935e999c8.js} +23 -23
- package/out/_next/static/chunks/pages/{changelog-e7fec5abbaa7fd76.js → changelog-afd18276fe018b24.js} +1 -1
- package/out/_next/static/chunks/pages/changes-2a976f9efeb719aa.js +1 -0
- package/out/_next/static/chunks/pages/custom-types/{[customTypeId]-97ab3b90b85d645d.js → [customTypeId]-3f862ad6111a1fc0.js} +1 -1
- package/out/_next/static/chunks/pages/{custom-types-3c8e721ec6802127.js → custom-types-94b8f8dbf7727412.js} +1 -1
- package/out/_next/static/chunks/pages/index-64cfb8b0948ba8ef.js +1 -0
- package/out/_next/static/chunks/pages/{labs-6e4db3f376f06dd9.js → labs-ee206005948f8e87.js} +1 -1
- package/out/_next/static/chunks/pages/page-types/{[pageTypeId]-84a22c5e480d3fa9.js → [pageTypeId]-d1ffca11c42f2603.js} +1 -1
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]/{simulator-154af07027964d85.js → simulator-897ca93c114a1435.js} +1 -1
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-b2a9d773ce5d7739.js +1 -0
- package/out/_next/static/chunks/pages/slices-e9c70c082ca3e3f9.js +1 -0
- package/out/_next/static/css/{0a8858de76498e62.css → 200244e3e0463c39.css} +1 -1
- 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 -3
- package/pages/_app.tsx +32 -34
- package/pages/changes.tsx +41 -27
- package/pages/slices.tsx +8 -20
- package/src/apiClient.ts +22 -1
- package/src/components/FieldSet/FieldSet.stories.tsx +36 -3
- package/src/components/SideNav/SideNav.css.ts +1 -1
- package/src/components/SideNav/SideNav.tsx +5 -9
- package/src/components/SideNav/SideNavEnvironmentSelector.tsx +1 -7
- package/src/domain/__tests__/customType.test.ts +0 -179
- package/src/domain/customType.ts +2 -110
- package/src/domain/slice.ts +0 -38
- package/src/features/autoSave/AutoSaveStatusIndicator.tsx +4 -4
- package/src/features/autoSave/useAutoSave.tsx +177 -0
- package/src/features/customTypes/PageTypeOnboarding.tsx +26 -21
- package/src/features/customTypes/__tests__/createCustomType.test.ts +159 -0
- package/src/features/customTypes/actions/convertCustomToPageType.ts +10 -14
- package/src/features/customTypes/actions/deleteCustomType.ts +3 -13
- package/src/features/customTypes/actions/renameCustomType.ts +4 -10
- package/src/features/customTypes/customTypesBuilder/CustomTypeProvider.tsx +10 -11
- package/src/features/customTypes/customTypesBuilder/CustomTypesBuilderPage.tsx +3 -5
- package/src/features/customTypes/customTypesTable/CustomTypesTable.tsx +8 -8
- package/src/features/customTypes/customTypesTable/CustomTypesTablePage.tsx +17 -18
- package/src/features/customTypes/customTypesTable/createCustomType.ts +107 -0
- package/src/features/environments/actions/setEnvironment.ts +3 -3
- package/src/features/legacyState/actions/getLegacySliceMachineState.ts +53 -0
- package/src/features/legacyState/useLegacySliceMachineState.ts +7 -0
- package/src/features/slices/actions/createSlice.ts +29 -5
- package/src/features/slices/sliceBuilder/SliceBuilderProvider.tsx +10 -12
- package/src/hooks/useModelStatus.ts +78 -0
- package/src/hooks/useUnSyncChanges.ts +88 -0
- package/src/modules/availableCustomTypes/index.ts +135 -29
- package/src/modules/loading/types.ts +5 -0
- package/src/modules/modal/types.ts +3 -0
- package/src/modules/slices/index.ts +193 -27
- package/src/modules/slices/selector.ts +14 -0
- package/src/modules/useSliceMachineActions.ts +89 -70
- package/src/modules/userContext/index.ts +3 -3
- package/src/redux/saga.ts +4 -0
- package/test/__testutils__/index.tsx +5 -8
- package/test/components/CreateCustomTypeModal.test.tsx +73 -0
- package/test/components/LoginModal.test.tsx +67 -0
- package/test/src/hooks/useModelStatus.test.ts +115 -0
- package/test/src/modules/availableCustomTypes/index.test.ts +243 -2
- package/test/src/modules/slices.test.ts +267 -1
- package/components/Navigation/ChangesItem.tsx +0 -117
- package/out/_next/static/chunks/25-3aa4d4b24167d340.js +0 -1
- package/out/_next/static/chunks/727-c831123e1c86b720.js +0 -1
- package/out/_next/static/chunks/799-23b4576fcfc3120b.js +0 -1
- package/out/_next/static/chunks/904-01fd75f7fda35678.js +0 -1
- package/out/_next/static/chunks/pages/changes-62c82c4a394f2205.js +0 -1
- package/out/_next/static/chunks/pages/index-cf93d16e9c63b6db.js +0 -1
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-d19b12efd6e632f9.js +0 -1
- package/out/_next/static/chunks/pages/slices-cdb42209ce1f0b88.js +0 -1
- package/src/features/customTypes/actions/createCustomType.ts +0 -69
- package/src/features/slices/actions/deleteSlice.ts +0 -33
- package/src/features/slices/actions/renameSlice.ts +0 -37
- package/src/features/sync/AutoSyncProvider.tsx +0 -243
- package/src/features/sync/components/AutoSyncStatusIndicator.module.css +0 -19
- package/src/features/sync/components/AutoSyncStatusIndicator.module.css.d.ts +0 -5
- package/src/features/sync/components/AutoSyncStatusIndicator.tsx +0 -59
- package/src/features/sync/fetchUnSyncChanges.ts +0 -40
- package/src/features/sync/getUnSyncChanges.ts +0 -144
- package/src/features/sync/useUnSyncChanges.ts +0 -32
- package/src/hooks/useActionQueue.tsx +0 -177
- package/src/hooks/useAuthStatus.ts +0 -12
- package/src/hooks/useOnMountEffect.ts +0 -6
- package/src/icons/SyncFailed.tsx +0 -30
- package/src/icons/Synced.tsx +0 -19
- package/src/icons/Syncing.tsx +0 -23
- /package/out/_next/static/{Fwm-rgKzl3GHiphGOBICh → HXkyCNwSfsIXY_W6wsobB}/_ssgManifest.js +0 -0
- /package/src/features/{sync → changes}/actions/pushChanges.ts +0 -0
- /package/src/features/{sync → changes}/actions/trackPushChangesSuccess.ts +0 -0
|
@@ -6,23 +6,19 @@ import { ChangesSectionHeader } from "@components/ChangesSectionHeader";
|
|
|
6
6
|
import { CustomTypeTable } from "@components/CustomTypeTable/changesPage";
|
|
7
7
|
import Grid from "@components/Grid";
|
|
8
8
|
import { ComponentUI } from "@lib/models/common/ComponentUI";
|
|
9
|
+
import { ModelStatusInformation } from "@src/hooks/useModelStatus";
|
|
9
10
|
import ScreenshotChangesModal from "@components/ScreenshotChangesModal";
|
|
10
11
|
import { countMissingScreenshots } from "@src/domain/slice";
|
|
11
12
|
import { useScreenshotChangesModal } from "@src/hooks/useScreenshotChangesModal";
|
|
12
13
|
import { ModelStatus } from "@lib/models/common/ModelStatus";
|
|
13
14
|
import { LocalOrRemoteCustomType } from "@lib/models/common/ModelData";
|
|
14
15
|
import { SharedSliceCard } from "@src/features/slices/sliceCards/SharedSliceCard";
|
|
15
|
-
import { AuthStatus } from "@src/modules/userContext/types";
|
|
16
|
-
import { ModelsStatuses } from "@src/features/sync/getUnSyncChanges";
|
|
17
16
|
|
|
18
17
|
import { DevCollaborationExperiment } from "./DevCollaborationExperiment";
|
|
19
18
|
|
|
20
|
-
interface ChangesItemsProps {
|
|
19
|
+
interface ChangesItemsProps extends ModelStatusInformation {
|
|
21
20
|
unSyncedCustomTypes: LocalOrRemoteCustomType[];
|
|
22
21
|
unSyncedSlices: ComponentUI[];
|
|
23
|
-
modelsStatuses: ModelsStatuses;
|
|
24
|
-
authStatus: AuthStatus;
|
|
25
|
-
isOnline: boolean;
|
|
26
22
|
}
|
|
27
23
|
|
|
28
24
|
export const ChangesItems: React.FC<ChangesItemsProps> = ({
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Link from "next/link";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { Box, Text } from "theme-ui";
|
|
4
|
+
import { ModelStatusInformation } from "@src/hooks/useModelStatus";
|
|
4
5
|
import { CustomTypeSM } from "@lib/models/common/CustomType";
|
|
5
6
|
import { ModelStatus } from "@lib/models/common/ModelStatus";
|
|
6
7
|
import {
|
|
@@ -9,26 +10,18 @@ import {
|
|
|
9
10
|
} from "@lib/models/common/ModelData";
|
|
10
11
|
import { StatusBadge } from "@src/features/changes/StatusBadge";
|
|
11
12
|
import { CUSTOM_TYPES_CONFIG } from "@src/features/customTypes/customTypesConfig";
|
|
12
|
-
import { AuthStatus } from "@src/modules/userContext/types";
|
|
13
|
-
import { ModelsStatuses } from "@src/features/sync/getUnSyncChanges";
|
|
14
13
|
|
|
15
|
-
interface CustomTypeTableProps {
|
|
14
|
+
interface CustomTypeTableProps extends ModelStatusInformation {
|
|
16
15
|
customTypes: LocalOrRemoteCustomType[];
|
|
17
|
-
modelsStatuses: ModelsStatuses;
|
|
18
|
-
authStatus: AuthStatus;
|
|
19
|
-
isOnline: boolean;
|
|
20
16
|
}
|
|
21
17
|
|
|
22
18
|
const firstColumnWidth = "40%";
|
|
23
19
|
const secondColumnWidth = "40%";
|
|
24
20
|
const thirdColumnWidth = "20%";
|
|
25
21
|
|
|
26
|
-
const CustomTypeChangeRow: React.FC<
|
|
27
|
-
ct: CustomTypeSM;
|
|
28
|
-
|
|
29
|
-
authStatus: AuthStatus;
|
|
30
|
-
isOnline: boolean;
|
|
31
|
-
}> = ({ ct, status, authStatus, isOnline }) => {
|
|
22
|
+
const CustomTypeChangeRow: React.FC<
|
|
23
|
+
{ ct: CustomTypeSM; status: ModelStatus } & ModelStatusInformation
|
|
24
|
+
> = ({ ct, status, authStatus, isOnline }) => {
|
|
32
25
|
return (
|
|
33
26
|
<>
|
|
34
27
|
<Box as={"td"} style={{ width: firstColumnWidth }}>
|
|
@@ -87,6 +80,7 @@ export const CustomTypeTable: React.FC<CustomTypeTableProps> = ({
|
|
|
87
80
|
status={modelsStatuses.customTypes[customType.local.id]}
|
|
88
81
|
authStatus={authStatus}
|
|
89
82
|
isOnline={isOnline}
|
|
83
|
+
modelsStatuses={modelsStatuses}
|
|
90
84
|
key={customType.local.id}
|
|
91
85
|
/>
|
|
92
86
|
</tr>
|
|
@@ -103,6 +97,7 @@ export const CustomTypeTable: React.FC<CustomTypeTableProps> = ({
|
|
|
103
97
|
status={modelsStatuses.customTypes[customType.remote.id]}
|
|
104
98
|
authStatus={authStatus}
|
|
105
99
|
isOnline={isOnline}
|
|
100
|
+
modelsStatuses={modelsStatuses}
|
|
106
101
|
key={customType.remote.id}
|
|
107
102
|
/>
|
|
108
103
|
</tr>
|
|
@@ -1,57 +1,46 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
|
-
import { MdOutlineDelete } from "react-icons/md";
|
|
3
|
-
import { Close, Flex, Heading, Paragraph, Text, useThemeUI } from "theme-ui";
|
|
4
|
-
|
|
5
1
|
import SliceMachineModal from "@components/SliceMachineModal";
|
|
2
|
+
import { useSelector } from "react-redux";
|
|
3
|
+
import { SliceMachineStoreType } from "@src/redux/type";
|
|
4
|
+
import { isModalOpen } from "@src/modules/modal";
|
|
5
|
+
import { ModalKeysEnum } from "@src/modules/modal/types";
|
|
6
6
|
import useSliceMachineActions from "@src/modules/useSliceMachineActions";
|
|
7
|
+
import { Close, Flex, Heading, Paragraph, Text, useThemeUI } from "theme-ui";
|
|
7
8
|
import Card from "@components/Card";
|
|
9
|
+
import { MdOutlineDelete } from "react-icons/md";
|
|
8
10
|
import { Button } from "@components/Button";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
+
import { LoadingKeysEnum } from "@src/modules/loading/types";
|
|
12
|
+
import { isLoading } from "@src/modules/loading";
|
|
11
13
|
|
|
12
14
|
type DeleteSliceModalProps = {
|
|
13
|
-
isOpen: boolean;
|
|
14
|
-
libName: string;
|
|
15
15
|
sliceId: string;
|
|
16
16
|
sliceName: string;
|
|
17
|
-
|
|
17
|
+
libName: string;
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
export const DeleteSliceModal: React.FunctionComponent<
|
|
21
21
|
DeleteSliceModalProps
|
|
22
|
-
> = ({ sliceId, sliceName, libName
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
setIsDeleting(true);
|
|
22
|
+
> = ({ sliceId, sliceName, libName }) => {
|
|
23
|
+
const { isSliceModalOpen, isDeletingSlice } = useSelector(
|
|
24
|
+
(store: SliceMachineStoreType) => ({
|
|
25
|
+
isSliceModalOpen: isModalOpen(store, ModalKeysEnum.DELETE_SLICE),
|
|
26
|
+
isDeletingSlice: isLoading(store, LoadingKeysEnum.DELETE_SLICE),
|
|
27
|
+
}),
|
|
28
|
+
);
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
sliceID: sliceId,
|
|
33
|
-
sliceName,
|
|
34
|
-
libraryID: libName,
|
|
35
|
-
onSuccess: () => {
|
|
36
|
-
deleteSliceSuccess(sliceId, libName);
|
|
37
|
-
syncChanges();
|
|
38
|
-
},
|
|
39
|
-
});
|
|
30
|
+
const { closeModals, deleteSlice } = useSliceMachineActions();
|
|
40
31
|
|
|
41
|
-
|
|
42
|
-
setIsDeleting(false);
|
|
43
|
-
};
|
|
32
|
+
const { theme } = useThemeUI();
|
|
44
33
|
|
|
45
34
|
return (
|
|
46
35
|
<SliceMachineModal
|
|
47
|
-
isOpen={
|
|
36
|
+
isOpen={isSliceModalOpen}
|
|
48
37
|
shouldCloseOnOverlayClick={true}
|
|
49
38
|
style={{
|
|
50
39
|
content: {
|
|
51
40
|
maxWidth: 612,
|
|
52
41
|
},
|
|
53
42
|
}}
|
|
54
|
-
onRequestClose={
|
|
43
|
+
onRequestClose={closeModals}
|
|
55
44
|
>
|
|
56
45
|
<Card
|
|
57
46
|
bodySx={{
|
|
@@ -90,7 +79,7 @@ export const DeleteSliceModal: React.FunctionComponent<
|
|
|
90
79
|
Delete Slice
|
|
91
80
|
</Heading>
|
|
92
81
|
</Flex>
|
|
93
|
-
<Close type="button" onClick={
|
|
82
|
+
<Close type="button" onClick={closeModals} />
|
|
94
83
|
</Flex>
|
|
95
84
|
)}
|
|
96
85
|
Footer={() => (
|
|
@@ -107,7 +96,7 @@ export const DeleteSliceModal: React.FunctionComponent<
|
|
|
107
96
|
<Button
|
|
108
97
|
label="Cancel"
|
|
109
98
|
variant="secondary"
|
|
110
|
-
onClick={
|
|
99
|
+
onClick={() => closeModals()}
|
|
111
100
|
sx={{
|
|
112
101
|
mr: "10px",
|
|
113
102
|
fontWeight: "bold",
|
|
@@ -118,11 +107,9 @@ export const DeleteSliceModal: React.FunctionComponent<
|
|
|
118
107
|
<Button
|
|
119
108
|
label="Delete"
|
|
120
109
|
variant="danger"
|
|
121
|
-
isLoading={
|
|
110
|
+
isLoading={isDeletingSlice}
|
|
122
111
|
sx={{ minHeight: 39, minWidth: 78 }}
|
|
123
|
-
onClick={() =>
|
|
124
|
-
void onDelete();
|
|
125
|
-
}}
|
|
112
|
+
onClick={() => deleteSlice(sliceId, sliceName, libName)}
|
|
126
113
|
/>
|
|
127
114
|
</Flex>
|
|
128
115
|
)}
|
|
@@ -2,29 +2,25 @@ import { SetStateAction, useState } from "react";
|
|
|
2
2
|
import { Box } from "theme-ui";
|
|
3
3
|
import { FormikErrors } from "formik";
|
|
4
4
|
import { useSelector } from "react-redux";
|
|
5
|
-
import { useRouter } from "next/router";
|
|
6
5
|
|
|
7
6
|
import ModalFormCard from "@components/ModalFormCard";
|
|
7
|
+
import { InputBox } from "../components/InputBox";
|
|
8
|
+
import { SelectRepeatable } from "../components/SelectRepeatable";
|
|
8
9
|
import useSliceMachineActions from "@src/modules/useSliceMachineActions";
|
|
9
10
|
import { SliceMachineStoreType } from "@src/redux/type";
|
|
10
11
|
import {
|
|
11
12
|
selectAllCustomTypeIds,
|
|
12
13
|
selectAllCustomTypeLabels,
|
|
13
14
|
} from "@src/modules/availableCustomTypes";
|
|
15
|
+
import { isModalOpen } from "@src/modules/modal";
|
|
16
|
+
import { ModalKeysEnum } from "@src/modules/modal/types";
|
|
17
|
+
import { isLoading } from "@src/modules/loading";
|
|
18
|
+
import { LoadingKeysEnum } from "@src/modules/loading/types";
|
|
19
|
+
import { telemetry } from "@src/apiClient";
|
|
14
20
|
import { slugify } from "@lib/utils/str";
|
|
15
21
|
import { API_ID_REGEX } from "@lib/consts";
|
|
16
22
|
import type { CustomTypeFormat } from "@slicemachine/manager";
|
|
17
23
|
import { CUSTOM_TYPES_MESSAGES } from "@src/features/customTypes/customTypesMessages";
|
|
18
|
-
import {
|
|
19
|
-
CustomTypeOrigin,
|
|
20
|
-
createCustomType,
|
|
21
|
-
} from "@src/features/customTypes/actions/createCustomType";
|
|
22
|
-
import { CUSTOM_TYPES_CONFIG } from "@src/features/customTypes/customTypesConfig";
|
|
23
|
-
import { getFormat } from "@src/domain/customType";
|
|
24
|
-
import { useAutoSync } from "@src/features/sync/AutoSyncProvider";
|
|
25
|
-
|
|
26
|
-
import { InputBox } from "../components/InputBox";
|
|
27
|
-
import { SelectRepeatable } from "../components/SelectRepeatable";
|
|
28
24
|
|
|
29
25
|
interface FormValues {
|
|
30
26
|
id: string;
|
|
@@ -34,67 +30,46 @@ interface FormValues {
|
|
|
34
30
|
|
|
35
31
|
type CreateCustomTypeModalProps = {
|
|
36
32
|
format: CustomTypeFormat;
|
|
37
|
-
|
|
38
|
-
isOpen: boolean;
|
|
39
|
-
origin?: CustomTypeOrigin;
|
|
40
|
-
onCreateChange: (isCreating: boolean) => void;
|
|
41
|
-
onOpenChange: (isOpen: boolean) => void;
|
|
33
|
+
origin?: "onboarding" | "table";
|
|
42
34
|
};
|
|
43
35
|
|
|
44
36
|
export const CreateCustomTypeModal: React.FC<CreateCustomTypeModalProps> = ({
|
|
45
37
|
format,
|
|
46
|
-
isCreating,
|
|
47
|
-
isOpen,
|
|
48
38
|
origin = "table",
|
|
49
|
-
onCreateChange,
|
|
50
|
-
onOpenChange,
|
|
51
39
|
}) => {
|
|
52
|
-
const {
|
|
53
|
-
|
|
54
|
-
const {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
)
|
|
40
|
+
const { createCustomType, closeModals } = useSliceMachineActions();
|
|
41
|
+
|
|
42
|
+
const {
|
|
43
|
+
customTypeIds,
|
|
44
|
+
isCreateCustomTypeModalOpen,
|
|
45
|
+
isCreatingCustomType,
|
|
46
|
+
customTypeLabels,
|
|
47
|
+
} = useSelector((store: SliceMachineStoreType) => ({
|
|
48
|
+
customTypeIds: selectAllCustomTypeIds(store),
|
|
49
|
+
customTypeLabels: selectAllCustomTypeLabels(store),
|
|
50
|
+
isCreateCustomTypeModalOpen: isModalOpen(
|
|
51
|
+
store,
|
|
52
|
+
ModalKeysEnum.CREATE_CUSTOM_TYPE,
|
|
53
|
+
),
|
|
54
|
+
isCreatingCustomType: isLoading(store, LoadingKeysEnum.CREATE_CUSTOM_TYPE),
|
|
55
|
+
}));
|
|
60
56
|
const customTypesMessages = CUSTOM_TYPES_MESSAGES[format];
|
|
61
57
|
const [isIdFieldPristine, setIsIdFieldPristine] = useState(true);
|
|
62
|
-
const { syncChanges } = useAutoSync();
|
|
63
|
-
const router = useRouter();
|
|
64
58
|
|
|
65
|
-
const
|
|
66
|
-
|
|
59
|
+
const createCustomTypeAndTrack = ({ id, label, repeatable }: FormValues) => {
|
|
60
|
+
const name = label || id;
|
|
67
61
|
|
|
68
|
-
|
|
69
|
-
|
|
62
|
+
void telemetry.track({
|
|
63
|
+
event: "custom-type:created",
|
|
70
64
|
id,
|
|
71
|
-
|
|
65
|
+
name,
|
|
66
|
+
format,
|
|
67
|
+
type: repeatable ? "repeatable" : "single",
|
|
72
68
|
origin,
|
|
73
|
-
repeatable,
|
|
74
|
-
onSuccess: async (newCustomType) => {
|
|
75
|
-
createCustomTypeSuccess(newCustomType);
|
|
76
|
-
|
|
77
|
-
const format = getFormat(newCustomType);
|
|
78
|
-
const customTypesConfig = CUSTOM_TYPES_CONFIG[format];
|
|
79
|
-
|
|
80
|
-
setIsIdFieldPristine(true);
|
|
81
|
-
|
|
82
|
-
await router.push({
|
|
83
|
-
pathname: customTypesConfig.getBuilderPagePathname(id),
|
|
84
|
-
query:
|
|
85
|
-
newCustomType.format === "page"
|
|
86
|
-
? {
|
|
87
|
-
newPageType: true,
|
|
88
|
-
}
|
|
89
|
-
: undefined,
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
syncChanges();
|
|
93
|
-
},
|
|
94
69
|
});
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
70
|
+
createCustomType(id, name, repeatable, format);
|
|
71
|
+
closeModals();
|
|
72
|
+
setIsIdFieldPristine(true);
|
|
98
73
|
};
|
|
99
74
|
|
|
100
75
|
const handleLabelChange = (
|
|
@@ -131,18 +106,16 @@ export const CreateCustomTypeModal: React.FC<CreateCustomTypeModalProps> = ({
|
|
|
131
106
|
return (
|
|
132
107
|
<ModalFormCard
|
|
133
108
|
dataCy="create-ct-modal"
|
|
134
|
-
isOpen={
|
|
109
|
+
isOpen={isCreateCustomTypeModalOpen}
|
|
135
110
|
widthInPx="530px"
|
|
136
111
|
formId="create-custom-type"
|
|
137
112
|
buttonLabel={"Create"}
|
|
138
113
|
close={() => {
|
|
139
|
-
|
|
114
|
+
closeModals();
|
|
140
115
|
setIsIdFieldPristine(true);
|
|
141
116
|
}}
|
|
142
|
-
onSubmit={
|
|
143
|
-
|
|
144
|
-
}}
|
|
145
|
-
isLoading={isCreating}
|
|
117
|
+
onSubmit={createCustomTypeAndTrack}
|
|
118
|
+
isLoading={isCreatingCustomType}
|
|
146
119
|
initialValues={{
|
|
147
120
|
repeatable: true,
|
|
148
121
|
id: "",
|
|
@@ -9,7 +9,6 @@ import ModalFormCard from "@components/ModalFormCard";
|
|
|
9
9
|
import { createSlice } from "@src/features/slices/actions/createSlice";
|
|
10
10
|
import useSliceMachineActions from "@src/modules/useSliceMachineActions";
|
|
11
11
|
import { getState } from "@src/apiClient";
|
|
12
|
-
import { useAutoSync } from "@src/features/sync/AutoSyncProvider";
|
|
13
12
|
|
|
14
13
|
import { validateSliceModalValues } from "../formsValidator";
|
|
15
14
|
import { InputBox } from "../components/InputBox";
|
|
@@ -31,7 +30,6 @@ export const CreateSliceModal: FC<CreateSliceModalProps> = ({
|
|
|
31
30
|
}) => {
|
|
32
31
|
const { createSliceSuccess } = useSliceMachineActions();
|
|
33
32
|
const [isCreatingSlice, setIsCreatingSlice] = useState(false);
|
|
34
|
-
const { syncChanges } = useAutoSync();
|
|
35
33
|
|
|
36
34
|
const onSubmit = async (values: FormValues) => {
|
|
37
35
|
const sliceName = values.sliceName;
|
|
@@ -47,8 +45,8 @@ export const CreateSliceModal: FC<CreateSliceModalProps> = ({
|
|
|
47
45
|
const serverState = await getState();
|
|
48
46
|
// Update Redux store
|
|
49
47
|
createSliceSuccess(serverState.libraries);
|
|
48
|
+
|
|
50
49
|
onSuccess(newSlice, libraryName);
|
|
51
|
-
syncChanges();
|
|
52
50
|
},
|
|
53
51
|
});
|
|
54
52
|
};
|
|
@@ -13,7 +13,6 @@ import { CustomTypeFormat } from "@slicemachine/manager";
|
|
|
13
13
|
import { CUSTOM_TYPES_MESSAGES } from "@src/features/customTypes/customTypesMessages";
|
|
14
14
|
|
|
15
15
|
import { renameCustomType } from "@src/features/customTypes/actions/renameCustomType";
|
|
16
|
-
import { useAutoSync } from "@src/features/sync/AutoSyncProvider";
|
|
17
16
|
|
|
18
17
|
interface RenameCustomTypeModalProps {
|
|
19
18
|
isChangesLocal: boolean;
|
|
@@ -32,8 +31,7 @@ export const RenameCustomTypeModal: React.FC<RenameCustomTypeModalProps> = ({
|
|
|
32
31
|
}) => {
|
|
33
32
|
const customTypeName = customType?.label ?? "";
|
|
34
33
|
const customTypeId = customType?.id ?? "";
|
|
35
|
-
const {
|
|
36
|
-
const { syncChanges } = useAutoSync();
|
|
34
|
+
const { renameAvailableCustomTypeSuccess } = useSliceMachineActions();
|
|
37
35
|
|
|
38
36
|
const [isRenaming, setIsRenaming] = useState(false);
|
|
39
37
|
|
|
@@ -48,10 +46,7 @@ export const RenameCustomTypeModal: React.FC<RenameCustomTypeModalProps> = ({
|
|
|
48
46
|
await renameCustomType({
|
|
49
47
|
model: customType,
|
|
50
48
|
newLabel: values.customTypeName,
|
|
51
|
-
onSuccess:
|
|
52
|
-
renameCustomTypeSuccess(renamedCustomType);
|
|
53
|
-
syncChanges();
|
|
54
|
-
},
|
|
49
|
+
onSuccess: renameAvailableCustomTypeSuccess,
|
|
55
50
|
});
|
|
56
51
|
}
|
|
57
52
|
setIsRenaming(false);
|
|
@@ -1,65 +1,50 @@
|
|
|
1
1
|
import { Box } from "theme-ui";
|
|
2
|
-
import { useSelector } from "react-redux";
|
|
3
|
-
|
|
4
2
|
import useSliceMachineActions from "@src/modules/useSliceMachineActions";
|
|
3
|
+
import ModalFormCard from "../../ModalFormCard";
|
|
4
|
+
import { InputBox } from "../components/InputBox";
|
|
5
|
+
import { useSelector } from "react-redux";
|
|
5
6
|
import { SliceMachineStoreType } from "@src/redux/type";
|
|
7
|
+
import { isModalOpen } from "@src/modules/modal";
|
|
8
|
+
import { ModalKeysEnum } from "@src/modules/modal/types";
|
|
6
9
|
import { getLibraries, getRemoteSlices } from "@src/modules/slices";
|
|
7
|
-
import { ComponentUI } from "@lib/models/common/ComponentUI";
|
|
8
|
-
import { renameSlice } from "@src/features/slices/actions/renameSlice";
|
|
9
|
-
import { useAutoSync } from "@src/features/sync/AutoSyncProvider";
|
|
10
|
-
|
|
11
|
-
import { InputBox } from "../components/InputBox";
|
|
12
|
-
import ModalFormCard from "../../ModalFormCard";
|
|
13
10
|
import { SliceModalValues } from "../formsTypes";
|
|
14
11
|
import { validateSliceModalValues } from "../formsValidator";
|
|
15
12
|
|
|
16
13
|
interface RenameSliceModalProps {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
sliceName: string;
|
|
15
|
+
sliceId: string;
|
|
16
|
+
libName: string;
|
|
20
17
|
}
|
|
21
18
|
|
|
22
19
|
export const RenameSliceModal: React.FC<RenameSliceModalProps> = ({
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
sliceName,
|
|
21
|
+
sliceId,
|
|
22
|
+
libName,
|
|
26
23
|
}) => {
|
|
27
|
-
const {
|
|
28
|
-
const {
|
|
29
|
-
const { localLibs, remoteLibs } = useSelector(
|
|
24
|
+
const { renameSlice, closeModals } = useSliceMachineActions();
|
|
25
|
+
const { isRenameSliceModalOpen, localLibs, remoteLibs } = useSelector(
|
|
30
26
|
(store: SliceMachineStoreType) => ({
|
|
27
|
+
isRenameSliceModalOpen: isModalOpen(store, ModalKeysEnum.RENAME_SLICE),
|
|
31
28
|
localLibs: getLibraries(store),
|
|
32
29
|
remoteLibs: getRemoteSlices(store),
|
|
33
30
|
}),
|
|
34
31
|
);
|
|
35
|
-
const initialSliceName = slice?.model.name ?? "";
|
|
36
|
-
|
|
37
|
-
const handleOnSubmit = async (values: SliceModalValues) => {
|
|
38
|
-
if (slice) {
|
|
39
|
-
await renameSlice({
|
|
40
|
-
slice,
|
|
41
|
-
newSliceName: values.sliceName,
|
|
42
|
-
onSuccess: (renamedSlice) => {
|
|
43
|
-
renameSliceSuccess(renamedSlice.from, renamedSlice.model);
|
|
44
|
-
syncChanges();
|
|
45
|
-
},
|
|
46
|
-
});
|
|
47
32
|
|
|
48
|
-
|
|
49
|
-
|
|
33
|
+
const handleOnSubmit = (values: SliceModalValues) => {
|
|
34
|
+
renameSlice(libName, sliceId, values.sliceName);
|
|
50
35
|
};
|
|
51
36
|
|
|
52
37
|
return (
|
|
53
38
|
<ModalFormCard<SliceModalValues>
|
|
54
39
|
dataCy="rename-slice-modal"
|
|
55
|
-
isOpen={
|
|
40
|
+
isOpen={isRenameSliceModalOpen}
|
|
56
41
|
widthInPx="530px"
|
|
57
|
-
formId={`rename-slice-modal-${
|
|
58
|
-
close={
|
|
42
|
+
formId={`rename-slice-modal-${sliceId}`}
|
|
43
|
+
close={closeModals}
|
|
59
44
|
buttonLabel="Rename"
|
|
60
|
-
onSubmit={
|
|
45
|
+
onSubmit={handleOnSubmit}
|
|
61
46
|
initialValues={{
|
|
62
|
-
sliceName:
|
|
47
|
+
sliceName: sliceName,
|
|
63
48
|
}}
|
|
64
49
|
content={{
|
|
65
50
|
title: "Rename a slice",
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
Text,
|
|
12
12
|
} from "theme-ui";
|
|
13
13
|
import SliceMachineModal from "@components/SliceMachineModal";
|
|
14
|
-
import { checkAuthStatus,
|
|
14
|
+
import { checkAuthStatus, startAuth } from "@src/apiClient";
|
|
15
15
|
import { buildEndpoints } from "@lib/prismic/endpoints";
|
|
16
16
|
import { startPolling } from "@lib/utils/poll";
|
|
17
17
|
import { CheckAuthStatusResponse } from "@models/common/Auth";
|
|
@@ -25,12 +25,6 @@ import { getEnvironment } from "@src/modules/environment";
|
|
|
25
25
|
import useSliceMachineActions from "@src/modules/useSliceMachineActions";
|
|
26
26
|
import preferWroomBase from "@lib/utils/preferWroomBase";
|
|
27
27
|
import { ToasterType } from "@src/modules/toaster";
|
|
28
|
-
import { getUnSyncedChanges } from "@src/features/sync/getUnSyncChanges";
|
|
29
|
-
import { normalizeFrontendCustomTypes } from "@lib/models/common/normalizers/customType";
|
|
30
|
-
import { normalizeFrontendSlices } from "@lib/models/common/normalizers/slices";
|
|
31
|
-
import { AuthStatus } from "@src/modules/userContext/types";
|
|
32
|
-
import { useAutoSync } from "@src/features/sync/AutoSyncProvider";
|
|
33
|
-
import { getActiveEnvironment } from "@src/features/environments/actions/getActiveEnvironment";
|
|
34
28
|
|
|
35
29
|
interface ValidAuthStatus extends CheckAuthStatusResponse {
|
|
36
30
|
status: "ok";
|
|
@@ -48,7 +42,7 @@ const LoginModal: React.FunctionComponent = () => {
|
|
|
48
42
|
env: getEnvironment(store),
|
|
49
43
|
}),
|
|
50
44
|
);
|
|
51
|
-
|
|
45
|
+
|
|
52
46
|
const { closeModals, startLoadingLogin, stopLoadingLogin, openToaster } =
|
|
53
47
|
useSliceMachineActions();
|
|
54
48
|
|
|
@@ -78,38 +72,6 @@ const LoginModal: React.FunctionComponent = () => {
|
|
|
78
72
|
openToaster("Logged in", ToasterType.SUCCESS);
|
|
79
73
|
stopLoadingLogin();
|
|
80
74
|
closeModals();
|
|
81
|
-
|
|
82
|
-
const serverState = await getState();
|
|
83
|
-
const slices = normalizeFrontendSlices(
|
|
84
|
-
serverState.libraries,
|
|
85
|
-
serverState.remoteSlices,
|
|
86
|
-
);
|
|
87
|
-
const customTypes = Object.values(
|
|
88
|
-
normalizeFrontendCustomTypes(
|
|
89
|
-
serverState.customTypes,
|
|
90
|
-
serverState.remoteCustomTypes,
|
|
91
|
-
),
|
|
92
|
-
);
|
|
93
|
-
const { changedCustomTypes, changedSlices } = getUnSyncedChanges({
|
|
94
|
-
authStatus: AuthStatus.AUTHORIZED,
|
|
95
|
-
customTypes,
|
|
96
|
-
isOnline: true,
|
|
97
|
-
libraries: serverState.libraries,
|
|
98
|
-
slices,
|
|
99
|
-
});
|
|
100
|
-
const { activeEnvironment } = await getActiveEnvironment();
|
|
101
|
-
|
|
102
|
-
if (
|
|
103
|
-
activeEnvironment?.kind === "dev" &&
|
|
104
|
-
(changedCustomTypes.length > 0 || changedSlices.length > 0)
|
|
105
|
-
) {
|
|
106
|
-
syncChanges({
|
|
107
|
-
environment: activeEnvironment,
|
|
108
|
-
loggedIn: true,
|
|
109
|
-
changedCustomTypes,
|
|
110
|
-
changedSlices,
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
75
|
} catch (e) {
|
|
114
76
|
stopLoadingLogin();
|
|
115
77
|
openToaster("Login failed", ToasterType.ERROR);
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { type FC, useState } from "react";
|
|
2
|
+
import Link from "next/link";
|
|
3
|
+
import { useRouter } from "next/router";
|
|
4
|
+
import { SliceMachineStoreType } from "@src/redux/type";
|
|
5
|
+
import { useSelector } from "react-redux";
|
|
6
|
+
|
|
7
|
+
import { SideNavLink, SideNavListItem } from "@src/components/SideNav";
|
|
8
|
+
import { RadarIcon } from "@src/icons/RadarIcon";
|
|
9
|
+
import { isLoading } from "@src/modules/loading";
|
|
10
|
+
import { LoadingKeysEnum } from "@src/modules/loading/types";
|
|
11
|
+
import {
|
|
12
|
+
HoverCard,
|
|
13
|
+
HoverCardCloseButton,
|
|
14
|
+
HoverCardDescription,
|
|
15
|
+
HoverCardMedia,
|
|
16
|
+
HoverCardTitle,
|
|
17
|
+
} from "@src/components/HoverCard";
|
|
18
|
+
import {
|
|
19
|
+
userHasSeenChangesToolTip,
|
|
20
|
+
userHasSeenSimulatorToolTip,
|
|
21
|
+
} from "@src/modules/userContext";
|
|
22
|
+
import useSliceMachineActions from "@src/modules/useSliceMachineActions";
|
|
23
|
+
import { ChangesRightElement } from "./ChangesRightElement";
|
|
24
|
+
|
|
25
|
+
export const ChangesListItem: FC = () => {
|
|
26
|
+
const { setSeenChangesToolTip } = useSliceMachineActions();
|
|
27
|
+
const open = useOpenChangesHoverCard();
|
|
28
|
+
const router = useRouter();
|
|
29
|
+
|
|
30
|
+
const onClose = () => {
|
|
31
|
+
setSeenChangesToolTip();
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<HoverCard
|
|
36
|
+
open={open}
|
|
37
|
+
openDelay={3000}
|
|
38
|
+
onClose={onClose}
|
|
39
|
+
side="right"
|
|
40
|
+
sideOffset={24}
|
|
41
|
+
collisionPadding={280}
|
|
42
|
+
trigger={
|
|
43
|
+
<SideNavListItem>
|
|
44
|
+
<SideNavLink
|
|
45
|
+
title="Changes"
|
|
46
|
+
href="/changes"
|
|
47
|
+
active={router.asPath.startsWith("/changes")}
|
|
48
|
+
component={Link}
|
|
49
|
+
Icon={RadarIcon}
|
|
50
|
+
RightElement={<ChangesRightElement />}
|
|
51
|
+
/>
|
|
52
|
+
</SideNavListItem>
|
|
53
|
+
}
|
|
54
|
+
>
|
|
55
|
+
<HoverCardTitle>Push your changes</HoverCardTitle>
|
|
56
|
+
<HoverCardMedia component="image" src="/push.png" />
|
|
57
|
+
<HoverCardDescription>
|
|
58
|
+
When you click Save, your changes are saved locally. Then, you can push
|
|
59
|
+
your models to Prismic from the Changes page.
|
|
60
|
+
</HoverCardDescription>
|
|
61
|
+
<HoverCardCloseButton>Got it</HoverCardCloseButton>
|
|
62
|
+
</HoverCard>
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const useOpenChangesHoverCard = () => {
|
|
67
|
+
const {
|
|
68
|
+
hasSeenChangesToolTip,
|
|
69
|
+
hasSeenSimulatorToolTip,
|
|
70
|
+
isSavingCustomType,
|
|
71
|
+
isSavingSlice,
|
|
72
|
+
} = useSelector((store: SliceMachineStoreType) => ({
|
|
73
|
+
hasSeenChangesToolTip: userHasSeenChangesToolTip(store),
|
|
74
|
+
hasSeenSimulatorToolTip: userHasSeenSimulatorToolTip(store),
|
|
75
|
+
isSavingCustomType: isLoading(store, LoadingKeysEnum.SAVE_CUSTOM_TYPE),
|
|
76
|
+
isSavingSlice: isLoading(store, LoadingKeysEnum.SAVE_SLICE),
|
|
77
|
+
}));
|
|
78
|
+
|
|
79
|
+
const isSaving = isSavingCustomType || isSavingSlice;
|
|
80
|
+
const [prevIsSaving, setPrevIsSaving] = useState(isSaving);
|
|
81
|
+
|
|
82
|
+
if (!prevIsSaving && isSaving) {
|
|
83
|
+
setPrevIsSaving(isSaving);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
!hasSeenChangesToolTip &&
|
|
88
|
+
hasSeenSimulatorToolTip &&
|
|
89
|
+
!isSaving &&
|
|
90
|
+
prevIsSaving
|
|
91
|
+
);
|
|
92
|
+
};
|