Skip to content

Commit

Permalink
Enable core api templating for compound children and external link node
Browse files Browse the repository at this point in the history
  • Loading branch information
stanleychh authored Oct 22, 2021
1 parent 3aa48d9 commit 0b3d903
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 28 deletions.
3 changes: 2 additions & 1 deletion core/src/services/routing.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ class RoutingClass {

let cNode2 = currentNode;
let hideSideNavInherited = nodeObject.hideSideNav;
if(hideSideNavInherited === undefined) {
if (hideSideNavInherited === undefined) {
while (cNode2) {
if (cNode2.tabNav && cNode2.hideSideNav === true) {
hideSideNavInherited = true;
Expand Down Expand Up @@ -500,6 +500,7 @@ class RoutingClass {
}

navigateToExternalLink(externalLink) {
externalLink.url = RoutingHelpers.getI18nViewUrl(externalLink.url);
const updatedExternalLink = {
...NAVIGATION_DEFAULTS.externalLink,
...externalLink
Expand Down
30 changes: 16 additions & 14 deletions core/src/services/web-components.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
registerEventListeners
} from '../utilities/helpers/web-component-helpers';
import { LuigiConfig } from '../core-api';
import { RoutingHelpers } from '../utilities/helpers';

/** Methods for dealing with web components based micro frontend handling */
class WebComponentSvcClass {
Expand Down Expand Up @@ -72,9 +73,10 @@ class WebComponentSvcClass {
* specified.
* @returns a promise that gets resolved after successfull import */
registerWCFromUrl(viewUrl, wc_id) {
const i18nViewUrl = RoutingHelpers.getI18nViewUrl(viewUrl);
return new Promise((resolve, reject) => {
if (this.checkWCUrl(viewUrl)) {
this.dynamicImport(viewUrl)
if (this.checkWCUrl(i18nViewUrl)) {
this.dynamicImport(i18nViewUrl)
.then(module => {
try {
if (!window.customElements.get(wc_id)) {
Expand All @@ -97,8 +99,8 @@ class WebComponentSvcClass {
})
.catch(err => reject(err));
} else {
console.warn(`View URL '${viewUrl}' not allowed to be included`);
reject(`View URL '${viewUrl}' not allowed`);
console.warn(`View URL '${i18nViewUrl}' not allowed to be included`);
reject(`View URL '${i18nViewUrl}' not allowed`);
}
});
}
Expand Down Expand Up @@ -170,26 +172,27 @@ class WebComponentSvcClass {
* If the web component is not defined yet, it gets imported.
*/
renderWebComponent(viewUrl, wc_container, context, node, nodeId) {
const i18nViewUrl = RoutingHelpers.substituteViewUrl(viewUrl, { context });
const wc_id =
node.webcomponent && node.webcomponent.tagName ? node.webcomponent.tagName : this.generateWCId(viewUrl);
node.webcomponent && node.webcomponent.tagName ? node.webcomponent.tagName : this.generateWCId(i18nViewUrl);
const wcItemPlaceholder = document.createElement('div');
wc_container.appendChild(wcItemPlaceholder);

if (window.customElements.get(wc_id)) {
this.attachWC(wc_id, wcItemPlaceholder, wc_container, context, viewUrl, nodeId);
this.attachWC(wc_id, wcItemPlaceholder, wc_container, context, i18nViewUrl, nodeId);
} else {
/** Custom import function, if defined */
if (window.luigiWCFn) {
window.luigiWCFn(viewUrl, wc_id, wcItemPlaceholder, () => {
this.attachWC(wc_id, wcItemPlaceholder, wc_container, context, viewUrl, nodeId);
window.luigiWCFn(i18nViewUrl, wc_id, wcItemPlaceholder, () => {
this.attachWC(wc_id, wcItemPlaceholder, wc_container, context, i18nViewUrl, nodeId);
});
} else if (node.webcomponent && node.webcomponent.selfRegistered) {
this.includeSelfRegisteredWCFromUrl(node, viewUrl, () => {
this.attachWC(wc_id, wcItemPlaceholder, wc_container, context, viewUrl, nodeId);
this.includeSelfRegisteredWCFromUrl(node, i18nViewUrl, () => {
this.attachWC(wc_id, wcItemPlaceholder, wc_container, context, i18nViewUrl, nodeId);
});
} else {
this.registerWCFromUrl(viewUrl, wc_id).then(() => {
this.attachWC(wc_id, wcItemPlaceholder, wc_container, context, viewUrl, nodeId);
this.registerWCFromUrl(i18nViewUrl, wc_id).then(() => {
this.attachWC(wc_id, wcItemPlaceholder, wc_container, context, i18nViewUrl, nodeId);
});
}
}
Expand Down Expand Up @@ -230,10 +233,9 @@ class WebComponentSvcClass {
*/
renderWebComponentCompound(navNode, wc_container, context) {
let renderer;

if (navNode.webcomponent && navNode.viewUrl) {
renderer = new DefaultCompoundRenderer();
renderer.viewUrl = navNode.viewUrl;
renderer.viewUrl = RoutingHelpers.substituteViewUrl(navNode.viewUrl, { context });
renderer.createCompoundItemContainer = layoutConfig => {
var cnt = document.createElement('div');
if (layoutConfig && layoutConfig.slot) {
Expand Down
21 changes: 15 additions & 6 deletions core/src/utilities/helpers/routing-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ class RoutingHelpersClass {
pathParams,
LuigiConfig.getConfigValue('routing.useHashRouting') ? '#' : ''
);
return link.url || link;
return this.getI18nViewUrl(link.url) || link;
}
return 'javascript:void(0)';
}
Expand Down Expand Up @@ -262,19 +262,28 @@ class RoutingHelpersClass {
return this.isDynamicNode(node) ? pathParams[node.pathSegment.substring(1)] : undefined;
}

/**
* Returns the viewUrl with current locale, e.g. luigi/{i18n.currentLocale}/ -> luigi/en
* if viewUrl contains {i18n.currentLocale} term, it will be replaced by current locale
* @param {*} viewUrl
*/
getI18nViewUrl(viewUrl) {
const i18n_currentLocale = '{i18n.currentLocale}';
const locale = LuigiI18N.getCurrentLocale();
const hasI18n = viewUrl && viewUrl.includes(i18n_currentLocale);

return hasI18n ? viewUrl.replace(i18n_currentLocale, locale) : viewUrl;
}

substituteViewUrl(viewUrl, componentData) {
const contextVarPrefix = 'context.';
const nodeParamsVarPrefix = 'nodeParams.';
const i18n_currentLocale = '{i18n.currentLocale}';
const searchQuery = 'routing.queryParams';

viewUrl = GenericHelpers.replaceVars(viewUrl, componentData.pathParams, ':', false);
viewUrl = GenericHelpers.replaceVars(viewUrl, componentData.context, contextVarPrefix);
viewUrl = GenericHelpers.replaceVars(viewUrl, componentData.nodeParams, nodeParamsVarPrefix);

if (viewUrl.includes(i18n_currentLocale)) {
viewUrl = viewUrl.replace(i18n_currentLocale, LuigiI18N.getCurrentLocale());
}
viewUrl = this.getI18nViewUrl(viewUrl);

if (viewUrl.includes(searchQuery)) {
const viewUrlSearchParam = viewUrl.split('?')[1];
Expand Down
20 changes: 17 additions & 3 deletions core/test/utilities/helpers/routing-helpers.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,28 @@ describe('Routing-helpers', () => {
setItem: sinon.stub()
};
sinon.stub(config, 'configChanged');
sinon.stub(LuigiI18N, '_notifyLocaleChange');
LuigiI18N.setCurrentLocale('en');
});
afterEach(() => {
sinon.restore();
});

it('substitutes {i18n.currentLocale} variable to current locale', () => {
sinon.stub(LuigiI18N, '_notifyLocaleChange');
LuigiI18N.setCurrentLocale('en');
it('getI18nViewUrl - substitutes {i18n.currentLocale} variable to current locale', () => {
const viewUrl = '/{i18n.currentLocale}/microfrontend.html';
const expected = '/en/microfrontend.html';

expect(RoutingHelpers.getI18nViewUrl(viewUrl)).to.equal(expected);
});

it('No substitution if {i18n.currentLocale} variable is not provided', () => {
const viewUrl = '/{i18n}/microfrontend.html';
const expected = '/{i18n}/microfrontend.html';

expect(RoutingHelpers.getI18nViewUrl(viewUrl)).to.equal(expected);
});

it('substituteViewUrl - substitutes {i18n.currentLocale} variable to current locale', () => {
const viewUrl = '/{i18n.currentLocale}/microfrontend.html';
const expected = '/en/microfrontend.html';

Expand Down
4 changes: 2 additions & 2 deletions docs/navigation-parameters-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ Node parameters are all the parameters that can be added to an individual naviga
- **attributes**:
- **sameWindow** defines if the external URL is opened in a new or current tab. The default value for this parameter
is `false`.
- **URL** is the external URL that the node leads to.
- **URL** is the external URL that the node leads to. If you are using [localization](https://docs.luigi-project.io/docs/i18n) and translating your page into different languages, you can also add a **{i18n.currentLocale}** parameter to the url part of your configuration.
### label
- **type**: string
Expand Down Expand Up @@ -510,7 +510,7 @@ Web components can communicate over an event bus.
- **description**: Array of web component nodes.
- **attributes**:
- **id**: unique `id` of the web component.
- **viewUrl**: URL which points to the web component `.js` file.
- **viewUrl**: URL which points to the web component `.js` file. If you are using [localization](https://docs.luigi-project.io/docs/i18n) and translating your page into different languages, you can also add a **{i18n.currentLocale}** parameter to the viewUrl part of your configuration.
- **context**: object, which you can pass to the web component.
- **layoutConfig**: config object to define the position of an item in a grid. The properties are `row` and `column` and get the same values as in the CSS grid standard. If you want to use the mechanism of nested web components, you can define a `slot` property with the slot name instead of the config object. In that case this web component node will be plugged in the parent web component.
- **eventListeners**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ export const projectDetailNavStructure = projectId => [
context: {
title: 'Hello WebComponent!'
},
viewUrl: '/assets/helloWorldWC.js',
viewUrl: '/assets/helloWorldWC.js?{i18n.currentLocale}',
webcomponent: true,
openNodeInModal: true
},
Expand All @@ -193,7 +193,7 @@ export const projectDetailNavStructure = projectId => [
context: {
title: 'Hello WebComponent!'
},
viewUrl: '/assets/helloWorldWC.js',
viewUrl: '/assets/helloWorldWC.js?{i18n.currentLocale}',
webcomponent: true
},
{
Expand Down Expand Up @@ -343,6 +343,15 @@ export const projectDetailNavStructure = projectId => [
},
icon: 'globe'
},
{
label: 'Open SAP Website',
category: 'Super useful Github links',
externalLink: {
url: 'http://sap.com/{i18n.currentLocale}',
sameWindow: true
},
icon: 'globe'
},
{
pathSegment: 'collapsibles',
label: 'Collapsible categories',
Expand Down

0 comments on commit 0b3d903

Please sign in to comment.