diff --git a/features/admin.roles.v2/components/role-list.tsx b/features/admin.roles.v2/components/role-list.tsx index 5b16a4c399a..237d0431923 100644 --- a/features/admin.roles.v2/components/role-list.tsx +++ b/features/admin.roles.v2/components/role-list.tsx @@ -29,6 +29,7 @@ import { IdentifiableComponentInterface, LoadableComponentInterface, RoleListInterface, + RolePropertyInterface, RolesInterface } from "@wso2is/core/models"; import { @@ -168,7 +169,7 @@ export const RoleList: React.FunctionComponent = (props: RoleList return ( = (props: RoleList ) } image={ getEmptyPlaceholderIllustrations().newList } imageSize="tiny" - title={ !isSubOrg && t("roles:list.emptyPlaceholders.emptyRoleList.title", + title={ t("roles:list.emptyPlaceholders.emptyRoleList.title", { type: "role" }) } - subtitle={ isSubOrg - ? [ - t("roles:list.emptyPlaceholders.emptyRoleList.subtitles.0", - { type: "roles" }) - ] - : [ - t("roles:list.emptyPlaceholders.emptyRoleList.subtitles.0", - { type: "roles" }), - t("roles:list.emptyPlaceholders.emptyRoleList.subtitles.1", - { type: "role" }), - t("roles:list.emptyPlaceholders.emptyRoleList.subtitles.2", - { type: "role" }) - ] + subtitle={ [ + t("roles:list.emptyPlaceholders.emptyRoleList.subtitles.0", + { type: "roles" }), + t("roles:list.emptyPlaceholders.emptyRoleList.subtitles.1", + { type: "role" }), + t("roles:list.emptyPlaceholders.emptyRoleList.subtitles.2", + { type: "role" }) + ] } /> ); @@ -236,6 +232,19 @@ export const RoleList: React.FunctionComponent = (props: RoleList /> { role?.displayName } + { + (() => { + const isSharedRole: boolean = role?.properties?.some( + (property: RolePropertyInterface) => + property?.name === "isSharedRole" && property?.value === "true"); + + return isSharedRole && ( + + ); + })() + } ), @@ -296,8 +305,10 @@ export const RoleList: React.FunctionComponent = (props: RoleList }, { hidden: (role: RolesInterface) => { - return isSubOrg - || role?.meta?.systemRole + const isSharedRole: boolean = role?.properties?.some((property: RolePropertyInterface) => + property?.name === "isSharedRole" && property?.value === "true"); + + return role?.meta?.systemRole || ( role?.displayName === CommonRoleConstants.ADMIN_ROLE || role?.displayName === CommonRoleConstants.ADMIN_GROUP || @@ -306,7 +317,8 @@ export const RoleList: React.FunctionComponent = (props: RoleList || !isFeatureEnabled(userRolesFeatureConfig, RoleConstants.FEATURE_DICTIONARY.get("ROLE_DELETE")) || !hasRequiredScopes(userRolesFeatureConfig, - userRolesFeatureConfig?.scopes?.delete, allowedScopes); + userRolesFeatureConfig?.scopes?.delete, allowedScopes) + || isSharedRole; }, icon: (): SemanticICONS => "trash alternate", onClick: (e: SyntheticEvent, role: RolesInterface): void => { diff --git a/features/admin.roles.v2/components/wizard-updated/role-basics.tsx b/features/admin.roles.v2/components/wizard-updated/role-basics.tsx index e4de4087cc3..21c7c666131 100644 --- a/features/admin.roles.v2/components/wizard-updated/role-basics.tsx +++ b/features/admin.roles.v2/components/wizard-updated/role-basics.tsx @@ -23,8 +23,9 @@ import Alert from "@oxygen-ui/react/Alert"; import { useApplicationList } from "@wso2is/admin.applications.v1/api/application"; import { ApplicationManagementConstants } from "@wso2is/admin.applications.v1/constants/application-management"; import { ApplicationListItemInterface } from "@wso2is/admin.applications.v1/models/application"; -import { history, store } from "@wso2is/admin.core.v1"; +import { OrganizationType, history, store } from "@wso2is/admin.core.v1"; import { AppConstants } from "@wso2is/admin.core.v1/constants"; +import { useGetCurrentOrganizationType } from "@wso2is/admin.organizations.v1/hooks/use-get-organization-type"; import { IdentifiableComponentInterface } from "@wso2is/core/models"; import { Field, Form } from "@wso2is/form"; import { Link } from "@wso2is/react-components"; @@ -111,6 +112,9 @@ export const RoleBasics: FunctionComponent = (props: RoleBasicPr isValidating: isRolesListValidating } = useGetRolesList(undefined, undefined, roleNameSearchQuery, "users,groups,permissions,associatedApplications"); + const { organizationType } = useGetCurrentOrganizationType(); + const isSubOrg: boolean = organizationType === OrganizationType.SUBORGANIZATION; + useEffect(() => { if (applicationListFetchRequestError) { setIsDisplayNoAppScopeApplicatioError(true); @@ -367,12 +371,20 @@ export const RoleBasics: FunctionComponent = (props: RoleBasicPr ? ( { - roleAudience === RoleAudienceTypes.ORGANIZATION - ? t("roles:addRoleWizard.forms.roleBasicDetails.notes" + - ".orgNote") - : t("roles:addRoleWizard.forms.roleBasicDetails.notes" + - ".appNote") + !isSubOrg ? ( + roleAudience === RoleAudienceTypes.ORGANIZATION + ? t("roles:addRoleWizard.forms.roleBasicDetails.notes" + + ".orgNote") + : t("roles:addRoleWizard.forms.roleBasicDetails.notes" + + ".appNote") // TODO: need to add a learn more for this. + ) : ( + roleAudience === RoleAudienceTypes.ORGANIZATION + ? t("roles:addRoleWizard.forms.roleBasicDetails.notes.subOrganization" + + ".orgNote") + : t("roles:addRoleWizard.forms.roleBasicDetails.notes.subOrganization" + + ".appNote") + ) } ) : ( diff --git a/features/admin.roles.v2/pages/role.tsx b/features/admin.roles.v2/pages/role.tsx index d9225bf731f..aadf32fffe9 100644 --- a/features/admin.roles.v2/pages/role.tsx +++ b/features/admin.roles.v2/pages/role.tsx @@ -221,27 +221,28 @@ const RolesPage: FunctionComponent = ( return ( 0) - ? ( - - handleCreateRole() } - > - - { t("roles:list.buttons.addButton", { type: "Role" }) } - - - ) : null + ( + !isRolesListLoading && (rolesList?.totalResults > 0) + ? ( + + handleCreateRole() } + > + + { t("roles:list.buttons.addButton", { type: "Role" }) } + + + ): null + ) } title={ t("pages:roles.title") } pageTitle={ t("pages:roles.title") } - description={ isSubOrg - ? t("pages:roles.alternateSubTitle") - : ( + description={ + ( <> { t("pages:roles.subTitle") } create an application that supports application audience roles to proceed." + appNote: "When the role audience is application, you can associate the role with an application " + + "which allows application audience roles.", + cannotCreateRole: "You cannot create a role with role audience as application because there are " + + "currently no applications that support application audience roles. " + + "Please <1>create an application that supports application audience roles to proceed.", + orgNote: "When the role audience is organization, you can associate the role with an " + + "application which allows organization audience roles.", + subOrganization: { + appNote: "When the role audience is application, you can associate the role with an " + + "application which allows application audience roles. " + + "You cannot associate the role with a shared application.", + orgNote: "When the role audience is organization, you can associate the role with an " + + "application which allows organization audience roles. You cannot associate the " + + "role with a shared application." + } }, assignedApplication: { hint: "Assign an application for the role. Note that assigned application for this role cannot be edited after the role is created.", @@ -364,6 +376,9 @@ export const roles: rolesNS = { }, name: "Role" }, + labels: { + shared: "Shared role" + }, confirmations: { deleteItem: { assertionHint: "Please confirm your action.",