Sub-Pages — Category Toggle Sections: Advanced¶
Part of: Category Toggle Sections See also: Basics | Membership Tabs
Critical: Clearing Members When Switching to “Anyone”¶
The most important implementation detail: When the user switches from “Specified members” to “Anyone” (setting *category to "all"), all existing members must be removed before saving. The API does NOT automatically clear members.
Implementation in onSave¶
// Helper to remove all users and groups, then save
const onDeleteAllUsersAndSave = (
usersToDelete: string[],
groupsToDelete: string[]
) => {
if (usersToDelete.length === 0 && groupsToDelete.length === 0) {
onSaveRule();
return;
}
// Remove users first
if (usersToDelete.length > 0) {
const payload: AddRemoveUserToEntityPayload = {
toId: props.entity.cn as string,
type: "user",
listOfMembers: usersToDelete,
};
removeUserMutation(payload).then((response) => {
if ("data" in response) {
// Then remove groups
if (groupsToDelete.length > 0) {
const groupPayload = { ...payload, type: "group", listOfMembers: groupsToDelete };
removeUserMutation(groupPayload).then(() => {
props.onRefresh();
onSaveRule();
});
} else {
props.onRefresh();
onSaveRule();
}
}
});
} else if (groupsToDelete.length > 0) {
const payload = { toId: props.entity.cn as string, type: "group", listOfMembers: groupsToDelete };
removeUserMutation(payload).then(() => {
props.onRefresh();
onSaveRule();
});
}
};
// Main save handler
const onSave = () => {
setSaving(true);
const modifiedValues = props.modifiedValues();
const keysInObject = Object.keys(modifiedValues);
// Check if category is being changed to "all" (Anyone)
if (
keysInObject.includes("usercategory") &&
modifiedValues.usercategory === "all"
) {
const usersToRemove = props.entity.memberuser_user || [];
const groupsToRemove = props.entity.memberuser_group || [];
onDeleteAllUsersAndSave(usersToRemove, groupsToRemove);
} else if (
keysInObject.includes("hostcategory") &&
modifiedValues.hostcategory === "all"
) {
const hostsToRemove = props.entity.memberhost_host || [];
const hostGroupsToRemove = props.entity.memberhost_hostgroup || [];
onDeleteAllHostsAndSave(hostsToRemove, hostGroupsToRemove);
} else {
// Regular save without category changes
onSaveRule();
}
};
API Method Naming Conventions¶
Different IPA entities use different API method naming conventions:
SELinux User Maps¶
Users/Groups:
selinuxusermap_add_user,selinuxusermap_remove_userParameter
userfor users,groupfor user groups
Hosts/Host Groups:
selinuxusermap_add_host,selinuxusermap_remove_hostParameter
hostfor hosts,hostgroupfor host groups
Sudo Rules¶
Users/Groups:
sudorule_add_user,sudorule_remove_userHosts/Host Groups:
sudorule_add_host,sudorule_remove_hostCommands:
sudorule_add_allow_command,sudorule_add_deny_command, etc.
HBAC Rules¶
Users/Groups:
hbacrule_add_user,hbacrule_remove_userHosts/Host Groups:
hbacrule_add_host,hbacrule_remove_host
Checklist for Category Toggle Sections¶
[ ] Membership fields typed as
string[]inglobalDataTypes.ts[ ] Membership fields NOT in
simpleValuesin entity utils[ ] Membership fields initialized as
[]increateEmpty<Entity>()[ ] Membership fields filtered out in save mutation (NOT sent to
*_mod)[ ] Separate RPC mutations for add/remove operations
[ ]
onSavehandles category change to “all” by removing members first[ ]
CategoryToggleSectioncomponent configured with correct props[ ]
useCategoryMembershipOperationshook configured with correct extractors
Reference Files¶
Generic Components:
src/components/CategoryToggleSection/CategoryToggleSection.tsxsrc/hooks/useCategoryMembershipOperations.ts
Example Implementations:
src/pages/SELinuxUserMaps/SELinuxUserMapsSettings.tsxsrc/pages/SudoRules/SudoRulesSettings.tsxsrc/components/SudoRuleSections/SudoRulesWho.tsxsrc/components/SudoRuleSections/AccessThisHost.tsx