slice-machine-ui 1.25.1-beta.1 → 1.25.1-beta.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/Simulator/components/FailedConnect/index.tsx +1 -1
- package/components/Simulator/index.tsx +17 -57
- package/lib/builders/SliceBuilder/SimulatorButton/index.tsx +4 -26
- package/lib/builders/SliceBuilder/index.tsx +1 -11
- package/lib/models/common/Environment.ts +0 -1
- package/out/404.html +1 -1
- package/out/_next/static/UH_nSG8k25NO9SYLlVW9n/_buildManifest.js +1 -0
- package/out/_next/static/chunks/{474-5a072e6fac61f703.js → 210-aee6116139329803.js} +2 -2
- package/out/_next/static/chunks/46-d22d7a121254e31d.js +8 -0
- package/out/_next/static/chunks/{696-b12edad30a3617e5.js → 696-b992b9e1ce75777e.js} +1 -1
- package/out/_next/static/chunks/{904-bed9c8dade39dc27.js → 904-1a755ebb0f5ee4ac.js} +1 -1
- package/out/_next/static/chunks/pages/{_app-e32e7f8142e6cde0.js → _app-dd7fea6283b73c4e.js} +23 -23
- package/out/_next/static/chunks/pages/custom-types/{[customTypeId]-97ab3b90b85d645d.js → [customTypeId]-d1a4a07e6b600fa6.js} +1 -1
- package/out/_next/static/chunks/pages/page-types/{[pageTypeId]-84a22c5e480d3fa9.js → [pageTypeId]-a724ff12ef322020.js} +1 -1
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]/simulator-3eb0fdce3228d389.js +1 -0
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-ba6c3e2624f32fcd.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 -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 -5
- package/src/apiClient.ts +0 -6
- package/src/modules/environment/index.ts +0 -6
- package/src/modules/modal/types.ts +0 -1
- package/src/modules/simulator/index.ts +5 -133
- package/src/modules/simulator/types.ts +0 -6
- package/src/modules/useSliceMachineActions.ts +1 -11
- package/test/__testutils__/createTestPlugin.ts +0 -1
- package/test/src/modules/__fixtures__/serverState.ts +0 -1
- package/test/src/modules/simulator.test.ts +0 -196
- package/components/CodeSpan/index.tsx +0 -23
- package/components/HTMLRenderer/index.tsx +0 -137
- package/components/Simulator/components/SetupModal/TextWithInlineCode.tsx +0 -21
- package/components/Simulator/components/SetupModal/index.tsx +0 -165
- package/out/_next/static/PAJQyEuW0rRHPSn18wYrk/_buildManifest.js +0 -1
- package/out/_next/static/chunks/777-7bc4ca95c82802e5.js +0 -8
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]/simulator-a8213af71b0a99c9.js +0 -1
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-60858a3cead6dc81.js +0 -1
- /package/out/_next/static/{PAJQyEuW0rRHPSn18wYrk → UH_nSG8k25NO9SYLlVW9n}/_ssgManifest.js +0 -0
|
@@ -1,56 +1,18 @@
|
|
|
1
|
+
import { fork, put, takeLeading, race, take, delay } from "redux-saga/effects";
|
|
1
2
|
import { Reducer } from "redux";
|
|
2
|
-
import { SliceMachineStoreType } from "@src/redux/type";
|
|
3
3
|
import { ActionType, createAsyncAction, getType } from "typesafe-actions";
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
call,
|
|
7
|
-
fork,
|
|
8
|
-
put,
|
|
9
|
-
select,
|
|
10
|
-
takeLeading,
|
|
11
|
-
race,
|
|
12
|
-
take,
|
|
13
|
-
delay,
|
|
14
|
-
} from "redux-saga/effects";
|
|
15
|
-
import { checkSimulatorSetup, getSimulatorSetupSteps } from "@src/apiClient";
|
|
16
|
-
import {
|
|
17
|
-
selectIsSimulatorAvailableForFramework,
|
|
18
|
-
updateManifestCreator,
|
|
19
|
-
} from "@src/modules/environment";
|
|
20
|
-
import { withLoader } from "@src/modules/loading";
|
|
4
|
+
|
|
21
5
|
import { LoadingKeysEnum } from "@src/modules/loading/types";
|
|
22
|
-
import {
|
|
6
|
+
import { SliceMachineStoreType } from "@src/redux/type";
|
|
7
|
+
import { withLoader } from "@src/modules/loading";
|
|
23
8
|
|
|
24
|
-
import {
|
|
25
|
-
import { ModalKeysEnum } from "../modal/types";
|
|
9
|
+
import { SimulatorStoreType } from "./types";
|
|
26
10
|
|
|
27
11
|
export const initialState: SimulatorStoreType = {
|
|
28
|
-
setupSteps: null,
|
|
29
12
|
iframeStatus: null,
|
|
30
|
-
setupStatus: {
|
|
31
|
-
manifest: null,
|
|
32
|
-
},
|
|
33
13
|
isWaitingForIframeCheck: false,
|
|
34
14
|
};
|
|
35
15
|
|
|
36
|
-
export const checkSimulatorSetupCreator = createAsyncAction(
|
|
37
|
-
"SIMULATOR/CHECK_SETUP.REQUEST",
|
|
38
|
-
"SIMULATOR/CHECK_SETUP.SUCCESS",
|
|
39
|
-
"SIMULATOR/CHECK_SETUP.FAILURE",
|
|
40
|
-
)<
|
|
41
|
-
{
|
|
42
|
-
callback?: () => void;
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
setupSteps: NonNullable<SimulatorStoreType["setupSteps"]>;
|
|
46
|
-
setupStatus: SimulatorStoreType["setupStatus"];
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
setupSteps?: NonNullable<SimulatorStoreType["setupSteps"]>;
|
|
50
|
-
error: Error;
|
|
51
|
-
}
|
|
52
|
-
>();
|
|
53
|
-
|
|
54
16
|
export const connectToSimulatorIframeCreator = createAsyncAction(
|
|
55
17
|
"SIMULATOR/CONNECT_TO_SIMULATOR_IFRAME.REQUEST",
|
|
56
18
|
"SIMULATOR/CONNECT_TO_SIMULATOR_IFRAME.SUCCESS",
|
|
@@ -61,16 +23,10 @@ type SimulatorActions = ActionType<
|
|
|
61
23
|
| typeof connectToSimulatorIframeCreator.success
|
|
62
24
|
| typeof connectToSimulatorIframeCreator.request
|
|
63
25
|
| typeof connectToSimulatorIframeCreator.failure
|
|
64
|
-
| typeof checkSimulatorSetupCreator.success
|
|
65
|
-
| typeof checkSimulatorSetupCreator.failure
|
|
66
26
|
>;
|
|
67
27
|
|
|
68
28
|
// Selectors
|
|
69
29
|
|
|
70
|
-
export const selectSetupStatus = (
|
|
71
|
-
state: SliceMachineStoreType,
|
|
72
|
-
): SimulatorStoreType["setupStatus"] => state.simulator.setupStatus;
|
|
73
|
-
|
|
74
30
|
export const selectIsWaitingForIFrameCheck = (
|
|
75
31
|
state: SliceMachineStoreType,
|
|
76
32
|
): boolean => state.simulator.isWaitingForIframeCheck;
|
|
@@ -79,10 +35,6 @@ export const selectIframeStatus = (
|
|
|
79
35
|
state: SliceMachineStoreType,
|
|
80
36
|
): string | null => state.simulator.iframeStatus;
|
|
81
37
|
|
|
82
|
-
export const selectSetupSteps = (
|
|
83
|
-
state: SliceMachineStoreType,
|
|
84
|
-
): SimulatorStoreType["setupSteps"] => state.simulator.setupSteps;
|
|
85
|
-
|
|
86
38
|
// Reducer
|
|
87
39
|
export const simulatorReducer: Reducer<SimulatorStoreType, SimulatorActions> = (
|
|
88
40
|
state = initialState,
|
|
@@ -107,62 +59,11 @@ export const simulatorReducer: Reducer<SimulatorStoreType, SimulatorActions> = (
|
|
|
107
59
|
iframeStatus: "ko",
|
|
108
60
|
isWaitingForIframeCheck: false,
|
|
109
61
|
};
|
|
110
|
-
case getType(checkSimulatorSetupCreator.failure):
|
|
111
|
-
return {
|
|
112
|
-
...state,
|
|
113
|
-
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
114
|
-
setupSteps: action.payload.setupSteps || null,
|
|
115
|
-
setupStatus: {
|
|
116
|
-
...state.setupStatus,
|
|
117
|
-
manifest: "ko",
|
|
118
|
-
},
|
|
119
|
-
};
|
|
120
|
-
case getType(checkSimulatorSetupCreator.success):
|
|
121
|
-
return {
|
|
122
|
-
...state,
|
|
123
|
-
setupSteps: action.payload.setupSteps,
|
|
124
|
-
setupStatus: {
|
|
125
|
-
...state.setupStatus,
|
|
126
|
-
manifest: "ok",
|
|
127
|
-
},
|
|
128
|
-
};
|
|
129
62
|
default:
|
|
130
63
|
return state;
|
|
131
64
|
}
|
|
132
65
|
};
|
|
133
66
|
|
|
134
|
-
// Sagas
|
|
135
|
-
export function* checkSetupSaga(
|
|
136
|
-
action: ReturnType<typeof checkSimulatorSetupCreator.request>,
|
|
137
|
-
) {
|
|
138
|
-
try {
|
|
139
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
140
|
-
const setupStatus: SimulatorCheckResponse = yield call(checkSimulatorSetup);
|
|
141
|
-
|
|
142
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
143
|
-
const setupSteps: Awaited<ReturnType<typeof getSimulatorSetupSteps>> =
|
|
144
|
-
yield call(getSimulatorSetupSteps);
|
|
145
|
-
|
|
146
|
-
if (setupStatus.manifest === "ok") {
|
|
147
|
-
yield put(
|
|
148
|
-
checkSimulatorSetupCreator.success({
|
|
149
|
-
setupSteps: setupSteps.steps,
|
|
150
|
-
setupStatus,
|
|
151
|
-
}),
|
|
152
|
-
);
|
|
153
|
-
yield put(updateManifestCreator({ value: setupStatus.value }));
|
|
154
|
-
if (action.payload.callback) {
|
|
155
|
-
action.payload.callback();
|
|
156
|
-
}
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
yield call(failCheckSetupSaga, { setupSteps: setupSteps.steps });
|
|
160
|
-
} catch (error) {
|
|
161
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
162
|
-
yield put(checkSimulatorSetupCreator.failure({ error: error as Error }));
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
67
|
function* connectToSimulatorIframe() {
|
|
167
68
|
yield put(connectToSimulatorIframeCreator.request());
|
|
168
69
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
@@ -185,34 +86,6 @@ function* connectToSimulatorIframe() {
|
|
|
185
86
|
yield put(connectToSimulatorIframeCreator.failure());
|
|
186
87
|
}
|
|
187
88
|
|
|
188
|
-
export function* failCheckSetupSaga({
|
|
189
|
-
setupSteps,
|
|
190
|
-
}: { setupSteps?: NonNullable<SimulatorStoreType["setupSteps"]> } = {}) {
|
|
191
|
-
const isPreviewAvailableForFramework = (yield select(
|
|
192
|
-
selectIsSimulatorAvailableForFramework,
|
|
193
|
-
)) as ReturnType<typeof selectIsSimulatorAvailableForFramework>;
|
|
194
|
-
|
|
195
|
-
if (!isPreviewAvailableForFramework) {
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
yield put(
|
|
200
|
-
checkSimulatorSetupCreator.failure({
|
|
201
|
-
setupSteps,
|
|
202
|
-
error: new Error(),
|
|
203
|
-
}),
|
|
204
|
-
);
|
|
205
|
-
yield put(modalOpenCreator({ modalKey: ModalKeysEnum.SIMULATOR_SETUP }));
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Saga watchers
|
|
209
|
-
function* watchCheckSetup() {
|
|
210
|
-
yield takeLeading(
|
|
211
|
-
getType(checkSimulatorSetupCreator.request),
|
|
212
|
-
withLoader(checkSetupSaga, LoadingKeysEnum.CHECK_SIMULATOR),
|
|
213
|
-
);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
89
|
function* watchIframeCheck() {
|
|
217
90
|
yield takeLeading(
|
|
218
91
|
getType(connectToSimulatorIframeCreator.request),
|
|
@@ -225,6 +98,5 @@ function* watchIframeCheck() {
|
|
|
225
98
|
|
|
226
99
|
// Saga Exports
|
|
227
100
|
export function* watchSimulatorSagas() {
|
|
228
|
-
yield fork(watchCheckSetup);
|
|
229
101
|
yield fork(watchIframeCheck);
|
|
230
102
|
}
|
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
import { SimulatorManagerReadSliceSimulatorSetupStep } from "@slicemachine/manager/client";
|
|
2
|
-
|
|
3
1
|
export type SimulatorStoreType = {
|
|
4
|
-
setupSteps: SimulatorManagerReadSliceSimulatorSetupStep[] | null;
|
|
5
2
|
// we use strings to check if key is defined
|
|
6
3
|
iframeStatus: "ok" | "ko" | null;
|
|
7
|
-
setupStatus: {
|
|
8
|
-
manifest: "ok" | "ko" | null;
|
|
9
|
-
};
|
|
10
4
|
isWaitingForIframeCheck: boolean;
|
|
11
5
|
};
|
|
@@ -12,10 +12,7 @@ import {
|
|
|
12
12
|
changesPushSuccess,
|
|
13
13
|
} from "./userContext";
|
|
14
14
|
import { refreshStateCreator } from "./environment";
|
|
15
|
-
import {
|
|
16
|
-
checkSimulatorSetupCreator,
|
|
17
|
-
connectToSimulatorIframeCreator,
|
|
18
|
-
} from "./simulator";
|
|
15
|
+
import { connectToSimulatorIframeCreator } from "./simulator";
|
|
19
16
|
import ServerState from "@models/server/ServerState";
|
|
20
17
|
import {
|
|
21
18
|
customTypeCreateSuccess,
|
|
@@ -42,9 +39,6 @@ import { SaveSliceMockRequest } from "@src/apiClient";
|
|
|
42
39
|
const useSliceMachineActions = () => {
|
|
43
40
|
const dispatch = useDispatch();
|
|
44
41
|
|
|
45
|
-
const checkSimulatorSetup = (callback?: () => void) =>
|
|
46
|
-
dispatch(checkSimulatorSetupCreator.request({ callback }));
|
|
47
|
-
|
|
48
42
|
const connectToSimulatorIframe = () =>
|
|
49
43
|
dispatch(connectToSimulatorIframeCreator.request());
|
|
50
44
|
const connectToSimulatorFailure = () =>
|
|
@@ -62,8 +56,6 @@ const useSliceMachineActions = () => {
|
|
|
62
56
|
dispatch(modalOpenCreator({ modalKey: ModalKeysEnum.SCREENSHOTS }));
|
|
63
57
|
const openScreenshotPreviewModal = () =>
|
|
64
58
|
dispatch(modalOpenCreator({ modalKey: ModalKeysEnum.SCREENSHOT_PREVIEW }));
|
|
65
|
-
const openSimulatorSetupModal = () =>
|
|
66
|
-
dispatch(modalOpenCreator({ modalKey: ModalKeysEnum.SIMULATOR_SETUP }));
|
|
67
59
|
|
|
68
60
|
// Loading module
|
|
69
61
|
const startLoadingReview = () =>
|
|
@@ -190,7 +182,6 @@ const useSliceMachineActions = () => {
|
|
|
190
182
|
const pushChangesSuccess = () => dispatch(changesPushSuccess());
|
|
191
183
|
|
|
192
184
|
return {
|
|
193
|
-
checkSimulatorSetup,
|
|
194
185
|
connectToSimulatorFailure,
|
|
195
186
|
connectToSimulatorSuccess,
|
|
196
187
|
connectToSimulatorIframe,
|
|
@@ -215,7 +206,6 @@ const useSliceMachineActions = () => {
|
|
|
215
206
|
setSeenSimulatorToolTip,
|
|
216
207
|
setSeenChangesToolTip,
|
|
217
208
|
openScreenshotPreviewModal,
|
|
218
|
-
openSimulatorSetupModal,
|
|
219
209
|
closeModals,
|
|
220
210
|
pushChangesSuccess,
|
|
221
211
|
createCustomTypeSuccess,
|
|
@@ -30,7 +30,6 @@ const REQUIRED_ADAPTER_HOOKS: SliceMachineHookTypes[] = [
|
|
|
30
30
|
"custom-type:asset:read",
|
|
31
31
|
"custom-type:asset:delete",
|
|
32
32
|
"custom-type-library:read",
|
|
33
|
-
"slice-simulator:setup:read",
|
|
34
33
|
];
|
|
35
34
|
|
|
36
35
|
type CreateTestPluginArgs<TPluginOptions extends SliceMachinePluginOptions> =
|
|
@@ -6,23 +6,9 @@ import {
|
|
|
6
6
|
initialState,
|
|
7
7
|
simulatorReducer,
|
|
8
8
|
connectToSimulatorIframeCreator,
|
|
9
|
-
checkSimulatorSetupCreator,
|
|
10
|
-
failCheckSetupSaga,
|
|
11
9
|
} from "@src/modules/simulator";
|
|
12
|
-
import { select } from "redux-saga/effects";
|
|
13
|
-
import { testSaga, expectSaga } from "redux-saga-test-plan";
|
|
14
|
-
import { checkSetupSaga } from "@src/modules/simulator";
|
|
15
10
|
import { SimulatorStoreType } from "@src/modules/simulator/types";
|
|
16
11
|
|
|
17
|
-
import {
|
|
18
|
-
selectIsSimulatorAvailableForFramework,
|
|
19
|
-
updateManifestCreator,
|
|
20
|
-
} from "@src/modules/environment";
|
|
21
|
-
|
|
22
|
-
import { modalOpenCreator } from "@src/modules/modal";
|
|
23
|
-
import { ModalKeysEnum } from "@src/modules/modal/types";
|
|
24
|
-
import { checkSimulatorSetup, getSimulatorSetupSteps } from "@src/apiClient";
|
|
25
|
-
|
|
26
12
|
const dummySimulatorState: SimulatorStoreType = initialState;
|
|
27
13
|
|
|
28
14
|
describe("[Simulator module]", () => {
|
|
@@ -41,38 +27,6 @@ describe("[Simulator module]", () => {
|
|
|
41
27
|
).toEqual(dummySimulatorState);
|
|
42
28
|
});
|
|
43
29
|
|
|
44
|
-
it("should update the state when given checkSimulatorSetupCreator.success action", () => {
|
|
45
|
-
const initialState: SimulatorStoreType = dummySimulatorState;
|
|
46
|
-
const setupStatusResponse: SimulatorStoreType["setupStatus"] = {
|
|
47
|
-
manifest: "ok",
|
|
48
|
-
};
|
|
49
|
-
const setupStepsResponse = [
|
|
50
|
-
{
|
|
51
|
-
title: "foo",
|
|
52
|
-
body: "bar",
|
|
53
|
-
description: "baz",
|
|
54
|
-
isComplete: true,
|
|
55
|
-
validationMessages: [],
|
|
56
|
-
},
|
|
57
|
-
];
|
|
58
|
-
|
|
59
|
-
const action = checkSimulatorSetupCreator.success({
|
|
60
|
-
setupStatus: setupStatusResponse,
|
|
61
|
-
setupSteps: setupStepsResponse,
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
const expectedState: SimulatorStoreType = {
|
|
65
|
-
...dummySimulatorState,
|
|
66
|
-
setupStatus: {
|
|
67
|
-
...dummySimulatorState.setupStatus,
|
|
68
|
-
...setupStatusResponse,
|
|
69
|
-
},
|
|
70
|
-
setupSteps: setupStepsResponse,
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
expect(simulatorReducer(initialState, action)).toEqual(expectedState);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
30
|
it("should update the state when given connectToSimulatorIframeCreator.success action", () => {
|
|
77
31
|
const initialState: SimulatorStoreType = dummySimulatorState;
|
|
78
32
|
|
|
@@ -85,155 +39,5 @@ describe("[Simulator module]", () => {
|
|
|
85
39
|
|
|
86
40
|
expect(simulatorReducer(initialState, action)).toEqual(expectedState);
|
|
87
41
|
});
|
|
88
|
-
|
|
89
|
-
it("should set manifest status to ko if checkSimulatorSetupCreator.failure action", () => {
|
|
90
|
-
const initialState: SimulatorStoreType = dummySimulatorState;
|
|
91
|
-
// @ts-expect-error TS(2345) FIXME: Argument of type 'Error' is not assignable to para... Remove this comment to see the full error message
|
|
92
|
-
const action = checkSimulatorSetupCreator.failure(new Error("Error"));
|
|
93
|
-
|
|
94
|
-
const expectedState: SimulatorStoreType = {
|
|
95
|
-
...dummySimulatorState,
|
|
96
|
-
setupStatus: {
|
|
97
|
-
manifest: "ko",
|
|
98
|
-
},
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
expect(simulatorReducer(initialState, action)).toEqual(expectedState);
|
|
102
|
-
});
|
|
103
|
-
it("should call the api and dispatch the success action", () => {
|
|
104
|
-
const setupSimulatorAction: ReturnType<
|
|
105
|
-
typeof checkSimulatorSetupCreator.request
|
|
106
|
-
> = {
|
|
107
|
-
payload: {},
|
|
108
|
-
type: "SIMULATOR/CHECK_SETUP.REQUEST",
|
|
109
|
-
};
|
|
110
|
-
const saga = testSaga(checkSetupSaga, setupSimulatorAction);
|
|
111
|
-
saga.next().call(checkSimulatorSetup);
|
|
112
|
-
const response = { manifest: "ok" } as const;
|
|
113
|
-
saga.next(response).call(getSimulatorSetupSteps);
|
|
114
|
-
const response2 = {
|
|
115
|
-
steps: [
|
|
116
|
-
{
|
|
117
|
-
title: "foo",
|
|
118
|
-
body: "bar",
|
|
119
|
-
description: "baz",
|
|
120
|
-
isComplete: true,
|
|
121
|
-
validationMessages: [],
|
|
122
|
-
},
|
|
123
|
-
],
|
|
124
|
-
errors: [],
|
|
125
|
-
};
|
|
126
|
-
saga.next(response2).put(
|
|
127
|
-
checkSimulatorSetupCreator.success({
|
|
128
|
-
setupStatus: response,
|
|
129
|
-
setupSteps: response2.steps,
|
|
130
|
-
}),
|
|
131
|
-
);
|
|
132
|
-
saga.next().put(updateManifestCreator({ value: undefined }));
|
|
133
|
-
saga.next().isDone();
|
|
134
|
-
});
|
|
135
|
-
it("should call the api and dispatch the failure action", () => {
|
|
136
|
-
const setupSimulatorAction: ReturnType<
|
|
137
|
-
typeof checkSimulatorSetupCreator.request
|
|
138
|
-
> = {
|
|
139
|
-
payload: {},
|
|
140
|
-
type: "SIMULATOR/CHECK_SETUP.REQUEST",
|
|
141
|
-
};
|
|
142
|
-
const saga = testSaga(checkSetupSaga, setupSimulatorAction);
|
|
143
|
-
saga.next().call(checkSimulatorSetup);
|
|
144
|
-
const response = { manifest: "ko" } as const;
|
|
145
|
-
saga.next(response).call(getSimulatorSetupSteps);
|
|
146
|
-
const response2 = {
|
|
147
|
-
steps: [
|
|
148
|
-
{
|
|
149
|
-
title: "foo",
|
|
150
|
-
body: "bar",
|
|
151
|
-
description: "baz",
|
|
152
|
-
isComplete: true,
|
|
153
|
-
validationMessages: [],
|
|
154
|
-
},
|
|
155
|
-
],
|
|
156
|
-
errors: [],
|
|
157
|
-
};
|
|
158
|
-
saga
|
|
159
|
-
.next(response2)
|
|
160
|
-
.call(failCheckSetupSaga, { setupSteps: response2.steps });
|
|
161
|
-
saga.next().isDone();
|
|
162
|
-
});
|
|
163
|
-
it("should open setup modal if checkSimulatorSetupCreator.failure action", () => {
|
|
164
|
-
const payload = {
|
|
165
|
-
setupSteps: [
|
|
166
|
-
{
|
|
167
|
-
title: "foo",
|
|
168
|
-
body: "bar",
|
|
169
|
-
description: "baz",
|
|
170
|
-
isComplete: true,
|
|
171
|
-
validationMessages: [],
|
|
172
|
-
},
|
|
173
|
-
],
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
const saga = testSaga(failCheckSetupSaga, payload);
|
|
177
|
-
|
|
178
|
-
saga.next().select(selectIsSimulatorAvailableForFramework);
|
|
179
|
-
saga.next(true).put(
|
|
180
|
-
checkSimulatorSetupCreator.failure({
|
|
181
|
-
setupSteps: payload.setupSteps,
|
|
182
|
-
error: new Error(),
|
|
183
|
-
}),
|
|
184
|
-
);
|
|
185
|
-
saga
|
|
186
|
-
.next()
|
|
187
|
-
.put(modalOpenCreator({ modalKey: ModalKeysEnum.SIMULATOR_SETUP }));
|
|
188
|
-
});
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
describe("[failCheckSetupSaga]", () => {
|
|
192
|
-
it("stores setup steps even on failure", async () => {
|
|
193
|
-
const payload = {
|
|
194
|
-
setupSteps: [
|
|
195
|
-
{
|
|
196
|
-
title: "foo",
|
|
197
|
-
body: "bar",
|
|
198
|
-
description: "baz",
|
|
199
|
-
isComplete: true,
|
|
200
|
-
validationMessages: [],
|
|
201
|
-
},
|
|
202
|
-
],
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
await expectSaga(failCheckSetupSaga, payload)
|
|
206
|
-
.provide([[select(selectIsSimulatorAvailableForFramework), true]])
|
|
207
|
-
.put(
|
|
208
|
-
checkSimulatorSetupCreator.failure({
|
|
209
|
-
setupSteps: payload.setupSteps,
|
|
210
|
-
error: new Error(),
|
|
211
|
-
}),
|
|
212
|
-
)
|
|
213
|
-
.put(
|
|
214
|
-
modalOpenCreator({
|
|
215
|
-
modalKey: ModalKeysEnum.SIMULATOR_SETUP,
|
|
216
|
-
}),
|
|
217
|
-
)
|
|
218
|
-
.run();
|
|
219
|
-
});
|
|
220
|
-
it("should early return if the framework doesn't support the simulator feature", () => {
|
|
221
|
-
const payload = {
|
|
222
|
-
setupSteps: [
|
|
223
|
-
{
|
|
224
|
-
title: "foo",
|
|
225
|
-
body: "bar",
|
|
226
|
-
description: "baz",
|
|
227
|
-
isComplete: true,
|
|
228
|
-
validationMessages: [],
|
|
229
|
-
},
|
|
230
|
-
],
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
const saga = testSaga(failCheckSetupSaga, payload);
|
|
234
|
-
|
|
235
|
-
saga.next().select(selectIsSimulatorAvailableForFramework);
|
|
236
|
-
saga.next(false).isDone();
|
|
237
|
-
});
|
|
238
42
|
});
|
|
239
43
|
});
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Box } from "theme-ui";
|
|
2
|
-
|
|
3
|
-
type CodeSpanProps = {
|
|
4
|
-
// TODO: Can `string` be removed?
|
|
5
|
-
children?: React.ReactElement | string;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export const CodeSpan = ({ children }: CodeSpanProps) => {
|
|
9
|
-
return (
|
|
10
|
-
<Box
|
|
11
|
-
as="code"
|
|
12
|
-
sx={{
|
|
13
|
-
bg: "rgba(0, 0, 0, 0.05)",
|
|
14
|
-
borderRadius: 3,
|
|
15
|
-
padding: "2px 4px",
|
|
16
|
-
}}
|
|
17
|
-
>
|
|
18
|
-
{children}
|
|
19
|
-
</Box>
|
|
20
|
-
);
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export default CodeSpan;
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { useState, useRef } from "react";
|
|
2
|
-
import { Box, Flex, Button, useThemeUI } from "theme-ui";
|
|
3
|
-
import parse, {
|
|
4
|
-
domToReact,
|
|
5
|
-
Element,
|
|
6
|
-
HTMLReactParserOptions,
|
|
7
|
-
} from "html-react-parser";
|
|
8
|
-
import { MdCheck, MdContentCopy } from "react-icons/md";
|
|
9
|
-
|
|
10
|
-
import CodeSpan from "@components/CodeSpan";
|
|
11
|
-
|
|
12
|
-
const Pre = ({ children, ...props }: { children?: React.ReactNode }) => {
|
|
13
|
-
const { theme } = useThemeUI();
|
|
14
|
-
|
|
15
|
-
const [isCopied, setIsCopied] = useState(false);
|
|
16
|
-
const preRef = useRef<HTMLPreElement>(null);
|
|
17
|
-
|
|
18
|
-
const copy = (): void => {
|
|
19
|
-
if (preRef.current) {
|
|
20
|
-
navigator.clipboard
|
|
21
|
-
.writeText(preRef.current.innerText)
|
|
22
|
-
.then(() => {
|
|
23
|
-
setIsCopied(true);
|
|
24
|
-
setTimeout(() => {
|
|
25
|
-
setIsCopied(false);
|
|
26
|
-
}, 1200);
|
|
27
|
-
})
|
|
28
|
-
.catch(() => {
|
|
29
|
-
// ignored
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<Box
|
|
36
|
-
{...props}
|
|
37
|
-
sx={{
|
|
38
|
-
backgroundColor: "codeBlockBackground",
|
|
39
|
-
borderRadius: 8,
|
|
40
|
-
}}
|
|
41
|
-
>
|
|
42
|
-
<Flex
|
|
43
|
-
sx={{
|
|
44
|
-
px: "26px",
|
|
45
|
-
py: "22px",
|
|
46
|
-
color: "#FFF",
|
|
47
|
-
flexDirection: "row",
|
|
48
|
-
justifyContent: "space-between",
|
|
49
|
-
alignItems: "center",
|
|
50
|
-
borderBottom: "1px solid rgba(111, 110, 119, 0.2)",
|
|
51
|
-
}}
|
|
52
|
-
>
|
|
53
|
-
<Flex sx={{ alignItems: "center" }}>
|
|
54
|
-
{/*
|
|
55
|
-
<FileIcon size={14} style={{ marginRight: "12px" }} />
|
|
56
|
-
{fileName}
|
|
57
|
-
*/}
|
|
58
|
-
</Flex>
|
|
59
|
-
<Button
|
|
60
|
-
onClick={copy}
|
|
61
|
-
variant="transparent"
|
|
62
|
-
sx={{
|
|
63
|
-
display: "flex",
|
|
64
|
-
justifyContent: "center",
|
|
65
|
-
alignItems: "center",
|
|
66
|
-
p: 0,
|
|
67
|
-
fontSize: "12px",
|
|
68
|
-
color: "#FFF",
|
|
69
|
-
}}
|
|
70
|
-
>
|
|
71
|
-
Copy
|
|
72
|
-
{isCopied ? (
|
|
73
|
-
<MdCheck size={16} color={String(theme?.colors?.success)} />
|
|
74
|
-
) : (
|
|
75
|
-
<MdContentCopy size={16} style={{ marginLeft: "8px" }} />
|
|
76
|
-
)}
|
|
77
|
-
</Button>
|
|
78
|
-
</Flex>
|
|
79
|
-
<Box
|
|
80
|
-
ref={preRef}
|
|
81
|
-
as="pre"
|
|
82
|
-
sx={{
|
|
83
|
-
color: "#c9d1d9",
|
|
84
|
-
padding: "16px 20px",
|
|
85
|
-
overflow: "auto",
|
|
86
|
-
}}
|
|
87
|
-
>
|
|
88
|
-
{children}
|
|
89
|
-
</Box>
|
|
90
|
-
</Box>
|
|
91
|
-
);
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const defaultComponents: NonNullable<HTMLRendererProps["components"]> = {
|
|
95
|
-
code: ({ children }) => {
|
|
96
|
-
return <CodeSpan>{children}</CodeSpan>;
|
|
97
|
-
},
|
|
98
|
-
pre: ({ children, ...props }) => {
|
|
99
|
-
return <Pre {...props}>{children}</Pre>;
|
|
100
|
-
},
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
type HTMLRendererProps = {
|
|
104
|
-
html: string;
|
|
105
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
106
|
-
components?: Record<string, React.ComponentType<any>>;
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const HTMLRenderer = ({
|
|
110
|
-
html,
|
|
111
|
-
components = {},
|
|
112
|
-
}: HTMLRendererProps): JSX.Element => {
|
|
113
|
-
const parserOptions: HTMLReactParserOptions = {
|
|
114
|
-
replace: (domNode) => {
|
|
115
|
-
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
116
|
-
if (domNode instanceof Element && domNode.attribs) {
|
|
117
|
-
const children = domToReact(domNode.children, parserOptions);
|
|
118
|
-
|
|
119
|
-
const resolvedComponents = { ...components, ...defaultComponents };
|
|
120
|
-
const Comp = resolvedComponents[domNode.name];
|
|
121
|
-
|
|
122
|
-
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
123
|
-
if (Comp) {
|
|
124
|
-
return (
|
|
125
|
-
<Comp name={domNode.name} {...domNode.attribs}>
|
|
126
|
-
{children}
|
|
127
|
-
</Comp>
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
},
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
return <>{parse(html, parserOptions)}</>;
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
export default HTMLRenderer;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import CodeSpan from "@components/CodeSpan";
|
|
2
|
-
|
|
3
|
-
type TextWithInlineCodeProps = {
|
|
4
|
-
children: string;
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
const TextWithInlineCode = ({
|
|
8
|
-
children,
|
|
9
|
-
}: TextWithInlineCodeProps): JSX.Element => {
|
|
10
|
-
const res = children.split("`").map((part, i) => {
|
|
11
|
-
if (i % 2 === 1) {
|
|
12
|
-
return <CodeSpan>{part}</CodeSpan>;
|
|
13
|
-
} else {
|
|
14
|
-
return part;
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
return <>{res}</>;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export default TextWithInlineCode;
|