@applicaster/zapp-react-native-utils 16.0.0-alpha.1263110541 → 16.0.0-alpha.1314750780
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/actionUtils/index.ts +3 -1
- package/actionsExecutor/ActionExecutor.ts +10 -1
- package/actionsExecutor/ActionExecutorContext.tsx +13 -1
- package/actionsExecutor/__tests__/ActionExecutor.test.ts +71 -0
- package/actionsExecutor/__tests__/StorageActions.test.ts +98 -0
- package/actionsExecutor/__tests__/feedDecorator.test.ts +30 -0
- package/actionsExecutor/__tests__/screenToggleFlag.test.ts +90 -0
- package/actionsExecutor/actions/__tests__/dismissBottomSheet.test.ts +3 -0
- package/actionsExecutor/actions/__tests__/navigateToScreen.test.ts +186 -5
- package/actionsExecutor/actions/__tests__/openBottomSheet.customContent.test.ts +24 -0
- package/actionsExecutor/actions/__tests__/openBottomSheet.inlineItems.test.ts +273 -1
- package/actionsExecutor/actions/__tests__/presentScreen.test.ts +127 -0
- package/actionsExecutor/actions/__tests__/showAlert.test.ts +49 -0
- package/actionsExecutor/actions/__tests__/showToast.test.ts +2 -2
- package/actionsExecutor/actions/dismissBottomSheet.ts +2 -1
- package/actionsExecutor/actions/index.ts +4 -0
- package/actionsExecutor/actions/navigateToScreen.ts +33 -43
- package/actionsExecutor/actions/openBottomSheet.ts +36 -16
- package/actionsExecutor/actions/presentScreen.ts +78 -0
- package/actionsExecutor/actions/screenToggleFlag.ts +1 -3
- package/actionsExecutor/actions/showAlert.ts +51 -0
- package/actionsExecutor/actions/showToast.ts +2 -2
- package/actionsExecutor/consts.ts +2 -0
- package/actionsExecutor/feedDecorator.ts +6 -0
- package/actionsExecutor/types.ts +7 -0
- package/appUtils/contextKeysManager/__tests__/getKey/failure.test.ts +1 -22
- package/appUtils/contextKeysManager/__tests__/getKey/success/fullSearch.test.ts +1 -25
- package/appUtils/contextKeysManager/__tests__/getKey/success/searchInSecure.test.ts +1 -7
- package/appUtils/contextKeysManager/__tests__/removeKey/failure.test.ts +0 -25
- package/appUtils/contextKeysManager/__tests__/removeKey/success.test.ts +0 -6
- package/appUtils/contextKeysManager/__tests__/setKey/failure/failedToSaveInStorage.test.ts +0 -40
- package/appUtils/contextKeysManager/__tests__/setKey/{success/saveItemAndReference.test.ts → success.test.ts} +2 -42
- package/appUtils/contextKeysManager/index.ts +28 -129
- package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +4 -11
- package/appUtils/playerManager/OverlayObserver/__tests__/getUpcomingQueue.test.ts +67 -0
- package/appUtils/playerManager/OverlayObserver/__tests__/utils.test.ts +9 -2
- package/appUtils/playerManager/OverlayObserver/getUpcomingQueue.ts +15 -2
- package/appUtils/playerManager/OverlayObserver/utils.ts +2 -5
- package/appUtils/playerManager/__tests__/playerDiagnostics.test.ts +62 -0
- package/appUtils/playerManager/__tests__/playerNative.test.ts +76 -0
- package/appUtils/playerManager/__tests__/playerNativeCommand.test.ts +62 -0
- package/appUtils/playerManager/__tests__/playerToolbox.test.ts +281 -0
- package/appUtils/playerManager/__tests__/usePlayerControllerSetup.test.tsx +62 -0
- package/appUtils/playerManager/const.ts +13 -0
- package/appUtils/playerManager/index.ts +7 -0
- package/appUtils/playerManager/player.ts +25 -0
- package/appUtils/playerManager/playerNative.ts +22 -0
- package/appUtils/playerManager/playerNativeCommand.ts +3 -6
- package/appUtils/playerManager/playerToolbox.ts +196 -0
- package/appUtils/playerManager/usePlayerControllerSetup.tsx +6 -0
- package/arrayUtils/__tests__/reorderByIds.test.ts +13 -0
- package/arrayUtils/index.ts +26 -43
- package/cellUtils/__tests__/getButtonsEnabled.test.ts +28 -0
- package/cellUtils/__tests__/getCellNavigationEnabled.test.ts +36 -0
- package/cellUtils/__tests__/getIsCellNavigationEnabled.test.ts +35 -0
- package/cellUtils/__tests__/isCellNavigationEnabled.test.ts +21 -0
- package/cellUtils/index.ts +40 -0
- package/configurationUtils/__tests__/manifestKeyParser.test.ts +21 -0
- package/configurationUtils/__tests__/modalBlocksParser.test.ts +297 -1
- package/configurationUtils/manifestKeyParser.ts +12 -1
- package/configurationUtils/modalBlocksParser.ts +78 -4
- package/entryActions/__tests__/buildEntryActions.test.ts +97 -18
- package/entryActions/aliasPresentation.ts +26 -42
- package/entryActions/buildEntryActions.ts +1 -0
- package/entryActions/index.ts +0 -2
- package/focusManager/FocusManager.ts +26 -0
- package/focusManager/__tests__/FocusManager.test.ts +9 -0
- package/localizationUtils/index.ts +12 -6
- package/logger/__tests__/xrayToolbox.test.ts +69 -0
- package/logger/xrayToolbox.ts +67 -0
- package/manifestUtils/defaultManifestConfigurations/generalContent.js +6 -0
- package/manifestUtils/defaultManifestConfigurations/player.js +8 -0
- package/manifestUtils/keys.js +7 -2
- package/manifestUtils/mobileAction/container/__tests__/mobileActionButtonsContainer.test.js +21 -0
- package/manifestUtils/mobileAction/groups/__tests__/buildMobileActionButtonGroups.test.js +1 -1
- package/manifestUtils/mobileAction/groups/defaults.js +2 -1
- package/modalState/ModalOrchestrator.ts +23 -9
- package/modalState/RemoteEditableCollection.ts +9 -1
- package/modalState/__tests__/ModalOrchestrator.phase3.test.ts +39 -0
- package/modalState/__tests__/RemoteEditableCollection.test.ts +90 -1
- package/modalState/__tests__/index.test.ts +30 -1
- package/modalState/__tests__/useModalStoreState.test.ts +142 -0
- package/modalState/index.ts +8 -1
- package/modalState/store.ts +9 -2
- package/modalState/types.ts +42 -2
- package/modalState/useBottomSheetContent.ts +24 -17
- package/navigationUtils/xrayNavigator.ts +12 -0
- package/package.json +3 -2
- package/pluginUtils/__tests__/pluginUtils.test.js +32 -0
- package/pluginUtils/index.ts +29 -0
- package/quickBrickAssets/__tests__/index.test.ts +18 -0
- package/quickBrickAssets/index.ts +35 -0
- package/reactHooks/__tests__/getPluginConfiguration.test.ts +82 -0
- package/reactHooks/actions/index.ts +29 -23
- package/reactHooks/cell-click/__tests__/index.test.js +131 -1
- package/reactHooks/cell-click/index.ts +30 -15
- package/reactHooks/connection/index.tsx +8 -5
- package/reactHooks/feed/__tests__/feedInvalidation.test.tsx +338 -0
- package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +8 -2
- package/reactHooks/feed/__tests__/useMarkPipesDataStale.test.tsx +243 -0
- package/reactHooks/feed/useFeedLoader.tsx +28 -1
- package/reactHooks/feed/useLoadPipesDataDispatch.ts +12 -11
- package/reactHooks/feed/useMarkPipesDataStale.ts +68 -23
- package/reactHooks/navigation/__tests__/index.test.tsx +176 -1
- package/reactHooks/navigation/__tests__/usePresentScreen.test.ts +154 -0
- package/reactHooks/navigation/index.ts +2 -0
- package/reactHooks/navigation/usePresentScreen.ts +157 -0
- package/reactHooks/navigation/useRoute.ts +22 -5
- package/reactHooks/usePluginConfiguration.ts +84 -46
- package/riverComponetsMeasurementProvider/index.tsx +3 -1
- package/uiActionsRegistrator/__tests__/subscribe.test.ts +26 -0
- package/uiActionsRegistrator/registry.ts +16 -0
- package/appUtils/contextKeysManager/__tests__/getKey/success/byReference.test.ts +0 -56
- package/appUtils/contextKeysManager/__tests__/getKeyByReference/failure.test.ts +0 -265
- package/appUtils/contextKeysManager/__tests__/getKeyByReference/success.test.ts +0 -303
- package/appUtils/contextKeysManager/__tests__/removeReferenceForKey/failure.test.ts +0 -82
- package/appUtils/contextKeysManager/__tests__/removeReferenceForKey/success.test.ts +0 -41
- package/appUtils/contextKeysManager/__tests__/setKey/success/saveItemButNotReference.test.ts +0 -208
- package/appUtils/contextKeysManager/__tests__/setReferenceForKey/failure.test.ts +0 -93
- package/appUtils/contextKeysManager/__tests__/setReferenceForKey/success.test.ts +0 -45
|
@@ -8,6 +8,7 @@ import { modalOrchestrator } from "../../modalState/ModalOrchestrator";
|
|
|
8
8
|
import { openBottomSheetModal } from "../../modalState/store";
|
|
9
9
|
import {
|
|
10
10
|
DynamicCollectionOptions,
|
|
11
|
+
getMenuItemActions,
|
|
11
12
|
isPresentSubMenuAction,
|
|
12
13
|
Menu,
|
|
13
14
|
MenuItem,
|
|
@@ -91,6 +92,7 @@ export function entryToMenuItem(
|
|
|
91
92
|
icon: firstImage?.src,
|
|
92
93
|
isSelected: currentSelection.includes(itemId),
|
|
93
94
|
action: primaryAction,
|
|
95
|
+
actions: tapActions,
|
|
94
96
|
entryActions: entry.extensions?.entry_action || [],
|
|
95
97
|
};
|
|
96
98
|
}
|
|
@@ -206,7 +208,11 @@ export async function openBottomSheetAction(
|
|
|
206
208
|
items: [],
|
|
207
209
|
onPress: () => {},
|
|
208
210
|
contentComponent: content.component,
|
|
209
|
-
contentComponentProps:
|
|
211
|
+
contentComponentProps: {
|
|
212
|
+
...(content.props || {}),
|
|
213
|
+
actionContext: context,
|
|
214
|
+
},
|
|
215
|
+
themePluginId,
|
|
210
216
|
},
|
|
211
217
|
});
|
|
212
218
|
|
|
@@ -222,7 +228,18 @@ export async function openBottomSheetAction(
|
|
|
222
228
|
|
|
223
229
|
let dynamicCollection: DynamicCollectionOptions | undefined;
|
|
224
230
|
|
|
225
|
-
|
|
231
|
+
const rawDynamicCollection =
|
|
232
|
+
content?.dynamicCollection ??
|
|
233
|
+
content?.extensions?.dynamic_collection_options;
|
|
234
|
+
|
|
235
|
+
// An empty items array is a valid starting state for a provider-backed or
|
|
236
|
+
// offline collection. A sheet with neither items nor a source still errors.
|
|
237
|
+
const hasDynamicCollection = Boolean(rawDynamicCollection);
|
|
238
|
+
|
|
239
|
+
if (
|
|
240
|
+
Array.isArray(inlineItems) &&
|
|
241
|
+
(inlineItems.length > 0 || hasDynamicCollection)
|
|
242
|
+
) {
|
|
226
243
|
log_info("openBottomSheet: using inline items from action options", {
|
|
227
244
|
count: inlineItems.length,
|
|
228
245
|
});
|
|
@@ -234,10 +251,7 @@ export async function openBottomSheetAction(
|
|
|
234
251
|
entryToMenuItem(entry, behavior?.currentSelection ?? [])
|
|
235
252
|
);
|
|
236
253
|
|
|
237
|
-
dynamicCollection = parseDynamicCollectionOptions(
|
|
238
|
-
content?.dynamicCollection ??
|
|
239
|
-
content?.extensions?.dynamic_collection_options
|
|
240
|
-
);
|
|
254
|
+
dynamicCollection = parseDynamicCollectionOptions(rawDynamicCollection);
|
|
241
255
|
} else if (itemsUrl) {
|
|
242
256
|
log_info(`openBottomSheet: loading items from source: ${itemsUrl}`);
|
|
243
257
|
|
|
@@ -275,6 +289,9 @@ export async function openBottomSheetAction(
|
|
|
275
289
|
dynamicCollection,
|
|
276
290
|
themePluginId,
|
|
277
291
|
styleOverrides: styleOverrides ?? content?.styleOverrides,
|
|
292
|
+
emptyMessage: content?.emptyMessage,
|
|
293
|
+
operationButtons: content?.operationButtons,
|
|
294
|
+
context,
|
|
278
295
|
},
|
|
279
296
|
};
|
|
280
297
|
|
|
@@ -288,18 +305,21 @@ export async function openBottomSheetAction(
|
|
|
288
305
|
* reference it.
|
|
289
306
|
*/
|
|
290
307
|
const onItemPress = async (item: MenuItem): Promise<void> => {
|
|
291
|
-
|
|
292
|
-
// Submenu navigation is handled internally by the orchestrator
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
308
|
+
const actions = getMenuItemActions(item);
|
|
295
309
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
{
|
|
299
|
-
...context,
|
|
300
|
-
entry: item as any,
|
|
301
|
-
} as any
|
|
310
|
+
const executableActions = actions.filter(
|
|
311
|
+
(action) => !isPresentSubMenuAction(action)
|
|
302
312
|
);
|
|
313
|
+
|
|
314
|
+
if (executableActions.length > 0) {
|
|
315
|
+
await actionExecutor.handleActions(
|
|
316
|
+
executableActions as ActionType[],
|
|
317
|
+
{
|
|
318
|
+
...context,
|
|
319
|
+
entry: item as any,
|
|
320
|
+
} as any
|
|
321
|
+
);
|
|
322
|
+
}
|
|
303
323
|
};
|
|
304
324
|
|
|
305
325
|
if (action.options?.replace) {
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/// <reference types="@applicaster/applicaster-types" />
|
|
2
|
+
import { ActionResult } from "../ActionExecutor";
|
|
3
|
+
import { ActionHandler, ActionExecutionContext } from "../types";
|
|
4
|
+
import type { PresentScreenFn } from "../../reactHooks/navigation/usePresentScreen";
|
|
5
|
+
import { createLogger } from "../../logger";
|
|
6
|
+
|
|
7
|
+
const { log_error } = createLogger({
|
|
8
|
+
subsystem: "ActionExecutorContext",
|
|
9
|
+
category: "General",
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Options for the presentScreen action.
|
|
14
|
+
*/
|
|
15
|
+
export interface PresentScreenOptions {
|
|
16
|
+
/** The screen type to present (from content types mapping) */
|
|
17
|
+
typeMapping: string;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Entry to present the screen with. Can be:
|
|
21
|
+
* - "@{entry/}" to use the context entry
|
|
22
|
+
* - A ZappEntry object
|
|
23
|
+
* - undefined to present the screen without an entry
|
|
24
|
+
*/
|
|
25
|
+
entry?: "@{entry/}" | ZappEntry;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Creates a present-screen action handler with the provided dependencies.
|
|
30
|
+
*
|
|
31
|
+
* Unlike navigateToScreen, this action does not return until the presented
|
|
32
|
+
* screen reports a result, so a screen that gates the flow (a parental lock,
|
|
33
|
+
* for example) can stop the remaining actions by being cancelled.
|
|
34
|
+
*
|
|
35
|
+
* @param presentScreen - Presents a screen as a modal and resolves with its result
|
|
36
|
+
* @returns An action handler that presents a screen and awaits its outcome
|
|
37
|
+
*/
|
|
38
|
+
export function createPresentScreenAction(
|
|
39
|
+
presentScreen: PresentScreenFn
|
|
40
|
+
): ActionHandler<PresentScreenOptions> {
|
|
41
|
+
return async function presentScreenAction(
|
|
42
|
+
action,
|
|
43
|
+
context?: ActionExecutionContext
|
|
44
|
+
): Promise<ActionResult> {
|
|
45
|
+
const typeMapping = action.options?.typeMapping;
|
|
46
|
+
|
|
47
|
+
if (!typeMapping) {
|
|
48
|
+
log_error("presentScreen: typeMapping option is missing");
|
|
49
|
+
|
|
50
|
+
return ActionResult.Error;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const entrySource = action.options?.entry;
|
|
54
|
+
|
|
55
|
+
const entry = entrySource
|
|
56
|
+
? entrySource === "@{entry/}"
|
|
57
|
+
? context?.entry
|
|
58
|
+
: entrySource
|
|
59
|
+
: undefined;
|
|
60
|
+
|
|
61
|
+
if (entry && typeof entry !== "object") {
|
|
62
|
+
log_error(
|
|
63
|
+
`presentScreen: entry option is not an object, entry: ${entry}`
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
return ActionResult.Error;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const result = await presentScreen({ typeMapping, entry });
|
|
70
|
+
|
|
71
|
+
if (result.error) {
|
|
72
|
+
return ActionResult.Error;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Anything short of success stops the remaining actions in the chain.
|
|
76
|
+
return result.success ? ActionResult.Success : ActionResult.Cancel;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -27,12 +27,10 @@ export const screenToggleFlagAction: ActionHandler<
|
|
|
27
27
|
const screenRoute = context?.screenRoute;
|
|
28
28
|
const screenStateStore = context?.screenStateStore;
|
|
29
29
|
|
|
30
|
-
await screenToggleFlag(
|
|
30
|
+
return await screenToggleFlag(
|
|
31
31
|
screenRoute,
|
|
32
32
|
screenStateStore,
|
|
33
33
|
{ entry: context?.entry, options: action.options },
|
|
34
34
|
action
|
|
35
35
|
);
|
|
36
|
-
|
|
37
|
-
return ActionResult.Success;
|
|
38
36
|
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/// <reference types="@applicaster/applicaster-types" />
|
|
2
|
+
import { showAlertDialog } from "../../alertUtils";
|
|
3
|
+
import { ActionResult } from "../ActionExecutor";
|
|
4
|
+
import { ActionHandler } from "../types";
|
|
5
|
+
import { createLogger } from "../../logger";
|
|
6
|
+
|
|
7
|
+
const { log_info } = createLogger({
|
|
8
|
+
subsystem: "ActionExecutorContext",
|
|
9
|
+
category: "General",
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Options for the showAlert action.
|
|
14
|
+
*/
|
|
15
|
+
export interface ShowAlertOptions {
|
|
16
|
+
/** Dialog title (required) */
|
|
17
|
+
title: string;
|
|
18
|
+
|
|
19
|
+
/** Dialog message */
|
|
20
|
+
message?: string;
|
|
21
|
+
|
|
22
|
+
/** Dismiss button text. Defaults to "OK" */
|
|
23
|
+
okButtonText?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Tells the user something and waits for them to acknowledge it.
|
|
28
|
+
*
|
|
29
|
+
* One button, because there is nothing to decide. Use `confirmDialog` when the
|
|
30
|
+
* user is choosing between going on and backing out; a `confirmDialog` without
|
|
31
|
+
* a cancel label still renders two buttons, the second one blank.
|
|
32
|
+
*
|
|
33
|
+
* Always resolves to Success: dismissing a notice is not a cancellation, so the
|
|
34
|
+
* rest of the chain runs.
|
|
35
|
+
*/
|
|
36
|
+
export const showAlertAction: ActionHandler<ShowAlertOptions> = async (
|
|
37
|
+
action
|
|
38
|
+
): Promise<ActionResult> => {
|
|
39
|
+
log_info("handleAction: showAlert event");
|
|
40
|
+
|
|
41
|
+
const options = action.options as ShowAlertOptions;
|
|
42
|
+
|
|
43
|
+
return new Promise<ActionResult>((resolve) => {
|
|
44
|
+
showAlertDialog({
|
|
45
|
+
title: options?.title,
|
|
46
|
+
message: options?.message,
|
|
47
|
+
okButtonText: options?.okButtonText || "OK",
|
|
48
|
+
completion: () => resolve(ActionResult.Success),
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
};
|
|
@@ -5,7 +5,7 @@ import { postEvent } from "../../reactHooks/useSubscriberFor";
|
|
|
5
5
|
|
|
6
6
|
export const CONFIRMATION_TOAST_SOURCE = "confirmation";
|
|
7
7
|
|
|
8
|
-
export const CONFIRMATION_TOAST_DEFAULT_TIMEOUT =
|
|
8
|
+
export const CONFIRMATION_TOAST_DEFAULT_TIMEOUT = 5000;
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Shows a mobile confirmation toast with Theme defaults from
|
|
@@ -13,7 +13,7 @@ export const CONFIRMATION_TOAST_DEFAULT_TIMEOUT = 1000;
|
|
|
13
13
|
*
|
|
14
14
|
* This action is confirmation-only by design: it always stamps
|
|
15
15
|
* `source: "confirmation"` (so Theme confirmation styles apply) and defaults
|
|
16
|
-
* `timeout` to
|
|
16
|
+
* `timeout` to 5000 ms. Non-confirmation toasts (e.g. Offline Experience)
|
|
17
17
|
* must post on the shared `"showToast"` event bus directly and omit `source`.
|
|
18
18
|
* Callers may override individual style fields; Theme supplies the rest.
|
|
19
19
|
*
|
|
@@ -9,6 +9,7 @@ export const ACTION_TYPES = {
|
|
|
9
9
|
PRESENT_SUB_MENU: "presentSubMenu",
|
|
10
10
|
SEND_CLOUD_EVENT: "sendCloudEvent",
|
|
11
11
|
NAVIGATE_TO_SCREEN: "navigateToScreen",
|
|
12
|
+
PRESENT_SCREEN: "presentScreen",
|
|
12
13
|
GO_BACK: "goBack",
|
|
13
14
|
GO_HOME: "goHome",
|
|
14
15
|
SHOW_TOAST: "showToast",
|
|
@@ -22,6 +23,7 @@ export const ACTION_TYPES = {
|
|
|
22
23
|
SWITCH_LAYOUT: "switchLayout",
|
|
23
24
|
APP_RESTART: "appRestart",
|
|
24
25
|
CONFIRM_DIALOG: "confirmDialog",
|
|
26
|
+
SHOW_ALERT: "showAlert",
|
|
25
27
|
SCREEN_SET_VARIABLE: "screenSetVariable",
|
|
26
28
|
SCREEN_TOGGLE_FLAG: "screenToggleFlag",
|
|
27
29
|
} as const;
|
|
@@ -47,6 +47,11 @@ function makeMultiSelect(feed: ZappFeed, key, decoratedFeed) {
|
|
|
47
47
|
? "sessionStorageToggleFlag"
|
|
48
48
|
: "localStorageToggleFlag";
|
|
49
49
|
|
|
50
|
+
// the toggle actions read their limit from their own options
|
|
51
|
+
const maxItems = Number(
|
|
52
|
+
decoratedFeed.extensions?.preference_editor_options?.max_items
|
|
53
|
+
);
|
|
54
|
+
|
|
50
55
|
decoratedFeed.entry?.forEach((entry: ZappEntry) => {
|
|
51
56
|
entry.type.value = "action";
|
|
52
57
|
entry.id = entry.extensions?.tag || entry.id;
|
|
@@ -59,6 +64,7 @@ function makeMultiSelect(feed: ZappFeed, key, decoratedFeed) {
|
|
|
59
64
|
type: actionType,
|
|
60
65
|
options: {
|
|
61
66
|
key,
|
|
67
|
+
...(maxItems > 0 && { max_items: maxItems }),
|
|
62
68
|
},
|
|
63
69
|
},
|
|
64
70
|
],
|
package/actionsExecutor/types.ts
CHANGED
|
@@ -30,6 +30,13 @@ export interface ActionExecutionContext {
|
|
|
30
30
|
/** Context entry for additional data */
|
|
31
31
|
entryContext?: ZappEntry;
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Sets the entry that the screen opened by this tap reads as `@{entry/...}`.
|
|
35
|
+
* Actions that open a screen call it themselves, so a tap that does not open
|
|
36
|
+
* one (a selection toggle) does not update the shared entry context.
|
|
37
|
+
*/
|
|
38
|
+
setEntryContext?: (entry: ZappEntry) => void;
|
|
39
|
+
|
|
33
40
|
/** Callback function for action completion */
|
|
34
41
|
callback?: (result: { success: boolean; error: any; abort: boolean }) => void;
|
|
35
42
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ContextKeysManager
|
|
1
|
+
import { ContextKeysManager } from "../..";
|
|
2
2
|
|
|
3
3
|
describe("Context Keys Manager - getKey", () => {
|
|
4
4
|
it("returns null if key is invalid", async () => {
|
|
@@ -34,8 +34,6 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
34
34
|
secureStorage: mockedSecureStorage,
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
-
const getKeyByReference = jest.spyOn(contextManager, "getKeyByReference");
|
|
38
|
-
|
|
39
37
|
// run
|
|
40
38
|
const result = await contextManager.getKey(invalidKey);
|
|
41
39
|
|
|
@@ -50,7 +48,6 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
50
48
|
data: { key: invalidKey },
|
|
51
49
|
});
|
|
52
50
|
|
|
53
|
-
expect(getKeyByReference).not.toHaveBeenCalled();
|
|
54
51
|
expect(mockedSessionStorage.getItem).not.toHaveBeenCalled();
|
|
55
52
|
expect(mockedLocalStorage.getItem).not.toHaveBeenCalled();
|
|
56
53
|
expect(mockedSecureStorage.getItem).not.toHaveBeenCalled();
|
|
@@ -90,10 +87,6 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
90
87
|
secureStorage: mockedSecureStorage,
|
|
91
88
|
});
|
|
92
89
|
|
|
93
|
-
const getKeyByReference = jest
|
|
94
|
-
.spyOn(contextManager, "getKeyByReference")
|
|
95
|
-
.mockResolvedValueOnce(NOTHING);
|
|
96
|
-
|
|
97
90
|
// run
|
|
98
91
|
const result = await contextManager.getKey(key);
|
|
99
92
|
|
|
@@ -107,8 +100,6 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
107
100
|
data: { key },
|
|
108
101
|
});
|
|
109
102
|
|
|
110
|
-
expect(getKeyByReference).toHaveBeenCalledWith("key", "namespace");
|
|
111
|
-
|
|
112
103
|
expect(mockedSessionStorage.getItem).toHaveBeenCalledWith(
|
|
113
104
|
"key",
|
|
114
105
|
"namespace"
|
|
@@ -152,10 +143,6 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
152
143
|
secureStorage: mockedSecureStorage,
|
|
153
144
|
});
|
|
154
145
|
|
|
155
|
-
const getKeyByReference = jest
|
|
156
|
-
.spyOn(contextManager, "getKeyByReference")
|
|
157
|
-
.mockResolvedValueOnce(NOTHING);
|
|
158
|
-
|
|
159
146
|
// run
|
|
160
147
|
const result = await contextManager.getKey(key);
|
|
161
148
|
|
|
@@ -169,8 +156,6 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
169
156
|
data: { key },
|
|
170
157
|
});
|
|
171
158
|
|
|
172
|
-
expect(getKeyByReference).toHaveBeenCalledWith("key", "namespace");
|
|
173
|
-
|
|
174
159
|
expect(mockedSessionStorage.getItem).toHaveBeenCalledWith(
|
|
175
160
|
"key",
|
|
176
161
|
"namespace"
|
|
@@ -214,10 +199,6 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
214
199
|
secureStorage: mockedSecureStorage,
|
|
215
200
|
});
|
|
216
201
|
|
|
217
|
-
const getKeyByReference = jest
|
|
218
|
-
.spyOn(contextManager, "getKeyByReference")
|
|
219
|
-
.mockResolvedValueOnce(NOTHING);
|
|
220
|
-
|
|
221
202
|
// run
|
|
222
203
|
const result = await contextManager.getKey(key);
|
|
223
204
|
|
|
@@ -231,8 +212,6 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
231
212
|
data: { key },
|
|
232
213
|
});
|
|
233
214
|
|
|
234
|
-
expect(getKeyByReference).toHaveBeenCalledWith("key", "namespace");
|
|
235
|
-
|
|
236
215
|
expect(mockedSessionStorage.getItem).toHaveBeenCalledWith(
|
|
237
216
|
"key",
|
|
238
217
|
"namespace"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ContextKeysManager
|
|
1
|
+
import { ContextKeysManager } from "../../..";
|
|
2
2
|
|
|
3
3
|
describe("Context Keys Manager - getKey", () => {
|
|
4
4
|
it("returns value if found in session-storage", async () => {
|
|
@@ -35,10 +35,6 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
35
35
|
secureStorage: mockedSecureStorage,
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
-
const getKeyByReference = jest
|
|
39
|
-
.spyOn(contextManager, "getKeyByReference")
|
|
40
|
-
.mockResolvedValueOnce(NOTHING);
|
|
41
|
-
|
|
42
38
|
// run
|
|
43
39
|
const result = await contextManager.getKey(key);
|
|
44
40
|
|
|
@@ -47,8 +43,6 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
47
43
|
|
|
48
44
|
expect(mockedLogger.warn).not.toHaveBeenCalled();
|
|
49
45
|
|
|
50
|
-
expect(getKeyByReference).toHaveBeenCalledWith("key", "namespace");
|
|
51
|
-
|
|
52
46
|
expect(mockedSessionStorage.getItem).toHaveBeenCalledWith(
|
|
53
47
|
"key",
|
|
54
48
|
"namespace"
|
|
@@ -92,10 +86,6 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
92
86
|
secureStorage: mockedSecureStorage,
|
|
93
87
|
});
|
|
94
88
|
|
|
95
|
-
const getKeyByReference = jest
|
|
96
|
-
.spyOn(contextManager, "getKeyByReference")
|
|
97
|
-
.mockResolvedValueOnce(NOTHING);
|
|
98
|
-
|
|
99
89
|
// run
|
|
100
90
|
const result = await contextManager.getKey(key);
|
|
101
91
|
|
|
@@ -104,8 +94,6 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
104
94
|
|
|
105
95
|
expect(mockedLogger.warn).not.toHaveBeenCalled();
|
|
106
96
|
|
|
107
|
-
expect(getKeyByReference).toHaveBeenCalledWith("key", "namespace");
|
|
108
|
-
|
|
109
97
|
expect(mockedSessionStorage.getItem).toHaveBeenCalledWith(
|
|
110
98
|
"key",
|
|
111
99
|
"namespace"
|
|
@@ -149,10 +137,6 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
149
137
|
secureStorage: mockedSecureStorage,
|
|
150
138
|
});
|
|
151
139
|
|
|
152
|
-
const getKeyByReference = jest
|
|
153
|
-
.spyOn(contextManager, "getKeyByReference")
|
|
154
|
-
.mockResolvedValueOnce(NOTHING);
|
|
155
|
-
|
|
156
140
|
// run
|
|
157
141
|
const result = await contextManager.getKey(key);
|
|
158
142
|
|
|
@@ -161,8 +145,6 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
161
145
|
|
|
162
146
|
expect(mockedLogger.warn).not.toHaveBeenCalled();
|
|
163
147
|
|
|
164
|
-
expect(getKeyByReference).toHaveBeenCalledWith("key", "namespace");
|
|
165
|
-
|
|
166
148
|
expect(mockedSessionStorage.getItem).toHaveBeenCalledWith(
|
|
167
149
|
"key",
|
|
168
150
|
"namespace"
|
|
@@ -209,10 +191,6 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
209
191
|
secureStorage: mockedSecureStorage,
|
|
210
192
|
});
|
|
211
193
|
|
|
212
|
-
const getKeyByReference = jest
|
|
213
|
-
.spyOn(contextManager, "getKeyByReference")
|
|
214
|
-
.mockResolvedValueOnce(NOTHING);
|
|
215
|
-
|
|
216
194
|
// run
|
|
217
195
|
const result = await contextManager.getKey(key);
|
|
218
196
|
|
|
@@ -221,8 +199,6 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
221
199
|
|
|
222
200
|
expect(mockedLogger.warn).not.toHaveBeenCalled();
|
|
223
201
|
|
|
224
|
-
expect(getKeyByReference).toHaveBeenCalledWith("key", "namespace");
|
|
225
|
-
|
|
226
202
|
expect(mockedSessionStorage.getItem).toHaveBeenCalledWith(
|
|
227
203
|
"key",
|
|
228
204
|
"namespace"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ContextKeysManager
|
|
1
|
+
import { ContextKeysManager } from "../../..";
|
|
2
2
|
import { DEFAULT_NAMESPACE } from "../../../consts";
|
|
3
3
|
|
|
4
4
|
describe("Context Keys Manager - getKey", () => {
|
|
@@ -36,10 +36,6 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
36
36
|
secureStorage: mockedSecureStorage,
|
|
37
37
|
});
|
|
38
38
|
|
|
39
|
-
const getKeyByReference = jest
|
|
40
|
-
.spyOn(contextManager, "getKeyByReference")
|
|
41
|
-
.mockResolvedValueOnce(NOTHING);
|
|
42
|
-
|
|
43
39
|
// run
|
|
44
40
|
const result = await contextManager.getKey(key);
|
|
45
41
|
|
|
@@ -48,8 +44,6 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
48
44
|
|
|
49
45
|
expect(mockedLogger.warn).not.toHaveBeenCalled();
|
|
50
46
|
|
|
51
|
-
expect(getKeyByReference).toHaveBeenCalledWith("key", DEFAULT_NAMESPACE);
|
|
52
|
-
|
|
53
47
|
expect(mockedSessionStorage.getItem).toHaveBeenCalledWith(
|
|
54
48
|
"key",
|
|
55
49
|
DEFAULT_NAMESPACE
|
|
@@ -34,11 +34,6 @@ describe("Context Keys Manager - removeKey", () => {
|
|
|
34
34
|
secureStorage: mockedSecureStorage,
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
-
const removeReferenceForKey = jest.spyOn(
|
|
38
|
-
contextManager,
|
|
39
|
-
"removeReferenceForKey"
|
|
40
|
-
);
|
|
41
|
-
|
|
42
37
|
// run
|
|
43
38
|
const result = await contextManager.removeKey(key);
|
|
44
39
|
|
|
@@ -51,8 +46,6 @@ describe("Context Keys Manager - removeKey", () => {
|
|
|
51
46
|
data: { key },
|
|
52
47
|
});
|
|
53
48
|
|
|
54
|
-
expect(removeReferenceForKey).not.toHaveBeenCalled();
|
|
55
|
-
|
|
56
49
|
expect(mockedSessionStorage.removeItem).not.toHaveBeenCalled();
|
|
57
50
|
expect(mockedLocalStorage.removeItem).not.toHaveBeenCalled();
|
|
58
51
|
expect(mockedSecureStorage.removeItem).not.toHaveBeenCalled();
|
|
@@ -92,10 +85,6 @@ describe("Context Keys Manager - removeKey", () => {
|
|
|
92
85
|
secureStorage: mockedSecureStorage,
|
|
93
86
|
});
|
|
94
87
|
|
|
95
|
-
const removeReferenceForKey = jest
|
|
96
|
-
.spyOn(contextManager, "removeReferenceForKey")
|
|
97
|
-
.mockResolvedValueOnce(true);
|
|
98
|
-
|
|
99
88
|
// run
|
|
100
89
|
const result = await contextManager.removeKey(key);
|
|
101
90
|
|
|
@@ -107,8 +96,6 @@ describe("Context Keys Manager - removeKey", () => {
|
|
|
107
96
|
data: { key },
|
|
108
97
|
});
|
|
109
98
|
|
|
110
|
-
expect(removeReferenceForKey).toHaveBeenCalledWith("key", "namespace");
|
|
111
|
-
|
|
112
99
|
expect(mockedSessionStorage.removeItem).toHaveBeenCalledWith(
|
|
113
100
|
"key",
|
|
114
101
|
"namespace"
|
|
@@ -159,10 +146,6 @@ describe("Context Keys Manager - removeKey", () => {
|
|
|
159
146
|
secureStorage: mockedSecureStorage,
|
|
160
147
|
});
|
|
161
148
|
|
|
162
|
-
const removeReferenceForKey = jest
|
|
163
|
-
.spyOn(contextManager, "removeReferenceForKey")
|
|
164
|
-
.mockResolvedValueOnce(true);
|
|
165
|
-
|
|
166
149
|
// run
|
|
167
150
|
const result = await contextManager.removeKey(key);
|
|
168
151
|
|
|
@@ -174,8 +157,6 @@ describe("Context Keys Manager - removeKey", () => {
|
|
|
174
157
|
data: { key },
|
|
175
158
|
});
|
|
176
159
|
|
|
177
|
-
expect(removeReferenceForKey).toHaveBeenCalledWith("key", "namespace");
|
|
178
|
-
|
|
179
160
|
expect(mockedSessionStorage.removeItem).toHaveBeenCalledWith(
|
|
180
161
|
"key",
|
|
181
162
|
"namespace"
|
|
@@ -226,10 +207,6 @@ describe("Context Keys Manager - removeKey", () => {
|
|
|
226
207
|
secureStorage: mockedSecureStorage,
|
|
227
208
|
});
|
|
228
209
|
|
|
229
|
-
const removeReferenceForKey = jest
|
|
230
|
-
.spyOn(contextManager, "removeReferenceForKey")
|
|
231
|
-
.mockResolvedValueOnce(true);
|
|
232
|
-
|
|
233
210
|
// run
|
|
234
211
|
const result = await contextManager.removeKey(key);
|
|
235
212
|
|
|
@@ -241,8 +218,6 @@ describe("Context Keys Manager - removeKey", () => {
|
|
|
241
218
|
data: { key },
|
|
242
219
|
});
|
|
243
220
|
|
|
244
|
-
expect(removeReferenceForKey).toHaveBeenCalledWith("key", "namespace");
|
|
245
|
-
|
|
246
221
|
expect(mockedSessionStorage.removeItem).toHaveBeenCalledWith(
|
|
247
222
|
"key",
|
|
248
223
|
"namespace"
|
|
@@ -34,10 +34,6 @@ describe("Context Keys Manager - removeKey", () => {
|
|
|
34
34
|
secureStorage: mockedSecureStorage,
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
-
const removeReferenceForKey = jest
|
|
38
|
-
.spyOn(contextManager, "removeReferenceForKey")
|
|
39
|
-
.mockResolvedValueOnce(true);
|
|
40
|
-
|
|
41
37
|
// run
|
|
42
38
|
const result = await contextManager.removeKey(key);
|
|
43
39
|
|
|
@@ -46,8 +42,6 @@ describe("Context Keys Manager - removeKey", () => {
|
|
|
46
42
|
|
|
47
43
|
expect(mockedLogger.warn).not.toHaveBeenCalled();
|
|
48
44
|
|
|
49
|
-
expect(removeReferenceForKey).toHaveBeenCalledWith("key", "namespace");
|
|
50
|
-
|
|
51
45
|
expect(mockedSessionStorage.removeItem).toHaveBeenCalledWith(
|
|
52
46
|
"key",
|
|
53
47
|
"namespace"
|