Skip to content

Commit c3b28d7

Browse files
vivekdomadiyaVivek Domadiya
andauthored
feat: add optional translation support for card labels and titles (#4079)
* feat: add optional translation support for card labels and titles * chore: updated snapshot for publicAPI test * chore: include yarn.lock in react build artifacts for test app and build * chore: correct yarn.lock path in react build artifacts --------- Co-authored-by: Vivek Domadiya <Vivek.Domadiya@ibm.com>
1 parent 6637669 commit c3b28d7

16 files changed

Lines changed: 126 additions & 11 deletions

File tree

.github/workflows/test-app.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jobs:
5353
cd packages/react
5454
yarn build
5555
mkdir -p dist
56-
cp -rf package.json umd scss lib es css ./dist
56+
cp -rf package.json ../../yarn.lock umd scss lib es css ./dist
5757
5858
- name: Archive build artifacts
5959
if: ${{ success() }} && steps.changes.outputs.react == 'true'

packages/react/src/components/Card/Card.jsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ import {
2121
} from '../../constants/LayoutConstants';
2222
import { CardPropTypes } from '../../constants/CardPropTypes';
2323
import { getCardMinSize, filterValidAttributes } from '../../utils/componentUtilityFunctions';
24-
import { getUpdatedCardSize, useCardResizing } from '../../utils/cardUtilityFunctions';
24+
import {
25+
getUpdatedCardSize,
26+
useCardResizing,
27+
getTranslatedLabel,
28+
} from '../../utils/cardUtilityFunctions';
2529
import { parseValue } from '../DateTimePicker/dateTimePickerUtils';
2630
import useSizeObserver from '../../hooks/useSizeObserver';
2731
import EmptyState from '../EmptyState/EmptyState';
@@ -273,14 +277,15 @@ export const defaultProps = {
273277
type: null,
274278
data: null,
275279
content: null,
280+
shouldUseTranslatedLabels: false,
276281
};
277282

278283
/** Dumb component that renders the card basics */
279284
const Card = (props) => {
280285
const {
281286
size,
282287
children,
283-
title,
288+
title: titleProp,
284289
subtitle: subtitleProp,
285290
hasTitleWrap,
286291
layout,
@@ -320,9 +325,13 @@ const Card = (props) => {
320325
type,
321326
data,
322327
content,
328+
shouldUseTranslatedLabels,
323329
...others
324330
} = props;
325331

332+
// Get translated title if shouldUseTranslatedLabels is true
333+
const title = getTranslatedLabel(titleProp, shouldUseTranslatedLabels, i18n);
334+
326335
// TODO: remove once final version of range prop is supported
327336
useEffect(() => {
328337
if (__DEV__ && typeof availableActions?.range === 'string') {

packages/react/src/components/CardEditor/CardEditForm/CardEditForm.jsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ const propTypes = {
4949
modalHelpText: PropTypes.string,
5050
modalIconDescription: PropTypes.string,
5151
}),
52+
/** whether to use translated labels in cards */
53+
shouldUseTranslatedLabels: PropTypes.bool,
5254
/** if provided, returns an array of strings which are the dataItems to be allowed
5355
* on each card
5456
* getValidDataItems(card, selectedTimeRange)
@@ -112,6 +114,7 @@ const defaultProps = {
112114
'The JSON definition for this card is provided below. You can modify this data directly to update the card configuration.',
113115
modalIconDescription: 'Close',
114116
},
117+
shouldUseTranslatedLabels: false,
115118
getValidDataItems: null,
116119
getValidTimeRanges: null,
117120
dataItems: [],
@@ -154,6 +157,7 @@ const CardEditForm = ({
154157
dataSeriesItemLinks,
155158
// eslint-disable-next-line react/prop-types
156159
onFetchDynamicDemoHotspots,
160+
shouldUseTranslatedLabels,
157161
actions,
158162
}) => {
159163
const mergedI18n = useMemo(() => ({ ...defaultProps.i18n, ...i18n }), [i18n]);
@@ -173,6 +177,7 @@ const CardEditForm = ({
173177
onChange={onChange}
174178
isSummaryDashboard={isSummaryDashboard}
175179
i18n={mergedI18n}
180+
shouldUseTranslatedLabels={shouldUseTranslatedLabels}
176181
dataItems={dataItems}
177182
availableDimensions={availableDimensions}
178183
getValidDataItems={getValidDataItems}

packages/react/src/components/CardEditor/CardEditForm/CardEditFormContent.jsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ const propTypes = {
8282
thisQuarterLabel: PropTypes.string,
8383
thisYearLabel: PropTypes.string,
8484
}),
85+
/** whether to use translated labels in cards */
86+
shouldUseTranslatedLabels: PropTypes.bool,
8587
/** if provided, returns an array of strings which are the timeRanges to be allowed
8688
* on each card
8789
* getValidTimeRanges(card, selectedDataItems)
@@ -119,6 +121,7 @@ const propTypes = {
119121
const defaultProps = {
120122
cardConfig: {},
121123
i18n: {},
124+
shouldUseTranslatedLabels: false,
122125
getValidDataItems: null,
123126
getValidTimeRanges: null,
124127
dataItems: [],
@@ -155,6 +158,7 @@ const CardEditFormContent = ({
155158
isSummaryDashboard,
156159
onChange,
157160
i18n,
161+
shouldUseTranslatedLabels,
158162
dataItems,
159163
getValidDataItems,
160164
getValidTimeRanges,
@@ -183,6 +187,7 @@ const CardEditFormContent = ({
183187
key={`${cardConfig.id}-common`} // fix because I need to regenerate the form state when switching between cards
184188
onChange={onChange}
185189
i18n={mergedI18n}
190+
shouldUseTranslatedLabels={shouldUseTranslatedLabels}
186191
getValidTimeRanges={getValidTimeRanges}
187192
currentBreakpoint={currentBreakpoint}
188193
selectedDataItems={selectedDataItems}
@@ -236,6 +241,7 @@ const CardEditFormContent = ({
236241
getValidDataItems={getValidDataItems}
237242
availableDimensions={availableDimensions}
238243
i18n={mergedI18n}
244+
shouldUseTranslatedLabels={shouldUseTranslatedLabels}
239245
dataSeriesItemLinks={dataSeriesItemLinks}
240246
translateWithId={handleTranslation}
241247
actions={actions}

packages/react/src/components/CardEditor/CardEditForm/CardEditFormItems/DataSeriesFormItemModal.jsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
import ColorDropdown from '../../../ColorDropdown/ColorDropdown';
3232
import { BAR_CHART_TYPES, CARD_TYPES } from '../../../../constants/LayoutConstants';
3333
import Button from '../../../Button';
34+
import { getTranslatedLabel } from '../../../../utils/cardUtilityFunctions';
3435

3536
import ThresholdsFormItem from './ThresholdsFormItem';
3637

@@ -144,6 +145,8 @@ const propTypes = {
144145
primaryButtonLabelText: PropTypes.string,
145146
secondaryButtonLabelText: PropTypes.string,
146147
}),
148+
/** whether to use translated labels in cards */
149+
shouldUseTranslatedLabels: PropTypes.bool,
147150
actions: DashboardEditorActionsPropTypes,
148151
/**
149152
* Used to override the default behaviour of handleDataItemEdit. if we dont pass any function then it uses handleDefaultDataItemEdit function by default
@@ -198,6 +201,7 @@ const defaultProps = {
198201
secondaryButtonLabelText: 'Cancel',
199202
decimalPlacesLabel: 'Decimal places',
200203
},
204+
shouldUseTranslatedLabels: false,
201205
editDataSeries: [],
202206
showEditor: false,
203207
setShowEditor: null,
@@ -256,6 +260,7 @@ const DataSeriesFormItemModal = ({
256260
availableDimensions,
257261
onChange,
258262
i18n,
263+
shouldUseTranslatedLabels,
259264
isLarge,
260265
testId,
261266
actions: {
@@ -441,7 +446,7 @@ const DataSeriesFormItemModal = ({
441446
label: evt.target.value,
442447
})
443448
}
444-
value={editDataItem.label}
449+
value={getTranslatedLabel(editDataItem.label, shouldUseTranslatedLabels, i18n)}
445450
helperText={mergedI18n.dataItemEditorDataItemHelperText(
446451
mergedI18n.dataItemSource,
447452
editDataItem.dataItemId
@@ -637,6 +642,7 @@ const DataSeriesFormItemModal = ({
637642
hasThresholds,
638643
hasTooltip,
639644
hasUnit,
645+
i18n,
640646
id,
641647
initialAggregation,
642648
initialGrain,
@@ -646,6 +652,7 @@ const DataSeriesFormItemModal = ({
646652
onAddAggregations,
647653
selectedDimensionFilter,
648654
setEditDataItem,
655+
shouldUseTranslatedLabels,
649656
testId,
650657
type,
651658
]

packages/react/src/components/CardEditor/CardEditForm/CardEditFormItems/DataSeriesFormItems/DataSeriesFormContent.jsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { Dropdown } from '../../../../Dropdown';
1919
import DataSeriesFormItemModal from '../DataSeriesFormItemModal';
2020
import { CARD_TYPES, BAR_CHART_TYPES } from '../../../../../constants/LayoutConstants';
2121
import ContentFormItemTitle from '../ContentFormItemTitle';
22+
import { getTranslatedLabel } from '../../../../../utils/cardUtilityFunctions';
2223

2324
import BarChartDataSeriesContent from './BarChartDataSeriesContent';
2425

@@ -111,6 +112,8 @@ const propTypes = {
111112
incrementNumberText: PropTypes.string,
112113
decrementNumberText: PropTypes.string,
113114
}),
115+
/** whether to use translated labels in cards */
116+
shouldUseTranslatedLabels: PropTypes.bool,
114117
translateWithId: PropTypes.func.isRequired,
115118
actions: DashboardEditorActionsPropTypes,
116119
};
@@ -150,6 +153,7 @@ const defaultProps = {
150153
incrementNumberText: 'Increment number',
151154
decrementNumberText: 'Decrement number',
152155
},
156+
shouldUseTranslatedLabels: false,
153157
getValidDataItems: null,
154158
dataItems: [],
155159
selectedDataItems: [],
@@ -262,6 +266,7 @@ const DataSeriesFormItem = ({
262266
selectedTimeRange,
263267
availableDimensions,
264268
i18n,
269+
shouldUseTranslatedLabels,
265270
dataSeriesItemLinks,
266271
translateWithId,
267272
actions,
@@ -404,7 +409,11 @@ const DataSeriesFormItem = ({
404409
return {
405410
id: dataItem.dataSourceId,
406411
content: {
407-
value: dataItem.label || dataItem.dataItemId,
412+
value: getTranslatedLabel(
413+
dataItem.label || dataItem.dataItemId,
414+
shouldUseTranslatedLabels,
415+
i18n
416+
),
408417
icon:
409418
cardConfig.type === CARD_TYPES.TIMESERIES || cardConfig.type === CARD_TYPES.BAR ? (
410419
<div
@@ -446,8 +455,10 @@ const DataSeriesFormItem = ({
446455
dataSection,
447456
handleEditButton,
448457
handleRemoveButton,
458+
i18n,
449459
mergedI18n.edit,
450460
mergedI18n.remove,
461+
shouldUseTranslatedLabels,
451462
]
452463
);
453464

@@ -467,6 +478,7 @@ const DataSeriesFormItem = ({
467478
dataSection={dataSection}
468479
onChange={onChange}
469480
i18n={mergedI18n}
481+
shouldUseTranslatedLabels={shouldUseTranslatedLabels}
470482
actions={actions}
471483
options={{
472484
hasColorDropdown: type === CARD_TYPES.TIMESERIES || type === CARD_TYPES.BAR,

packages/react/src/components/CardEditor/CardEditForm/CommonCardEditFormFields.jsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { TextArea } from '../../TextArea';
1212
import { TextInput } from '../../TextInput';
1313
import { Dropdown } from '../../Dropdown';
1414
import { timeRangeToJSON } from '../../DashboardEditor/editorUtils';
15+
import { getTranslatedLabel } from '../../../utils/cardUtilityFunctions';
1516

1617
const { iotPrefix } = settings;
1718

@@ -76,6 +77,8 @@ const propTypes = {
7677
thisQuarterLabel: PropTypes.string,
7778
thisYearLabel: PropTypes.string,
7879
}),
80+
/** whether to use translated labels in cards */
81+
shouldUseTranslatedLabels: PropTypes.bool,
7982
/** if provided, returns an array of strings which are the timeRanges to be allowed
8083
* on each card
8184
* getValidTimeRanges(card, selectedDataItems)
@@ -110,6 +113,7 @@ const defaultProps = {
110113
thisQuarterLabel: 'This quarter',
111114
thisYearLabel: 'This year',
112115
},
116+
shouldUseTranslatedLabels: false,
113117
selectedDataItems: [],
114118
getValidTimeRanges: null,
115119
currentBreakpoint: 'xl',
@@ -144,6 +148,7 @@ const CommonCardEditFormFields = ({
144148
cardConfig,
145149
onChange,
146150
i18n,
151+
shouldUseTranslatedLabels,
147152
getValidTimeRanges,
148153
currentBreakpoint,
149154
selectedDataItems,
@@ -172,7 +177,7 @@ const CommonCardEditFormFields = ({
172177
labelText={mergedI18n.cardTitle}
173178
light
174179
onChange={(evt) => onChange({ ...cardConfig, title: evt.target.value })}
175-
value={title}
180+
value={getTranslatedLabel(title, shouldUseTranslatedLabels, mergedI18n)}
176181
/>
177182
</div>
178183
<div className={`${baseClassName}--input`}>

packages/react/src/components/CardEditor/CardEditor.jsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ const propTypes = {
128128
searchPlaceHolderText: PropTypes.string,
129129
editDataItems: PropTypes.string,
130130
}),
131+
/** whether to use translated labels in cards */
132+
shouldUseTranslatedLabels: PropTypes.bool,
131133
currentBreakpoint: PropTypes.string,
132134
isSummaryDashboard: PropTypes.bool,
133135
/** Id that can be used for testing */
@@ -163,6 +165,7 @@ const defaultProps = {
163165
'The JSON definition for this card is provided below. You can modify this data directly to update the card configuration.',
164166
modalIconDescription: 'Close',
165167
},
168+
shouldUseTranslatedLabels: false,
166169
getValidDimensions: null,
167170
getValidDataItems: null,
168171
getValidTimeRanges: null,
@@ -308,6 +311,7 @@ const CardEditor = ({
308311
onRenderCardEditForm,
309312
icons,
310313
i18n,
314+
shouldUseTranslatedLabels,
311315
currentBreakpoint,
312316
testId,
313317
dataSeriesItemLinks,
@@ -398,6 +402,7 @@ const CardEditor = ({
398402
getValidTimeRanges={getValidTimeRanges}
399403
availableDimensions={availableDimensions}
400404
i18n={mergedI18n}
405+
shouldUseTranslatedLabels={shouldUseTranslatedLabels}
401406
currentBreakpoint={currentBreakpoint}
402407
dataSeriesItemLinks={dataSeriesItemLinks}
403408
onFetchDynamicDemoHotspots={onFetchDynamicDemoHotspots}

packages/react/src/components/DashboardEditor/DashboardEditor.jsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { DASHBOARD_EDITOR_CARD_TYPES, CARD_TYPES } from '../../constants/LayoutC
99
import DashboardGrid from '../Dashboard/DashboardGrid';
1010
import CardEditor from '../CardEditor/CardEditor';
1111
import ImageGalleryModal, { ImagePropTypes } from '../ImageGalleryModal/ImageGalleryModal';
12+
import { getTranslatedLabel } from '../../utils/cardUtilityFunctions';
1213

1314
import DashboardEditorHeader from './DashboardEditorHeader/DashboardEditorHeader';
1415
import DashboardEditorCardRenderer from './DashboardEditorCardRenderer';
@@ -295,6 +296,8 @@ const propTypes = {
295296

296297
editDataItems: PropTypes.string,
297298
}),
299+
/** whether to use translated labels in cards */
300+
shouldUseTranslatedLabels: PropTypes.bool,
298301
/** locale data */
299302
locale: PropTypes.string,
300303
/** optional link href's for each card type that will appear in a tooltip */
@@ -384,6 +387,7 @@ const defaultProps = {
384387
saveTitleButton: 'Save title',
385388
editDataItems: 'Edit data items',
386389
},
390+
shouldUseTranslatedLabels: false,
387391
locale: 'en',
388392
dataSeriesItemLinks: null,
389393
onFetchDynamicDemoHotspots: () => Promise.resolve([{ x: 50, y: 50, type: 'fixed' }]),
@@ -443,6 +447,7 @@ const DashboardEditor = ({
443447
isSummaryDashboard,
444448
isLoading,
445449
i18n,
450+
shouldUseTranslatedLabels,
446451
locale,
447452
dataSeriesItemLinks,
448453
isTitleEditable,
@@ -705,7 +710,9 @@ const DashboardEditor = ({
705710
renderHeader()
706711
) : (
707712
<DashboardEditorHeader
708-
title={dashboardJson?.title || title}
713+
title={
714+
getTranslatedLabel(dashboardJson?.title, shouldUseTranslatedLabels, i18n) || title
715+
}
709716
breadcrumbs={headerBreadcrumbs}
710717
onImport={onImport}
711718
onExport={() => onExport(dashboardJson, imagesToUpload)}
@@ -808,6 +815,7 @@ const DashboardEditor = ({
808815
key={cardConfig.id}
809816
isResizable={isCardResizable}
810817
i18n={mergedI18n}
818+
shouldUseTranslatedLabels={shouldUseTranslatedLabels}
811819
isSelected={isSelected}
812820
availableDimensions={availableDimensions}
813821
onFetchDynamicDemoHotspots={onFetchDynamicDemoHotspots}
@@ -858,6 +866,7 @@ const DashboardEditor = ({
858866
getValidDimensions={getValidDimensions}
859867
availableDimensions={availableDimensions}
860868
i18n={mergedI18n}
869+
shouldUseTranslatedLabels={shouldUseTranslatedLabels}
861870
currentBreakpoint={currentBreakpoint}
862871
dataSeriesItemLinks={dataSeriesItemLinks}
863872
onFetchDynamicDemoHotspots={onFetchDynamicDemoHotspots}

0 commit comments

Comments
 (0)