fix(localize,form-core): wait for localize before updating feedback

This commit is contained in:
jorenbroekema 2021-07-07 17:47:34 +02:00
parent 5e7e43d221
commit 8a766644db
5 changed files with 71 additions and 3 deletions

View file

@ -0,0 +1,6 @@
---
'@lion/form-core': minor
'@lion/localize': minor
---
Make ValidateMixin feedback message wait for localize loadingComplete, to ensure getting the right fieldName if this refers to a localized label.

View file

@ -98,7 +98,7 @@ Let's look at both cases in depth.
```js ```js
// use the dynamic import to load static assets // use the dynamic import to load static assets
localize.loadNamespace({ localize.loadNamespace({
'my-hello-component': locale => { 'my-hello-component': async locale => {
// resolves to a module with the module.default `{ greeting: 'Hallo {name}!' }` // resolves to a module with the module.default `{ greeting: 'Hallo {name}!' }`
return import(`./translations/${locale}.js`); return import(`./translations/${locale}.js`);
}, },

View file

@ -644,6 +644,7 @@ export const ValidateMixinImplementation = superclass =>
* @private * @private
*/ */
async __getFeedbackMessages(validators) { async __getFeedbackMessages(validators) {
await localize.loadingComplete;
let fieldName = await this.fieldName; let fieldName = await this.fieldName;
return Promise.all( return Promise.all(
validators.map(async validator => { validators.map(async validator => {

View file

@ -1,6 +1,7 @@
import { expect, fixture, defineCE } from '@open-wc/testing'; import { expect, fixture, defineCE } from '@open-wc/testing';
import { html, unsafeStatic } from 'lit/static-html.js'; import { html, unsafeStatic } from 'lit/static-html.js';
import { Required, DefaultSuccess, Validator } from '@lion/form-core'; import { Required, DefaultSuccess, Validator } from '@lion/form-core';
import { localize } from '@lion/localize';
import { loadDefaultFeedbackMessages } from '@lion/validate-messages'; import { loadDefaultFeedbackMessages } from '@lion/validate-messages';
import { LionInput } from '@lion/input'; import { LionInput } from '@lion/input';
import sinon from 'sinon'; import sinon from 'sinon';
@ -117,5 +118,62 @@ describe('Form Validation Integrations', () => {
await el.feedbackComplete; await el.feedbackComplete;
expect(spy.called).to.be.false; expect(spy.called).to.be.false;
}); });
it('correctly renders localized fieldName (label), even on locale changes', async () => {
class DefaultLabelInput extends LionInput {
constructor() {
super();
this.setDefaultLabel();
}
async updateLabel() {
await localize.loadingComplete;
this.label = localize.msg('test-default-label:label');
}
async setDefaultLabel() {
localize.loadNamespace({
'test-default-label': /** @param {string} locale */ async locale => {
switch (locale) {
case 'nl-NL':
return { label: 'Tekst' };
default:
return { label: 'Text' };
}
},
});
this.boundUpdateLabel = this.updateLabel.bind(this);
this.boundUpdateLabel();
localize.addEventListener('localeChanged', this.boundUpdateLabel);
}
}
const elTagString = defineCE(DefaultLabelInput);
const elTag = unsafeStatic(elTagString);
const el = /** @type {LionInput} */ (
await fixture(html`
<${elTag}
.validators=${[new Required()]}
>${lightDom}</${elTag}>
`)
);
el.touched = true;
el.dirty = true;
await el.updateComplete;
await el.feedbackComplete;
const { _feedbackNode } = getFormControlMembers(el);
expect(_feedbackNode.feedbackData?.[0].message).to.equal('Please enter a(n) Text.');
localize.locale = 'nl-NL';
await el.updateComplete;
await el.feedbackComplete;
expect(el.label).to.equal('Tekst');
expect(_feedbackNode.feedbackData?.[0].message).to.equal('Vul een Tekst in.');
localize.locale = 'en-GB';
await el.updateComplete;
await el.feedbackComplete;
expect(el.label).to.equal('Text');
expect(_feedbackNode.feedbackData?.[0].message).to.equal('Please enter a(n) Text.');
});
}); });
}); });

View file

@ -173,10 +173,13 @@ export class LocalizeManager {
} }
/** /**
* @returns {Promise.<Object>} * @returns {Promise.<Object|void>}
*/ */
get loadingComplete() { get loadingComplete() {
return Promise.all(Object.values(this.__namespaceLoaderPromisesCache[this.locale])); if (typeof this.__namespaceLoaderPromisesCache[this.locale] === 'object') {
return Promise.all(Object.values(this.__namespaceLoaderPromisesCache[this.locale]));
}
return Promise.resolve();
} }
reset() { reset() {