diff --git a/.changeset/long-rules-joke.md b/.changeset/long-rules-joke.md new file mode 100644 index 00000000000..5198f1c3fcf --- /dev/null +++ b/.changeset/long-rules-joke.md @@ -0,0 +1,7 @@ +--- +"@wso2is/admin.users.v1": patch +"@wso2is/myaccount": patch +"@wso2is/console": patch +--- + +Improve multi email and mobile UI diff --git a/apps/console/src/public/deployment.config.json b/apps/console/src/public/deployment.config.json index 12e8caa41cd..a12c70e2088 100644 --- a/apps/console/src/public/deployment.config.json +++ b/apps/console/src/public/deployment.config.json @@ -1282,7 +1282,7 @@ "isHeaderAvatarLabelAllowed": false, "isLeftNavigationCategorized": true, "isMarketingConsentBannerEnabled": false, - "isMultipleEmailsAndMobileNumbersEnabled": false, + "isMultipleEmailsAndMobileNumbersEnabled": true, "isPasswordInputValidationEnabled": true, "isRequestPathAuthenticationEnabled": false, "isSAASDeployment": false, diff --git a/apps/myaccount/src/components/profile/profile.scss b/apps/myaccount/src/components/profile/profile.scss index 8d4e000c6c0..ef998670c17 100644 --- a/apps/myaccount/src/components/profile/profile.scss +++ b/apps/myaccount/src/components/profile/profile.scss @@ -21,22 +21,18 @@ width: 100%; } - .accordion-details { - border-radius: 8px; - padding: 2px; - - .multi-value-table { - .multi-value-table-data-row { - &:last-child td, &:last-child th { - border: none; - } + .multi-value-table { + .multi-value-table-data-row { + &:last-child td, &:last-child th { + border: none; } .table-c1 { display: flex; flex-wrap: nowrap; align-items: center; - + padding: 0.2em 0; + .c1-value{ margin-bottom: 0; flex-shrink: 0; @@ -59,6 +55,11 @@ align-items: center; justify-content: flex-end; gap: 4px; + padding: 0.2em 0; + + .text-btn { + padding: 0px; + } } } } diff --git a/apps/myaccount/src/components/profile/profile.tsx b/apps/myaccount/src/components/profile/profile.tsx index 8fb881854bb..62f93ff4a3c 100644 --- a/apps/myaccount/src/components/profile/profile.tsx +++ b/apps/myaccount/src/components/profile/profile.tsx @@ -21,8 +21,8 @@ import TableBody from "@mui/material/TableBody"; import TableCell from "@mui/material/TableCell"; import TableContainer from "@mui/material/TableContainer"; import TableRow from "@mui/material/TableRow"; -import Accordion from "@oxygen-ui/react/Accordion"; -import AccordionDetails from "@oxygen-ui/react/AccordionDetails"; +import Button from "@oxygen-ui/react/Button"; +import Chip from "@oxygen-ui/react/Chip"; import IconButton from "@oxygen-ui/react/IconButton"; import MenuItem from "@oxygen-ui/react/MenuItem"; import Paper from "@oxygen-ui/react/Paper"; @@ -30,6 +30,7 @@ import Select from "@oxygen-ui/react/Select"; import Typography from "@oxygen-ui/react/Typography"; import { ProfileConstants } from "@wso2is/core/constants"; import { IdentityAppsApiException } from "@wso2is/core/exceptions"; + /** * `useRequiredScopes` is not supported for myaccount. */ @@ -168,10 +169,6 @@ export const Profile: FunctionComponent = (props: ProfileProps): R const [ isMobileVerificationEnabled, setIsMobileVerificationEnabled ] = useState(false); const [ isEmailVerificationEnabled, setIsEmailVerificationEnabled ] = useState(false); - const [ expandMultiAttributeAccordion, setExpandMultiAttributeAccordion ] = useState>({ - [EMAIL_ADDRESSES_ATTRIBUTE]: false, - [MOBILE_NUMBERS_ATTRIBUTE]: false - }); const [ isMultipleEmailAndMobileNumberEnabled, setIsMultipleEmailAndMobileNumberEnabled ] = useState(false); @@ -1465,12 +1462,10 @@ export const Profile: FunctionComponent = (props: ProfileProps): R let verifiedAttributeValueList: string[] = []; let primaryAttributeValue: string = ""; let verificationEnabled: boolean = false; - let verifyPopupHeader: string = ""; let pendingEmailAddress: string = ""; let maxAllowedLimit: number = 0; if (schema.name === EMAIL_ADDRESSES_ATTRIBUTE) { - verifyPopupHeader = t("myAccount:components.profile.actions.verifyEmail"); attributeValueList = profileInfo?.get(EMAIL_ADDRESSES_ATTRIBUTE)?.split(",") ?? []; verifiedAttributeValueList = profileInfo?.get(VERIFIED_EMAIL_ADDRESSES_ATTRIBUTE)?.split(",") ?? []; pendingEmailAddress = profileDetails?.profileInfo?.pendingEmails?.length > 0 @@ -1485,7 +1480,6 @@ export const Profile: FunctionComponent = (props: ProfileProps): R maxAllowedLimit = ProfileConstants.MAX_EMAIL_ADDRESSES_ALLOWED; } else if (schema.name === MOBILE_NUMBERS_ATTRIBUTE) { - verifyPopupHeader = t("myAccount:components.profile.actions.verifyMobile"); attributeValueList = profileInfo?.get(MOBILE_NUMBERS_ATTRIBUTE)?.split(",") ?? []; verifiedAttributeValueList = profileInfo?.get(VERIFIED_MOBILE_NUMBERS_ATTRIBUTE)?.split(",") ?? []; primaryAttributeValue = profileInfo?.get(ProfileConstants.SCIM2_SCHEMA_DICTIONARY.get("MOBILE")); @@ -1515,7 +1509,7 @@ export const Profile: FunctionComponent = (props: ProfileProps): R (verifiedAttributeValueList.includes(value) || value === primaryAttributeValue); }; - const showPrimaryPopup = (value: string): boolean => { + const showPrimaryChip = (value: string): boolean => { return value === primaryAttributeValue; }; @@ -1564,176 +1558,155 @@ export const Profile: FunctionComponent = (props: ProfileProps): R } /> + ) + } + + + +
+ + + +
+
+ + ) + ) } + + + = (props: ProfileProps): R (verifiedAttributeValueList.includes(value) || value === primaryAttributeValue); }; - const showPrimaryPopup = (value: string): boolean => { + const showPrimaryChip = (value: string): boolean => { return value === primaryAttributeValue; }; - return ( - <> - { - attributeValueList.length < 1 - ? generatePlaceholderLink(schema, fieldName) - : ( - + { generatePendingEmailPopup() } + ) - } - - ); + } + { + showVerifiedPopup(value) + && ( +
+ { generateVerifiedPopup() } +
+ ) + } + { + showPrimaryChip(value) + && ( +
+ +
+ ) + } + + ); + }; + + if (attributeValueList.length < 1) { + return generatePlaceholderLink(schema, fieldName); + } + + if (attributeValueList.length > 1) { + return ( + + ); + } + + return renderSingleMenuItem(attributeValueList[0], 0); }; const generatePlaceholderLink = (schema: ProfileSchema, fieldName: string): JSX.Element => { @@ -2300,32 +2278,12 @@ export const Profile: FunctionComponent = (props: ProfileProps): R trigger={ ( - ) - } - header= { t("common:verified") } - inverted - /> - ); - }; - - const generatePrimaryPopup= (): JSX.Element => { - - return ( - ) } - header= { t("common:primary") } + header= { t("common:verified") } inverted /> ); diff --git a/apps/myaccount/src/public/deployment.config.json b/apps/myaccount/src/public/deployment.config.json index 3bc5c223cda..8c446d0c8bd 100644 --- a/apps/myaccount/src/public/deployment.config.json +++ b/apps/myaccount/src/public/deployment.config.json @@ -116,7 +116,7 @@ }, "isCookieConsentBannerEnabled": true, "isHeaderAvatarLabelAllowed": true, - "isMultipleEmailsAndMobileNumbersEnabled": false, + "isMultipleEmailsAndMobileNumbersEnabled": true, "isPasswordInputValidationEnabled": true, "isProfileUsernameReadonly": true, "privacyPolicyConfigs": {}, diff --git a/features/admin.users.v1/components/user-profile.scss b/features/admin.users.v1/components/user-profile.scss index c0a6593b35c..fb60ac85fa6 100644 --- a/features/admin.users.v1/components/user-profile.scss +++ b/features/admin.users.v1/components/user-profile.scss @@ -16,75 +16,48 @@ * under the License. */ -.multi-valued-accordion { - .accordion-summary { - display: flex; - padding: 0px 12px 0px 8px; - flex-wrap: nowrap; - align-items: center; - gap: 4px; - border-radius: 8px; - - .accordion-label { - margin: 0 0 0 8px; - flex-shrink: 0; - padding-right: 4px; - min-width: 250px; - - &.mobile-label { - min-width: 150px; - } + .multi-value-table { + .multi-value-table-data-row { + &:last-child td, &:last-child th { + border: none; } - .verified-icon, .primary-icon { + .table-c1 { + display: flex; + flex-wrap: nowrap; align-items: center; - padding: 0 4px; - } - } - - .accordion-details { - border-radius: 8px; - .multi-value-table { - .multi-value-table-data-row { - &:last-child td, &:last-child th { - border: none; + font-size: 1rem; + padding: 0.2em 0; + + .c1-value{ + margin-bottom: 0; + flex-shrink: 0; + padding-right: 12px; + min-width: 250px; + + &.mobile-label { + min-width: 150px; } } - - .table-c1 { - display: flex; - flex-wrap: nowrap; + + .verified-icon, .primary-icon { align-items: center; - font-size: 1rem; - - .c1-value{ - margin-bottom: 0; - flex-shrink: 0; - padding-right: 12px; - min-width: 250px; - - &.mobile-label { - min-width: 150px; - } - } - - .verified-icon, .primary-icon { - align-items: center; - padding: 0 4px; - } + padding: 0 4px; } + } + + .table-c2 { + display: flex; + flex-wrap: nowrap; + align-items: center; + justify-content: flex-end; + gap: 4px; + padding: 0.2em 0; - .table-c2 { - display: flex; - flex-wrap: nowrap; - align-items: center; - justify-content: flex-end; - gap: 4px; + .text-btn { + padding: 0px; + white-space: nowrap; } } } - - .MuiAccordionDetails-root { - padding: 0px; - } } diff --git a/features/admin.users.v1/components/user-profile.tsx b/features/admin.users.v1/components/user-profile.tsx index cf520608937..1f2664f55e9 100644 --- a/features/admin.users.v1/components/user-profile.tsx +++ b/features/admin.users.v1/components/user-profile.tsx @@ -21,13 +21,11 @@ import TableBody from "@mui/material/TableBody"; import TableCell from "@mui/material/TableCell"; import TableContainer from "@mui/material/TableContainer"; import TableRow from "@mui/material/TableRow"; -import Accordion from "@oxygen-ui/react/Accordion"; -import AccordionDetails from "@oxygen-ui/react/AccordionDetails"; -import AccordionSummary from "@oxygen-ui/react/AccordionSummary"; import Alert from "@oxygen-ui/react/Alert"; +import OxygenButton from "@oxygen-ui/react/Button"; +import Chip from "@oxygen-ui/react/Chip"; import IconButton from "@oxygen-ui/react/IconButton"; import Paper from "@oxygen-ui/react/Paper"; -import { CheckIcon, ChevronDownIcon, StarIcon, TrashIcon } from "@oxygen-ui/react-icons"; import { Show, useRequiredScopes } from "@wso2is/access-control"; import { AppConstants, AppState, FeatureConfigInterface, history } from "@wso2is/admin.core.v1"; import useUIConfig from "@wso2is/admin.core.v1/hooks/use-ui-configs"; @@ -67,7 +65,7 @@ import { DangerZone, DangerZoneGroup, EmphasizedSegment, - Tooltip, + Popup, useConfirmationModalAlert } from "@wso2is/react-components"; import { AxiosError, AxiosResponse } from "axios"; @@ -77,7 +75,7 @@ import React, { FunctionComponent, ReactElement, ReactNode, useCallback, useEffe import { useTranslation } from "react-i18next"; import { useDispatch, useSelector } from "react-redux"; import { Dispatch } from "redux"; -import { Button, CheckboxProps, Divider, DropdownItemProps, Form, Grid, Input } from "semantic-ui-react"; +import { Button, CheckboxProps, Divider, DropdownItemProps, Form, Grid, Icon, Input } from "semantic-ui-react"; import { ChangePasswordComponent } from "./user-change-password"; import { updateUserInfo } from "../api"; import { @@ -240,10 +238,6 @@ export const UserProfile: FunctionComponent = ( const oneTimePassword: string = user[userConfig.userProfileSchema]?.oneTimePassword; const isCurrentUserAdmin: boolean = user?.roles?.some((role: RolesMemberInterface) => role.display === administratorConfig.adminRoleName) ?? false; - const [ expandMultiAttributeAccordion, setExpandMultiAttributeAccordion ] = useState>({ - [EMAIL_ADDRESSES_ATTRIBUTE]: false, - [MOBILE_NUMBERS_ATTRIBUTE]: false - }); const [ isFormStale, setIsFormStale ] = useState(false); const [ isMultipleEmailAndMobileNumberEnabled, setIsMultipleEmailAndMobileNumberEnabled ] = useState(false); @@ -1933,7 +1927,6 @@ export const UserProfile: FunctionComponent = ( attributeValueList.unshift(primaryAttributeValue); } const showAccordion: boolean = attributeValueList.length >= 1; - const accordionLabelValue: string = showAccordion ? attributeValueList[0] : ""; const showVerifiedPopup = (value: string): boolean => { return verificationEnabled && @@ -2024,99 +2017,39 @@ export const UserProfile: FunctionComponent = ( } /> + + + ) + ) } + + + );