@applicaster/zapp-react-native-utils 16.0.0-rc.124 → 16.0.0-rc.125
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/actionsExecutor/actions/__tests__/openBottomSheet.inlineItems.test.ts +72 -0
- package/actionsExecutor/actions/openBottomSheet.ts +1 -0
- package/configurationUtils/__tests__/modalBlocksParser.test.ts +11 -0
- package/modalState/ModalOrchestrator.ts +1 -0
- package/modalState/__tests__/ModalOrchestrator.phase3.test.ts +23 -0
- package/modalState/index.ts +2 -0
- package/modalState/types.ts +11 -0
- package/package.json +2 -2
|
@@ -2,6 +2,22 @@ import { openBottomSheetAction } from "../openBottomSheet";
|
|
|
2
2
|
import { actionExecutor, ActionResult } from "../../ActionExecutor";
|
|
3
3
|
import { modalOrchestrator } from "../../../modalState/ModalOrchestrator";
|
|
4
4
|
|
|
5
|
+
jest.mock("@applicaster/zapp-pipes-v2-client", () => ({
|
|
6
|
+
PipesClientResponseHelper: jest.fn(() => ({ error: null })),
|
|
7
|
+
RequestBuilder: jest.fn(() => ({
|
|
8
|
+
setEntryContext: jest.fn().mockReturnThis(),
|
|
9
|
+
setScreenContext: jest.fn().mockReturnThis(),
|
|
10
|
+
setUrl: jest.fn().mockReturnThis(),
|
|
11
|
+
buildAxiosRequest: jest.fn().mockResolvedValue(undefined),
|
|
12
|
+
call: jest.fn().mockResolvedValue({
|
|
13
|
+
response: {
|
|
14
|
+
entry: [],
|
|
15
|
+
extensions: { dynamic_collection_options: { operations: "add" } },
|
|
16
|
+
},
|
|
17
|
+
}),
|
|
18
|
+
})),
|
|
19
|
+
}));
|
|
20
|
+
|
|
5
21
|
jest.mock("../../../modalState/store", () => ({
|
|
6
22
|
openBottomSheetModal: jest.fn(),
|
|
7
23
|
}));
|
|
@@ -165,6 +181,62 @@ describe("openBottomSheetAction inline items", () => {
|
|
|
165
181
|
expect(menu.content.emptyMessage).toBe("Queued items will be added here");
|
|
166
182
|
});
|
|
167
183
|
|
|
184
|
+
it("forwards content.operationButtons onto the menu", async () => {
|
|
185
|
+
const result = await openBottomSheetAction({
|
|
186
|
+
type: "openBottomSheet",
|
|
187
|
+
options: {
|
|
188
|
+
header: { title: "Playlists" },
|
|
189
|
+
content: {
|
|
190
|
+
items: [{ id: "p1", title: "Playlist 1" }],
|
|
191
|
+
operationButtons: {
|
|
192
|
+
add: {
|
|
193
|
+
title: "Create New Playlist",
|
|
194
|
+
iconURL: "https://example.com/add.png",
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
} as any);
|
|
200
|
+
|
|
201
|
+
expect(result).toBe(ActionResult.Success);
|
|
202
|
+
|
|
203
|
+
const [menu] = (modalOrchestrator.open as jest.Mock).mock.calls[0];
|
|
204
|
+
|
|
205
|
+
expect(menu.content.operationButtons).toEqual({
|
|
206
|
+
add: {
|
|
207
|
+
title: "Create New Playlist",
|
|
208
|
+
iconURL: "https://example.com/add.png",
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it("preserves Add presentation when loading itemsUrl content", async () => {
|
|
214
|
+
const result = await openBottomSheetAction({
|
|
215
|
+
type: "openBottomSheet",
|
|
216
|
+
options: {
|
|
217
|
+
content: {
|
|
218
|
+
itemsUrl: "https://example.com/collections",
|
|
219
|
+
operationButtons: {
|
|
220
|
+
add: {
|
|
221
|
+
title: "Create Collection",
|
|
222
|
+
iconURL: "file:///bundled-add.png",
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
expect(result).toBe(ActionResult.Success);
|
|
230
|
+
const [menu] = (modalOrchestrator.open as jest.Mock).mock.calls[0];
|
|
231
|
+
|
|
232
|
+
expect(menu.content).toMatchObject({
|
|
233
|
+
operationButtons: {
|
|
234
|
+
add: { title: "Create Collection", iconURL: "file:///bundled-add.png" },
|
|
235
|
+
},
|
|
236
|
+
dynamicCollection: { operations: ["add"] },
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
|
|
168
240
|
it("pushes a new sheet by default even when another sheet is already open", async () => {
|
|
169
241
|
(modalOrchestrator as any).stackSize = 1;
|
|
170
242
|
|
|
@@ -171,6 +171,17 @@ describe("parseModalBlocksConfiguration", () => {
|
|
|
171
171
|
expect(result.item.checkbox.default).toBeUndefined();
|
|
172
172
|
expect(result.item.actionButtons.default).toBeUndefined();
|
|
173
173
|
});
|
|
174
|
+
|
|
175
|
+
it("parses the generic button leading icon asset", () => {
|
|
176
|
+
const result = parseModalBlocksConfiguration(
|
|
177
|
+
{ "button.leading_icon.asset": "https://example.com/add.png" },
|
|
178
|
+
"playlist-experience"
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
expect(result.button.leadingIcon.default?.asset).toBe(
|
|
182
|
+
"https://example.com/add.png"
|
|
183
|
+
);
|
|
184
|
+
});
|
|
174
185
|
});
|
|
175
186
|
|
|
176
187
|
describe("getEmptyModalBlocksStructure", () => {
|
|
@@ -60,4 +60,27 @@ describe("ModalOrchestrator phase 3", () => {
|
|
|
60
60
|
|
|
61
61
|
expect(props.emptyMessage).toBe("Queued items will be added here");
|
|
62
62
|
});
|
|
63
|
+
|
|
64
|
+
it("forwards operationButtons onto the sheet props unchanged", () => {
|
|
65
|
+
const operationButtons = {
|
|
66
|
+
add: {
|
|
67
|
+
title: "Create New Playlist",
|
|
68
|
+
iconURL: "https://example.com/add.png",
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
modalOrchestrator.open({
|
|
73
|
+
header: { title: "Playlists" },
|
|
74
|
+
content: {
|
|
75
|
+
title: "Playlists",
|
|
76
|
+
items: [],
|
|
77
|
+
operationButtons,
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const props = (modalStore.getState().modalState.screen as any)
|
|
82
|
+
?.modalBottomSheetContentProps;
|
|
83
|
+
|
|
84
|
+
expect(props.operationButtons).toEqual(operationButtons);
|
|
85
|
+
});
|
|
63
86
|
});
|
package/modalState/index.ts
CHANGED
package/modalState/types.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { EntryAction } from "../entryActions/types";
|
|
2
|
+
|
|
1
3
|
export interface Header {
|
|
2
4
|
title: string;
|
|
3
5
|
subtitle?: string;
|
|
@@ -107,6 +109,13 @@ export interface DynamicCollectionOptions {
|
|
|
107
109
|
events?: Record<CollectionScopedOperation | string, Action[]>;
|
|
108
110
|
}
|
|
109
111
|
|
|
112
|
+
/** Presentation of a sheet-synthesized operation control; same fields as an entry action button. */
|
|
113
|
+
export type OperationButton = Pick<EntryAction["button"], "title" | "iconURL">;
|
|
114
|
+
|
|
115
|
+
export type OperationButtons = Partial<
|
|
116
|
+
Record<CollectionScopedOperation | string, OperationButton>
|
|
117
|
+
>;
|
|
118
|
+
|
|
110
119
|
export interface Content {
|
|
111
120
|
title: string;
|
|
112
121
|
stickyTitle?: boolean;
|
|
@@ -120,6 +129,8 @@ export interface Content {
|
|
|
120
129
|
styleOverrides?: Record<string, any>;
|
|
121
130
|
/** Shown under Next Up when the queue sheet has no upcoming items. */
|
|
122
131
|
emptyMessage?: string;
|
|
132
|
+
/** Producer-owned presentation for sheet-synthesized operation controls (e.g. `add`). */
|
|
133
|
+
operationButtons?: OperationButtons;
|
|
123
134
|
context?: Record<string, any>;
|
|
124
135
|
}
|
|
125
136
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-utils",
|
|
3
|
-
"version": "16.0.0-rc.
|
|
3
|
+
"version": "16.0.0-rc.125",
|
|
4
4
|
"description": "Applicaster Zapp React Native utilities package",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@applicaster/applicaster-types": "16.0.0-rc.
|
|
30
|
+
"@applicaster/applicaster-types": "16.0.0-rc.125",
|
|
31
31
|
"buffer": "^5.2.1",
|
|
32
32
|
"camelize": "^1.0.0",
|
|
33
33
|
"dayjs": "^1.11.10",
|