From ce36e6d81cb2c3716bc1859a9815efbdfd53fdeb Mon Sep 17 00:00:00 2001 From: Luca Stauble Date: Wed, 4 Jan 2023 14:16:13 +0100 Subject: [PATCH] feat(settings): choose the "from" address within all the available addresses * feat(settings): choose the "from" address within all the available addresses refactor: fixed/added types refactor: changed the type-check of the identity to avoid relying on the translation value * refactor(settings): onChange callback of the sender address selection * chore: updated CODEOWNERS file refs: IRIS-3609 (#177) --- .github/CODEOWNERS | 2 +- package-lock.json | 25 +++-- package.json | 5 +- src/network/edit-settings.ts | 3 - src/settings/account-wrapper.tsx | 43 ++++---- src/settings/accounts-settings.tsx | 97 ++++++++++++++++--- .../account-settings/accounts-list.tsx | 9 +- .../account-settings/persona-use-section.tsx | 30 +++--- .../primary-account-settings.tsx | 23 ++--- .../settings-sent-messages.tsx | 90 ++++++++++------- types/account/index.d.ts | 5 + types/misc/index.d.ts | 7 ++ 12 files changed, 227 insertions(+), 112 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 63a4fd54..dc21705b 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @nubsthead @geeky-abhishek @giuliano176 @dhavaldodiya @Gammax92 @gnekoz +* @nubsthead @giuliano176 @dhavaldodiya @Gammax92 @gnekoz @Zextras/shuffled-waffles diff --git a/package-lock.json b/package-lock.json index ffe8d1fb..b2663dfb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -99,7 +99,7 @@ }, "peerDependencies": { "@reduxjs/toolkit": "^1.6.2", - "@zextras/carbonio-design-system": "^0.5.0", + "@zextras/carbonio-design-system": "^0.5.3", "core-js": "^3.19.1", "moment": "^2.29.1", "node-fetch": "^2.6.6", @@ -5079,12 +5079,19 @@ "license": "MIT" }, "node_modules/caniuse-lite": { - "version": "1.0.30001304", - "license": "CC-BY-4.0", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } + "version": "1.0.30001441", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz", + "integrity": "sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] }, "node_modules/ccount": { "version": "2.0.1", @@ -18413,7 +18420,9 @@ "version": "1.0.0" }, "caniuse-lite": { - "version": "1.0.30001304" + "version": "1.0.30001441", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz", + "integrity": "sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==" }, "ccount": { "version": "2.0.1" diff --git a/package.json b/package.json index aba80c8c..1a1c446d 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,6 @@ "author": "Zextras Crab Onions Team ", "maintainers": [ "Gabriele Marino ", - "Abhishek Kumar ", "Giuliano Caregnato ", "Dhaval Dodiya ", "Francesco Gottardi ", @@ -101,7 +100,7 @@ "@fontsource/roboto": "^4.5.7", "@sentry/browser": "^6.17.7", "@tinymce/tinymce-react": "^3.13.0", - "@zextras/carbonio-design-system": "^0.5.3", + "@zextras/carbonio-design-system": "^0.5.2", "@zextras/carbonio-ui-preview": "^0.2.4", "darkreader": "4.9.46", "history": "^5.2.0", @@ -128,7 +127,7 @@ }, "peerDependencies": { "@reduxjs/toolkit": "^1.6.2", - "@zextras/carbonio-design-system": "^0.5.0", + "@zextras/carbonio-design-system": "^0.5.2", "core-js": "^3.19.1", "moment": "^2.29.1", "node-fetch": "^2.6.6", diff --git a/src/network/edit-settings.ts b/src/network/edit-settings.ts index dac64f0a..c6b47e8a 100644 --- a/src/network/edit-settings.ts +++ b/src/network/edit-settings.ts @@ -195,9 +195,6 @@ export const editSettings = ( displayName: find(mods?.identity?.modifyList, (item) => item.id === s?.account?.id)?.prefs .zimbraPrefIdentityName || s.account?.displayName, - name: - find(mods?.identity?.modifyList, (item) => item.id === s?.account?.id)?.prefs - .zimbraPrefFromAddress || s.account?.name, identities: { identity: typeof s.account !== 'undefined' diff --git a/src/settings/account-wrapper.tsx b/src/settings/account-wrapper.tsx index c573b254..18c24653 100644 --- a/src/settings/account-wrapper.tsx +++ b/src/settings/account-wrapper.tsx @@ -9,35 +9,42 @@ import React, { useMemo } from 'react'; import { useUserAccount } from '../store/account'; import { getT } from '../store/i18n'; import { AccountsSettings } from './accounts-settings'; +import { IdentityProps } from '../../types'; const AccountWrapper = (): React.ReactElement | null => { const accountSettings = useUserAccount(); const t = getT(); const identitiesDefault = useMemo(() => { - const temp = map(accountSettings?.identities.identity, (item, index) => ({ - id: item.name === 'DEFAULT' ? '0' : (index + 1).toString(), - type: item.name === 'DEFAULT' ? t('label.primary', 'Primary') : t('label.persona', 'Persona'), - identityId: item._attrs.zimbraPrefIdentityId || '', - fromAddress: item._attrs.zimbraPrefFromAddress || '', - identityName: item._attrs.zimbraPrefIdentityName || '', - fromDisplay: item._attrs.zimbraPrefFromDisplay || '', - recoveryAccount: item._attrs.zimbraRecoveryAccount || '', - replyToDisplay: item._attrs.zimbraPrefReplyToDisplay || '', - replyToAddress: item._attrs.zimbraPrefReplyToAddress || '', - replyToEnabled: item._attrs.zimbraPrefReplyToEnabled || '', - saveToSent: item._attrs.zimbraPrefSaveToSent || '', - sentMailFolder: item._attrs.zimbraPrefSentMailFolder || '', - whenInFoldersEnabled: item._attrs.zimbraPrefWhenInFoldersEnabled || '', - whenSentToEnabled: item._attrs.zimbraPrefWhenSentToEnabled || '', - whenSentToAddresses: item._attrs.zimbraPrefWhenSentToAddresses || '' - })); + const temp = map( + accountSettings?.identities.identity, + (item, index) => + ({ + id: item.name === 'DEFAULT' ? '0' : (index + 1).toString(), + flgType: item.name === 'DEFAULT' ? 'primary' : 'persona', + type: + item.name === 'DEFAULT' ? t('label.primary', 'Primary') : t('label.persona', 'Persona'), + identityId: item._attrs.zimbraPrefIdentityId || '', + fromAddress: item._attrs.zimbraPrefFromAddress || '', + identityName: item._attrs.zimbraPrefIdentityName || '', + fromDisplay: item._attrs.zimbraPrefFromDisplay || '', + recoveryAccount: item._attrs.zimbraRecoveryAccount || '', + replyToDisplay: item._attrs.zimbraPrefReplyToDisplay || '', + replyToAddress: item._attrs.zimbraPrefReplyToAddress || '', + replyToEnabled: item._attrs.zimbraPrefReplyToEnabled || '', + saveToSent: item._attrs.zimbraPrefSaveToSent || '', + sentMailFolder: item._attrs.zimbraPrefSentMailFolder || '', + whenInFoldersEnabled: item._attrs.zimbraPrefWhenInFoldersEnabled || '', + whenSentToEnabled: item._attrs.zimbraPrefWhenSentToEnabled || '', + whenSentToAddresses: item._attrs.zimbraPrefWhenSentToAddresses || '' + } as IdentityProps) + ); const result = [temp[temp.length - 1], ...temp]; result.pop(); return result; }, [accountSettings, t]); return identitiesDefault.length > 0 ? ( - + ) : null; }; diff --git a/src/settings/accounts-settings.tsx b/src/settings/accounts-settings.tsx index 43a567c3..579f962d 100644 --- a/src/settings/accounts-settings.tsx +++ b/src/settings/accounts-settings.tsx @@ -7,12 +7,22 @@ import React, { useCallback, useMemo, useState, useEffect, ReactElement } from 'react'; import { Container, useSnackbar } from '@zextras/carbonio-design-system'; import { TFunction } from 'react-i18next'; -import { map, includes, findIndex, reduce, find, replace, lowerFirst, isEmpty } from 'lodash'; +import { + map, + includes, + findIndex, + reduce, + find, + replace, + lowerFirst, + isEmpty, + uniq, + isArray +} from 'lodash'; import { useUserSettings } from '../store/account/hooks'; import { editSettings } from '../network/edit-settings'; import { SHELL_APP_ID } from '../constants'; -import { Mods, IdentityProps, CreateIdentityProps } from '../../types'; -import { useAccountStore } from '../store/account/store'; +import { Mods, IdentityProps, CreateIdentityProps, Account, AccountSettings } from '../../types'; import AccountsList from './components/account-settings/accounts-list'; import PrimaryAccountSettings from './components/account-settings/primary-account-settings'; import SettingsSentMessages from './components/account-settings/settings-sent-messages'; @@ -36,19 +46,71 @@ type AddModProps = { createList?: { prefs: CreateIdentityProps }[]; }; type AccountSettingsProps = { + account: Account; identitiesDefault: IdentityProps[]; t: TFunction; }; type UserRightsProps = { email: string; right: string }; -export const AccountsSettings = ({ identitiesDefault, t }: AccountSettingsProps): ReactElement => { + +/** + * Compose a unique list of all identities' email addresses + * + * The list is composed of: + * - the email address of the current account + * - the email addresses of all the shared accounts (taken from the rights infos) + * - all the aliases + * + * @param account + * @param settings + * + * @returns a list of unique email addresses + */ +const getAvailableEmailAddresses = (account: Account, settings: AccountSettings): string[] => { + const result: string[] = []; + + // Adds the email address of the primary account + result.push(account.name); + + // Adds the email addresses of all the shared accounts + if (account.rights?.targets) { + account.rights?.targets.forEach((target) => { + if (target.right === 'sendAs' && target.target) { + target.target.forEach((user) => { + if (user.type === 'account' && user.email) { + user.email.forEach((email) => { + result.push(email.addr); + }); + } + }); + } + }); + } + + // Adds all the aliases + if (settings.attrs.zimbraMailAlias) { + if (isArray(settings.attrs.zimbraMailAlias)) { + result.push(...settings.attrs.zimbraMailAlias); + } else { + result.push(String(settings.attrs.zimbraMailAlias)); + } + } + + return uniq(result); +}; + +export const AccountsSettings = ({ + account, + identitiesDefault, + t +}: AccountSettingsProps): ReactElement => { const [mods, setMods] = useState({}); const [activeDelegateView, setActiveDelegateView] = useState('0'); const [selectedIdentityId, setSelectedIdentityId] = useState(0); const [identities, setIdentities] = useState(identitiesDefault); const [delegates, setDelegates] = useState([]); - - const maxIdentities = useUserSettings().attrs.zimbraIdentityMaxNumEntries; + const settings = useUserSettings(); + const maxIdentities = settings.attrs.zimbraIdentityMaxNumEntries; const addMod = useCallback( (arg: AddModProps) => { const { type, modifyProp, deleteList, createList } = arg; @@ -245,6 +307,11 @@ export const AccountsSettings = ({ identitiesDefault, t }: AccountSettingsProps) const onCancel = useCallback(() => setMods({}), []); const title: string = t('label.accounts', 'Accounts'); const isDirty = useMemo(() => !isEmpty(mods), [mods]); + const availableEmailAddresses = useMemo( + () => getAvailableEmailAddresses(account, settings), + [account, settings] + ); + return ( <> @@ -257,6 +324,7 @@ export const AccountsSettings = ({ identitiesDefault, t }: AccountSettingsProps) > - {identities[selectedIdentityId]?.type === t('label.primary', 'Primary') && ( + {identities[selectedIdentityId]?.flgType === 'primary' && ( <> {/* )} - {identities[selectedIdentityId]?.type === t('label.persona', 'Persona') && ( + {identities[selectedIdentityId]?.flgType === 'persona' && ( <> )} - {includes(['IMAP', 'POP'], identities[selectedIdentityId]?.type) && ( + {includes(['IMAP', 'POP'], identities[selectedIdentityId]?.flgType) && ( <> {/* diff --git a/src/settings/components/account-settings/accounts-list.tsx b/src/settings/components/account-settings/accounts-list.tsx index d596acb3..5118e8f5 100644 --- a/src/settings/components/account-settings/accounts-list.tsx +++ b/src/settings/components/account-settings/accounts-list.tsx @@ -19,10 +19,11 @@ import { } from '@zextras/carbonio-design-system'; import { TFunction } from 'i18next'; import { map, filter, max, noop } from 'lodash'; -import { IdentityProps, CreateIdentityProps } from '../../../../types'; +import { IdentityProps, CreateIdentityProps, Account } from '../../../../types'; type AccountsListProps = { t: TFunction; + account: Account; identities: IdentityProps[]; setIdentities: (identities: IdentityProps[]) => void; selectedIdentityId: number; @@ -33,6 +34,7 @@ type AccountsListProps = { const AccountsList = ({ t, + account, selectedIdentityId, identities, setIdentities, @@ -64,7 +66,7 @@ const AccountsList = ({ - ({item.fromAddress}) + ({item.flgType === 'primary' ? account.name : item.fromAddress}) @@ -104,6 +106,7 @@ const AccountsList = ({ const newPersonaName = `New Persona ${newPersonaNextNumber || 1}`; identities.push({ id: `${identities.length}`, + flgType: 'persona', type: t('label.persona', 'Persona'), identityId: createListrequestId, fromAddress: identities[0]?.fromAddress, @@ -249,7 +252,7 @@ const AccountsList = ({ onClick={(): void => onDelete()} color="error" type="outlined" - disabled={identities[selectedIdentityId]?.type === t('label.primary', 'Primary')} + disabled={identities[selectedIdentityId]?.flgType === 'primary'} /> diff --git a/src/settings/components/account-settings/persona-use-section.tsx b/src/settings/components/account-settings/persona-use-section.tsx index bccb983b..b5daefd5 100644 --- a/src/settings/components/account-settings/persona-use-section.tsx +++ b/src/settings/components/account-settings/persona-use-section.tsx @@ -12,7 +12,7 @@ import { EMAIL_VALIDATION_REGEX } from '../../../constants'; type PersonaUseSectionProps = { t: TFunction; - items: IdentityProps; + identity: IdentityProps; updateIdentities: (modifyList: { id: string | number; key: string; @@ -22,7 +22,7 @@ type PersonaUseSectionProps = { const PersonaUseSection = ({ t, - items, + identity, updateIdentities }: PersonaUseSectionProps): ReactElement => { const title = useMemo(() => t('label.use_persona', 'Use this persona'), [t]); @@ -33,20 +33,20 @@ const PersonaUseSection = ({ // const onClose = useCallback(() => setOpen(false), []); const [whenInFoldersEnabled, setWhenInFoldersEnabled] = useState( - items.whenInFoldersEnabled === 'TRUE' + identity.whenInFoldersEnabled === 'TRUE' ); - const [whenSentToEnabled, setWhenSentToEnabled] = useState(items.whenSentToEnabled === 'TRUE'); - const [whenSentToAddresses, setWhenSentToAddresses] = useState(items.whenSentToAddresses); + const [whenSentToEnabled, setWhenSentToEnabled] = useState(identity.whenSentToEnabled === 'TRUE'); + const [whenSentToAddresses, setWhenSentToAddresses] = useState(identity.whenSentToAddresses); useEffect(() => { - setWhenSentToEnabled(items.whenSentToEnabled === 'TRUE'); - }, [items.whenSentToEnabled]); + setWhenSentToEnabled(identity.whenSentToEnabled === 'TRUE'); + }, [identity.whenSentToEnabled]); useEffect(() => { - setWhenSentToAddresses(items.whenSentToAddresses); - }, [items.whenSentToAddresses]); + setWhenSentToAddresses(identity.whenSentToAddresses); + }, [identity.whenSentToAddresses]); useEffect(() => { - setWhenInFoldersEnabled(items.whenInFoldersEnabled === 'TRUE'); - }, [items.whenInFoldersEnabled]); + setWhenInFoldersEnabled(identity.whenInFoldersEnabled === 'TRUE'); + }, [identity.whenInFoldersEnabled]); const whenSentToAddressesLabel = useMemo( () => (whenSentToAddresses ? '' : t('label.recipents', 'Recipients')), @@ -55,12 +55,12 @@ const PersonaUseSection = ({ const onClickWhenSentToEnabled = useCallback(() => { setWhenSentToEnabled(!whenSentToEnabled); const modifyProp = { - id: items.identityId, + id: identity.identityId, key: 'zimbraPrefWhenSentToEnabled', value: whenSentToEnabled ? 'FALSE' : 'TRUE' }; updateIdentities(modifyProp); - }, [items.identityId, updateIdentities, whenSentToEnabled]); + }, [identity.identityId, updateIdentities, whenSentToEnabled]); const isValidEmail = useMemo( () => whenSentToEnabled && !EMAIL_VALIDATION_REGEX.test(whenSentToAddresses || ''), @@ -71,14 +71,14 @@ const PersonaUseSection = ({ (value: string) => { setWhenSentToAddresses(value); const modifyProp = { - id: items.identityId, + id: identity.identityId, key: 'zimbraPrefWhenSentToAddresses', value }; updateIdentities(modifyProp); }, - [updateIdentities, items.identityId] + [updateIdentities, identity.identityId] ); // this function is work in progress for when the mails sync is implemented diff --git a/src/settings/components/account-settings/primary-account-settings.tsx b/src/settings/components/account-settings/primary-account-settings.tsx index 8e331732..ef7b262c 100644 --- a/src/settings/components/account-settings/primary-account-settings.tsx +++ b/src/settings/components/account-settings/primary-account-settings.tsx @@ -7,11 +7,12 @@ import React, { useMemo, useCallback, ReactElement, useState, useEffect } from 'react'; import { Container, Text, Padding, Input, Row } from '@zextras/carbonio-design-system'; import { TFunction } from 'i18next'; -import { IdentityProps } from '../../../../types'; +import { Account, IdentityProps } from '../../../../types'; interface PrimaryAccountSettingsProps { t: TFunction; - items: IdentityProps; + account: Account; + identity: IdentityProps; updateIdentities: (modifyList: { id: string | number; key: string; @@ -21,17 +22,17 @@ interface PrimaryAccountSettingsProps { const PrimaryAccountSettings = ({ t, - items, + account, + identity, updateIdentities }: PrimaryAccountSettingsProps): ReactElement => { - const emailValue = useMemo(() => items?.fromAddress, [items]); const emailLabel = useMemo( - () => (emailValue ? '' : t('label.email_address', 'E-mail address')), - [emailValue, t] + () => (account.name ? '' : t('label.email_address', 'E-mail address')), + [account.name, t] ); - const [accountNameValue, setAccountNameValue] = useState(items?.identityName); + const [accountNameValue, setAccountNameValue] = useState(identity?.identityName); - useEffect(() => setAccountNameValue(items.identityName), [items.identityName]); + useEffect(() => setAccountNameValue(identity.identityName), [identity.identityName]); const accountLabel = useMemo( () => (accountNameValue ? '' : t('label.account_name', 'Account Name')), [accountNameValue, t] @@ -43,14 +44,14 @@ const PrimaryAccountSettings = ({ setAccountNameValue(value); const modifyProp = { - id: items.identityId, + id: identity.identityId, key: 'zimbraPrefIdentityName', value }; updateIdentities(modifyProp); }, - [updateIdentities, items.identityId] + [updateIdentities, identity.identityId] ); return ( @@ -75,7 +76,7 @@ const PrimaryAccountSettings = ({ mainAlignment="flex-start" > - + void; + availableEmailAddresses?: string[]; }; -const blankItem = { label: '', value: '' }; +const blankItem: SelectItem = { label: '', value: '' }; const SettingsSentMessages = ({ t, - items, + identity, isExternalAccount, - updateIdentities + updateIdentities, + availableEmailAddresses }: SettingsSentMessagesProps): ReactElement => { const title = useMemo(() => t('label.settings_sent_messages', 'Settings for Sent Messages'), [t]); - const [replyToEnabledValue, setReplyToEnabledValue] = useState(items.replyToEnabled === 'TRUE'); - const [replyToAddress, setReplyToAddress] = useState(items.replyToAddress); + const [replyToEnabledValue, setReplyToEnabledValue] = useState( + identity.replyToEnabled === 'TRUE' + ); + const [replyToAddress, setReplyToAddress] = useState(identity.replyToAddress); const [dropdownOpen, setDropdownOpen] = useState(false); - const [fromDisplayValue, setFromDisplayValue] = useState(items.fromDisplay); - const [replyToDisplay, setReplyToDisplay] = useState(items?.replyToDisplay); + const [fromDisplayValue, setFromDisplayValue] = useState(identity.fromDisplay); + const [replyToDisplay, setReplyToDisplay] = useState(identity?.replyToDisplay); const fromAddressArray = useMemo( - () => [{ value: items.fromAddress ?? '', label: items.fromAddress ?? '' }], - [items?.fromAddress] + () => + availableEmailAddresses + ? availableEmailAddresses.map((address) => ({ value: address, label: address })) + : [blankItem], + [availableEmailAddresses] ); const [fromAddress, setFromAddress] = useState( - () => find(fromAddressArray, (item) => item.value === items.fromAddress) ?? blankItem + () => find(fromAddressArray, (item) => item.value === identity.fromAddress) ?? blankItem ); useEffect(() => { - setReplyToEnabledValue(items.replyToEnabled === 'TRUE'); - }, [items.replyToEnabled]); + setReplyToEnabledValue(identity.replyToEnabled === 'TRUE'); + }, [identity.replyToEnabled]); useEffect(() => { - setFromDisplayValue(items.fromDisplay); - }, [items.fromDisplay]); + setFromDisplayValue(identity.fromDisplay); + }, [identity.fromDisplay]); useEffect(() => { - const k = find(fromAddressArray, (item) => item.value === items.fromAddress) ?? blankItem; + const k = find(fromAddressArray, (item) => item.value === identity.fromAddress) ?? blankItem; setFromAddress(k); - }, [fromAddressArray, items.fromAddress]); + }, [fromAddressArray, identity.fromAddress]); useEffect(() => { - setReplyToDisplay(items?.replyToDisplay === undefined ? '' : items?.replyToDisplay); - }, [items?.replyToDisplay]); + setReplyToDisplay(identity?.replyToDisplay === undefined ? '' : identity?.replyToDisplay); + }, [identity?.replyToDisplay]); useEffect(() => { - setReplyToAddress(items.replyToAddress); - }, [items.replyToAddress]); + setReplyToAddress(identity.replyToAddress); + }, [identity.replyToAddress]); const onClickReplyToEnabled = useCallback(() => { setReplyToEnabledValue(!replyToEnabledValue); const modifyProp = { - id: items.identityId, + id: identity.identityId, key: 'zimbraPrefReplyToEnabled', value: replyToEnabledValue ? 'FALSE' : 'TRUE' }; updateIdentities(modifyProp); - }, [items.identityId, replyToEnabledValue, updateIdentities]); + }, [identity.identityId, replyToEnabledValue, updateIdentities]); const fromDisplayLabel = useMemo( () => (fromDisplayValue ? '' : t('label.from_name', 'From: "Name"')), @@ -88,7 +97,7 @@ const SettingsSentMessages = ({ const onChangeFromDisplayValue = (value: string): void => { setFromDisplayValue(value); const modifyProp = { - id: items.identityId, + id: identity.identityId, key: 'zimbraPrefFromDisplay', value }; @@ -100,17 +109,24 @@ const SettingsSentMessages = ({ [fromAddress, t] ); - const onChangeFromAddress = useCallback( - (newVal) => { - setFromAddress(filter(fromAddressArray, (item) => item.value === newVal)[0]); + const onChangeFromAddress = useCallback( + (newAddress) => { + if (!newAddress || typeof newAddress !== 'string') { + return; + } + + if (fromAddress?.value === newAddress) { + return; + } + setFromAddress(filter(fromAddressArray, (item) => item.value === newAddress)[0]); const modifyProp = { - id: items.identityId, + id: identity.identityId, key: 'zimbraPrefFromAddress', - value: newVal + value: newAddress }; updateIdentities(modifyProp); }, - [items.identityId, updateIdentities, fromAddressArray] + [identity.identityId, updateIdentities, fromAddressArray, fromAddress.value] ); const replyToEnabledLabel = t( @@ -126,13 +142,13 @@ const SettingsSentMessages = ({ (value: string): void => { setReplyToDisplay(value); const modifyProp = { - id: items.identityId, + id: identity.identityId, key: 'zimbraPrefReplyToDisplay', value }; updateIdentities(modifyProp); }, - [updateIdentities, items.identityId] + [updateIdentities, identity.identityId] ); const replyToAddressLabel = useMemo( @@ -144,23 +160,23 @@ const SettingsSentMessages = ({ () => [ { id: '0', - label: items.fromAddress ?? '' + label: identity.fromAddress ?? '' } ], - [items.fromAddress] + [identity.fromAddress] ); const onChangeReplyToAddress = useCallback( (value: string) => { setReplyToAddress(value); const modifyProp = { - id: items.identityId, + id: identity.identityId, key: 'zimbraPrefReplyToAddress', value }; updateIdentities(modifyProp); }, - [updateIdentities, items.identityId] + [updateIdentities, identity.identityId] ); const isValidEmail = useMemo( @@ -207,7 +223,7 @@ const SettingsSentMessages = ({ items={fromAddressArray} showCheckbox={false} background="gray5" - onChange={(): unknown => onChangeFromAddress} + onChange={onChangeFromAddress} /> )} diff --git a/types/account/index.d.ts b/types/account/index.d.ts index f86d6215..413bb721 100644 --- a/types/account/index.d.ts +++ b/types/account/index.d.ts @@ -61,11 +61,16 @@ export type AccountSettings = { props: Array; }; +export type AccountRightTargetEmail = { + addr: string; +}; + export type AccountRightTarget = { d: string; id: string; name: string; type: string; + email: Array; }; export type AccountRightName = diff --git a/types/misc/index.d.ts b/types/misc/index.d.ts index 49ca01fd..d53ebf07 100644 --- a/types/misc/index.d.ts +++ b/types/misc/index.d.ts @@ -86,6 +86,13 @@ export type AccountProps = { export type IdentityProps = { id: string; + /** + * Type of the identity + */ + flgType: 'primary' | 'persona' | 'IMAP' | 'POP'; + /** + * Localized description of the type of identity + */ type: string; identityId: string | number; fromAddress?: string;