Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
250 changes: 118 additions & 132 deletions plugin-hrm-form/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion plugin-hrm-form/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
"@testing-library/user-event": "^14.1.1",
"@twilio/flex-plugin": "^7.1.0",
"@twilio/flex-plugin-scripts": "^7.1.0",
"@twilio/flex-ui": "2.13.3",
"@twilio/flex-ui": "2.16.0",
"@twilio/flex-ui-dev-proxy": "^1.1.2",
"@types/jest": "^27.5.2",
"@types/react": "^17.0.47",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,6 @@ describe('Working copy reducers', () => {
cases: {
1: {
...initialState.cases[1],
lastReferencedDate: expect.any(Date),
caseWorkingCopy: {
...initialState.cases[1].caseWorkingCopy,
caseSummary: {
Expand Down Expand Up @@ -640,7 +639,10 @@ describe('Working copy reducers', () => {
};

const removeResult = reduce({ ...stubRootState, connectedCase: initialState }, removeCaseSummaryWorkingCopy('1'));
expect(removeResult).toStrictEqual({ ...stubRootState, connectedCase: expectedResult });
expect(removeResult).toStrictEqual({
...stubRootState,
connectedCase: expectedResult,
});
delete initialState.cases[1].caseWorkingCopy.caseSummary;

const noopResult = reduce({ ...stubRootState, connectedCase: initialState }, removeCaseSummaryWorkingCopy('1'));
Expand Down
21 changes: 6 additions & 15 deletions plugin-hrm-form/src/___tests__/translations/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,22 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/

import { Manager } from '@twilio/flex-ui';

import { loadTranslations, initLocalization, lookupTranslation } from '../../translations';

jest.mock('../../translations/en.json', () => ({}), { virtual: true });
jest.mock('../../translations/en-US.json', () => ({}), { virtual: true });
jest.mock('../../translations/en-GB.json', () => ({}), { virtual: true });

jest.mock('@twilio/flex-ui', () => ({
Manager: {
getInstance: jest.fn(),
},
}));

const mockGetAseloFeatureFlags = jest.fn();
const mockGetHrmConfig = jest.fn();
const mockGetDefinitionVersions = jest.fn();
const mockGetTemplateStrings = jest.fn();

jest.mock('../../hrmConfig', () => ({
getAseloFeatureFlags: () => mockGetAseloFeatureFlags(),
getHrmConfig: () => mockGetHrmConfig(),
getDefinitionVersions: () => mockGetDefinitionVersions(),
getTemplateStrings: () => mockGetTemplateStrings(),
}));

describe('Hierarchical Translations', () => {
Expand Down Expand Up @@ -169,29 +162,27 @@ describe('Hierarchical Translations', () => {
});

describe('lookupTranslation', () => {
const mockManagerGetInstance = Manager.getInstance as jest.MockedFunction<typeof Manager.getInstance>;

afterEach(() => {
jest.clearAllMocks();
});

test('returns compiled string for a key that exists in Manager strings', () => {
mockManagerGetInstance.mockReturnValue({ strings: { MyKey: 'Hello World' } } as any);
mockGetTemplateStrings.mockReturnValue({ MyKey: 'Hello World' });
expect(lookupTranslation('MyKey')).toBe('Hello World');
});

test('falls back to using the code itself as template when key does not exist in Manager strings', () => {
mockManagerGetInstance.mockReturnValue({ strings: {} } as any);
mockGetTemplateStrings.mockReturnValue({});
expect(lookupTranslation('FallbackKey')).toBe('FallbackKey');
});

test('passes parameters to the Handlebars template', () => {
mockManagerGetInstance.mockReturnValue({ strings: { Greeting: 'Hello {{name}}!' } } as any);
mockGetTemplateStrings.mockReturnValue({ Greeting: 'Hello {{name}}!' });
expect(lookupTranslation('Greeting', { name: 'World' })).toBe('Hello World!');
});

test('uses empty parameters object by default', () => {
mockManagerGetInstance.mockReturnValue({ strings: { SimpleMsg: 'No params here' } } as any);
mockGetTemplateStrings.mockReturnValue({ SimpleMsg: 'No params here' });
expect(lookupTranslation('SimpleMsg')).toBe('No params here');
});
});
5 changes: 3 additions & 2 deletions plugin-hrm-form/src/components/caseList/CaseListTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { useDispatch, useSelector } from 'react-redux';
import { Template } from '@twilio/flex-ui';
import InfoIcon from '@material-ui/icons/Info';

import { lookupTranslation } from '../../translations';
import { DataCell, DataTableRow, LoadingCell, StandardTable, TableContainer } from '../../styles';
import Filters from './filters/Filters';
import CaseListTableHead from './CaseListTableHead';
Expand Down Expand Up @@ -57,7 +58,7 @@ const CaseListTable: React.FC<OwnProps> = ({ loading, caseList, caseCount, handl
}, []);

const pagesCount = Math.ceil(caseCount / CASES_PER_PAGE);

const spinnerTitle = lookupTranslation('CaseList-LoadingPlaceholder-ProgressBarTitle');
return (
<>
<Filters caseCount={caseCount} currentDefinitionVersion={currentDefinitionVersion} />
Expand All @@ -75,7 +76,7 @@ const CaseListTable: React.FC<OwnProps> = ({ loading, caseList, caseCount, handl
}}
>
<LoadingCell>
<CircularProgress size={50} />
<CircularProgress title={spinnerTitle} aria-label={spinnerTitle} size={50} />
</LoadingCell>
</DataTableRow>
</TableBody>
Expand Down
3 changes: 2 additions & 1 deletion plugin-hrm-form/src/components/teamsView/teamsViewFilters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,9 @@ const generateFilterDefinitionFactoryForInputExpression = ({
}): FilterDefinitionFactory => (state, teamsViewProps) => {
const values = state.flex.supervisor.appliedFilters.find(af => af.name === id)?.values ?? [];
const selections = Array.isArray(values) ? values : [values];
const selectionStrings = (selections as string[]).filter(s => typeof s === 'string');
if (selections.length) {
filterInputExpressionStrings[id] = queryGenerator(selections);
filterInputExpressionStrings[id] = queryGenerator(selectionStrings);
} else {
// Assume nothing is selected if no values are set in the state, therefore we don't apply any filtering for this filter
delete filterInputExpressionStrings[id];
Expand Down
1 change: 1 addition & 0 deletions plugin-hrm-form/src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@
"CaseList-Filters-DateFilterOptions-NextXDays": "Next {{days}} days",
"CaseList-Filters-DateFilterOptions-WithoutDate": "No {{labelKey}}",
"CaseList-Filters-DateFilterOptions-CustomRange": "Custom",
"CaseList-LoadingPlaceholder-ProgressBarTitle": "Loading Cases",
"ContactPreview-CopyButton": "Copy information",
"ContactPreview-ExpandButton": "Open case details",
"ContactPreview-MoreOptionsButton": "More options",
Expand Down
6 changes: 2 additions & 4 deletions plugin-hrm-form/src/translations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
import Handlebars from 'handlebars';
import { Manager } from '@twilio/flex-ui';

import { getDefinitionVersions } from '../hrmConfig';
import { getDefinitionVersions, getTemplateStrings } from '../hrmConfig';

// default language to initialize plugin
export const defaultLocale = 'en-US';
Expand Down Expand Up @@ -122,6 +121,5 @@ export const initLocalization = (localizationConfig: LocalizationConfig, helplin
};

export const lookupTranslation = (code: string, parameters: Record<string, string> = {}): string => {
const { strings } = Manager.getInstance();
return Handlebars.compile(strings[code] ?? code)(parameters);
return Handlebars.compile(getTemplateStrings()[code] ?? code)(parameters);
};
Loading