Skip to content

CHI-3945: UI update for voicemails, translation key name change, couple of minor fixes - #4627

Open
stephenhand wants to merge 10 commits into
masterfrom
CHI-3945-voicemail_ui_polish
Open

CHI-3945: UI update for voicemails, translation key name change, couple of minor fixes#4627
stephenhand wants to merge 10 commits into
masterfrom
CHI-3945-voicemail_ui_polish

Conversation

@stephenhand

Copy link
Copy Markdown
Collaborator

Description

  • Update Voicemail UI as specified in ticket
  • Rename a translation key to fit with our 3 part convention
  • Fix voicemail channel type display
  • Add fallbacks to lookupTranslation function
  • Fix issue that causes startup console error in ContactAddedToCaseBanner

Checklist

  • Corresponding issue has been opened
  • New tests added
  • Feature flags added
  • Strings are localized
  • Tested for chat contacts
  • Tested for call contacts

Other Related Issues

None

Verification steps

AFTER YOU MERGE

  1. Cut a release tag using the Github workflow. Wait for it to complete and notify in the #aselo-deploys Slack channel.
  2. Comment on the ticket with the release tag version AND any additional instructions required to configure an environment to test the changes.
  3. Only then move the ticket into the QA column in JIRA

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

@stephenhand

Copy link
Copy Markdown
Collaborator Author

@copilot - add unit test cases for scenarios when multiple keys are specified in the lookupTranslation method

stephenhand and others added 2 commits August 20, 2026 17:26
…x fallback bug

Co-authored-by: stephenhand <1694716+stephenhand@users.noreply.github.com>

Copilot AI commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

@copilot - add unit test cases for scenarios when multiple keys are specified in the lookupTranslation method

Added unit tests for the multiple keys scenarios in a new describe('multiple keys', ...) block covering:

  • First matching key is returned when multiple keys exist in template strings
  • Falls back to subsequent keys when the first is missing
  • Returns the first key (fallback) when none of the keys exist
  • Parameters are passed correctly to the Handlebars template
  • Single-element array works correctly
  • Multi-element array fallback to first element

Also fixed a related bug: code[0]codes[0] in the fallback return — when a plain string was passed and not found, code[0] was returning the first character of the string rather than the key itself.

@stephenhand
stephenhand marked this pull request as ready for review August 20, 2026 17:00
@stephenhand
stephenhand requested review from gpaoloni and a lite review from Copilot August 20, 2026 17:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 voicemail task 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 return undefined; destructuring const [, 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 removed isCallTask prop (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.

Comment on lines 94 to +97
<CaseLink
type="button"
color={!canViewcase && '#000'}
permission={!canViewcase && 'none'}
color={canViewcase ? null : '#000'}
permission={canViewcase ? 'permitted' : 'denied'}
Comment on lines +683 to +685
"TaskListItem-Voicemail-SecondLine": "Voicemail from queue {{queue}} (status)",
"TaskListItem-Voicemail-SecondLine/pending": "Incoming voicemail from queue {{queue}}",
"IncomingTaskCanvas-Voicemail-SecondLine": "Queue {{queue}}"

@gpaoloni gpaoloni left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! 🚀

Comment thread plugin-hrm-form/src/components/callTypeButtons/CallTypeButtons.tsx
Comment on lines +123 to +131
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];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ?? [];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only look for the timestamp, but a task SID would be good too, yes

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was planning to update your PR after you merged it but if you could that would be great

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants