forked from elastic/kibana
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Canvas][i18n] Elements (elastic#27904)
* [Canvas][i18n] Elements * Addressing feedback; using global i18n * Fixing unit test to reflect globals * Making i18n more flexible * Switching to a Provider strategy for i18n
- Loading branch information
1 parent
6cefed9
commit fa475e2
Showing
10 changed files
with
400 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
x-pack/plugins/canvas/canvas_plugin_src/strings/apply_strings.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { ElementFactory } from '../elements/types'; | ||
import { getElementStrings } from './index'; | ||
|
||
/** | ||
* This function takes a set of Canvas Element specification factories, runs them, | ||
* replaces relevant strings (if available) and returns a new factory. We do this | ||
* so the specifications themselves have no dependency on i18n, for clarity for both | ||
* our and external plugin developers. | ||
*/ | ||
export const applyElementStrings = (elements: ElementFactory[]) => { | ||
const elementStrings = getElementStrings(); | ||
|
||
return elements.map(spec => { | ||
const result = spec(); | ||
const { name } = result; | ||
const strings = elementStrings[name]; | ||
|
||
// If we have registered strings for this spec, we should replace any that are available. | ||
if (strings) { | ||
const { displayName, help } = strings; | ||
// If the function has a registered help string, replace it on the spec. | ||
if (help) { | ||
result.help = help; | ||
} | ||
|
||
if (displayName) { | ||
result.displayName = displayName; | ||
} | ||
} | ||
|
||
return () => result; | ||
}); | ||
}; |
43 changes: 43 additions & 0 deletions
43
x-pack/plugins/canvas/canvas_plugin_src/strings/element_strings.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { i18nProvider } from './i18n_provider'; | ||
i18nProvider.init(); | ||
|
||
import { getElementStrings } from '.'; | ||
import { elementSpecs } from '../elements'; | ||
|
||
beforeAll(() => { | ||
i18nProvider.init(); | ||
}); | ||
|
||
describe('ElementStrings', () => { | ||
const elementStrings = getElementStrings(); | ||
const elementNames = elementSpecs.map(spec => spec().name); | ||
const stringKeys = Object.keys(elementStrings); | ||
|
||
test('All element names should exist in the strings definition', () => { | ||
elementNames.forEach(name => expect(stringKeys).toContain(name)); | ||
}); | ||
|
||
test('All string definitions should correspond to an existing element', () => { | ||
stringKeys.forEach(key => expect(elementNames).toContain(key)); | ||
}); | ||
|
||
const strings = Object.values(elementStrings); | ||
|
||
test('All elements should have a displayName string defined', () => { | ||
strings.forEach(value => { | ||
expect(value).toHaveProperty('displayName'); | ||
}); | ||
}); | ||
|
||
test('All elements should have a help string defined', () => { | ||
strings.forEach(value => { | ||
expect(value).toHaveProperty('help'); | ||
}); | ||
}); | ||
}); |
236 changes: 236 additions & 0 deletions
236
x-pack/plugins/canvas/canvas_plugin_src/strings/element_strings.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,236 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { i18nProvider } from './i18n_provider'; | ||
|
||
interface ElementStrings { | ||
displayName: string; | ||
help: string; | ||
} | ||
|
||
interface ElementStringDict { | ||
[elementName: string]: ElementStrings; | ||
} | ||
|
||
/** | ||
* This function will return a dictionary of strings, organized by Canvas | ||
* Element specification. This function requires that `i18nProvider` be | ||
* properly initialized. | ||
*/ | ||
export const getElementStrings = (): ElementStringDict => { | ||
const i18n = i18nProvider.getInstance(); | ||
|
||
return { | ||
areaChart: { | ||
displayName: i18n.translate('xpack.canvas.elements.areaChartDisplayName', { | ||
defaultMessage: 'Area chart', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.areaChartHelpText', { | ||
defaultMessage: 'A line chart with a filled body', | ||
}), | ||
}, | ||
bubbleChart: { | ||
displayName: i18n.translate('xpack.canvas.elements.bubbleChartDisplayName', { | ||
defaultMessage: 'Bubble chart', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.bubbleChartHelpText', { | ||
defaultMessage: 'A customizable bubble chart', | ||
}), | ||
}, | ||
debug: { | ||
displayName: i18n.translate('xpack.canvas.elements.debugDisplayName', { | ||
defaultMessage: 'Debug', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.debugHelpText', { | ||
defaultMessage: 'Just dumps the configuration of the element', | ||
}), | ||
}, | ||
donut: { | ||
displayName: i18n.translate('xpack.canvas.elements.donutChartDisplayName', { | ||
defaultMessage: 'Donut chart', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.donutChartHelpText', { | ||
defaultMessage: 'A customizable donut chart', | ||
}), | ||
}, | ||
dropdown_filter: { | ||
displayName: i18n.translate('xpack.canvas.elements.dropdownFilterDisplayName', { | ||
defaultMessage: 'Dropdown Filter', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.dropdownFilterHelpText', { | ||
defaultMessage: 'A dropdown from which you can select values for an "exactly" filter', | ||
}), | ||
}, | ||
horizontalBarChart: { | ||
displayName: i18n.translate('xpack.canvas.elements.horizontalBarChartDisplayName', { | ||
defaultMessage: 'Horizontal Bar chart', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.horizontalBarChartHelpText', { | ||
defaultMessage: 'A customizable horizontal bar chart', | ||
}), | ||
}, | ||
horizontalProgressBar: { | ||
displayName: i18n.translate('xpack.canvas.elements.horizontalProgressBarDisplayName', { | ||
defaultMessage: 'Horizontal Progress Bar', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.horizontalProgressBarHelpText', { | ||
defaultMessage: 'Displays progress as a portion of a horizontal bar', | ||
}), | ||
}, | ||
horizontalProgressPill: { | ||
displayName: i18n.translate('xpack.canvas.elements.horizontalProgressPillDisplayName', { | ||
defaultMessage: 'Horizontal Progress Pill', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.horizontalProgressPillHelpText', { | ||
defaultMessage: 'Displays progress as a portion of a horizontal pill', | ||
}), | ||
}, | ||
image: { | ||
displayName: i18n.translate('xpack.canvas.elements.imageDisplayName', { | ||
defaultMessage: 'Image', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.imageHelpText', { | ||
defaultMessage: 'A static image', | ||
}), | ||
}, | ||
lineChart: { | ||
displayName: i18n.translate('xpack.canvas.elements.lineChartDisplayName', { | ||
defaultMessage: 'Line chart', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.lineChartHelpText', { | ||
defaultMessage: 'A customizable line chart', | ||
}), | ||
}, | ||
markdown: { | ||
displayName: i18n.translate('xpack.canvas.elements.markdownDisplayName', { | ||
defaultMessage: 'Markdown', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.markdownHelpText', { | ||
defaultMessage: 'Markup from Markdown', | ||
}), | ||
}, | ||
metric: { | ||
displayName: i18n.translate('xpack.canvas.elements.metricDisplayName', { | ||
defaultMessage: 'Metric', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.metricHelpText', { | ||
defaultMessage: 'A number with a label', | ||
}), | ||
}, | ||
pie: { | ||
displayName: i18n.translate('xpack.canvas.elements.pieDisplayName', { | ||
defaultMessage: 'Pie chart', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.pieHelpText', { | ||
defaultMessage: 'Pie chart', | ||
}), | ||
}, | ||
plot: { | ||
displayName: i18n.translate('xpack.canvas.elements.plotDisplayName', { | ||
defaultMessage: 'Coordinate plot', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.plotHelpText', { | ||
defaultMessage: 'Mixed line, bar or dot charts', | ||
}), | ||
}, | ||
progressGauge: { | ||
displayName: i18n.translate('xpack.canvas.elements.progressGaugeDisplayName', { | ||
defaultMessage: 'Progress Gauge', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.progressGaugeHelpText', { | ||
defaultMessage: 'Displays progress as a portion of a gauge', | ||
}), | ||
}, | ||
progressSemicircle: { | ||
displayName: i18n.translate('xpack.canvas.elements.progressSemicircleDisplayName', { | ||
defaultMessage: 'Progress Semicircle', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.progressSemicircleHelpText', { | ||
defaultMessage: 'Displays progress as a portion of a semicircle', | ||
}), | ||
}, | ||
progressWheel: { | ||
displayName: i18n.translate('xpack.canvas.elements.progressWheelDisplayName', { | ||
defaultMessage: 'Progress Wheel', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.progressWheelHelpText', { | ||
defaultMessage: 'Displays progress as a portion of a wheel', | ||
}), | ||
}, | ||
repeatImage: { | ||
displayName: i18n.translate('xpack.canvas.elements.repeatImageDisplayName', { | ||
defaultMessage: 'Image repeat', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.repeatImageHelpText', { | ||
defaultMessage: 'Repeats an image N times', | ||
}), | ||
}, | ||
revealImage: { | ||
displayName: i18n.translate('xpack.canvas.elements.revealImageDisplayName', { | ||
defaultMessage: 'Image reveal', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.revealImageHelpText', { | ||
defaultMessage: 'Reveals a percentage of an image', | ||
}), | ||
}, | ||
shape: { | ||
displayName: i18n.translate('xpack.canvas.elements.shapeDisplayName', { | ||
defaultMessage: 'Shape', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.shapeHelpText', { | ||
defaultMessage: 'A customizable shape', | ||
}), | ||
}, | ||
table: { | ||
displayName: i18n.translate('xpack.canvas.elements.tableDisplayName', { | ||
defaultMessage: 'Data table', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.tableHelpText', { | ||
defaultMessage: 'A scrollable grid for displaying data in a tabular format', | ||
}), | ||
}, | ||
tiltedPie: { | ||
displayName: i18n.translate('xpack.canvas.elements.tiltedPieDisplayName', { | ||
defaultMessage: 'Tilted pie chart', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.tiltedPieHelpText', { | ||
defaultMessage: 'A customizable tilted pie chart', | ||
}), | ||
}, | ||
time_filter: { | ||
displayName: i18n.translate('xpack.canvas.elements.timeFilterDisplayName', { | ||
defaultMessage: 'Time filter', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.timeFilterHelpText', { | ||
defaultMessage: 'Set a time window', | ||
}), | ||
}, | ||
verticalBarChart: { | ||
displayName: i18n.translate('xpack.canvas.elements.verticalBarChartDisplayName', { | ||
defaultMessage: 'Vertical bar chart', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.verticalBarChartHelpText', { | ||
defaultMessage: 'A customizable vertical bar chart', | ||
}), | ||
}, | ||
verticalProgressBar: { | ||
displayName: i18n.translate('xpack.canvas.elements.verticalProgressBarDisplayName', { | ||
defaultMessage: 'Vertical Progress Bar', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.verticalProgressBarHelpText', { | ||
defaultMessage: 'Displays progress as a portion of a vertical bar', | ||
}), | ||
}, | ||
verticalProgressPill: { | ||
displayName: i18n.translate('xpack.canvas.elements.verticalProgressPillDisplayName', { | ||
defaultMessage: 'Vertical Progress Pill', | ||
}), | ||
help: i18n.translate('xpack.canvas.elements.verticalProgressPillHelpText', { | ||
defaultMessage: 'Displays progress as a portion of a vertical pill', | ||
}), | ||
}, | ||
}; | ||
}; |
36 changes: 36 additions & 0 deletions
36
x-pack/plugins/canvas/canvas_plugin_src/strings/i18n_provider.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { i18n as i18nCore } from '@kbn/i18n'; | ||
|
||
let i18nCoreInstance: typeof i18nCore | null = null; | ||
|
||
/** | ||
* @kbn/i18n is provided as a global module, but there's a difference between the version provided by Kibana, which is properly | ||
* initialized, and the one imported directly from the global module. We need the former, as the latter, for example, won't | ||
* be set to the proper locale, (set in kibana.yml or the command line). | ||
* | ||
* As a result, we need to initialize our own provider before using i18n in Canvas code. This simple singleton is here for that | ||
* purpose. | ||
*/ | ||
export const i18nProvider = { | ||
// For simplicity in cases like testing, you can just init this Provider without parameters... but you won't have the | ||
// Kibana-initialized i18n runtime. | ||
init: (i18n: typeof i18nCore = i18nCore): typeof i18nCore => { | ||
if (i18nCoreInstance === null) { | ||
i18nCoreInstance = i18n; | ||
} | ||
return i18nCoreInstance; | ||
}, | ||
getInstance: (): typeof i18nCore => { | ||
if (i18nCoreInstance === null) { | ||
throw new Error( | ||
'i18nProvider not initialized; you must first call `init` with an instance of `@kbn/i18n`' | ||
); | ||
} | ||
return i18nCoreInstance; | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
export * from './apply_strings'; | ||
export * from './element_strings'; | ||
export * from './i18n_provider'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.