Skip to content

Commit

Permalink
ContextSwitcher label cache (SAP#1467)
Browse files Browse the repository at this point in the history
  • Loading branch information
maxmarkus authored Jul 27, 2020
1 parent 575ecb8 commit 88f1777
Show file tree
Hide file tree
Showing 13 changed files with 116 additions and 28 deletions.
9 changes: 6 additions & 3 deletions core/src/navigation/ContextSwitcher.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,21 @@
{#if !isMobile}
<div class="fd-shellbar__action fd-shellbar__action--desktop">
<div class="fd-popover fd-popover--right">
<div class="fd-popover__control" on:click|stopPropagation="{() => {}}">
<div class="fd-popover__control" on:click|stopPropagation="{()=> {}}">
<button
class="fd-button fd-button--transparent fd-button--menu fd-shellbar__button--menu lui-ctx-switch-menu"
aria-expanded="{dropDownStates.contextSwitcherPopover || false}"
aria-haspopup="true"
title="{selectedLabel ? selectedLabel : config.defaultLabel}"
on:click="{() => {if (renderAsDropdown) toggleDropdownState()}}"
on:click="{()=> {if (renderAsDropdown) toggleDropdownState()}}"
aria-disabled="{!renderAsDropdown}"
data-testid="luigi-contextswitcher-button"
>
{#if selectedOption && customSelectedOptionRenderer }
{@html customSelectedOptionRenderer(selectedOption)}
{:else}
{#if !selectedLabel}{$getTranslation(config.defaultLabel)} {:else}{selectedLabel}{/if}
{#if !selectedLabel}{$getTranslation(config.defaultLabel)}
{:else}{selectedLabel}{/if}
{/if}
</button>
</div>
Expand Down Expand Up @@ -180,6 +181,8 @@ <h3 class="fd-dialog__title">

fallbackLabelResolver = contextSwitcherConfig.fallbackLabelResolver;

ContextSwitcherHelpers.resetFallbackLabelCache();

// options are loaded lazy by default
if (!contextSwitcherConfig.lazyloadOptions) {
await fetchOptions();
Expand Down
12 changes: 6 additions & 6 deletions core/src/navigation/ContextSwitcherNav.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
'bottom'].includes(node.position)}
<li
class="fd-menu__item"
on:click="{() => onActionClick(node)}"
on:click="{()=> onActionClick(node)}"
data-testid="{getTestId(node)}"
>
<a
href="{getRouteLink(node)}"
on:click|preventDefault="{() => {}}"
on:click|preventDefault="{()=> {}}"
class="fd-menu__link"
>
<span class="fd-menu__title">{$getTranslation(node.label)}</span>
Expand All @@ -33,15 +33,15 @@
node.id)} {:then label}
<li
class="fd-menu__item"
on:click="{() => goToOption(node, selectedOption)}"
on:click="{()=> goToOption(node, selectedOption)}"
data-testid="{getTestId(node)}"
>
{#if customOptionsRenderer}
{@html customOptionsRenderer(node, label === selectedLabel)}
{:else}
<a
href="{getRouteLink(node)}"
on:click|preventDefault="{() => {}}"
on:click|preventDefault="{()=> {}}"
class="fd-menu__link {label === selectedLabel ? 'is-selected' : ''}"
title="{label}"
>
Expand All @@ -56,12 +56,12 @@
{#each actions as node} {#if node.position === 'bottom'}
<li
class="fd-menu__item"
on:click="{() => onActionClick(node)}"
on:click="{()=> onActionClick(node)}"
data-testid="{getTestId(node)}"
>
<a
href="{getRouteLink(node)}"
on:click|preventDefault="{() => {}}"
on:click|preventDefault="{()=> {}}"
class="fd-menu__link"
>
<span class="fd-menu__title">{$getTranslation(node.label)}</span>
Expand Down
24 changes: 23 additions & 1 deletion core/src/navigation/services/context-switcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import { Routing } from '../../services/routing';
import { LuigiConfig } from '../../core-api';

export const ContextSwitcherHelpers = {
_fallbackLabels: new Map(),

resetFallbackLabelCache() {
this._fallbackLabels.clear();
},

getPreparedParentNodePath(config) {
if (!config.parentNodePath || !config.parentNodePath.startsWith('/')) {
console.error(
Expand Down Expand Up @@ -67,7 +73,23 @@ export const ContextSwitcherHelpers = {
},

async getFallbackLabel(fallbackLabelResolver, id) {
return fallbackLabelResolver ? await fallbackLabelResolver(id) : id;
if (!fallbackLabelResolver) {
return id;
}

const useFallbackLabelCache = LuigiConfig.getConfigBooleanValue(
'navigation.contextSwitcher.useFallbackLabelCache'
);
const labelCache = ContextSwitcherHelpers._fallbackLabels;
if (useFallbackLabelCache) {
if (labelCache.has(id)) {
return labelCache.get(id);
}
}

const label = await fallbackLabelResolver(id);
useFallbackLabelCache && labelCache.set(id, label);
return label;
},

getSelectedId(currentPath, options, parentNodePath) {
Expand Down
75 changes: 65 additions & 10 deletions core/test/context-switcher.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,17 @@ import { LuigiConfig } from '../src/core-api';
import { Routing } from '../src/services/routing';

describe('Context-switcher', function() {
let myResolverFn;
beforeEach(() => {
CSHelpers._fallbackLabels.clear();
myResolverFn = sinon.spy(id => {
return '##' + id + '##';
});
});
afterEach(() => {
sinon.restore();
sinon.reset();
sinon.resetHistory();
sinon.restore();
});

const getMockConfig = () => ({
Expand All @@ -26,10 +34,6 @@ describe('Context-switcher', function() {
options: []
});

const myResolverFn = id => {
return '##' + id + '##';
};

describe('getPreparedParentNodePath', () => {
let mockConfig;
beforeEach(() => {
Expand Down Expand Up @@ -71,6 +75,10 @@ describe('Context-switcher', function() {
});

describe('getFallbackLabel', () => {
beforeEach(() => {
sinon.stub(LuigiConfig, 'getConfigBooleanValue').returns(false);
});

it('works without fallback resolver', async () => {
const result = await CSHelpers.getFallbackLabel(undefined, 'some_id');
assert.equal(result, 'some_id');
Expand All @@ -79,6 +87,48 @@ describe('Context-switcher', function() {
it('works with fallback resolver', async () => {
const result = await CSHelpers.getFallbackLabel(myResolverFn, 'some_id');
assert.equal(result, '##some_id##');

sinon.assert.calledWithExactly(
LuigiConfig.getConfigBooleanValue,
'navigation.contextSwitcher.useFallbackLabelCache'
);
});

it('works with fallback resolver cached', async () => {
LuigiConfig.getConfigBooleanValue.returns(true);

const result = await CSHelpers.getFallbackLabel(myResolverFn, 'some_id');
assert.equal(result, '##some_id##');

const result2 = await CSHelpers.getFallbackLabel(myResolverFn, 'some_id');
assert.equal(result2, '##some_id##');

sinon.assert.calledOnce(myResolverFn);
});

it('works with fallback resolver cache disabled', async () => {
const result = await CSHelpers.getFallbackLabel(myResolverFn, 'some_id');
assert.equal(result, '##some_id##');

const result2 = await CSHelpers.getFallbackLabel(myResolverFn, 'some_id');
assert.equal(result2, '##some_id##');

sinon.assert.calledTwice(myResolverFn);
});
});

describe('resetFallbackLabelCache', () => {
beforeEach(() => {
CSHelpers._fallbackLabels.set('id_1', 'a');
CSHelpers._fallbackLabels.set('id_2', 'b');
});

it('works without fallback resolver', async () => {
assert.equal(CSHelpers._fallbackLabels.size, 2);

CSHelpers.resetFallbackLabelCache();

assert.equal(CSHelpers._fallbackLabels.size, 0);
});
});

Expand Down Expand Up @@ -429,7 +479,8 @@ describe('Context-switcher', function() {
'/environmentWhatever',
[],
parentNodePath,
myResolverFn
myResolverFn,
false
);
assert.equal(result, undefined);
});
Expand All @@ -439,7 +490,8 @@ describe('Context-switcher', function() {
'/something',
[],
parentNodePath,
myResolverFn
myResolverFn,
false
);
assert.equal(result, undefined);
});
Expand All @@ -451,7 +503,8 @@ describe('Context-switcher', function() {
'/environment/env2',
[env1, env2],
parentNodePath,
myResolverFn
myResolverFn,
false
);
assert.equal(result, env2.label);
});
Expand All @@ -463,7 +516,8 @@ describe('Context-switcher', function() {
'/environment/env3',
[env1, env2],
parentNodePath,
myResolverFn
myResolverFn,
false
);
assert.equal(result, '##env3##');
});
Expand All @@ -473,7 +527,8 @@ describe('Context-switcher', function() {
'/environment/env1?mask=opatol',
null,
parentNodePath,
myResolverFn
myResolverFn,
false
);
assert.equal(result, '##env1##');
});
Expand Down
1 change: 1 addition & 0 deletions docs/navigation-advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ contextSwitcher: {
parentNodePath: '/environments',
lazyloadOptions: false,
fallbackLabelResolver: (id) => (id.toUpperCase()),
useFallbackLabelCache: true,
options: [{label, pathValue,customRendererCategory}, {label, pathValue, customRendererCategory}],
customSelectedOptionRenderer: (option) => {
let color = "white";
Expand Down
1 change: 1 addition & 0 deletions docs/navigation-configuration-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ Luigi.setConfig({
parentNodePath: '/environments',
lazyloadOptions: false,
fallbackLabelResolver: (id) => (id.toUpperCase()),
useFallbackLabelCache: true,
options: [{label,pathValue}, {label,pathValue}],
actions: [{label,link,position,clickHandler}]
},
Expand Down
5 changes: 5 additions & 0 deletions docs/navigation-parameters-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,11 @@ The context switcher is a drop-down list available in the top navigation bar. It
- **type**: any
- **description**: specifies a function used to fetch the **label** for **options** with no **label** defined. Additionally, it fetches the drop-down label for non-existing **options**.
### useFallbackLabelCache
- **type**: boolean
- **description**: if set to `true`, the labels retrieved through **fallbackLabelResolver** are cached within Luigi. This is useful, if **fallbackLabelResolver** is an async function which does a remote server call to fetch its value.
- **since**: NEXTRELEASE
### preserveSubPathOnSwitch
- **type**: boolean
- **description**: if set to `true`, the sub-path is preserved on context switch.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,8 @@ class Navigation {
* context (option) is not listed in available options (eg kyma-system namespace),
* or if options have not been fetched yet
*/
fallbackLabelResolver: id => id.replace(/\b\w/g, l => l.toUpperCase())
fallbackLabelResolver: id => id.replace(/\b\w/g, l => l.toUpperCase()),
useFallbackLabelCache: true
};

getProductSwitcherItems = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<!-- Excerpt -->

<p>The Luigi project is growing quickly and attracting more attention in the open-source community. Micro frontend architecture is becoming more popular as an efficient strategy for future-proof, scalable applications. New features are added to Luigi regularly, and we want to keep you up to date.</p>
<p>This is why we are adding a blog to our website to inform you of the latest Luigi releases, updates, and other important news! You can expect regular posts in the future documenting every release and other Luigi-related topics. If you have an idea for a blog post, you can write to <a href="mailto:&#97;&#108;&#101;&#107;&#115;&#97;&#x6e;&#100;&#114;&#x61;&#x2e;&#115;&#105;&#x6d;&#x65;&#111;&#x6e;&#111;&#118;&#x61;&#64;&#115;&#x61;&#x70;&#x2e;&#99;&#x6f;&#109;">&#97;&#108;&#101;&#107;&#115;&#97;&#x6e;&#100;&#114;&#x61;&#x2e;&#115;&#105;&#x6d;&#x65;&#111;&#x6e;&#111;&#118;&#x61;&#64;&#115;&#x61;&#x70;&#x2e;&#99;&#x6f;&#109;</a>.</p>
<p>This is why we are adding a blog to our website to inform you of the latest Luigi releases, updates, and other important news! You can expect regular posts in the future documenting every release and other Luigi-related topics. If you have an idea for a blog post, you can write to <a href="mailto:&#97;&#108;&#101;&#107;&#x73;&#97;&#110;&#100;&#x72;&#97;&#46;&#x73;&#105;&#x6d;&#101;&#x6f;&#x6e;&#x6f;&#118;&#x61;&#x40;&#115;&#x61;&#112;&#x2e;&#99;&#x6f;&#x6d;">&#97;&#108;&#101;&#107;&#x73;&#97;&#110;&#100;&#x72;&#97;&#46;&#x73;&#105;&#x6d;&#101;&#x6f;&#x6e;&#x6f;&#118;&#x61;&#x40;&#115;&#x61;&#112;&#x2e;&#99;&#x6f;&#x6d;</a>.</p>
<p>And yes, our first blog post is just to let you know that we have a blog now. #meta #nerdy</p>
<p>P.S. Follow us on <a href="https://twitter.com/luigiprojectio?lang=en">Twitter</a> and <a href="https://www.youtube.com/channel/UC5WsYsHapDlg2K3iXS4n4AQ">YouTube</a> for more Luigi content.</p>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
<!-- Excerpt -->

<p>The Luigi project is growing quickly and attracting more attention in the open-source community. Micro frontend architecture is becoming more popular as an efficient strategy for future-proof, scalable applications. New features are added to Luigi regularly, and we want to keep you up to date.</p>
<p>This is why we are adding a blog to our website to inform you of the latest Luigi releases, updates, and other important news! You can expect regular posts in the future documenting every release and other Luigi-related topics. If you have an idea for a blog post, you can write to <a href="mailto:&#97;&#108;&#101;&#107;&#115;&#97;&#x6e;&#100;&#114;&#x61;&#x2e;&#115;&#105;&#x6d;&#x65;&#111;&#x6e;&#111;&#118;&#x61;&#64;&#115;&#x61;&#x70;&#x2e;&#99;&#x6f;&#109;">&#97;&#108;&#101;&#107;&#115;&#97;&#x6e;&#100;&#114;&#x61;&#x2e;&#115;&#105;&#x6d;&#x65;&#111;&#x6e;&#111;&#118;&#x61;&#64;&#115;&#x61;&#x70;&#x2e;&#99;&#x6f;&#109;</a>.</p>
<p>This is why we are adding a blog to our website to inform you of the latest Luigi releases, updates, and other important news! You can expect regular posts in the future documenting every release and other Luigi-related topics. If you have an idea for a blog post, you can write to <a href="mailto:&#97;&#108;&#101;&#107;&#x73;&#97;&#110;&#100;&#x72;&#97;&#46;&#x73;&#105;&#x6d;&#101;&#x6f;&#x6e;&#x6f;&#118;&#x61;&#x40;&#115;&#x61;&#112;&#x2e;&#99;&#x6f;&#x6d;">&#97;&#108;&#101;&#107;&#x73;&#97;&#110;&#100;&#x72;&#97;&#46;&#x73;&#105;&#x6d;&#101;&#x6f;&#x6e;&#x6f;&#118;&#x61;&#x40;&#115;&#x61;&#112;&#x2e;&#99;&#x6f;&#x6d;</a>.</p>
<p>And yes, our first blog post is just to let you know that we have a blog now. #meta #nerdy</p>
<p>P.S. Follow us on <a href="https://twitter.com/luigiprojectio?lang=en">Twitter</a> and <a href="https://www.youtube.com/channel/UC5WsYsHapDlg2K3iXS4n4AQ">YouTube</a> for more Luigi content.</p>

Expand Down
4 changes: 2 additions & 2 deletions website/landingpage/public/blog/feeds/atom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<feed xmlns="http://www.w3.org/2005/Atom">
<id>https://luigi-project.io/blog</id>
<title>Luigi Blog</title>
<updated>2020-07-16T15:00:55.152Z</updated>
<updated>2020-07-24T09:46:04.365Z</updated>
<generator>Luigi Project</generator>
<author>
<name>Luigi project authors</name>
Expand All @@ -26,7 +26,7 @@
<!-- Excerpt -->
<p>The Luigi project is growing quickly and attracting more attention in the open-source community. Micro frontend architecture is becoming more popular as an efficient strategy for future-proof, scalable applications. New features are added to Luigi regularly, and we want to keep you up to date.</p>
<p>This is why we are adding a blog to our website to inform you of the latest Luigi releases, updates, and other important news! You can expect regular posts in the future documenting every release and other Luigi-related topics. If you have an idea for a blog post, you can write to <a href="mailto:&#97;&#108;&#101;&#107;&#115;&#97;&#x6e;&#100;&#114;&#x61;&#x2e;&#115;&#105;&#x6d;&#x65;&#111;&#x6e;&#111;&#118;&#x61;&#64;&#115;&#x61;&#x70;&#x2e;&#99;&#x6f;&#109;">&#97;&#108;&#101;&#107;&#115;&#97;&#x6e;&#100;&#114;&#x61;&#x2e;&#115;&#105;&#x6d;&#x65;&#111;&#x6e;&#111;&#118;&#x61;&#64;&#115;&#x61;&#x70;&#x2e;&#99;&#x6f;&#109;</a>.</p>
<p>This is why we are adding a blog to our website to inform you of the latest Luigi releases, updates, and other important news! You can expect regular posts in the future documenting every release and other Luigi-related topics. If you have an idea for a blog post, you can write to <a href="mailto:&#97;&#108;&#101;&#107;&#x73;&#97;&#110;&#100;&#x72;&#97;&#46;&#x73;&#105;&#x6d;&#101;&#x6f;&#x6e;&#x6f;&#118;&#x61;&#x40;&#115;&#x61;&#112;&#x2e;&#99;&#x6f;&#x6d;">&#97;&#108;&#101;&#107;&#x73;&#97;&#110;&#100;&#x72;&#97;&#46;&#x73;&#105;&#x6d;&#101;&#x6f;&#x6e;&#x6f;&#118;&#x61;&#x40;&#115;&#x61;&#112;&#x2e;&#99;&#x6f;&#x6d;</a>.</p>
<p>And yes, our first blog post is just to let you know that we have a blog now. #meta #nerdy</p>
<p>P.S. Follow us on <a href="https://twitter.com/luigiprojectio?lang=en">Twitter</a> and <a href="https://www.youtube.com/channel/UC5WsYsHapDlg2K3iXS4n4AQ">YouTube</a> for more Luigi content.</p>
]]></content>
Expand Down
2 changes: 1 addition & 1 deletion website/landingpage/public/blog/feeds/feed.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"items": [
{
"id": "https://luigi-project.io/blog/2020-06-18-welcome-to-luigi-blog",
"content_html": "<p>The new blog section of our website will help you stay on top of the latest Luigi news and updates.</p>\n<!-- Excerpt -->\n\n<p>The Luigi project is growing quickly and attracting more attention in the open-source community. Micro frontend architecture is becoming more popular as an efficient strategy for future-proof, scalable applications. New features are added to Luigi regularly, and we want to keep you up to date.</p>\n<p>This is why we are adding a blog to our website to inform you of the latest Luigi releases, updates, and other important news! You can expect regular posts in the future documenting every release and other Luigi-related topics. If you have an idea for a blog post, you can write to <a href=\"mailto:&#97;&#108;&#101;&#107;&#115;&#97;&#x6e;&#100;&#114;&#x61;&#x2e;&#115;&#105;&#x6d;&#x65;&#111;&#x6e;&#111;&#118;&#x61;&#64;&#115;&#x61;&#x70;&#x2e;&#99;&#x6f;&#109;\">&#97;&#108;&#101;&#107;&#115;&#97;&#x6e;&#100;&#114;&#x61;&#x2e;&#115;&#105;&#x6d;&#x65;&#111;&#x6e;&#111;&#118;&#x61;&#64;&#115;&#x61;&#x70;&#x2e;&#99;&#x6f;&#109;</a>.</p>\n<p>And yes, our first blog post is just to let you know that we have a blog now. #meta #nerdy</p>\n<p>P.S. Follow us on <a href=\"https://twitter.com/luigiprojectio?lang=en\">Twitter</a> and <a href=\"https://www.youtube.com/channel/UC5WsYsHapDlg2K3iXS4n4AQ\">YouTube</a> for more Luigi content.</p>\n",
"content_html": "<p>The new blog section of our website will help you stay on top of the latest Luigi news and updates.</p>\n<!-- Excerpt -->\n\n<p>The Luigi project is growing quickly and attracting more attention in the open-source community. Micro frontend architecture is becoming more popular as an efficient strategy for future-proof, scalable applications. New features are added to Luigi regularly, and we want to keep you up to date.</p>\n<p>This is why we are adding a blog to our website to inform you of the latest Luigi releases, updates, and other important news! You can expect regular posts in the future documenting every release and other Luigi-related topics. If you have an idea for a blog post, you can write to <a href=\"mailto:&#97;&#108;&#101;&#107;&#x73;&#97;&#110;&#100;&#x72;&#97;&#46;&#x73;&#105;&#x6d;&#101;&#x6f;&#x6e;&#x6f;&#118;&#x61;&#x40;&#115;&#x61;&#112;&#x2e;&#99;&#x6f;&#x6d;\">&#97;&#108;&#101;&#107;&#x73;&#97;&#110;&#100;&#x72;&#97;&#46;&#x73;&#105;&#x6d;&#101;&#x6f;&#x6e;&#x6f;&#118;&#x61;&#x40;&#115;&#x61;&#112;&#x2e;&#99;&#x6f;&#x6d;</a>.</p>\n<p>And yes, our first blog post is just to let you know that we have a blog now. #meta #nerdy</p>\n<p>P.S. Follow us on <a href=\"https://twitter.com/luigiprojectio?lang=en\">Twitter</a> and <a href=\"https://www.youtube.com/channel/UC5WsYsHapDlg2K3iXS4n4AQ\">YouTube</a> for more Luigi content.</p>\n",
"url": "https://luigi-project.io/blog/2020-06-18-welcome-to-luigi-blog",
"title": "Welcome to the Luigi blog!",
"summary": "This is our first blog entry and it introduces our new blog section.",
Expand Down
Loading

0 comments on commit 88f1777

Please sign in to comment.