Bug 1920806 - Allow for tab orientation set pref actions and multi-actions to auto trigger when the Single Select picker renders r=hanna_a,omc-reviewers

Allow the inclusion of an "autoTrigger" attribute on AboutWelcome SingleSelect components `content` prop`. When set to true, the action for the tile with the id matching `content.selected` (if no value provided, defaults to the first tile in the list) is automatically triggered when the tile renders.

Because this deviates from our usual patterns for triggering actions, a guard is included to ensure this can only be used for sidebar prefs (with room to expand for other actions/prefs in the future).

Differential Revision: https://phabricator.services.mozilla.com/D223422
This commit is contained in:
Meg Viar 2024-09-26 17:26:37 +00:00
parent b8bc36b96b
commit d527c22039
4 changed files with 142 additions and 4 deletions

View File

@ -17,13 +17,49 @@ export const SingleSelect = ({
}) => {
const category = content.tiles?.category?.type || content.tiles?.type;
const isSingleSelect = category === "single-select";
const autoTriggerAllowed = itemAction => {
// Currently only enabled for sidebar experiment prefs
const allowedActions = ["SET_PREF"];
const allowedPrefs = ["sidebar.revamp", "sidebar.verticalTabs"];
const checkAction = action => {
if (!allowedActions.includes(action.type)) {
return false;
}
if (
action.type === "SET_PREF" &&
!allowedPrefs.includes(action.data?.pref.name)
) {
return false;
}
return true;
};
if (itemAction.type === "MULTI_ACTION") {
// Only allow autoTrigger if all actions are allowed
return !itemAction.data.actions.some(action => !checkAction(action));
}
return checkAction(itemAction);
};
// When screen renders for first time or user navigates back, update state to
// check default option.
useEffect(() => {
if (isSingleSelect && !activeSingleSelect) {
let newActiveSingleSelect =
content.tiles?.selected || content.tiles.data[0].id;
content.tiles?.selected || content.tiles?.data[0].id;
setActiveSingleSelect(newActiveSingleSelect);
let selectedTile = content.tiles?.data.find(
opt => opt.id === newActiveSingleSelect
);
// If applicable, automatically trigger the action for the default
// selected tile.
if (
isSingleSelect &&
content.tiles?.autoTrigger &&
autoTriggerAllowed(selectedTile?.action)
) {
handleAction({ currentTarget: { value: selectedTile.id } });
}
}
}, []); // eslint-disable-line react-hooks/exhaustive-deps

View File

@ -1537,12 +1537,42 @@ const SingleSelect = ({
}) => {
const category = content.tiles?.category?.type || content.tiles?.type;
const isSingleSelect = category === "single-select";
const autoTriggerAllowed = itemAction => {
// Currently only enabled for sidebar experiment prefs
const allowedActions = ["SET_PREF"];
const allowedPrefs = ["sidebar.revamp", "sidebar.verticalTabs"];
const checkAction = action => {
if (!allowedActions.includes(action.type)) {
return false;
}
if (action.type === "SET_PREF" && !allowedPrefs.includes(action.data?.pref.name)) {
return false;
}
return true;
};
if (itemAction.type === "MULTI_ACTION") {
// Only allow autoTrigger if all actions are allowed
return !itemAction.data.actions.some(action => !checkAction(action));
}
return checkAction(itemAction);
};
// When screen renders for first time or user navigates back, update state to
// check default option.
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
if (isSingleSelect && !activeSingleSelect) {
let newActiveSingleSelect = content.tiles?.selected || content.tiles.data[0].id;
let newActiveSingleSelect = content.tiles?.selected || content.tiles?.data[0].id;
setActiveSingleSelect(newActiveSingleSelect);
let selectedTile = content.tiles?.data.find(opt => opt.id === newActiveSingleSelect);
// If applicable, automatically trigger the action for the default
// selected tile.
if (isSingleSelect && content.tiles?.autoTrigger && autoTriggerAllowed(selectedTile?.action)) {
handleAction({
currentTarget: {
value: selectedTile.id
}
});
}
}
}, []); // eslint-disable-line react-hooks/exhaustive-deps

View File

@ -493,7 +493,7 @@ describe("MultiStageAboutWelcome module", () => {
type: "SET_PREF",
data: {
pref: {
name: "test1.pref",
name: "sidebar.revamp",
value: true,
},
},
@ -514,7 +514,7 @@ describe("MultiStageAboutWelcome module", () => {
type: "SET_PREF",
data: {
pref: {
name: "test2.pref",
name: "sidebar.revamp",
value: false,
},
},
@ -586,6 +586,77 @@ describe("MultiStageAboutWelcome module", () => {
assert.ok(flair.exists());
assert.ok(flair.text() === "New!");
});
it("should automatically trigger the selected tile's action for an approved action", () => {
SINGLE_SELECT_SCREEN_PROPS.content.tiles.autoTrigger = true;
mount(<WelcomeScreen {...SINGLE_SELECT_SCREEN_PROPS} />);
assert.calledOnce(AboutWelcomeUtils.handleUserAction);
});
it("should not trigger the selected tile's action for an unapproved action", () => {
SINGLE_SELECT_SCREEN_PROPS.content.tiles.autoTrigger = true;
SINGLE_SELECT_SCREEN_PROPS.content.tiles.data[0].action = "OPEN_URL";
mount(<WelcomeScreen {...SINGLE_SELECT_SCREEN_PROPS} />);
assert.notCalled(AboutWelcomeUtils.handleUserAction);
});
it("should not trigger the selected tile's action for an unapproved pref with SET_PREF action", () => {
SINGLE_SELECT_SCREEN_PROPS.content.tiles.autoTrigger = true;
SINGLE_SELECT_SCREEN_PROPS.content.tiles.data[0].action.data.pref =
"unapproved.pref";
mount(<WelcomeScreen {...SINGLE_SELECT_SCREEN_PROPS} />);
assert.notCalled(AboutWelcomeUtils.handleUserAction);
});
it("should trigger all of the selected tile's actions if MULTI_ACTION is used with SET_PREF and allowed prefs", () => {
SINGLE_SELECT_SCREEN_PROPS.content.tiles.autoTrigger = true;
SINGLE_SELECT_SCREEN_PROPS.content.tiles.data[0].action = {
type: "MULTI_ACTION",
data: {
actions: [
{
type: "SET_PREF",
data: {
pref: {
name: "sidebar.revamp",
},
},
},
{
type: "SET_PREF",
data: {
pref: {
name: "sidebar.verticalTabs",
},
},
},
],
},
};
mount(<WelcomeScreen {...SINGLE_SELECT_SCREEN_PROPS} />);
assert.calledOnce(AboutWelcomeUtils.handleUserAction);
});
it("should not trigger any of the selected tile's action if MULTI_ACTION is used with one unallowed pref", () => {
SINGLE_SELECT_SCREEN_PROPS.content.tiles.autoTrigger = true;
SINGLE_SELECT_SCREEN_PROPS.content.tiles.data[0].action = {
type: "MULTI_ACTION",
data: {
actions: [
{
type: "OPEN_URL",
},
{
type: "SET_PREF",
data: {
pref: "sidebar.verticalTabs",
},
},
],
},
};
mount(<WelcomeScreen {...SINGLE_SELECT_SCREEN_PROPS} />);
assert.notCalled(AboutWelcomeUtils.handleUserAction);
});
});
describe("#handleAction", () => {

View File

@ -219,6 +219,7 @@ export const SpecialMessageActions = {
"messaging-system.askForFeedback",
"browser.toolbars.bookmarks.visibility",
"sidebar.verticalTabs",
"sidebar.revamp",
];
if (