Skip to content
Snippets Groups Projects
Commit f3659a0b authored by Reiter, Christoph's avatar Reiter, Christoph :snake:
Browse files

app-shell: keep the activity list on the welcome page in sync with the main menu

Instead of handling the visibility checks at render time we keep around a list
of visible routes and emit an event when they change. This way the welcome activity
can mirror what the menu shows and update at the same time.
parent 1921f653
No related branches found
No related tags found
No related merge requests found
Pipeline #17801 failed
...@@ -50,6 +50,7 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) { ...@@ -50,6 +50,7 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) {
this.subtitle = ''; this.subtitle = '';
this.description = ''; this.description = '';
this.routes = []; this.routes = [];
this.visibleRoutes = [];
this.metadata = {}; this.metadata = {};
this.topic = {}; this.topic = {};
this.basePath = '/'; this.basePath = '/';
...@@ -236,6 +237,7 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) { ...@@ -236,6 +237,7 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) {
entryPointUrl: { type: String, attribute: 'entry-point-url' }, entryPointUrl: { type: String, attribute: 'entry-point-url' },
keycloakConfig: { type: Object, attribute: 'keycloak-config' }, keycloakConfig: { type: Object, attribute: 'keycloak-config' },
metadata: { type: Object, attribute: false }, metadata: { type: Object, attribute: false },
visibleRoutes: { type: Array, attribute: false },
topic: { type: Object, attribute: false }, topic: { type: Object, attribute: false },
subtitle: { type: String, attribute: false }, subtitle: { type: String, attribute: false },
description: { type: String, attribute: false }, description: { type: String, attribute: false },
...@@ -291,6 +293,11 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) { ...@@ -291,6 +293,11 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) {
this.subtitle = this.activeMetaDataText("short_name"); this.subtitle = this.activeMetaDataText("short_name");
this.description = this.activeMetaDataText("description"); this.description = this.activeMetaDataText("description");
break; break;
case 'metadata':
{
this._updateVisibleRoutes();
}
break;
case 'auth': case 'auth':
{ {
if (this.auth.person) { if (this.auth.person) {
...@@ -298,6 +305,7 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) { ...@@ -298,6 +305,7 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) {
} else { } else {
this._roles = []; this._roles = [];
} }
this._updateVisibleRoutes();
const loginStatus = this.auth['login-status']; const loginStatus = this.auth['login-status'];
if (loginStatus !== this._loginStatus) { if (loginStatus !== this._loginStatus) {
...@@ -770,6 +778,36 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) { ...@@ -770,6 +778,36 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) {
return elm; return elm;
} }
_updateVisibleRoutes() {
let visibleRoutes = [];
for (let routingName of this.routes) {
const data = this.metadata[routingName];
const requiredRoles = data['required_roles'];
let visible = data['visible'];
// Hide them until the user is logged in and we know the roles of the user
for (let role of requiredRoles) {
if (!this._roles.includes(role)) {
visible = false;
break;
}
}
if (visible) {
visibleRoutes.push(routingName);
}
}
this.visibleRoutes = visibleRoutes;
const event = new CustomEvent("visibility-changed", {
bubbles: false,
cancelable: true,
});
this.dispatchEvent(event);
}
render() { render() {
const getSelectClasses = (name => { const getSelectClasses = (name => {
return classMap({selected: this.activeView === name}); return classMap({selected: this.activeView === name});
...@@ -797,22 +835,8 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) { ...@@ -797,22 +835,8 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) {
// build the menu // build the menu
let menuTemplates = []; let menuTemplates = [];
for (let routingName of this.routes) { for (let routingName of this.visibleRoutes) {
const data = this.metadata[routingName]; menuTemplates.push(html`<li><a @click="${(e) => this.onMenuItemClick(e)}" href="${this.router.getPathname({component: routingName})}" data-nav class="${getSelectClasses(routingName)}" title="${this.metaDataText(routingName, "description")}">${this.metaDataText(routingName, "short_name")}</a></li>`);
const requiredRoles = data['required_roles'];
let visible = data['visible'];
// Hide them until the user is logged in and we knwo the roles of the user
for (let role of requiredRoles) {
if (!this._roles.includes(role)) {
visible = false;
break;
}
}
if (visible) {
menuTemplates.push(html`<li><a @click="${(e) => this.onMenuItemClick(e)}" href="${this.router.getPathname({component: routingName})}" data-nav class="${getSelectClasses(routingName)}" title="${this.metaDataText(routingName, "description")}">${this.metaDataText(routingName, "short_name")}</a></li>`);
}
} }
const imprintUrl = this.lang === "en" ? const imprintUrl = this.lang === "en" ?
......
...@@ -11,6 +11,8 @@ class AppShellWelcome extends ScopedElementsMixin(LitElement) { ...@@ -11,6 +11,8 @@ class AppShellWelcome extends ScopedElementsMixin(LitElement) {
constructor() { constructor() {
super(); super();
this.lang = i18n.language; this.lang = i18n.language;
this._onVisibilityChanged = this._onVisibilityChanged.bind(this);
} }
static get properties() { static get properties() {
...@@ -54,9 +56,26 @@ class AppShellWelcome extends ScopedElementsMixin(LitElement) { ...@@ -54,9 +56,26 @@ class AppShellWelcome extends ScopedElementsMixin(LitElement) {
`; `;
} }
_onVisibilityChanged() {
this.requestUpdate();
}
connectedCallback() {
super.connectedCallback();
const app = AppShellWelcome._app;
app.addEventListener('visibility-changed', this._onVisibilityChanged);
}
disconnectedCallback() {
const app = AppShellWelcome._app;
app.removeEventListener('visibility-changed', this._onVisibilityChanged);
super.disconnectedCallback();
}
render() { render() {
const app = AppShellWelcome._app; const app = AppShellWelcome._app;
let metadata = app.metadata;
let itemTemplates = []; let itemTemplates = [];
const switchActivity = (e, data) => { const switchActivity = (e, data) => {
...@@ -64,9 +83,10 @@ class AppShellWelcome extends ScopedElementsMixin(LitElement) { ...@@ -64,9 +83,10 @@ class AppShellWelcome extends ScopedElementsMixin(LitElement) {
app.switchComponent(data.routing_name); app.switchComponent(data.routing_name);
}; };
for (let [key, data] of Object.entries(metadata)) { for (let routeName of app.visibleRoutes) {
let data = app.metadata[routeName];
if (data['visible'] && (key !== "welcome")) { if (routeName !== "welcome") {
itemTemplates.push(html` itemTemplates.push(html`
<div class="item"> <div class="item">
<h2><a href="#" @click=${(e) => {switchActivity(e, data);}}>${data.name[this.lang]}</a></h2> <h2><a href="#" @click=${(e) => {switchActivity(e, data);}}>${data.name[this.lang]}</a></h2>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment