CHI-3945: UI update for voicemails, translation key name change, couple of minor fixes - #4627
CHI-3945: UI update for voicemails, translation key name change, couple of minor fixes#4627stephenhand wants to merge 10 commits into
Conversation
|
@copilot - add unit test cases for scenarios when multiple keys are specified in the lookupTranslation method |
…x fallback bug Co-authored-by: stephenhand <1694716+stephenhand@users.noreply.github.com>
Added unit tests for the multiple keys scenarios in a new
Also fixed a related bug: |
There was a problem hiding this comment.
Pull request overview
Updates Flex UI to support a dedicated voicemail task experience, including a new voicemail channel registration, a redesigned voicemail task panel, and translation key cleanups to match updated naming conventions.
Changes:
- Adds and registers a dedicated
voicemailtask channel with custom icon/color and task list/incoming canvas strings. - Reworks voicemail UI into a Task Canvas tab/panel layout and expands voicemail-specific strings.
- Renames the “Close Contact” translation key to a 3-part convention and adjusts call-type dialog behavior accordingly.
Reviewed changes
Copilot reviewed 34 out of 34 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| plugin-hrm-form/src/voicemail/VoicemailTaskPanel.tsx | New voicemail task panel layout/controls and callback attempt display |
| plugin-hrm-form/src/voicemail/setUpVoicemailComponents.tsx | Adds Voicemail tab and removes header actions for voicemail tasks |
| plugin-hrm-form/src/utils/setUpComponents.tsx | Adjusts manual pulling chat-channel lookup |
| plugin-hrm-form/src/utils/mappers.ts | Adds voicemail channel label mapping |
| plugin-hrm-form/src/translations/th.json | Renames CloseContact translation key |
| plugin-hrm-form/src/translations/pt.json | Renames CloseContact translation key |
| plugin-hrm-form/src/translations/index.ts | Adds lookupTranslation fallback support for multiple keys |
| plugin-hrm-form/src/translations/hu.json | Renames CloseContact translation key |
| plugin-hrm-form/src/translations/fr.json | Renames CloseContact translation key |
| plugin-hrm-form/src/translations/es.json | Renames CloseContact translation key |
| plugin-hrm-form/src/translations/en.json | Adds voicemail UI strings; renames CloseContact translation key |
| plugin-hrm-form/src/translations/en-MT.json | Renames CloseContact translation key |
| plugin-hrm-form/src/translations/en-GB.json | Renames CloseContact translation key |
| plugin-hrm-form/src/translations/en-CA.json | Renames CloseContact translation key |
| plugin-hrm-form/src/styles/twilioTaskPanel.tsx | Adds styled wrappers to match Twilio task panel styling |
| plugin-hrm-form/src/styles/banners.ts | Fixes cursor behavior based on permission string |
| plugin-hrm-form/src/HrmFormPlugin.tsx | Registers voicemail channel setup |
| plugin-hrm-form/src/components/profile/IdentifierBanner/iconsFromTask.ts | Uses voice icon for voicemail identifiers banner |
| plugin-hrm-form/src/components/common/icons/VoicemailIcon.tsx | Fixes voicemail SVG viewBox sizing |
| plugin-hrm-form/src/components/common/forms/SectionEntry/SectionEntryValue.tsx | Renders multiple template codes as individual <Template> components |
| plugin-hrm-form/src/components/caseMergingBanners/ContactAddedToCaseBanner.tsx | Adjusts CaseLink props to avoid startup console error |
| plugin-hrm-form/src/components/callTypeButtons/SaveContactCallTypeDialog.tsx | Changes confirm button label logic and replaces isCallTask with taskType |
| plugin-hrm-form/src/components/callTypeButtons/CallTypeButtons.tsx | Determines task type (chat/call/default) and passes to dialog |
| plugin-hrm-form/src/channels/setUpChannels.tsx | Adds voicemail channel creation/registration and translated strings |
| plugin-hrm-form/src/channels/colors.ts | Updates voicemail channel color |
| plugin-hrm-form/src/_tests/translations/index.test.ts | Adds tests for multi-key lookupTranslation fallback behavior |
| plugin-hrm-form/src/_tests/callTypeButtons/CallTypeButtons.test.tsx | Updates tests to treat SMS as chat-type via customChannelType |
| lambdas/packages/hrm-form-definitions/form-definitions/usnm/v1/customStrings/Substitutions.json | Renames CloseContact substitution key |
| lambdas/packages/hrm-form-definitions/form-definitions/usnc/v1/customStrings/Substitutions.json | Renames CloseContact substitution key; removes one substitution entry |
| lambdas/packages/hrm-form-definitions/form-definitions/uscr/v1/customStrings/Substitutions.json | Renames CloseContact substitution key |
| lambdas/packages/hrm-form-definitions/form-definitions/sg/v1/customStrings/Substitutions.json | Renames CloseContact substitution key |
| lambdas/packages/hrm-form-definitions/form-definitions/nz/v1/customStrings/Substitutions.json | Renames CloseContact substitution key |
| lambdas/packages/hrm-form-definitions/form-definitions/clhs/v1/customStrings/Substitutions.json | Renames CloseContact substitution key |
| lambdas/packages/hrm-form-definitions/form-definitions/as/v1/CallTypeButtons.json | Reformats JSON and adds a new “voicemail” non-data call type |
Suppressed comments (2)
plugin-hrm-form/src/utils/setUpComponents.tsx:132
Array.from(manager.workerClient.channels).find(...)can returnundefined; destructuringconst [, chatChannel] = ...will then throw at startup. The added optional chaining in the predicate doesn’t prevent that.
Guard the find() result (or use optional indexing) and bail out (or log) when the chat channel can’t be found, before reading chatChannel.capacity / attaching listeners.
plugin-hrm-form/src/components/callTypeButtons/SaveContactCallTypeDialog.tsx:32
- This component now requires
taskType, but there are still call sites passing the removedisCallTaskprop (e.g.plugin-hrm-form/src/___tests__/callTypeButtons/NonDataCallTypeDialog.test.tsx:34). That will break the build.
Update remaining call sites/tests to pass taskType instead of isCallTask (or provide a backwards-compatible default here if you need to stage the change).
type OwnProps = {
isOpen: boolean;
taskType: 'chat' | 'call' | 'default';
isEnabled: boolean;
isInWrapupMode?: boolean;
handleConfirm: () => Promise<any>;
handleCancel: () => void;
};
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
| <CaseLink | ||
| type="button" | ||
| color={!canViewcase && '#000'} | ||
| permission={!canViewcase && 'none'} | ||
| color={canViewcase ? null : '#000'} | ||
| permission={canViewcase ? 'permitted' : 'denied'} |
| "TaskListItem-Voicemail-SecondLine": "Voicemail from queue {{queue}} (status)", | ||
| "TaskListItem-Voicemail-SecondLine/pending": "Incoming voicemail from queue {{queue}}", | ||
| "IncomingTaskCanvas-Voicemail-SecondLine": "Queue {{queue}}" |
| export const lookupTranslation = (code: string | string[], parameters: Record<string, string> = {}): string => { | ||
| const strings = getTemplateStrings(); | ||
| return Handlebars.compile(strings[code] ?? code)(parameters); | ||
| const codes = typeof code === 'string' ? [code] : code; | ||
| for (const code of codes) { | ||
| if (strings[code]) { | ||
| return Handlebars.compile(strings[code])(parameters); | ||
| } | ||
| } | ||
| return codes[0]; |
There was a problem hiding this comment.
This change returns the first code that exists in strings, right? The idea is to pass an array of codes then? How would that be used?
There was a problem hiding this comment.
It means you can pass a fallback key if the first one doesn't exist. It's for dynamic key cases mostly
For example, you could have a generic message for a task list item
"TaskListItem-Voicemail-Secondline"
but then want to override it for a specific status
"TaskListItem-Voicemail-Secondline/pending"
but you don't want to override all the statuses. In this case, you could set the 2 keys above, and then for the translation lookup provide [`TaskListItem-Voicemail-Secondline/${task.status}`, "TaskListItem-Voicemail-Secondline"] as the key
Then all the other statuses would use "TaskListItem-Voicemail-Secondline" whereas pending would use "TaskListItem-Voicemail-Secondline/pending". You could even only override certain statuses for specific helplines if you want
It's demonstrated how it works in the unit tests but sorry, yes should have talked you through it
| } | ||
|
|
||
| const { receivedTime, from, maxCallbackAttempts } = task.attributes; | ||
| const callbackAttempts = task.attributes.callbackAttempts ?? []; |
There was a problem hiding this comment.
I was not using this task.attributes.callbackAttempts in my PRs chain, so is something I will have to fix once this is merged. I'm happy to do so, just so you know that things won't immediately after PRs are merged.
What should we record in the task.attributes.callbackAttempts by the way? I mean what propery, a task sid?
There was a problem hiding this comment.
I only look for the timestamp, but a task SID would be good too, yes
There was a problem hiding this comment.
I was planning to update your PR after you merged it but if you could that would be great
Description
Checklist
Other Related Issues
None
Verification steps
AFTER YOU MERGE
You are responsible for ensuring the above steps are completed. If you move a ticket into QA without advising what version to test, the QA team will assume the latest tag has the changes. If it does not, the following confusion is on you! :-P