feat: get tab navigation items from config

This commit is contained in:
Rainer Killinger
2022-10-20 11:19:06 +00:00
parent 5e1a902d4c
commit c3130a392a
15 changed files with 365 additions and 284 deletions

View File

@@ -159,7 +159,6 @@ export const sampleIndexResponse: SCIndexResponse = {
menus: [
{
icon: 'icon',
id: 'main',
items: [
{
icon: 'icon',
@@ -175,13 +174,14 @@ export const sampleIndexResponse: SCIndexResponse = {
},
},
],
name: 'main',
title: 'main',
route: '/main',
translations: {
de: {
name: 'Haupt',
title: 'Haupt',
},
en: {
name: 'main',
title: 'main',
},
},
},

View File

@@ -15,9 +15,7 @@
import {NgModule} from '@angular/core';
import {PreloadAllModules, RouterModule, Routes} from '@angular/router';
const routes: Routes = [
{path: '', redirectTo: '/dashboard', pathMatch: 'full'},
];
const routes: Routes = [{path: '', redirectTo: '/overview', pathMatch: 'full'}];
/**
* TODO
@@ -30,7 +28,7 @@ const routes: Routes = [
errorHandler: error => {
// Handle unknown routes, at the moment this can only be done via window.location
if (error.message.includes('Cannot match any routes')) {
window.location.href = '/dashboard';
window.location.href = '/overview';
}
},
}),

View File

@@ -49,7 +49,6 @@
</div>
<ion-content fullscreen="true" #ionContent>
<stapps-navigation-section></stapps-navigation-section>
<stapps-search-section
#search
(focusin)="onSearchBarFocus($event)"

View File

@@ -37,7 +37,7 @@ import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
const catalogRoutes: Routes = [
{
path: 'dashboard',
path: 'overview',
component: DashboardComponent,
},
];

View File

@@ -30,13 +30,24 @@
</ion-toolbar>
</ion-header>
<ion-content *ngIf="menu">
<ion-list *ngFor="let category of menu">
<ion-list-header *ngIf="category.name !== ''">
<ion-list *ngFor="let category of menu; first as isFirst">
<ion-item
*ngIf="category.title !== ''"
[rootLink]="category.route"
[redirectedFrom]="isFirst ? '/' : category.route"
lines="none"
class="menu-category"
>
<ion-icon slot="end" [name]="category.icon"></ion-icon>
<ion-label>
{{ category.translations[language].name | titlecase }}
{{ category.translations[language].title | titlecase }}
</ion-label>
</ion-list-header>
<ion-item *ngFor="let item of category.items" [rootLink]="item.route">
</ion-item>
<ion-item
*ngFor="let item of category.items"
[rootLink]="item.route"
[redirectedFrom]="item.route"
>
<ion-icon slot="end" [name]="item.icon"></ion-icon>
<ion-label>
{{ item.translations[language].title | titlecase }}

View File

@@ -51,6 +51,13 @@ ion-router-outlet {
background: white;
}
.menu-category {
ion-label {
font-weight: bold;
font-size: 115%;
}
}
.link-active > * {
color: var(--ion-color-primary);

View File

@@ -19,7 +19,7 @@ import {RouterModule, Routes} from '@angular/router';
const routes: Routes = [
{
path: '',
redirectTo: '/dashboard',
redirectTo: '/overview',
pathMatch: 'full',
},
];

View File

@@ -14,6 +14,7 @@
*/
import {Component} from '@angular/core';
import {NavigationEnd, Router} from '@angular/router';
import {
SCAppConfigurationMenuCategory,
SCLanguage,
@@ -33,29 +34,44 @@ export class TabsComponent {
/**
* Possible languages to be used for translation
*/
language: keyof SCTranslations<SCLanguage> = 'en';
language: keyof SCTranslations<SCLanguage>;
/**
* Menu entries from config module
*/
menu: SCAppConfigurationMenuCategory;
menu: SCAppConfigurationMenuCategory[];
/**
* Core translator
*/
translator: SCThingTranslator;
/**
* Name of selected tab
*/
selectedTab: string;
constructor(
private readonly configProvider: ConfigProvider,
public translateService: TranslateService,
private readonly logger: NGXLogger,
private readonly router: Router,
) {
this.language = this.translateService
.currentLang as keyof SCTranslations<SCLanguage>;
this.translator = new SCThingTranslator(this.language);
void this.loadMenuEntries();
this.router.events.subscribe((event: unknown) => {
if (event instanceof NavigationEnd) {
this.selectTab(event.url);
}
});
this.selectTab(router.url);
translateService.onLangChange?.subscribe((event: LangChangeEvent) => {
this.language = event.lang as keyof SCTranslations<SCLanguage>;
this.translator = new SCThingTranslator(this.language);
});
this.translator = new SCThingTranslator('en');
}
/**
@@ -67,7 +83,7 @@ export class TabsComponent {
'menus',
)) as SCAppConfigurationMenuCategory[];
const menu = menus.find(menu => menu.id === 'main');
const menu = menus.slice(0, 5);
if (menu) {
this.menu = menu;
}
@@ -75,4 +91,19 @@ export class TabsComponent {
this.logger.error(`error from loading menu entries: ${error}`);
}
}
/* eslint-disable @typescript-eslint/no-explicit-any */
selectTab(url: string) {
if (!this.menu) {
return;
}
if (url === '/') {
this.selectedTab = (this.menu[0] as any)?.title ?? '';
return;
}
const candidate = this.menu
.slice(0, 5)
.find(category => url.includes(category.route));
this.selectedTab = candidate?.title ?? '';
}
}

View File

@@ -16,6 +16,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
import {TestBed, waitForAsync} from '@angular/core/testing';
import {RouterTestingModule} from '@angular/router/testing';
import {TabsComponent} from './tabs.component';
import {ConfigProvider} from '../../config/config.provider';
@@ -80,7 +81,7 @@ describe('Tabs', () => {
TestBed.configureTestingModule({
declarations: [TabsComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
imports: [TranslateModule.forRoot()],
imports: [RouterTestingModule, TranslateModule.forRoot()],
providers: [
{provide: Platform, useValue: platformSpy},
{provide: TranslateService, useValue: translateServiceSpy},

View File

@@ -12,9 +12,9 @@
~ You should have received a copy of the GNU General Public License along with
~ this program. If not, see <https://www.gnu.org/licenses/>.
-->
<!--
<ion-tab-bar slot="bottom">
<ion-tab-button rootLink="/dashboard" redirectedFrom="/" tab="dashboard">
<ion-tab-button rootLink="/overview" redirectedFrom="/" tab="overview">
<ion-icon name="home"></ion-icon>
<ion-label>{{ 'tabs.home' | translate }}</ion-label>
</ion-tab-button>
@@ -31,3 +31,18 @@
<ion-label>{{ 'tabs.map' | translate }}</ion-label>
</ion-tab-button>
</ion-tab-bar>
-->
<ion-tab-bar slot="bottom" [selectedTab]="selectedTab">
<ion-tab-button
*ngFor="let category of menu; first as isFirst"
[rootLink]="category.route"
[redirectedFrom]="category.route"
[tab]="category.title"
>
<ion-icon [name]="category.icon"></ion-icon>
<ion-label>{{
category.translations[language].title | titlecase
}}</ion-label>
</ion-tab-button>
</ion-tab-bar>

View File

@@ -30,13 +30,6 @@
"UNKNOWN": "Unbekannter Fehler."
}
},
"tabs": {
"home": "Home",
"canteens": "Mensa",
"schedule": "Studium",
"map": "Karte",
"profile": "Profil"
},
"assessments": {
"TITLE": "Noten",
"courseOfStudyAssessments": {

View File

@@ -30,13 +30,6 @@
"UNKNOWN": "Unknown problem."
}
},
"tabs": {
"home": "Home",
"canteens": "Canteens",
"schedule": "Study",
"map": "Map",
"profile": "Profile"
},
"assessments": {
"TITLE": "Grades",
"courseOfStudyAssessments": {