slice-machine-ui 1.23.2-beta.1 → 1.23.2-beta.11
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/.depcheckrc +3 -0
- package/components/ChangesEmptyState/OfflinePage.tsx +1 -1
- package/components/ChangesItems/ChangesItems.tsx +6 -2
- package/components/CustomTypeTable/changesPage.tsx +12 -7
- package/components/DeleteSliceModal/index.tsx +37 -24
- package/components/DeleteVariationModal/index.tsx +1 -0
- package/components/Forms/CreateCustomTypeModal/CreateCustomTypeModal.tsx +65 -38
- package/components/Forms/CreateSliceModal/CreateSliceModal.tsx +3 -1
- package/components/Forms/RenameCustomTypeModal/RenameCustomTypeModal.tsx +7 -2
- package/components/Forms/RenameSliceModal/RenameSliceModal.tsx +36 -21
- package/components/Forms/RenameVariationModal/RenameVariationModal.tsx +0 -1
- package/components/LoginModal/index.tsx +40 -2
- package/components/ModalFormCard/index.tsx +0 -1
- package/components/Navigation/ChangesItem.tsx +117 -0
- package/components/Navigation/Environment.tsx +51 -4
- package/components/Navigation/index.css.ts +1 -2
- package/components/Navigation/index.test.tsx +5 -85
- package/components/Navigation/index.tsx +32 -20
- package/components/ReviewModal/ReviewForm.tsx +0 -1
- package/lib/builders/SliceBuilder/index.tsx +3 -3
- package/lib/builders/common/EditModal/Form.jsx +0 -1
- package/lib/builders/common/Zone/Card/components/NewField.tsx +0 -1
- package/lib/models/common/ModelStatus/index.ts +25 -0
- package/lib/models/common/widgets/StructuredText/index.ts +1 -1
- package/out/404.html +1 -1
- package/out/_next/static/chunks/18539003-5f78714a35fde4a1.js +97 -0
- package/out/_next/static/chunks/25-3aa4d4b24167d340.js +1 -0
- package/out/_next/static/chunks/318-19dbcae10cdb6408.js +1 -0
- package/out/_next/static/chunks/727-de03055e40815a3a.js +1 -0
- package/out/_next/static/chunks/777-8c5507e3b119b5dc.js +8 -0
- package/out/_next/static/chunks/799-0af1215eb2b3c17e.js +1 -0
- package/out/_next/static/chunks/904-40686b0426716111.js +1 -0
- package/out/_next/static/chunks/pages/_app-bca191df4ac7078e.js +434 -0
- package/out/_next/static/chunks/pages/{changelog-afd18276fe018b24.js → changelog-cb1df3a70b20f1b8.js} +1 -1
- package/out/_next/static/chunks/pages/changes-ccfd715c2bdc4f83.js +1 -0
- package/out/_next/static/chunks/pages/custom-types/{[customTypeId]-3f862ad6111a1fc0.js → [customTypeId]-97ab3b90b85d645d.js} +1 -1
- package/out/_next/static/chunks/pages/{custom-types-94b8f8dbf7727412.js → custom-types-3c8e721ec6802127.js} +1 -1
- package/out/_next/static/chunks/pages/index-cf93d16e9c63b6db.js +1 -0
- package/out/_next/static/chunks/pages/{labs-ee206005948f8e87.js → labs-2adfb5127f9c4081.js} +1 -1
- package/out/_next/static/chunks/pages/page-types/{[pageTypeId]-d1ffca11c42f2603.js → [pageTypeId]-84a22c5e480d3fa9.js} +1 -1
- package/out/_next/static/chunks/pages/settings-94bcd7422e8b237d.js +1 -0
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]/{simulator-897ca93c114a1435.js → simulator-aaf65fbec8f5839c.js} +1 -1
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-90bb2ea76d2abf42.js +1 -0
- package/out/_next/static/chunks/pages/slices-e0ce615c38e8338d.js +1 -0
- package/out/_next/static/css/39e089aad1742a3a.css +1 -0
- package/out/_next/static/css/{37153180c3b0dd66.css → 838fd8bb5a7c32b0.css} +1 -1
- package/out/_next/static/css/ca32882a5d2d8d88.css +1 -0
- package/out/_next/static/dS_xZnzzna6Y6uwcTgf90/_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/labs.html +1 -1
- package/out/page-types/[pageTypeId].html +1 -1
- package/out/settings.html +1 -0
- 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 +9 -6
- package/pages/_app.tsx +34 -32
- package/pages/changes.tsx +27 -41
- package/pages/settings.tsx +1 -0
- package/pages/slices.tsx +20 -8
- package/postcss.config.js +10 -0
- package/src/apiClient.ts +1 -22
- package/src/components/FieldSet/FieldSet.stories.tsx +20 -11
- package/src/components/RelativeTime/RelativeTime.stories.tsx +25 -0
- package/src/components/RelativeTime/RelativeTime.tsx +40 -0
- package/src/components/RelativeTime/index.ts +1 -0
- package/src/components/SideNav/SideNav.css.ts +1 -1
- package/src/components/SideNav/SideNav.tsx +9 -5
- package/src/components/SideNav/SideNavEnvironmentSelector.tsx +31 -11
- package/src/domain/__tests__/customType.test.ts +205 -19
- package/src/domain/customType.ts +132 -7
- package/src/domain/slice.ts +38 -0
- package/src/features/autoSave/AutoSaveStatusIndicator.tsx +4 -4
- package/src/features/customTypes/PageTypeOnboarding.tsx +21 -26
- package/src/features/customTypes/actions/convertCustomToPageType.ts +14 -10
- package/src/features/customTypes/actions/createCustomType.ts +69 -0
- package/src/features/customTypes/actions/deleteCustomType.ts +13 -3
- package/src/features/customTypes/actions/renameCustomType.ts +10 -4
- package/src/features/customTypes/customTypesBuilder/CustomTypeProvider.tsx +11 -10
- package/src/features/customTypes/customTypesBuilder/CustomTypesBuilderPage.tsx +5 -3
- package/src/features/customTypes/customTypesTable/CustomTypesTable.tsx +8 -8
- package/src/features/customTypes/customTypesTable/CustomTypesTablePage.tsx +18 -17
- package/src/features/environments/actions/setEnvironment.ts +4 -4
- package/src/features/settings/SettingsPage.tsx +47 -0
- package/src/features/settings/git/ConnectGitRepository.tsx +126 -0
- package/src/features/settings/git/ConnectGitRepositoryBlankSlate.tsx +33 -0
- package/src/features/settings/git/GitOwnerSelect.tsx +71 -0
- package/src/features/settings/git/GitProvider.ts +40 -0
- package/src/features/settings/git/GitProviderConnectButtons.tsx +63 -0
- package/src/features/settings/git/GitRepositoriesList.tsx +76 -0
- package/src/features/settings/git/GitRepositoriesSearch.tsx +69 -0
- package/src/features/settings/git/GitRepositoryConnectDialog.tsx +85 -0
- package/src/features/settings/git/GitRepositoryDisconnectDialog.tsx +60 -0
- package/src/features/settings/git/useGitIntegrationExperiment.ts +8 -0
- package/src/features/settings/git/useGitOwners.ts +12 -0
- package/src/features/settings/git/useGitRepos.ts +24 -0
- package/src/features/settings/git/useLinkedGitRepos.ts +41 -0
- package/src/features/settings/git/useWriteAPIToken.ts +23 -0
- package/src/features/slices/actions/createSlice.ts +5 -29
- package/src/features/slices/actions/deleteSlice.ts +33 -0
- package/src/features/slices/actions/renameSlice.ts +37 -0
- package/src/features/slices/convertLegacySlice/ConvertLegacySliceAsNewSliceDialog.tsx +0 -1
- package/src/features/slices/convertLegacySlice/ConvertLegacySliceAsNewVariationDialog.tsx +0 -1
- package/src/features/slices/convertLegacySlice/ConvertLegacySliceMergeWithIdenticalDialog.tsx +0 -1
- package/src/features/slices/sliceBuilder/SliceBuilderProvider.tsx +12 -10
- package/src/features/sync/AutoSyncProvider.tsx +252 -0
- package/src/features/sync/components/AutoSyncStatusIndicator.module.css +17 -0
- package/src/features/sync/components/AutoSyncStatusIndicator.module.css.d.ts +5 -0
- package/src/features/sync/components/AutoSyncStatusIndicator.tsx +58 -0
- package/src/features/sync/fetchUnSyncChanges.ts +40 -0
- package/src/features/sync/getUnSyncChanges.ts +144 -0
- package/src/features/sync/useUnSyncChanges.ts +32 -0
- package/src/hooks/useActionQueue.tsx +177 -0
- package/src/hooks/useAuthStatus.ts +12 -0
- package/src/hooks/useUser.ts +14 -0
- package/src/icons/SettingsIcon.tsx +19 -0
- package/src/icons/SyncFailed.tsx +30 -0
- package/src/icons/Synced.tsx +19 -0
- package/src/icons/Syncing.tsx +23 -0
- package/src/modules/availableCustomTypes/index.ts +29 -135
- package/src/modules/loading/types.ts +0 -5
- package/src/modules/modal/types.ts +0 -3
- package/src/modules/slices/index.ts +27 -193
- package/src/modules/slices/selector.ts +0 -14
- package/src/modules/useSliceMachineActions.ts +70 -89
- package/src/modules/userContext/index.ts +3 -3
- package/src/redux/saga.ts +0 -4
- package/test/__testutils__/index.tsx +8 -5
- package/test/src/modules/__fixtures__/serverState.ts +1 -2
- package/test/src/modules/availableCustomTypes/index.test.ts +2 -243
- package/test/src/modules/slices.test.ts +1 -267
- package/components/Navigation/ChangesListItem.tsx +0 -92
- package/components/Navigation/ChangesRightElement.tsx +0 -33
- package/out/_next/static/chunks/18539003-5cc559566b738915.js +0 -97
- package/out/_next/static/chunks/25-37d6fa7f064be04b.js +0 -1
- package/out/_next/static/chunks/318-ce7e74f18f2d5b22.js +0 -1
- package/out/_next/static/chunks/376-7e784d6069e01654.js +0 -8
- package/out/_next/static/chunks/727-3a3bc32518778317.js +0 -1
- package/out/_next/static/chunks/731-501990ebe6a71b32.js +0 -1
- package/out/_next/static/chunks/904-9a4c1264727ae89a.js +0 -1
- package/out/_next/static/chunks/pages/_app-cd9d4c76a4abc11a.js +0 -432
- package/out/_next/static/chunks/pages/changes-2a976f9efeb719aa.js +0 -1
- package/out/_next/static/chunks/pages/index-64cfb8b0948ba8ef.js +0 -1
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-b2a9d773ce5d7739.js +0 -1
- package/out/_next/static/chunks/pages/slices-e9c70c082ca3e3f9.js +0 -1
- package/out/_next/static/css/200244e3e0463c39.css +0 -1
- package/out/_next/static/m6psnC5u1xT7Y6osWHKjp/_buildManifest.js +0 -1
- package/src/features/autoSave/useAutoSave.tsx +0 -177
- package/src/features/customTypes/__tests__/createCustomType.test.ts +0 -159
- package/src/features/customTypes/customTypesTable/createCustomType.ts +0 -107
- package/src/features/legacyState/actions/getLegacySliceMachineState.ts +0 -53
- package/src/features/legacyState/useLegacySliceMachineState.ts +0 -7
- package/src/hooks/useModelStatus.ts +0 -78
- package/src/hooks/useUnSyncChanges.ts +0 -88
- package/test/components/CreateCustomTypeModal.test.tsx +0 -73
- package/test/components/LoginModal.test.tsx +0 -67
- package/test/src/hooks/useModelStatus.test.ts +0 -115
- /package/out/_next/static/{m6psnC5u1xT7Y6osWHKjp → dS_xZnzzna6Y6uwcTgf90}/_ssgManifest.js +0 -0
- /package/src/features/{changes → sync}/actions/pushChanges.ts +0 -0
- /package/src/features/{changes → sync}/actions/trackPushChangesSuccess.ts +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
self.__BUILD_MANIFEST=function(s,c,a,e,t,i,f,b,n,u,d,h,l,k,j,p,g,o,r){return{__rewrites:{beforeFiles:[],afterFiles:[],fallback:[]},"/":[a,j,p,"static/chunks/pages/index-64cfb8b0948ba8ef.js"],"/_error":["static/chunks/pages/_error-69b4f498bafdd188.js"],"/changelog":[s,e,"static/chunks/870-0c7a8a9622de78b7.js","static/chunks/pages/changelog-afd18276fe018b24.js"],"/changes":[s,t,"static/chunks/8eec4907-b712959d9f984b68.js",i,"static/chunks/918-5bb55fb464e34768.js",c,b,"static/css/37153180c3b0dd66.css","static/chunks/pages/changes-2a976f9efeb719aa.js"],"/custom-types":[a,j,p,"static/chunks/pages/custom-types-94b8f8dbf7727412.js"],"/custom-types/[customTypeId]":[s,n,u,d,h,e,f,i,l,g,c,a,k,o,r,"static/chunks/pages/custom-types/[customTypeId]-3f862ad6111a1fc0.js"],"/labs":["static/chunks/pages/labs-ee206005948f8e87.js"],"/page-types/[pageTypeId]":[s,n,u,d,h,e,f,i,l,g,c,a,k,o,r,"static/chunks/pages/page-types/[pageTypeId]-d1ffca11c42f2603.js"],"/slices":[s,t,f,c,b,"static/css/f8eb526e10bc2441.css","static/chunks/pages/slices-e9c70c082ca3e3f9.js"],"/slices/[lib]/[sliceName]/[variation]":[s,t,n,u,d,h,e,f,i,l,c,k,b,"static/css/b22c0750c14cc089.css","static/chunks/pages/slices/[lib]/[sliceName]/[variation]-b2a9d773ce5d7739.js"],"/slices/[lib]/[sliceName]/[variation]/simulator":[t,"static/chunks/72585f70-28b4d7d5384b3703.js","static/chunks/18539003-5cc559566b738915.js","static/chunks/376-7e784d6069e01654.js","static/chunks/pages/slices/[lib]/[sliceName]/[variation]/simulator-897ca93c114a1435.js"],sortedPages:["/","/_app","/_error","/changelog","/changes","/custom-types","/custom-types/[customTypeId]","/labs","/page-types/[pageTypeId]","/slices","/slices/[lib]/[sliceName]/[variation]","/slices/[lib]/[sliceName]/[variation]/simulator"]}}("static/chunks/59b4e022-7a3b5554b806349f.js","static/chunks/25-37d6fa7f064be04b.js","static/chunks/731-501990ebe6a71b32.js","static/chunks/183-4feb6bb3eddbc768.js","static/chunks/c8eae200-966ce352f7b5d2b9.js","static/chunks/543-f8766685f7f451e2.js","static/chunks/50-cfc2514205b86001.js","static/chunks/286-ed90373e9a469944.js","static/chunks/f36c6662-03bb5e9d9aa0b0aa.js","static/chunks/4c744e84-e3161d754618373f.js","static/chunks/065a3ddb-9a38ca0d60f0bf2f.js","static/chunks/1cc2734a-2c5b6c0367fcde86.js","static/chunks/696-b12edad30a3617e5.js","static/chunks/318-ce7e74f18f2d5b22.js","static/chunks/727-3a3bc32518778317.js","static/css/be1f49e49a5aa7eb.css","static/chunks/474-5a072e6fac61f703.js","static/chunks/904-9a4c1264727ae89a.js","static/css/72465cc1225f28a2.css"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
useCallback,
|
|
3
|
-
useState,
|
|
4
|
-
useEffect,
|
|
5
|
-
SetStateAction,
|
|
6
|
-
Dispatch,
|
|
7
|
-
useMemo,
|
|
8
|
-
} from "react";
|
|
9
|
-
import { uniqueId } from "lodash";
|
|
10
|
-
import { toast } from "react-toastify";
|
|
11
|
-
import { Box, Button, Text } from "@prismicio/editor-ui";
|
|
12
|
-
|
|
13
|
-
export type AutoSaveStatus = "saving" | "saved" | "failed";
|
|
14
|
-
|
|
15
|
-
type UseAutoSaveArgs = {
|
|
16
|
-
autoSaveStatusDelay?: number;
|
|
17
|
-
errorMessage?: string;
|
|
18
|
-
retryDelay?: number;
|
|
19
|
-
retryMessage?: string;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
type UseAutoSaveReturnType = {
|
|
23
|
-
autoSaveStatus: AutoSaveStatus;
|
|
24
|
-
setNextSave: (nextSave: NextSave) => void;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
type AutoSaveStack = {
|
|
28
|
-
pendingSave: NextSave | undefined;
|
|
29
|
-
nextSave: NextSave | undefined;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
type NextSave = () => Promise<unknown>;
|
|
33
|
-
|
|
34
|
-
export const useAutoSave = (
|
|
35
|
-
args: UseAutoSaveArgs = {},
|
|
36
|
-
): UseAutoSaveReturnType => {
|
|
37
|
-
const {
|
|
38
|
-
autoSaveStatusDelay = 300,
|
|
39
|
-
errorMessage = "An error happened while saving",
|
|
40
|
-
retryDelay = 1000,
|
|
41
|
-
retryMessage = "Retry",
|
|
42
|
-
} = args;
|
|
43
|
-
|
|
44
|
-
const [autoSaveStack, setAutoSaveStack] = useState<AutoSaveStack>({
|
|
45
|
-
pendingSave: undefined,
|
|
46
|
-
nextSave: undefined,
|
|
47
|
-
});
|
|
48
|
-
const [autoSaveStatusActual, setAutoSaveStatusActual] =
|
|
49
|
-
useState<AutoSaveStatus>("saved");
|
|
50
|
-
const [autoSaveStatusDelayed, setAutoSaveStatusDelayed] =
|
|
51
|
-
useState<AutoSaveStatus>(autoSaveStatusActual);
|
|
52
|
-
|
|
53
|
-
const setNextSave = useCallback((nextSave: NextSave) => {
|
|
54
|
-
setAutoSaveStack((prevState) => ({
|
|
55
|
-
...prevState,
|
|
56
|
-
nextSave,
|
|
57
|
-
}));
|
|
58
|
-
}, []);
|
|
59
|
-
|
|
60
|
-
const executeSave = useCallback(
|
|
61
|
-
async (nextSave?: NextSave) => {
|
|
62
|
-
if (nextSave) {
|
|
63
|
-
setAutoSaveStatusActual("saving");
|
|
64
|
-
|
|
65
|
-
try {
|
|
66
|
-
await nextSave();
|
|
67
|
-
|
|
68
|
-
setAutoSaveStatusActual("saved");
|
|
69
|
-
} catch (error) {
|
|
70
|
-
setAutoSaveStatusActual("failed");
|
|
71
|
-
console.error(errorMessage, error);
|
|
72
|
-
|
|
73
|
-
toastError({
|
|
74
|
-
errorMessage,
|
|
75
|
-
retryDelay,
|
|
76
|
-
retryMessage,
|
|
77
|
-
setAutoSaveStatusActual,
|
|
78
|
-
setAutoSaveStack,
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
[errorMessage, retryDelay, retryMessage],
|
|
84
|
-
);
|
|
85
|
-
|
|
86
|
-
useEffect(() => {
|
|
87
|
-
if (autoSaveStatusActual === "saved" && autoSaveStack.nextSave) {
|
|
88
|
-
void executeSave(autoSaveStack.nextSave);
|
|
89
|
-
|
|
90
|
-
setAutoSaveStack({
|
|
91
|
-
pendingSave: autoSaveStack.nextSave,
|
|
92
|
-
nextSave: undefined,
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
}, [autoSaveStatusActual, autoSaveStack, executeSave]);
|
|
96
|
-
|
|
97
|
-
useEffect(() => {
|
|
98
|
-
if (autoSaveStatusActual === "saving") {
|
|
99
|
-
setAutoSaveStatusDelayed("saving");
|
|
100
|
-
} else {
|
|
101
|
-
const delayedTimeout = setTimeout(() => {
|
|
102
|
-
setAutoSaveStatusDelayed(autoSaveStatusActual);
|
|
103
|
-
}, autoSaveStatusDelay);
|
|
104
|
-
|
|
105
|
-
return () => {
|
|
106
|
-
clearTimeout(delayedTimeout);
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return;
|
|
111
|
-
}, [autoSaveStatusActual, autoSaveStatusDelay]);
|
|
112
|
-
|
|
113
|
-
return useMemo(
|
|
114
|
-
() => ({
|
|
115
|
-
autoSaveStatus: autoSaveStatusDelayed,
|
|
116
|
-
setNextSave,
|
|
117
|
-
}),
|
|
118
|
-
[autoSaveStatusDelayed, setNextSave],
|
|
119
|
-
);
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
type ToastErrorArgs = {
|
|
123
|
-
errorMessage: string;
|
|
124
|
-
retryDelay: number;
|
|
125
|
-
retryMessage: string;
|
|
126
|
-
setAutoSaveStatusActual: Dispatch<SetStateAction<AutoSaveStatus>>;
|
|
127
|
-
setAutoSaveStack: Dispatch<SetStateAction<AutoSaveStack>>;
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
function toastError(args: ToastErrorArgs) {
|
|
131
|
-
const {
|
|
132
|
-
errorMessage,
|
|
133
|
-
retryDelay,
|
|
134
|
-
retryMessage,
|
|
135
|
-
setAutoSaveStatusActual,
|
|
136
|
-
setAutoSaveStack,
|
|
137
|
-
} = args;
|
|
138
|
-
const toastId = uniqueId();
|
|
139
|
-
|
|
140
|
-
toast.error(
|
|
141
|
-
() => (
|
|
142
|
-
<Box gap={8} alignItems="center">
|
|
143
|
-
<Text color="grey1" variant="small">
|
|
144
|
-
{errorMessage}
|
|
145
|
-
</Text>
|
|
146
|
-
<Button
|
|
147
|
-
size="small"
|
|
148
|
-
color="grey"
|
|
149
|
-
onClick={() => {
|
|
150
|
-
toast.dismiss(toastId);
|
|
151
|
-
|
|
152
|
-
// Ensure saving is directly propagated before waiting for the retry
|
|
153
|
-
setAutoSaveStatusActual("saving");
|
|
154
|
-
|
|
155
|
-
setTimeout(() => {
|
|
156
|
-
// By setting the status to saved, the save effect will be triggered
|
|
157
|
-
// with the latest data to save.
|
|
158
|
-
setAutoSaveStatusActual("saved");
|
|
159
|
-
setAutoSaveStack((prevState) => ({
|
|
160
|
-
nextSave: prevState.nextSave ?? prevState.pendingSave,
|
|
161
|
-
pendingSave: undefined,
|
|
162
|
-
}));
|
|
163
|
-
}, retryDelay);
|
|
164
|
-
}}
|
|
165
|
-
>
|
|
166
|
-
{retryMessage}
|
|
167
|
-
</Button>
|
|
168
|
-
</Box>
|
|
169
|
-
),
|
|
170
|
-
{
|
|
171
|
-
autoClose: false,
|
|
172
|
-
closeOnClick: false,
|
|
173
|
-
draggable: false,
|
|
174
|
-
toastId,
|
|
175
|
-
},
|
|
176
|
-
);
|
|
177
|
-
}
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import { describe, expect } from "vitest";
|
|
2
|
-
import { createCustomType } from "@src/features/customTypes/customTypesTable/createCustomType";
|
|
3
|
-
|
|
4
|
-
describe("createCustomType test suite", () => {
|
|
5
|
-
it("should create a custom type with repeatable true", () => {
|
|
6
|
-
expect(createCustomType("id", "lama", true, "custom"))
|
|
7
|
-
.toMatchInlineSnapshot(`
|
|
8
|
-
{
|
|
9
|
-
"format": "custom",
|
|
10
|
-
"id": "id",
|
|
11
|
-
"json": {
|
|
12
|
-
"Main": {
|
|
13
|
-
"uid": {
|
|
14
|
-
"config": {
|
|
15
|
-
"label": "UID",
|
|
16
|
-
},
|
|
17
|
-
"type": "UID",
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
"label": "lama",
|
|
22
|
-
"repeatable": true,
|
|
23
|
-
"status": true,
|
|
24
|
-
}
|
|
25
|
-
`);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it("should create a custom type with repeatable false", () => {
|
|
29
|
-
const result = createCustomType("id", "lama", false, "custom");
|
|
30
|
-
expect(result.id).toBe("id");
|
|
31
|
-
expect(result.label).toBe("lama");
|
|
32
|
-
expect(result.format).toBe("custom");
|
|
33
|
-
expect(result.json).toHaveProperty("Main");
|
|
34
|
-
expect(result).toMatchInlineSnapshot(`
|
|
35
|
-
{
|
|
36
|
-
"format": "custom",
|
|
37
|
-
"id": "id",
|
|
38
|
-
"json": {
|
|
39
|
-
"Main": {},
|
|
40
|
-
},
|
|
41
|
-
"label": "lama",
|
|
42
|
-
"repeatable": false,
|
|
43
|
-
"status": true,
|
|
44
|
-
}
|
|
45
|
-
`);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it("should create a page type with a slice zone", () => {
|
|
49
|
-
const result = createCustomType("🥪", "label", true, "page");
|
|
50
|
-
expect(result.format).toBe("page");
|
|
51
|
-
expect(result.json).toHaveProperty("Main");
|
|
52
|
-
expect(result.json.Main).toHaveProperty("slices");
|
|
53
|
-
expect(result.json).toHaveProperty("SEO & Metadata");
|
|
54
|
-
expect(result).toMatchInlineSnapshot(`
|
|
55
|
-
{
|
|
56
|
-
"format": "page",
|
|
57
|
-
"id": "🥪",
|
|
58
|
-
"json": {
|
|
59
|
-
"Main": {
|
|
60
|
-
"slices": {
|
|
61
|
-
"config": {
|
|
62
|
-
"choices": {},
|
|
63
|
-
},
|
|
64
|
-
"fieldset": "Slice Zone",
|
|
65
|
-
"type": "Slices",
|
|
66
|
-
},
|
|
67
|
-
"uid": {
|
|
68
|
-
"config": {
|
|
69
|
-
"label": "UID",
|
|
70
|
-
},
|
|
71
|
-
"type": "UID",
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
"SEO & Metadata": {
|
|
75
|
-
"meta_description": {
|
|
76
|
-
"config": {
|
|
77
|
-
"label": "Meta Description",
|
|
78
|
-
"placeholder": "A brief summary of the page",
|
|
79
|
-
},
|
|
80
|
-
"type": "Text",
|
|
81
|
-
},
|
|
82
|
-
"meta_image": {
|
|
83
|
-
"config": {
|
|
84
|
-
"constraint": {
|
|
85
|
-
"height": 1260,
|
|
86
|
-
"width": 2400,
|
|
87
|
-
},
|
|
88
|
-
"label": "Meta Image",
|
|
89
|
-
"thumbnails": [],
|
|
90
|
-
},
|
|
91
|
-
"type": "Image",
|
|
92
|
-
},
|
|
93
|
-
"meta_title": {
|
|
94
|
-
"config": {
|
|
95
|
-
"label": "Meta Title",
|
|
96
|
-
"placeholder": "A title of the page used for social media and search engines",
|
|
97
|
-
},
|
|
98
|
-
"type": "Text",
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
"label": "label",
|
|
103
|
-
"repeatable": true,
|
|
104
|
-
"status": true,
|
|
105
|
-
}
|
|
106
|
-
`);
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it("when non repeatable page type is should contain Main with a slice-zone, no uid, and a SEO tab", () => {
|
|
111
|
-
const result = createCustomType("foo", "bar", false, "page");
|
|
112
|
-
expect(result).toMatchInlineSnapshot(`
|
|
113
|
-
{
|
|
114
|
-
"format": "page",
|
|
115
|
-
"id": "foo",
|
|
116
|
-
"json": {
|
|
117
|
-
"Main": {
|
|
118
|
-
"slices": {
|
|
119
|
-
"config": {
|
|
120
|
-
"choices": {},
|
|
121
|
-
},
|
|
122
|
-
"fieldset": "Slice Zone",
|
|
123
|
-
"type": "Slices",
|
|
124
|
-
},
|
|
125
|
-
},
|
|
126
|
-
"SEO & Metadata": {
|
|
127
|
-
"meta_description": {
|
|
128
|
-
"config": {
|
|
129
|
-
"label": "Meta Description",
|
|
130
|
-
"placeholder": "A brief summary of the page",
|
|
131
|
-
},
|
|
132
|
-
"type": "Text",
|
|
133
|
-
},
|
|
134
|
-
"meta_image": {
|
|
135
|
-
"config": {
|
|
136
|
-
"constraint": {
|
|
137
|
-
"height": 1260,
|
|
138
|
-
"width": 2400,
|
|
139
|
-
},
|
|
140
|
-
"label": "Meta Image",
|
|
141
|
-
"thumbnails": [],
|
|
142
|
-
},
|
|
143
|
-
"type": "Image",
|
|
144
|
-
},
|
|
145
|
-
"meta_title": {
|
|
146
|
-
"config": {
|
|
147
|
-
"label": "Meta Title",
|
|
148
|
-
"placeholder": "A title of the page used for social media and search engines",
|
|
149
|
-
},
|
|
150
|
-
"type": "Text",
|
|
151
|
-
},
|
|
152
|
-
},
|
|
153
|
-
},
|
|
154
|
-
"label": "bar",
|
|
155
|
-
"repeatable": false,
|
|
156
|
-
"status": true,
|
|
157
|
-
}
|
|
158
|
-
`);
|
|
159
|
-
});
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { CustomType } from "@prismicio/types-internal/lib/customtypes";
|
|
2
|
-
import type { CustomTypeFormat } from "@slicemachine/manager";
|
|
3
|
-
|
|
4
|
-
export function createCustomType(
|
|
5
|
-
id: string,
|
|
6
|
-
label: string,
|
|
7
|
-
repeatable: boolean,
|
|
8
|
-
format: CustomTypeFormat,
|
|
9
|
-
): CustomType {
|
|
10
|
-
const mainTab = makeMainTab(repeatable, format);
|
|
11
|
-
|
|
12
|
-
return {
|
|
13
|
-
id,
|
|
14
|
-
label,
|
|
15
|
-
format,
|
|
16
|
-
repeatable,
|
|
17
|
-
json: mainTab,
|
|
18
|
-
status: true,
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function makeMainTab(
|
|
23
|
-
repeatable: boolean,
|
|
24
|
-
format: CustomTypeFormat,
|
|
25
|
-
): CustomType["json"] {
|
|
26
|
-
if (repeatable === false && format === "page") {
|
|
27
|
-
return { ...DEFAULT_MAIN_WITH_SLICE_ZONE, ...DEFAULT_SEO_TAB };
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (repeatable === false) {
|
|
31
|
-
return DEFAULT_MAIN;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (format === "page") {
|
|
35
|
-
return {
|
|
36
|
-
...DEFAULT_MAIN_WITH_UID_AND_SLICE_ZONE,
|
|
37
|
-
...DEFAULT_SEO_TAB,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return DEFAULT_MAIN_WITH_UID;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const DEFAULT_MAIN: CustomType["json"] = {
|
|
45
|
-
Main: {},
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const DEFAULT_MAIN_WITH_SLICE_ZONE: CustomType["json"] = {
|
|
49
|
-
Main: {
|
|
50
|
-
slices: {
|
|
51
|
-
config: {
|
|
52
|
-
choices: {},
|
|
53
|
-
},
|
|
54
|
-
fieldset: "Slice Zone",
|
|
55
|
-
type: "Slices",
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
const DEFAULT_MAIN_WITH_UID: CustomType["json"] = {
|
|
61
|
-
Main: {
|
|
62
|
-
uid: {
|
|
63
|
-
config: {
|
|
64
|
-
label: "UID",
|
|
65
|
-
},
|
|
66
|
-
type: "UID",
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
const DEFAULT_MAIN_WITH_UID_AND_SLICE_ZONE: CustomType["json"] = {
|
|
72
|
-
Main: {
|
|
73
|
-
...DEFAULT_MAIN_WITH_UID.Main,
|
|
74
|
-
...DEFAULT_MAIN_WITH_SLICE_ZONE.Main,
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const DEFAULT_SEO_TAB: CustomType["json"] = {
|
|
79
|
-
"SEO & Metadata": {
|
|
80
|
-
meta_description: {
|
|
81
|
-
config: {
|
|
82
|
-
label: "Meta Description",
|
|
83
|
-
placeholder: "A brief summary of the page",
|
|
84
|
-
},
|
|
85
|
-
type: "Text",
|
|
86
|
-
},
|
|
87
|
-
meta_image: {
|
|
88
|
-
config: {
|
|
89
|
-
constraint: {
|
|
90
|
-
height: 1260,
|
|
91
|
-
width: 2400,
|
|
92
|
-
},
|
|
93
|
-
label: "Meta Image",
|
|
94
|
-
thumbnails: [],
|
|
95
|
-
},
|
|
96
|
-
type: "Image",
|
|
97
|
-
},
|
|
98
|
-
meta_title: {
|
|
99
|
-
config: {
|
|
100
|
-
label: "Meta Title",
|
|
101
|
-
placeholder:
|
|
102
|
-
"A title of the page used for social media and search engines",
|
|
103
|
-
},
|
|
104
|
-
type: "Text",
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
};
|
|
@@ -1,53 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
computeModelStatus,
|
|
3
|
-
ModelStatus,
|
|
4
|
-
} from "@lib/models/common/ModelStatus";
|
|
5
|
-
import { getAuthStatus } from "@src/modules/environment";
|
|
6
|
-
import { AuthStatus } from "@src/modules/userContext/types";
|
|
7
|
-
import { SliceMachineStoreType } from "@src/redux/type";
|
|
8
|
-
import { useSelector } from "react-redux";
|
|
9
|
-
import { useNetwork } from "./useNetwork";
|
|
10
|
-
import {
|
|
11
|
-
hasLocal,
|
|
12
|
-
LocalOrRemoteCustomType,
|
|
13
|
-
LocalOrRemoteModel,
|
|
14
|
-
LocalOrRemoteSlice,
|
|
15
|
-
} from "@lib/models/common/ModelData";
|
|
16
|
-
|
|
17
|
-
// Slices and Custom Types needs to be separated as Ids are not unique amongst each others.
|
|
18
|
-
export interface ModelStatusInformation {
|
|
19
|
-
modelsStatuses: {
|
|
20
|
-
slices: { [sliceId: string]: ModelStatus };
|
|
21
|
-
customTypes: { [ctId: string]: ModelStatus };
|
|
22
|
-
};
|
|
23
|
-
authStatus: AuthStatus;
|
|
24
|
-
isOnline: boolean;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function computeStatuses(
|
|
28
|
-
models: LocalOrRemoteCustomType[],
|
|
29
|
-
userHasAccessToModels: boolean,
|
|
30
|
-
): { [sliceId: string]: ModelStatus };
|
|
31
|
-
function computeStatuses(
|
|
32
|
-
models: LocalOrRemoteSlice[],
|
|
33
|
-
userHasAccessToModels: boolean,
|
|
34
|
-
): { [sliceId: string]: ModelStatus };
|
|
35
|
-
function computeStatuses(
|
|
36
|
-
models: LocalOrRemoteModel[],
|
|
37
|
-
userHasAccessToModels: boolean,
|
|
38
|
-
) {
|
|
39
|
-
return models.reduce<{ [id: string]: ModelStatus }>(
|
|
40
|
-
(acc, model) => {
|
|
41
|
-
const { status } = computeModelStatus(model, userHasAccessToModels);
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
...acc,
|
|
45
|
-
[hasLocal(model) ? model.local.id : model.remote.id]: status,
|
|
46
|
-
};
|
|
47
|
-
},
|
|
48
|
-
{} as { [sliceId: string]: ModelStatus },
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export const useModelStatus = ({
|
|
53
|
-
slices = [],
|
|
54
|
-
customTypes = [],
|
|
55
|
-
}: {
|
|
56
|
-
slices?: LocalOrRemoteSlice[];
|
|
57
|
-
customTypes?: LocalOrRemoteCustomType[];
|
|
58
|
-
}): ModelStatusInformation => {
|
|
59
|
-
const isOnline = useNetwork();
|
|
60
|
-
const { authStatus } = useSelector((store: SliceMachineStoreType) => ({
|
|
61
|
-
authStatus: getAuthStatus(store),
|
|
62
|
-
}));
|
|
63
|
-
const userHasAccessToModels =
|
|
64
|
-
isOnline &&
|
|
65
|
-
authStatus != AuthStatus.FORBIDDEN &&
|
|
66
|
-
authStatus != AuthStatus.UNAUTHORIZED;
|
|
67
|
-
|
|
68
|
-
const modelsStatuses = {
|
|
69
|
-
slices: computeStatuses(slices, userHasAccessToModels),
|
|
70
|
-
customTypes: computeStatuses(customTypes, userHasAccessToModels),
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
return {
|
|
74
|
-
modelsStatuses,
|
|
75
|
-
authStatus,
|
|
76
|
-
isOnline,
|
|
77
|
-
};
|
|
78
|
-
};
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { ComponentUI } from "@lib/models/common/ComponentUI";
|
|
2
|
-
import { ModelStatus } from "@lib/models/common/ModelStatus";
|
|
3
|
-
import { selectAllCustomTypes } from "@src/modules/availableCustomTypes";
|
|
4
|
-
import { getFrontendSlices, getLibraries } from "@src/modules/slices";
|
|
5
|
-
import { SliceMachineStoreType } from "@src/redux/type";
|
|
6
|
-
import { useSelector } from "react-redux";
|
|
7
|
-
import { ModelStatusInformation, useModelStatus } from "./useModelStatus";
|
|
8
|
-
import {
|
|
9
|
-
LocalOrRemoteCustomType,
|
|
10
|
-
RemoteOnlySlice,
|
|
11
|
-
getModelId,
|
|
12
|
-
isRemoteOnly,
|
|
13
|
-
} from "@lib/models/common/ModelData";
|
|
14
|
-
|
|
15
|
-
export const unSyncStatuses = [
|
|
16
|
-
ModelStatus.New,
|
|
17
|
-
ModelStatus.Modified,
|
|
18
|
-
ModelStatus.Deleted,
|
|
19
|
-
];
|
|
20
|
-
|
|
21
|
-
export interface UnSyncChanges extends ModelStatusInformation {
|
|
22
|
-
unSyncedSlices: ComponentUI[];
|
|
23
|
-
unSyncedCustomTypes: LocalOrRemoteCustomType[];
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// ComponentUI are manipulated on all the relevant pages
|
|
27
|
-
// But the data is not available for remote only slices
|
|
28
|
-
// which have been deleted locally
|
|
29
|
-
// Should revisit this with the sync improvements
|
|
30
|
-
const wrapDeletedSlice = (s: RemoteOnlySlice): ComponentUI => ({
|
|
31
|
-
model: s.remote,
|
|
32
|
-
screenshots: {},
|
|
33
|
-
from: "",
|
|
34
|
-
href: "",
|
|
35
|
-
pathToSlice: "",
|
|
36
|
-
fileName: "",
|
|
37
|
-
extension: "",
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
export const useUnSyncChanges = (): UnSyncChanges => {
|
|
41
|
-
const { customTypes, slices, libraries } = useSelector(
|
|
42
|
-
(store: SliceMachineStoreType) => ({
|
|
43
|
-
customTypes: selectAllCustomTypes(store),
|
|
44
|
-
slices: getFrontendSlices(store),
|
|
45
|
-
libraries: getLibraries(store),
|
|
46
|
-
}),
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
const { modelsStatuses, authStatus, isOnline } = useModelStatus({
|
|
50
|
-
slices,
|
|
51
|
-
customTypes,
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
const localComponents: ComponentUI[] = libraries.flatMap(
|
|
55
|
-
(lib) => lib.components,
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
const deletedComponents: ComponentUI[] = slices
|
|
59
|
-
.filter(isRemoteOnly)
|
|
60
|
-
.map(wrapDeletedSlice);
|
|
61
|
-
|
|
62
|
-
const components: ComponentUI[] = localComponents
|
|
63
|
-
.concat(deletedComponents)
|
|
64
|
-
.sort((s1, s2) => (s1.model.name > s2.model.name ? 1 : -1));
|
|
65
|
-
|
|
66
|
-
const unSyncedSlices = components.filter(
|
|
67
|
-
(component) =>
|
|
68
|
-
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
69
|
-
modelsStatuses.slices[component.model.id] &&
|
|
70
|
-
unSyncStatuses.includes(modelsStatuses.slices[component.model.id]),
|
|
71
|
-
);
|
|
72
|
-
const unSyncedCustomTypes = customTypes.filter(
|
|
73
|
-
(customType) =>
|
|
74
|
-
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
75
|
-
modelsStatuses.customTypes[getModelId(customType)] &&
|
|
76
|
-
unSyncStatuses.includes(
|
|
77
|
-
modelsStatuses.customTypes[getModelId(customType)],
|
|
78
|
-
),
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
return {
|
|
82
|
-
unSyncedSlices,
|
|
83
|
-
unSyncedCustomTypes,
|
|
84
|
-
modelsStatuses,
|
|
85
|
-
authStatus,
|
|
86
|
-
isOnline,
|
|
87
|
-
};
|
|
88
|
-
};
|