Skip to content

Commit

Permalink
Bug fixes related to conosle settings in primary organizations for ma…
Browse files Browse the repository at this point in the history
…naged deployments
  • Loading branch information
pavinduLakshan committed Oct 11, 2024
1 parent f176579 commit 2b95cff
Show file tree
Hide file tree
Showing 8 changed files with 1,523 additions and 64 deletions.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
import { useOrganizationConfigV2 } from "@wso2is/admin.administrators.v1/api/useOrganizationConfigV2";
import { AdministratorConstants } from "@wso2is/admin.administrators.v1/constants/users";
import { UseOrganizationConfigType } from "@wso2is/admin.administrators.v1/models/organization";
import { AddAdministratorWizard } from "@wso2is/admin.administrators.v1/wizard/add-administrator-wizard";
import {
AdvancedSearchWithBasicFilters,
AppConstants,
Expand Down Expand Up @@ -64,6 +63,7 @@ import AdministratorsTable from "./administrators-table";
import useAdministrators from "../../../hooks/use-administrators";
import useBulkAssignAdministratorRoles from "../../../hooks/use-bulk-assign-user-roles";
import AddExistingUserWizard from "../add-existing-user-wizard/add-existing-user-wizard";
import { AddAdministratorWizard } from "../add-external-admin-wizard/add-external-admin-wizard";
import InviteNewAdministratorWizard from "../invite-new-administrator-wizard/invite-new-administrator-wizard";

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ const ConsoleAdministrators: FunctionComponent<ConsoleAdministratorsInterface> =
value={ activeAdministratorGroup }
onChange={ (_: ChangeEvent<HTMLInputElement>, value: string) => setActiveAdministratorGroup(value) }
>
<FormControlLabel value="administrators" control={ <Radio /> } label="Administrators" />
<FormControlLabel value="privilegedUsers" control={ <Radio /> } label="Privileged Users" />
<FormControlLabel value="administrators" control={ <Radio /> } label="Asgardeo" />
<FormControlLabel value="privilegedUsers" control={ <Radio /> } label={ organizationName + " organization" } />
</RadioGroup>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@
.submit-button {
margin-top: 2rem;
}

.multi-option-radio-group {
gap: 40px;
margin: 20px 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,14 @@ import { RoleAudienceTypes } from "@wso2is/admin.roles.v2/constants/role-constan
import { RoleConstants } from "@wso2is/core/constants";
import { FeatureAccessConfigInterface, IdentifiableComponentInterface, RolesInterface } from "@wso2is/core/models";
import { ResourceTab, ResourceTabPaneInterface } from "@wso2is/react-components";
import React, { FunctionComponent, ReactElement, useEffect, useState } from "react";
import React, { ChangeEvent, FunctionComponent, ReactElement, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useSelector } from "react-redux";
import ConsoleRolePermissions from "./console-role-permissions";
import "./console-roles-edit.scss";
import RadioGroup from "@oxygen-ui/react/RadioGroup";
import { FormControlLabel } from "@mui/material";
import Radio from "@oxygen-ui/react/Radio";

/**
* Captures props needed for edit role component
Expand Down Expand Up @@ -64,40 +67,41 @@ interface ConsoleRolesEditPropsInterface extends IdentifiableComponentInterface
* @param props - contains role details to be edited.
*/
const ConsoleRolesEdit: FunctionComponent<ConsoleRolesEditPropsInterface> = (
props: ConsoleRolesEditPropsInterface): ReactElement => {

const {
isLoading,
roleObject,
onRoleUpdate,
defaultActiveIndex
} = props;
props: ConsoleRolesEditPropsInterface
): ReactElement => {
const { isLoading, roleObject, onRoleUpdate, defaultActiveIndex } = props;

const { t } = useTranslation();
const { isFirstLevelOrganization, isSubOrganization, organizationType } = useGetCurrentOrganizationType();

const userRolesFeatureConfig: FeatureAccessConfigInterface = useSelector(
(state: AppState) => state?.config?.ui?.features?.userRoles);
(state: AppState) => state?.config?.ui?.features?.userRoles
);
const hasRolesUpdatePermissions: boolean = useRequiredScopes(userRolesFeatureConfig?.scopes?.update);

const administratorRoleDisplayName: string = useSelector(
(state: AppState) => state?.config?.ui?.administratorRoleDisplayName);
(state: AppState) => state?.config?.ui?.administratorRoleDisplayName
);

const consoleSettingsFeatureConfig: FeatureAccessConfigInterface =
useSelector((state: AppState) => state?.config?.ui?.features?.consoleSettings);
const consoleSettingsFeatureConfig: FeatureAccessConfigInterface = useSelector(
(state: AppState) => state?.config?.ui?.features?.consoleSettings
);
const isConsoleRolesEditable: boolean = !consoleSettingsFeatureConfig?.disabledFeatures?.includes(
"consoleSettings.editableConsoleRoles"
);
const isPrivilegedUsersInConsoleSettingsEnabled: boolean = !consoleSettingsFeatureConfig?.disabledFeatures?.includes(
"consoleSettings.privilegedUsers"
);

const [ isAdminRole, setIsAdminRole ] = useState<boolean>(false);
const [ isEnterpriseLoginEnabled, setIsEnterpriseLoginEnabled ] = useState<boolean>(false);
const [ activeUserStore, setActiveUserStore ] = useState<string>("PRIMARY");

const organizationName: string = store.getState().auth.tenantDomain;

const useOrgConfig: UseOrganizationConfigType = useOrganizationConfigV2;

const saasFeatureStatus : FeatureStatus = useCheckFeatureStatus(
FeatureGateConstants.SAAS_FEATURES_IDENTIFIER);
const saasFeatureStatus: FeatureStatus = useCheckFeatureStatus(FeatureGateConstants.SAAS_FEATURES_IDENTIFIER);

const {
data: OrganizationConfig,
Expand All @@ -121,10 +125,12 @@ const ConsoleRolesEdit: FunctionComponent<ConsoleRolesEditPropsInterface> = (
* Set the if the role is `Internal/admin`.
*/
useEffect(() => {
if(roleObject) {
setIsAdminRole(roleObject.displayName === RoleConstants.ADMIN_ROLE ||
roleObject?.displayName === RoleConstants.ADMIN_GROUP ||
roleObject?.displayName === administratorRoleDisplayName);
if (roleObject) {
setIsAdminRole(
roleObject.displayName === RoleConstants.ADMIN_ROLE ||
roleObject?.displayName === RoleConstants.ADMIN_GROUP ||
roleObject?.displayName === administratorRoleDisplayName
);
}
}, [ roleObject ]);

Expand All @@ -135,8 +141,9 @@ const ConsoleRolesEdit: FunctionComponent<ConsoleRolesEditPropsInterface> = (
render: () => (
<ResourceTab.Pane controlledSegmentation attached={ false }>
<BasicRoleDetails
isReadOnly={ isSubOrg || isAdminRole || !isConsoleRolesEditable
|| !hasRolesUpdatePermissions }
isReadOnly={
isSubOrg || isAdminRole || !isConsoleRolesEditable || !hasRolesUpdatePermissions
}
role={ roleObject }
onRoleUpdate={ onRoleUpdate }
tabIndex={ 0 }
Expand All @@ -151,10 +158,7 @@ const ConsoleRolesEdit: FunctionComponent<ConsoleRolesEditPropsInterface> = (
<ResourceTab.Pane controlledSegmentation attached={ false }>
<ConsoleRolePermissions
isReadOnly={
isSubOrg
|| isAdminRole
|| !isConsoleRolesEditable
|| !hasRolesUpdatePermissions
isSubOrg || isAdminRole || !isConsoleRolesEditable || !hasRolesUpdatePermissions
}
role={ roleObject }
onRoleUpdate={ onRoleUpdate }
Expand All @@ -164,7 +168,7 @@ const ConsoleRolesEdit: FunctionComponent<ConsoleRolesEditPropsInterface> = (
</ResourceTab.Pane>
)
},
( (isFirstLevelOrganization() && isEnterpriseLoginEnabled) || isSubOrganization() ) && {
((isFirstLevelOrganization() && isEnterpriseLoginEnabled) || isSubOrganization()) && {
menuItem: t("roles:edit.menuItems.groups"),
render: () => (
<ResourceTab.Pane controlledSegmentation attached={ false }>
Expand All @@ -181,10 +185,34 @@ const ConsoleRolesEdit: FunctionComponent<ConsoleRolesEditPropsInterface> = (
menuItem: t("roles:edit.menuItems.users"),
render: () => (
<ResourceTab.Pane controlledSegmentation attached={ false }>
{ isFirstLevelOrganization() &&
isEnterpriseLoginEnabled &&
isPrivilegedUsersInConsoleSettingsEnabled && (
<RadioGroup
row
aria-labelledby="console-administrators-radio-group"
className="multi-option-radio-group"
defaultValue="PRIMARY"
name="console-administrators-radio-group-2"
value={ activeUserStore }
onChange={ (_: ChangeEvent<HTMLInputElement>, value: string) => {
setActiveUserStore(value);
} }
>
<FormControlLabel value="PRIMARY" control={ <Radio /> } label="Asgardeo" />
<FormControlLabel
value="DEFAULT"
control={ <Radio /> }
label={ organizationName + " organization" }
/>
</RadioGroup>
) }

<RoleUsersList
isReadOnly={ !hasRolesUpdatePermissions }
role={ roleObject }
onRoleUpdate={ onRoleUpdate }
activeUserStore={ activeUserStore }
tabIndex={ 3 }
/>
</ResourceTab.Pane>
Expand All @@ -211,13 +239,7 @@ const ConsoleRolesEdit: FunctionComponent<ConsoleRolesEditPropsInterface> = (
return panes;
};

return (
<ResourceTab
isLoading={ isLoading }
defaultActiveIndex={ defaultActiveIndex }
panes={ resolveResourcePanes() }
/>
);
return <ResourceTab isLoading={ isLoading } defaultActiveIndex={ defaultActiveIndex } panes={ resolveResourcePanes() } />;
};

ConsoleRolesEdit.defaultProps = {
Expand Down
74 changes: 46 additions & 28 deletions features/admin.roles.v2/components/edit-role/edit-role-users.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export const RoleUsersList: FunctionComponent<RoleUsersPropsInterface> = (
onRoleUpdate,
isReadOnly,
tabIndex,
activeUserStore,
[ "data-componentid" ]: componentId
} = props;

Expand All @@ -97,7 +98,7 @@ export const RoleUsersList: FunctionComponent<RoleUsersPropsInterface> = (
const [ activeOption, setActiveOption ] = useState<GroupsInterface|UserBasicInterface>(undefined);
const [ availableUserStores, setAvailableUserStores ] = useState<UserstoreDisplayItem[]>([]);
const [ selectedUserStoreDomainName, setSelectedUserStoreDomainName ] = useState<string>(
disabledUserstores.includes(RemoteUserStoreConstants.PRIMARY_USER_STORE_NAME) ? "DEFAULT" : "Primary"
activeUserStore ?? disabledUserstores.includes(RemoteUserStoreConstants.PRIMARY_USER_STORE_NAME) ? "DEFAULT" : "PRIMARY"
);
const [ isPlaceholderVisible, setIsPlaceholderVisible ] = useState<boolean>(true);
const [ selectedUsersFromUserStore, setSelectedUsersFromUserStore ] = useState<UserBasicInterface[]>([]);
Expand Down Expand Up @@ -125,10 +126,14 @@ export const RoleUsersList: FunctionComponent<RoleUsersPropsInterface> = (
const isUserBelongToSelectedUserStore = (user: UserBasicInterface, userStoreName: string) => {
const userNameChunks: string[] = user.userName.split("/");

return (userNameChunks.length === 1 && userStoreName === "Primary")
return (userNameChunks.length === 1 && userStoreName === "PRIMARY")
|| (userNameChunks.length === 2 && userNameChunks[0] === userStoreName.toUpperCase());
};

useEffect(() => {
setSelectedUserStoreDomainName(activeUserStore);
}, [ activeUserStore ]);

useEffect(() => {
if (!role?.users?.length) {
return;
Expand Down Expand Up @@ -189,6 +194,7 @@ export const RoleUsersList: FunctionComponent<RoleUsersPropsInterface> = (
if (!isReadOnly && userResponse?.totalResults > 0 && Array.isArray(userResponse?.Resources)) {
const usersAvailableToSelect: UserBasicInterface[] = userResponse?.Resources?.filter(
(user: UserBasicInterface) => {
console.log(selectedUserStoreDomainName, user);
const isUserInSelectedUserStore: boolean = isUserBelongToSelectedUserStore(
user, selectedUserStoreDomainName
);
Expand Down Expand Up @@ -295,6 +301,8 @@ export const RoleUsersList: FunctionComponent<RoleUsersPropsInterface> = (
path: "/v2/Roles/" + role.id
};

debugger;

const selectedUsers: UserBasicInterface[] = Object.keys(selectedAllUsers).map((userStoreName: string) => {
return selectedAllUsers[userStoreName];
}).flat();
Expand All @@ -303,8 +311,16 @@ export const RoleUsersList: FunctionComponent<RoleUsersPropsInterface> = (
const removedUsers: RolesMemberInterface[] = role?.users?.filter((user: RolesMemberInterface) => {
return selectedUsers?.find(
(selectedUser: UserBasicInterface) => selectedUser.id === user.value) === undefined;
}).filter(user => {
console.log(user);
const userNameChunks: string[] = user.display.split("/");

return (userNameChunks.length === 1 && selectedUserStoreDomainName === "PRIMARY")
|| (userNameChunks.length === 2 && userNameChunks[0] === selectedUserStoreDomainName.toUpperCase());
}) ?? [];



const removeOperations: PatchUserRemoveOpInterface[] = removedUsers?.map((user: RolesMemberInterface) => {
return ({
"op": "remove",
Expand Down Expand Up @@ -390,33 +406,35 @@ export const RoleUsersList: FunctionComponent<RoleUsersPropsInterface> = (
{
users && availableUserStores && !isReadOnly && (
<Grid container spacing={ 1 }>
<Grid xs={ 12 } sm={ 4 } md={ 2 } alignItems="center">
<FormControl fullWidth size="medium">
<Select
value={ selectedUserStoreDomainName }
onChange={
(e: SelectChangeEvent<unknown>) => {
updateSelectedAllUsers();
setSelectedUsersFromUserStore([]);
setSelectedUserStoreDomainName(e.target.value as string);
{ !activeUserStore && (
<Grid xs={ 12 } sm={ 4 } md={ 2 } alignItems="center">
<FormControl fullWidth size="medium">
<Select
value={ selectedUserStoreDomainName }
onChange={
(e: SelectChangeEvent<unknown>) => {
updateSelectedAllUsers();
setSelectedUsersFromUserStore([]);
setSelectedUserStoreDomainName(e.target.value as string);
}
}
}
data-componentid={ `${ componentId }-user-store-domain-dropdown` }
>
{ isUserStoresLoading
? <p>{ t("common:loading") }</p>
: availableUserStores?.map((userstore: UserStoreListItem) =>
(<MenuItem
key={ userstore.name }
value={ userstore.name }
>
{ userstore.name }
</MenuItem>)
)
}
</Select>
</FormControl>
</Grid>
data-componentid={ `${ componentId }-user-store-domain-dropdown` }
>
{ isUserStoresLoading
? <p>{ t("common:loading") }</p>
: availableUserStores?.map((userstore: UserStoreListItem) =>
(<MenuItem
key={ userstore.name }
value={ userstore.name }
>
{ userstore.name }
</MenuItem>)
)
}
</Select>
</FormControl>
</Grid>
) }
<Grid xs={ 12 } sm={ 4 } md={ 8 }>
<Autocomplete
multiple
Expand Down
7 changes: 7 additions & 0 deletions features/admin.roles.v2/models/roles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,13 @@ export interface RoleEditSectionsInterface {
* Tab index
*/
tabIndex: number;
/**
* active user store
*
* Note: used to conditionally determine whether the userstore is handled
* outside the component.
*/
activeUserStore?: string
}

/**
Expand Down

0 comments on commit 2b95cff

Please sign in to comment.