Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I18n manage current locale in luigi #635

Merged
merged 22 commits into from
Jul 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d4e6c1b
i18n manager
pekura Jun 25, 2019
6e38ce8
Merge branch 'master' into i18n-manage-current-locale-in-luigi
pekura Jun 28, 2019
35e82d7
Merge branch 'master' into i18n-manage-current-locale-in-luigi
pekura Jul 2, 2019
33c66e4
listener methods added; tets
pekura Jul 2, 2019
46e0042
luigi client communication
pekura Jul 4, 2019
a9f6035
Merge branch 'master' into i18n-manage-current-locale-in-luigi
pekura Jul 4, 2019
463b8c5
api doc update
pekura Jul 4, 2019
061ad42
Merge branch 'master' into i18n-manage-current-locale-in-luigi
pekura Jul 4, 2019
bc7e644
e2e tets
pekura Jul 5, 2019
0472566
Merge branch 'master' into i18n-manage-current-locale-in-luigi
jesusreal Jul 15, 2019
e6c6456
Merge branch 'master' into i18n-manage-current-locale-in-luigi
jesusreal Jul 15, 2019
82eebda
core api docu update
pekura Jul 16, 2019
26fd66c
core api docu update
pekura Jul 16, 2019
793d4ab
listener registration by id; tets
pekura Jul 16, 2019
0ccb9cc
private method renaming
pekura Jul 16, 2019
c719201
Small refactorings in unit tests for LuigiI18N
jesusreal Jul 16, 2019
6b744de
Merge branch 'master' into i18n-manage-current-locale-in-luigi
jesusreal Jul 16, 2019
017373f
Merge branch 'master' into i18n-manage-current-locale-in-luigi
pekura Jul 17, 2019
899180c
docu update
pekura Jul 18, 2019
b3e8343
added client permissions
pekura Jul 19, 2019
02fc8d9
change locale permission setting renamed
pekura Jul 19, 2019
d033b9b
Merge branch 'master' into i18n-manage-current-locale-in-luigi
pekura Jul 19, 2019
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
12 changes: 12 additions & 0 deletions client/luigi-client.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ export declare interface UxManager {
* @returns {promise} which is resolved when accepting the confirmation modal and rejected when dismissing it.
*/
showConfirmationModal: (settings: ConfirmationModalSettings) => Promise<void>;

/**
* Gets the current locale.
* @returns {string} current locale
*/
getCurrentLocale: () => string;

/**
* Sets current locale to the specified one.
* @param {string} locale locale to be set as the current locale
*/
setCurrentLocale: (locale: string) => void;
}

export declare interface LinkManager {
Expand Down
52 changes: 34 additions & 18 deletions client/src/lifecycleManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,6 @@ class LifecycleManager extends LuigiClientBase {
this._onInitFns = {};
this.authData = {};

/**
* Iterates over an object and executes all top-level functions
* with a given payload and the Luigi core domain
* @private
*/
const _callAllFns = (objWithFns, payload, luigiCoreOrigin) => {
for (let id in objWithFns) {
if (
objWithFns.hasOwnProperty(id) &&
helpers.isFunction(objWithFns[id])
) {
objWithFns[id](payload, luigiCoreOrigin);
}
}
};

/**
* Adds event listener for communication with Luigi Core and starts communication
* @private
Expand Down Expand Up @@ -82,7 +66,7 @@ class LifecycleManager extends LuigiClientBase {
setAuthData(e.data.authData);
helpers.setLuigiCoreDomain(e.origin);
this.luigiInitialized = true;
_callAllFns(this._onInitFns, this.currentContext.context, e.origin);
this._notifyInit(e.origin);
});

helpers.addEventListener('luigi.auth.tokenIssued', e => {
Expand All @@ -95,7 +79,7 @@ class LifecycleManager extends LuigiClientBase {
window.location.replace(e.data.viewUrl);
}
// execute the context change listener if set by the microfrontend
_callAllFns(this._onContextUpdatedFns, this.currentContext.context);
this._notifyUpdate();
helpers.sendPostMessageToLuigiCore({ msg: 'luigi.navigate.ok' });
});

Expand All @@ -114,6 +98,38 @@ class LifecycleManager extends LuigiClientBase {
luigiClientInit();
}

/**
* Iterates over an object and executes all top-level functions
* with a given payload.
* @private
* @memberof Lifecycle
*/
_callAllFns(objWithFns, payload) {
for (let id in objWithFns) {
if (objWithFns.hasOwnProperty(id) && helpers.isFunction(objWithFns[id])) {
objWithFns[id](payload);
}
}
}

/**
* Notifies all context init listeners.
* @private
* @memberof Lifecycle
*/
_notifyInit(origin) {
this._callAllFns(this._onInitFns, this.currentContext.context, origin);
}

/**
* Notifies all context update listeners.
* @private
* @memberof Lifecycle
*/
_notifyUpdate() {
this._callAllFns(this._onContextUpdatedFns, this.currentContext.context);
}

/**
* @private
* @memberof Lifecycle
Expand Down
41 changes: 40 additions & 1 deletion client/src/uxManager.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { LuigiClientBase } from './baseClass';
import { lifecycleManager } from './lifecycleManager';
import { helpers } from './helpers';

/**
Expand All @@ -9,6 +10,13 @@ class UxManager extends LuigiClientBase {
/** @private */
constructor() {
super();
helpers.addEventListener('luigi.current-locale-changed', e => {
if (e.data.currentLocale && lifecycleManager.currentContext?.internal) {
lifecycleManager.currentContext.internal.currentLocale =
e.data.currentLocale;
lifecycleManager._notifyUpdate();
}
});
}

/**
Expand Down Expand Up @@ -107,7 +115,7 @@ class UxManager extends LuigiClientBase {
* @param {string} settings.links.LINK_KEY.text text which replaces the link identifier in the alert content
* @param {string} settings.links.LINK_KEY.url url to navigate when you click the link. Currently, only internal links are supported in the form of relative or absolute paths.
* @param {number} settings.closeAfter (optional) time in milliseconds that tells Luigi when to close the Alert automatically. If not provided, the Alert will stay on until closed manually. It has to be greater than `100`.
* @returns {promise} which is resolved when the alert is dismissed.
* @returns {promise} which is resolved when the alert is dismissed.
* @example
* import LuigiClient from '@kyma-project/luigi-client';
* const settings = {
Expand Down Expand Up @@ -171,5 +179,36 @@ class UxManager extends LuigiClientBase {
this.setPromise('alerts', alerts);
}
}

/**
* Gets the current locale.
* @returns {string} current locale
* @memberof uxManager
*/
getCurrentLocale() {
return lifecycleManager.currentContext?.internal?.currentLocale;
}

/**
* Sets current locale to the specified one.
*
* **NOTE:** this must be explicitly allowed on the navigation node level by setting `clientPermissions.changeCurrentLocale` to `true`. (See {@link navigation-parameters-reference.md Node parameters}.)
*
* @param {string} locale locale to be set as the current locale
* @memberof uxManager
*/
setCurrentLocale(locale) {
if (locale) {
window.parent.postMessage(
{
msg: 'luigi.ux.set-current-locale',
data: {
currentLocale: locale
}
},
'*'
);
}
}
}
export const uxManager = new UxManager();
Original file line number Diff line number Diff line change
Expand Up @@ -321,5 +321,26 @@ describe('Luigi client ux manager features', () => {
cy.get('[data-cy=luigi-alert]').should('not.exist');
});
});
describe('Luigi Client Localization', () => {
it('set localization in client', () => {
cy.goToUxManagerMethods($iframeBody);

cy.wrap($iframeBody)
.find('[data-cy=luigi-current-locale]')
.should('contain', "'en'");

cy.wrap($iframeBody)
.find('[data-cy=luigi-input-locale]')
.type('pl_PL');

cy.wrap($iframeBody)
.find('[data-cy=set-current-locale]')
.click();

cy.wrap($iframeBody)
.find('[data-cy=luigi-current-locale]')
.should('contain', "'pl_PL'");
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,51 @@ <h1 class="fd-section__title">LuigiClient uxManager methods</h1>
Luigi alert has been dismissed
</p>
</div>

<div class="fd-panel fd-has-margin-bottom-small">
<p><strong>Localization</strong></p>
<div
class="fd-has-color-status-4 fd-has-type-1 fd-has-margin-bottom-base"
data-cy="luigi-current-locale"
>
Current locale is: '{{ currentLocale }}'
</div>
<p class="fd-has-margin-bottom-s">
<app-code-snippet
data="uxManager().getCurrentLocale()"
></app-code-snippet>
</p>
<div class="fd-container ">
<form #luigiLocalizationForm="ngForm" class="fd-col--3">
<div class="fd-form__set">
<div class="fd-form__item">
<label class="fd-form__label" for="locale">Locale </label>
<input
[ngModel]=""
class="fd-form__control"
type="text"
name="locale"
placeholder=""
data-cy="luigi-input-locale"
/>
</div>
</div>
</form>
</div>
<button
class="fd-button"
data-cy="set-current-locale"
(click)="setCurrentLocale()"
>
Set Current Locale
</button>
<p>
<app-code-snippet
data="uxManager().setCurrentLocale(locale)"
></app-code-snippet>
</p>
</div>

<div class="fd-panel fd-has-margin-bottom-small">
<p>
<strong
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { NgForm } from '@angular/forms';
})
export class ProjectComponent implements OnInit, OnDestroy {
@ViewChild('luigiAlertForm') luigiAlertForm: NgForm;
@ViewChild('luigiLocalizationForm') luigiLocalizationForm: NgForm;
public linkManager = linkManager;
public uxManager = uxManager;
public projectId: string;
Expand All @@ -38,6 +39,7 @@ export class ProjectComponent implements OnInit, OnDestroy {
public alertDismissed;
public alertTypes = ['success', 'info', 'warning', 'error'];
public isDirty = false;
public currentLocale = '';

public constructor(
private activatedRoute: ActivatedRoute,
Expand Down Expand Up @@ -81,6 +83,7 @@ export class ProjectComponent implements OnInit, OnDestroy {
if (ctx.contextType === 'init' || ctx.contextType === 'update') {
this.projectId = ctx.context.currentProject;
this.preservedViewCallbackContext = ctx.context.goBackContext;
this.currentLocale = uxManager().getCurrentLocale();
// Since Luigi runs outside of Zone.js, changes need
// to be updated manually
// Be sure to check for destroyed ChangeDetectorRef,
Expand All @@ -100,7 +103,7 @@ export class ProjectComponent implements OnInit, OnDestroy {
this.cudListener = addContextUpdateListener(updatedContext => {
// this.projectId = updatedContext.currentProject;
// this.preservedViewCallbackContext = updatedContext.goBackContext;

this.currentLocale = uxManager().getCurrentLocale();
// Be sure to check for destroyed ChangeDetectorRef,
// else you get runtime Errors
if (!this.cdr['destroyed']) {
Expand Down Expand Up @@ -171,6 +174,10 @@ export class ProjectComponent implements OnInit, OnDestroy {
});
}

setCurrentLocale() {
uxManager().setCurrentLocale(this.luigiLocalizationForm.value.locale);
}

checkIfPathExists() {
linkManager()
.pathExists(this.pathExists.formValue)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ export const projectsNavProviderFn = context =>
currentProject: project.id
},
icon: 'folder-blank',
clientPermissions: {
changeCurrentLocale: true
},
children: projectDetailNavProviderFn
});
});
Expand Down
7 changes: 4 additions & 3 deletions core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,13 @@
"test": "babel-node ./node_modules/nyc/bin/nyc.js mocha -- --recursive test",
"test:watch": "npm run test -- --watch",
"bundlesize": "npm run bundle && bundlesize",
"docu": "npm run docu:validate && npm run docu:generate:config && npm run docu:generate:dom-elements && npm run docu:generate:auth && npm run docu:generate:navigation",
"docu:validate": "documentation lint --shallow src/core-api/config.js src/core-api/elements.js src/core-api/auth.js src/core-api/navigation.js",
"docu": "npm run docu:validate && npm run docu:generate:config && npm run docu:generate:dom-elements && npm run docu:generate:auth && npm run docu:generate:navigation && npm run docu:generate:i18n",
"docu:validate": "documentation lint --shallow src/core-api/config.js src/core-api/elements.js src/core-api/auth.js src/core-api/navigation.js src/core-api/i18n.j",
"docu:generate:config": "documentation readme src/core-api/config.js --shallow -f md --section='Luigi Config' --readme-file=../docs/luigi-core-api.md --markdown-toc=false --github false --quiet",
"docu:generate:dom-elements": "documentation readme src/core-api/dom-elements.js --shallow -f md --section='Luigi.elements()' --readme-file=../docs/luigi-core-api.md --markdown-toc=false --github false --quiet",
"docu:generate:auth": "documentation readme src/core-api/auth.js --shallow -f md --section='Luigi.auth()' --readme-file=../docs/luigi-core-api.md --markdown-toc=false --github false --quiet",
"docu:generate:navigation": "documentation readme src/core-api/navigation.js --shallow -f md --section='Luigi.navigation()' --readme-file=../docs/luigi-core-api.md --markdown-toc=false --github false --quiet"
"docu:generate:navigation": "documentation readme src/core-api/navigation.js --shallow -f md --section='Luigi.navigation()' --readme-file=../docs/luigi-core-api.md --markdown-toc=false --github false --quiet",
"docu:generate:i18n": "documentation readme src/core-api/i18n.js --shallow -f md --section='Luigi.i18n()' --readme-file=../docs/luigi-core-api.md --markdown-toc=false --github false --quiet"
},
"bundlesize": [
{
Expand Down
27 changes: 25 additions & 2 deletions core/src/App.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import Alerts from './Alerts.html';
import Modal from './Modal.html';
import { LuigiConfig } from './core-api';
import { LuigiI18N } from './core-api';
import { Routing } from './services/routing';
import { Navigation } from './navigation/services/navigation';
import { Iframe } from './services/iframe';
Expand Down Expand Up @@ -299,6 +300,14 @@
isolateAllViews
};

LuigiI18N.addCurrentLocaleChangeListener(locale => {
const message = {
msg: 'luigi.current-locale-changed',
currentLocale: locale
};
IframeHelpers.broadcastMessageToAllIframes(message);
});

window.addEventListener('popstate', async e => {
const alertQueue = this.get().alerts;
if (!alertQueue || !alertQueue.length) return;
Expand Down Expand Up @@ -334,6 +343,8 @@
if ('luigi.navigate.ok' === e.data.msg) {
iframe.luigi.viewUrl = iframe.luigi.nextViewUrl;
iframe.luigi.nextViewUrl = '';
iframe.luigi.clientPermissions = iframe.luigi.nextClientPermissions;
delete iframe.luigi.nextClientPermissions;
config.navigateOk = true;

ViewGroupPreloading.preload();
Expand Down Expand Up @@ -521,6 +532,17 @@
/* keep it to avoid runtime errors in browser console */
});
}

if ('luigi.ux.set-current-locale' === e.data.msg) {
if (iframe.luigi.clientPermissions && iframe.luigi.clientPermissions.changeCurrentLocale) {
const { currentLocale } = e.data.data;
if (currentLocale) {
LuigiI18N.setCurrentLocale(currentLocale);
}
} else {
console.error('Current local change from client declined because client permission changeCurrentLocale is not set for this view.');
}
}
});

// listeners are not automatically removed — cancel
Expand All @@ -533,7 +555,7 @@
methods: {
getValidMessageSource(e) {
const allMessagesSources = [
...Iframe.getAllIframes(this.get().modalIframe),
...IframeHelpers.getAllIframes(this.get().modalIframe),
{ contentWindow: window, luigi: { viewUrl: window.location.href } }
];
const iframe = allMessagesSources.find(iframe =>
Expand Down Expand Up @@ -569,7 +591,8 @@
return {
isNavigateBack: this.get().isNavigateBack,
viewStackSize: this.get().preservedViews.length,
modal: modal
modal: modal,
currentLocale: LuigiI18N.getCurrentLocale()
};
},
closeLeftNav() {
Expand Down
3 changes: 2 additions & 1 deletion core/src/Modal.html
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ <h1 class="fd-modal__title">{modalSettings.title}</h1>
if (viewUrl) {
viewUrl = RoutingHelpers.substituteViewUrl(viewUrl, componentData);
}
const iframe = IframeHelpers.createIframe(viewUrl);

const iframe = IframeHelpers.createIframe(viewUrl, undefined, component.get().lastNode.clientPermissions);
const iframeCtn = document.querySelector('.iframeModalCtn');
iframeCtn.appendChild(iframe);
return iframe;
Expand Down
Loading