Localization "Index Patterns" tab#20525
Conversation
packages/__mocks__/@kbn/i18n.js
Outdated
There was a problem hiding this comment.
Note: workaround under current implementation (resolve client libraries for node env)
There was a problem hiding this comment.
I'd remove it and return empty string in default case
There was a problem hiding this comment.
- let's change default implementation if we really need these functions (
formatDatefor instance don't havedefaultMessage) - Or remove unnecessary properties at all and just change for tests
contextTypeforIntl
There was a problem hiding this comment.
According to Jest, if the module you are mocking is a Node module, the mock should be placed in the __mocks__ directory. At the same time there is a rule in kibana in which files under packages should use kebab case.
Since mocking the @kbn/i18n module is a workaround, after merging the PR #20513 I will revert this change.
There was a problem hiding this comment.
it's not root component, you don't need provider here. let's use Provider only in ReactDOM.render calls
There was a problem hiding this comment.
maybe let's rename to shallowWithIntl for more consistency?
…heck for translation type id
2e53185 to
463490f
Compare
50d5ac9 to
f186b43
Compare
…heck for translation type id
…a/kibana into i18n-index-patterns
bmcconaghy
left a comment
There was a problem hiding this comment.
This is coming along very nicely, just have a few concerns I've documented here, the primary one being creating a new object inside values each time (I only commented on this in one spot, but it happens a lot in this code).
| id="kbn.management.createIndexPattern.emptyStateLabel.emptyStateDetail" | ||
| defaultMessage="{needToIndex} {learnHowLink} or {getStartedLink}" | ||
| values={{ | ||
| needToIndex: ( |
There was a problem hiding this comment.
I think I would prefer the values object here to be declared as a constant above and then referenced here. This would make things easier to read, and would also prevent a new object being created with each rerender. See this for an explanation of why that might be bad: https://medium.com/@esamatti/react-js-pure-render-performance-anti-pattern-fb88c101332f
There was a problem hiding this comment.
@bmcconaghy Basically, this is common pattern for avoiding creation of new object, but I would not say, that in this case, because:
- Moving such objects to constants will decrease readability of code in general
- Some of values are React components too and use props. So if we move values to constant outside component we will not get props, if we will create it inside render it will be the same one
- This case is envisaged by react-intl guys. And for avoiding rerendering they espacially use shallow compare for
valuesprops. (Here)[https://github.com/yahoo/react-intl/blob/master/src/components/message.js#L43]
There was a problem hiding this comment.
Fair enough on the performance point. I actually find the FormattedMessage nested in FormattedMessage harder to read personally, as I get lost in the multiple levels of nesting, so would still like to see the values defined outside of the FormattedMessage and then referenced there.
There was a problem hiding this comment.
It feels like the right solution for this readability problem would be integrating i18n into EUI components at some point, so that this:
<EuiTextColor color="subdued">
<FormattedMessage
id="kbn.management.createIndexPattern.emptyStateLabel.needToIndexLabel"
defaultMessage="You'll need to index ....."
/>
</EuiTextColor>can be changed to:
<EuiTextColor color="subdued" i18n-id="kbn.management.createIndexPattern.emptyStateLabel.needToIndexLabel">
You'll need to index .....
</EuiTextColor>We'll still have to use values to keep all parts of the single message together though (can be quite important for RTL languges).
But that's a bigger effort that spans several teams and i18n should prove itself in practice first.
| <strong> | ||
| <FormattedMessage | ||
| id="kbn.management.createIndexPattern.step.status.matchAnyLabel.strongIndicesLabel" | ||
| defaultMessage="{allIndicesLength, plural, one {# index} other {# indices}}" |
There was a problem hiding this comment.
I think we could clean up the message here for the case when a single index exists. "any of your 1 index" sounds pretty silly. "any of your" should be made part of the conditional. I would suggest the messages should be: singular "...can match your index below" plural (remains the same)
| You can match any of your <strong>{allIndices.length} indices</strong>, below. | ||
| <FormattedMessage | ||
| id="kbn.management.createIndexPattern.step.status.notMatchLabel.notMatchDetail" | ||
| defaultMessage="The index pattern you've entered doesn't match any indices. You can match any of your {strongIndices}, below." |
| fieldName: '', | ||
| }; | ||
| const noTimeFieldLabel = i18n.translate('kbn.management.createIndexPattern.stepTime.noTimeFieldOptionLabel', { | ||
| defaultMessage: 'I don\'t want to use the Time Filter' |
There was a problem hiding this comment.
I would prefer that we use `` or "" for string delimiting if the string contains a ' character. Easier to read than using escaping.
There was a problem hiding this comment.
@bmcconaghy Actually, I agree with you that it sometimes maybe better for readabilty (and we use it in react components), but there are points why we did it in such way.
- We have eslint rule: "Strings must use singlequote"
- Template string cannot be used, because this restriction is set by tool for extracting messages and verifying them
There was a problem hiding this comment.
I guess I can live with this as it is. Is there a possibility of modifying the tool so that template strings would work?
There was a problem hiding this comment.
Basically there is possibility to do it, but babel creates quite hard AST with template strings, which is difficult to work with, so currently we have decided to use such approach
There was a problem hiding this comment.
Yeah, we just decided not to complicate things for now. If we allow using template strings for i18n ID's and default messages, someone will try to use it as a template string with dynamic parameter some day and then we'll have troubles :/
| toastNotifications.add(`'${this.indexPattern.title}' index pattern doesn't have a scripted field called '${fieldName}'`); | ||
| const message = i18n.translate('kbn.management.editIndexPattern.scripted.noFieldLabel', | ||
| { | ||
| defaultMessage: '\'{indexPatternTitle}\' index pattern doesn\'t have a scripted field called \'{fieldName}\'', |
There was a problem hiding this comment.
Again prefer other quotation marks here over escaping.
💚 Build Succeeded |
jen-huang
left a comment
There was a problem hiding this comment.
LGTM, I spot checked the changed files and ran branch locally and confirmed there were no functional regressions.
azasypkin
left a comment
There was a problem hiding this comment.
Looks good to me, just a couple of issues and a few nits/questions.
| <FormattedMessage | ||
| id="kbn.management.createIndexPattern.step.status.notMatchLabel.notMatchDetail" | ||
| defaultMessage="The index pattern you've entered doesn't match any indices. | ||
| You can match {indicesLength, plural, one {your} other {any of your}} {strongIndices}, below." |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
| errors={ | ||
| Array [ | ||
| "An index pattern cannot contain spaces or the characters: \\\\, /, ?, \\", <, >, |", | ||
| "An index pattern cannot contain spaces or the characters: {characterList}", |
There was a problem hiding this comment.
issue: having exact chars in the snapshot like it was before is important, can you please tweak test so that it properly expands {characterList}?
| Your index pattern can match any of your <strong>{allIndices.length} indices</strong>, below. | ||
| <FormattedMessage | ||
| id="kbn.management.createIndexPattern.step.status.matchAnyLabel.matchAnyDetail" | ||
| defaultMessage="Your index pattern can match any of your {strongIndices}, below." |
There was a problem hiding this comment.
note: there is no need to change anything in this PR, but for the following PRs: parameter name and message id should rather reflect what this parameters/message means, not how it looks like visually (strongIndicies vs indexCount). It will help localizers to understand context better as well.
| Your index pattern can match any of your <strong>{allIndices.length} indices</strong>, below. | ||
| <FormattedMessage | ||
| id="kbn.management.createIndexPattern.step.status.matchAnyLabel.matchAnyDetail" | ||
| defaultMessage="Your index pattern can match any of your {strongIndices}, below." |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
| label={ | ||
| <EuiFlexGroup gutterSize="xs" justifyContent="spaceBetween" alignItems="center"> | ||
| <EuiFlexItem grow={false}> | ||
| <span>Time Filter field name</span> |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
| target="_window" | ||
| href={getDocLink('scriptedFields.painless')} | ||
| > | ||
| <FormattedMessage id="common.ui.fieldEditor.syntax.defaultLabel.painlessLink" defaultMessage="Painless" /> |
There was a problem hiding this comment.
note: same question/note about Painless here.
| language: <EuiCode>{field.lang}</EuiCode>, | ||
| painlessLink: ( | ||
| <EuiLink target="_window" href={getDocLink('scriptedFields.painless')}> | ||
| <FormattedMessage |
| const { field, fieldTypeFormats, fieldFormatId, fieldFormatParams } = this.state; | ||
| const { fieldFormatEditors } = this.props.helpers; | ||
| const defaultFormat = fieldTypeFormats[0] && fieldTypeFormats[0].resolvedTitle; | ||
| const label = defaultFormat |
There was a problem hiding this comment.
question: likely I missed some related review comment from other folks, so just double checking: previously we had null if defaultFormat was not defined, now we render Format label: is that expected?
There was a problem hiding this comment.
Actually this is the same. Maybe you missed <span> outside?
| toastNotifications.addDanger({ | ||
| title: `Unknown field type ${spec.type}`, | ||
| text: `Field ${spec.name} in indexPattern ${indexPattern.title} is using an unknown field type.` | ||
| title: title, |
There was a problem hiding this comment.
nit: use shortcuts maybe?
title,
text| }); | ||
|
|
||
| const warningText = i18n.translate('common.ui.indexPattern.warningText', { | ||
| defaultMessage: 'For more information, view the ["{title}" index pattern in management]({link})', |
There was a problem hiding this comment.
question: was there any agreement to change the way we display that link?
💚 Build Succeeded |
azasypkin
left a comment
There was a problem hiding this comment.
LGTM, but please wait for green CI.
💔 Build Failed |
|
retest |
💚 Build Succeeded |
* Integrate i18n-engine into "Index Patterns" tab * Adjusted unit tests for "Index Patterns" tab * Localization of "Index patterns" section name * Rename the function shallowIntl to shallowWithIntl, remove needless check for translation type id * Refactoring of default message * Localization for FieldEditor component * Adjust unit tests for FieldEditor component * Integrate i18n-engine into "Index Patterns" tab * Adjusted unit tests for "Index Patterns" tab * Localization of "Index patterns" section name * Rename the function shallowIntl to shallowWithIntl, remove needless check for translation type id * Refactoring of default message * Localization for FieldEditor component * Adjust unit tests for FieldEditor component * Replace I18nContext to injectI18n according to changes in @kbn/i18n * Fix broken saving form * Adjust components importing according to changes in @kbn/i18n * Formatting and refactoring * Update ids * Fix invalid HTML and refactoring * Use i18n module instead of AngularJS service * Localize scripting_syntax.js, refactoring * Update message ids. * fix plural form in status messages * fix messages in status message, _field component * move back span in time_field * refactor enzyme helper for providing intl into context * do not translate Painless * test call params in formatMessage * clear formatMessage mock after each test Co-authored-by: maryia-lapata <mary.lopato@gmail.com>
* Integrate i18n-engine into "Index Patterns" tab * Adjusted unit tests for "Index Patterns" tab * Localization of "Index patterns" section name * Rename the function shallowIntl to shallowWithIntl, remove needless check for translation type id * Refactoring of default message * Localization for FieldEditor component * Adjust unit tests for FieldEditor component * Integrate i18n-engine into "Index Patterns" tab * Adjusted unit tests for "Index Patterns" tab * Localization of "Index patterns" section name * Rename the function shallowIntl to shallowWithIntl, remove needless check for translation type id * Refactoring of default message * Localization for FieldEditor component * Adjust unit tests for FieldEditor component * Replace I18nContext to injectI18n according to changes in @kbn/i18n * Fix broken saving form * Adjust components importing according to changes in @kbn/i18n * Formatting and refactoring * Update ids * Fix invalid HTML and refactoring * Use i18n module instead of AngularJS service * Localize scripting_syntax.js, refactoring * Update message ids. * fix plural form in status messages * fix messages in status message, _field component * move back span in time_field * refactor enzyme helper for providing intl into context * do not translate Painless * test call params in formatMessage * clear formatMessage mock after each test Co-authored-by: maryia-lapata <mary.lopato@gmail.com>
|
6.x/6.5: f6f4e68 |
It's integration "Index Patterns" tab and I18n engine
#19729