Browse Source

Extract page tabs

pull/6797/head
Thomas Kaul 4 weeks ago
parent
commit
717a760d91
  1. 24
      apps/client/src/app/pages/about/about-page.component.ts
  2. 31
      apps/client/src/app/pages/about/about-page.html
  3. 12
      apps/client/src/app/pages/admin/admin-page.component.ts
  4. 31
      apps/client/src/app/pages/admin/admin-page.html
  5. 22
      apps/client/src/app/pages/faq/faq-page.component.ts
  6. 31
      apps/client/src/app/pages/faq/faq-page.html
  7. 13
      apps/client/src/app/pages/home/home-page.component.ts
  8. 31
      apps/client/src/app/pages/home/home-page.html
  9. 21
      apps/client/src/app/pages/portfolio/portfolio-page.component.ts
  10. 31
      apps/client/src/app/pages/portfolio/portfolio-page.html
  11. 18
      apps/client/src/app/pages/resources/resources-page.component.ts
  12. 31
      apps/client/src/app/pages/resources/resources-page.html
  13. 24
      apps/client/src/app/pages/user-account/user-account-page.component.ts
  14. 31
      apps/client/src/app/pages/user-account/user-account-page.html
  15. 22
      apps/client/src/app/pages/zen/zen-page.component.ts
  16. 31
      apps/client/src/app/pages/zen/zen-page.html
  17. 3
      apps/client/src/styles.scss
  18. 1
      libs/ui/src/lib/page-tabs/index.ts
  19. 30
      libs/ui/src/lib/page-tabs/page-tabs.component.html
  20. 5
      libs/ui/src/lib/page-tabs/page-tabs.component.scss
  21. 23
      libs/ui/src/lib/page-tabs/page-tabs.component.ts

24
apps/client/src/app/pages/about/about-page.component.ts

@ -2,19 +2,11 @@ import { UserService } from '@ghostfolio/client/services/user/user.service';
import { TabConfiguration, User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { GfPageTabsComponent } from '@ghostfolio/ui/page-tabs';
import { DataService } from '@ghostfolio/ui/services';
import {
ChangeDetectorRef,
Component,
CUSTOM_ELEMENTS_SCHEMA,
DestroyRef,
OnInit
} from '@angular/core';
import { ChangeDetectorRef, Component, DestroyRef } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { MatTabsModule } from '@angular/material/tabs';
import { RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone';
import { addIcons } from 'ionicons';
import {
documentTextOutline,
@ -24,18 +16,15 @@ import {
shieldCheckmarkOutline,
sparklesOutline
} from 'ionicons/icons';
import { DeviceDetectorService } from 'ngx-device-detector';
@Component({
host: { class: 'page has-tabs' },
imports: [IonIcon, MatTabsModule, RouterModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
imports: [GfPageTabsComponent],
selector: 'gf-about-page',
styleUrls: ['./about-page.scss'],
templateUrl: './about-page.html'
})
export class AboutPageComponent implements OnInit {
public deviceType: string;
export class AboutPageComponent {
public hasPermissionForSubscription: boolean;
public tabs: TabConfiguration[] = [];
public user: User;
@ -44,7 +33,6 @@ export class AboutPageComponent implements OnInit {
private changeDetectorRef: ChangeDetectorRef,
private dataService: DataService,
private destroyRef: DestroyRef,
private deviceDetectorService: DeviceDetectorService,
private userService: UserService
) {
const { globalPermissions } = this.dataService.fetchInfo();
@ -112,8 +100,4 @@ export class AboutPageComponent implements OnInit {
sparklesOutline
});
}
public ngOnInit() {
this.deviceType = this.deviceDetectorService.getDeviceInfo().deviceType;
}
}

31
apps/client/src/app/pages/about/about-page.html

@ -1,30 +1 @@
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto">
<router-outlet />
</mat-tab-nav-panel>
<nav
mat-align-tabs="center"
mat-tab-nav-bar
[disablePagination]="true"
[tabPanel]="tabPanel"
>
@for (tab of tabs; track tab) {
@if (tab.showCondition !== false) {
<a
#rla="routerLinkActive"
class="no-min-width px-3"
mat-tab-link
routerLinkActive
[active]="rla.isActive"
[routerLink]="tab.routerLink"
[routerLinkActiveOptions]="{ exact: true }"
>
<ion-icon
[name]="tab.iconName"
[size]="deviceType === 'mobile' ? 'large' : 'small'"
/>
<div class="d-none d-sm-block ml-2">{{ tab.label }}</div>
</a>
}
}
</nav>
<gf-page-tabs [tabs]="tabs" />

12
apps/client/src/app/pages/admin/admin-page.component.ts

@ -1,10 +1,8 @@
import { TabConfiguration } from '@ghostfolio/common/interfaces';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { GfPageTabsComponent } from '@ghostfolio/ui/page-tabs';
import { Component, OnInit } from '@angular/core';
import { MatTabsModule } from '@angular/material/tabs';
import { RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone';
import { addIcons } from 'ionicons';
import {
flashOutline,
@ -13,20 +11,18 @@ import {
serverOutline,
settingsOutline
} from 'ionicons/icons';
import { DeviceDetectorService } from 'ngx-device-detector';
@Component({
host: { class: 'page has-tabs' },
imports: [IonIcon, MatTabsModule, RouterModule],
imports: [GfPageTabsComponent],
selector: 'gf-admin-page',
styleUrls: ['./admin-page.scss'],
templateUrl: './admin-page.html'
})
export class AdminPageComponent implements OnInit {
public deviceType: string;
public tabs: TabConfiguration[] = [];
public constructor(private deviceDetectorService: DeviceDetectorService) {
public constructor() {
addIcons({
flashOutline,
peopleOutline,
@ -37,8 +33,6 @@ export class AdminPageComponent implements OnInit {
}
public ngOnInit() {
this.deviceType = this.deviceDetectorService.getDeviceInfo().deviceType;
this.tabs = [
{
iconName: 'reader-outline',

31
apps/client/src/app/pages/admin/admin-page.html

@ -1,30 +1 @@
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto">
<router-outlet />
</mat-tab-nav-panel>
<nav
mat-align-tabs="center"
mat-tab-nav-bar
[disablePagination]="true"
[tabPanel]="tabPanel"
>
@for (tab of tabs; track tab) {
@if (tab.showCondition !== false) {
<a
#rla="routerLinkActive"
class="no-min-width px-3"
mat-tab-link
routerLinkActive
[active]="rla.isActive"
[routerLink]="tab.routerLink"
[routerLinkActiveOptions]="{ exact: true }"
>
<ion-icon
[name]="tab.iconName"
[size]="deviceType === 'mobile' ? 'large' : 'small'"
/>
<div class="d-none d-sm-block ml-2" [innerHTML]="tab.label"></div>
</a>
}
}
</nav>
<gf-page-tabs [tabs]="tabs" />

22
apps/client/src/app/pages/faq/faq-page.component.ts

@ -1,33 +1,25 @@
import { TabConfiguration } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { GfPageTabsComponent } from '@ghostfolio/ui/page-tabs';
import { DataService } from '@ghostfolio/ui/services';
import { CUSTOM_ELEMENTS_SCHEMA, Component, OnInit } from '@angular/core';
import { MatTabsModule } from '@angular/material/tabs';
import { RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone';
import { Component } from '@angular/core';
import { addIcons } from 'ionicons';
import { cloudyOutline, readerOutline, serverOutline } from 'ionicons/icons';
import { DeviceDetectorService } from 'ngx-device-detector';
@Component({
host: { class: 'page has-tabs' },
imports: [IonIcon, MatTabsModule, RouterModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
imports: [GfPageTabsComponent],
selector: 'gf-faq-page',
styleUrls: ['./faq-page.scss'],
templateUrl: './faq-page.html'
})
export class GfFaqPageComponent implements OnInit {
public deviceType: string;
export class GfFaqPageComponent {
public hasPermissionForSubscription: boolean;
public tabs: TabConfiguration[] = [];
public constructor(
private dataService: DataService,
private deviceDetectorService: DeviceDetectorService
) {
public constructor(private dataService: DataService) {
const { globalPermissions } = this.dataService.fetchInfo();
this.hasPermissionForSubscription = hasPermission(
@ -56,8 +48,4 @@ export class GfFaqPageComponent implements OnInit {
addIcons({ cloudyOutline, readerOutline, serverOutline });
}
public ngOnInit() {
this.deviceType = this.deviceDetectorService.getDeviceInfo().deviceType;
}
}

31
apps/client/src/app/pages/faq/faq-page.html

@ -1,30 +1 @@
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto">
<router-outlet />
</mat-tab-nav-panel>
<nav
mat-align-tabs="center"
mat-tab-nav-bar
[disablePagination]="true"
[tabPanel]="tabPanel"
>
@for (tab of tabs; track tab) {
@if (tab.showCondition !== false) {
<a
#rla="routerLinkActive"
class="no-min-width px-3"
mat-tab-link
routerLinkActive
[active]="rla.isActive"
[routerLink]="tab.routerLink"
[routerLinkActiveOptions]="{ exact: true }"
>
<ion-icon
[name]="tab.iconName"
[size]="deviceType === 'mobile' ? 'large' : 'small'"
/>
<div class="d-none d-sm-block ml-2">{{ tab.label }}</div>
</a>
}
}
</nav>
<gf-page-tabs [tabs]="tabs" />

13
apps/client/src/app/pages/home/home-page.component.ts

@ -3,18 +3,15 @@ import { UserService } from '@ghostfolio/client/services/user/user.service';
import { TabConfiguration, User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { GfPageTabsComponent } from '@ghostfolio/ui/page-tabs';
import {
ChangeDetectorRef,
Component,
CUSTOM_ELEMENTS_SCHEMA,
DestroyRef,
OnInit
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { MatTabsModule } from '@angular/material/tabs';
import { RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone';
import { addIcons } from 'ionicons';
import {
albumsOutline,
@ -23,18 +20,15 @@ import {
newspaperOutline,
readerOutline
} from 'ionicons/icons';
import { DeviceDetectorService } from 'ngx-device-detector';
@Component({
host: { class: 'page has-tabs' },
imports: [IonIcon, MatTabsModule, RouterModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
imports: [GfPageTabsComponent],
selector: 'gf-home-page',
styleUrls: ['./home-page.scss'],
templateUrl: './home-page.html'
})
export class GfHomePageComponent implements OnInit {
public deviceType: string;
public hasImpersonationId: boolean;
public tabs: TabConfiguration[] = [];
public user: User;
@ -42,7 +36,6 @@ export class GfHomePageComponent implements OnInit {
public constructor(
private changeDetectorRef: ChangeDetectorRef,
private destroyRef: DestroyRef,
private deviceDetectorService: DeviceDetectorService,
private impersonationStorageService: ImpersonationStorageService,
private userService: UserService
) {
@ -104,8 +97,6 @@ export class GfHomePageComponent implements OnInit {
}
public ngOnInit() {
this.deviceType = this.deviceDetectorService.getDeviceInfo().deviceType;
this.impersonationStorageService
.onChangeHasImpersonation()
.pipe(takeUntilDestroyed(this.destroyRef))

31
apps/client/src/app/pages/home/home-page.html

@ -1,30 +1 @@
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto">
<router-outlet />
</mat-tab-nav-panel>
<nav
mat-align-tabs="center"
mat-tab-nav-bar
[disablePagination]="true"
[tabPanel]="tabPanel"
>
@for (tab of tabs; track tab) {
@if (tab.showCondition !== false) {
<a
#rla="routerLinkActive"
class="no-min-width px-3"
mat-tab-link
routerLinkActive
[active]="rla.isActive"
[routerLink]="tab.routerLink"
[routerLinkActiveOptions]="{ exact: true }"
>
<ion-icon
[name]="tab.iconName"
[size]="deviceType === 'mobile' ? 'large' : 'small'"
/>
<div class="d-none d-sm-block ml-2">{{ tab.label }}</div>
</a>
}
}
</nav>
<gf-page-tabs [tabs]="tabs" />

21
apps/client/src/app/pages/portfolio/portfolio-page.component.ts

@ -1,16 +1,10 @@
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { TabConfiguration, User } from '@ghostfolio/common/interfaces';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { GfPageTabsComponent } from '@ghostfolio/ui/page-tabs';
import {
ChangeDetectorRef,
Component,
DestroyRef,
OnInit
} from '@angular/core';
import { ChangeDetectorRef, Component, DestroyRef } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { MatTabsModule } from '@angular/material/tabs';
import { RouterModule } from '@angular/router';
import { addIcons } from 'ionicons';
import {
analyticsOutline,
@ -19,24 +13,21 @@ import {
scanOutline,
swapVerticalOutline
} from 'ionicons/icons';
import { DeviceDetectorService } from 'ngx-device-detector';
@Component({
host: { class: 'page has-tabs' },
imports: [MatTabsModule, RouterModule],
imports: [GfPageTabsComponent],
selector: 'gf-portfolio-page',
styleUrls: ['./portfolio-page.scss'],
templateUrl: './portfolio-page.html'
})
export class PortfolioPageComponent implements OnInit {
public deviceType: string;
export class PortfolioPageComponent {
public tabs: TabConfiguration[] = [];
public user: User;
public constructor(
private changeDetectorRef: ChangeDetectorRef,
private destroyRef: DestroyRef,
private deviceDetectorService: DeviceDetectorService,
private userService: UserService
) {
this.userService.stateChanged
@ -86,8 +77,4 @@ export class PortfolioPageComponent implements OnInit {
swapVerticalOutline
});
}
public ngOnInit() {
this.deviceType = this.deviceDetectorService.getDeviceInfo().deviceType;
}
}

31
apps/client/src/app/pages/portfolio/portfolio-page.html

@ -1,30 +1 @@
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto">
<router-outlet />
</mat-tab-nav-panel>
<nav
mat-align-tabs="center"
mat-tab-nav-bar
[disablePagination]="true"
[tabPanel]="tabPanel"
>
@for (tab of tabs; track tab) {
@if (tab.showCondition !== false) {
<a
#rla="routerLinkActive"
class="no-min-width px-3"
mat-tab-link
routerLinkActive
[active]="rla.isActive"
[routerLink]="tab.routerLink"
[routerLinkActiveOptions]="{ exact: true }"
>
<ion-icon
[name]="tab.iconName"
[size]="deviceType === 'mobile' ? 'large' : 'small'"
/>
<div class="d-none d-sm-block ml-2">{{ tab.label }}</div>
</a>
}
}
</nav>
<gf-page-tabs [tabs]="tabs" />

18
apps/client/src/app/pages/resources/resources-page.component.ts

@ -1,10 +1,8 @@
import { TabConfiguration } from '@ghostfolio/common/interfaces';
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { GfPageTabsComponent } from '@ghostfolio/ui/page-tabs';
import { Component, OnInit } from '@angular/core';
import { MatTabsModule } from '@angular/material/tabs';
import { RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone';
import { Component } from '@angular/core';
import { addIcons } from 'ionicons';
import {
bookOutline,
@ -12,17 +10,15 @@ import {
newspaperOutline,
readerOutline
} from 'ionicons/icons';
import { DeviceDetectorService } from 'ngx-device-detector';
@Component({
host: { class: 'page has-tabs' },
imports: [IonIcon, MatTabsModule, RouterModule],
imports: [GfPageTabsComponent],
selector: 'gf-resources-page',
styleUrls: ['./resources-page.scss'],
templateUrl: './resources-page.html'
})
export class ResourcesPageComponent implements OnInit {
public deviceType: string;
export class ResourcesPageComponent {
public tabs: TabConfiguration[] = [
{
iconName: 'reader-outline',
@ -46,11 +42,7 @@ export class ResourcesPageComponent implements OnInit {
}
];
public constructor(private deviceDetectorService: DeviceDetectorService) {
public constructor() {
addIcons({ bookOutline, libraryOutline, newspaperOutline, readerOutline });
}
public ngOnInit() {
this.deviceType = this.deviceDetectorService.getDeviceInfo().deviceType;
}
}

31
apps/client/src/app/pages/resources/resources-page.html

@ -1,30 +1 @@
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto">
<router-outlet />
</mat-tab-nav-panel>
<nav
mat-align-tabs="center"
mat-tab-nav-bar
[disablePagination]="true"
[tabPanel]="tabPanel"
>
@for (tab of tabs; track tab) {
@if (tab.showCondition !== false) {
<a
#rla="routerLinkActive"
class="no-min-width px-3"
mat-tab-link
routerLinkActive
[active]="rla.isActive"
[routerLink]="tab.routerLink"
[routerLinkActiveOptions]="{ exact: true }"
>
<ion-icon
[name]="tab.iconName"
[size]="deviceType === 'mobile' ? 'large' : 'small'"
/>
<div class="d-none d-sm-block ml-2">{{ tab.label }}</div>
</a>
}
}
</nav>
<gf-page-tabs [tabs]="tabs" />

24
apps/client/src/app/pages/user-account/user-account-page.component.ts

@ -1,39 +1,27 @@
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { TabConfiguration, User } from '@ghostfolio/common/interfaces';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { GfPageTabsComponent } from '@ghostfolio/ui/page-tabs';
import {
ChangeDetectorRef,
Component,
CUSTOM_ELEMENTS_SCHEMA,
DestroyRef,
OnInit
} from '@angular/core';
import { ChangeDetectorRef, Component, DestroyRef } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { MatTabsModule } from '@angular/material/tabs';
import { RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone';
import { addIcons } from 'ionicons';
import { diamondOutline, keyOutline, settingsOutline } from 'ionicons/icons';
import { DeviceDetectorService } from 'ngx-device-detector';
@Component({
host: { class: 'page has-tabs' },
imports: [IonIcon, MatTabsModule, RouterModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
imports: [GfPageTabsComponent],
selector: 'gf-user-account-page',
styleUrls: ['./user-account-page.scss'],
templateUrl: './user-account-page.html'
})
export class GfUserAccountPageComponent implements OnInit {
public deviceType: string;
export class GfUserAccountPageComponent {
public tabs: TabConfiguration[] = [];
public user: User;
public constructor(
private changeDetectorRef: ChangeDetectorRef,
private destroyRef: DestroyRef,
private deviceDetectorService: DeviceDetectorService,
private userService: UserService
) {
this.userService.stateChanged
@ -68,8 +56,4 @@ export class GfUserAccountPageComponent implements OnInit {
addIcons({ diamondOutline, keyOutline, settingsOutline });
}
public ngOnInit() {
this.deviceType = this.deviceDetectorService.getDeviceInfo().deviceType;
}
}

31
apps/client/src/app/pages/user-account/user-account-page.html

@ -1,30 +1 @@
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto">
<router-outlet />
</mat-tab-nav-panel>
<nav
mat-align-tabs="center"
mat-tab-nav-bar
[disablePagination]="true"
[tabPanel]="tabPanel"
>
@for (tab of tabs; track tab) {
@if (tab.showCondition !== false) {
<a
#rla="routerLinkActive"
class="no-min-width px-3"
mat-tab-link
routerLinkActive
[active]="rla.isActive"
[routerLink]="tab.routerLink"
[routerLinkActiveOptions]="{ exact: true }"
>
<ion-icon
[name]="tab.iconName"
[size]="deviceType === 'mobile' ? 'large' : 'small'"
/>
<div class="d-none d-sm-block ml-2">{{ tab.label }}</div>
</a>
}
}
</nav>
<gf-page-tabs [tabs]="tabs" />

22
apps/client/src/app/pages/zen/zen-page.component.ts

@ -1,37 +1,27 @@
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { TabConfiguration, User } from '@ghostfolio/common/interfaces';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { GfPageTabsComponent } from '@ghostfolio/ui/page-tabs';
import {
ChangeDetectorRef,
Component,
DestroyRef,
OnInit
} from '@angular/core';
import { ChangeDetectorRef, Component, DestroyRef } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { MatTabsModule } from '@angular/material/tabs';
import { RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone';
import { addIcons } from 'ionicons';
import { albumsOutline, analyticsOutline } from 'ionicons/icons';
import { DeviceDetectorService } from 'ngx-device-detector';
@Component({
host: { class: 'page has-tabs' },
imports: [IonIcon, MatTabsModule, RouterModule],
imports: [GfPageTabsComponent],
selector: 'gf-zen-page',
styleUrls: ['./zen-page.scss'],
templateUrl: './zen-page.html'
})
export class GfZenPageComponent implements OnInit {
public deviceType: string;
export class GfZenPageComponent {
public tabs: TabConfiguration[] = [];
public user: User;
public constructor(
private changeDetectorRef: ChangeDetectorRef,
private destroyRef: DestroyRef,
private deviceDetectorService: DeviceDetectorService,
private userService: UserService
) {
this.userService.stateChanged
@ -58,8 +48,4 @@ export class GfZenPageComponent implements OnInit {
addIcons({ albumsOutline, analyticsOutline });
}
public ngOnInit() {
this.deviceType = this.deviceDetectorService.getDeviceInfo().deviceType;
}
}

31
apps/client/src/app/pages/zen/zen-page.html

@ -1,30 +1 @@
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto">
<router-outlet />
</mat-tab-nav-panel>
<nav
mat-align-tabs="center"
mat-tab-nav-bar
[disablePagination]="true"
[tabPanel]="tabPanel"
>
@for (tab of tabs; track tab) {
@if (tab.showCondition !== false) {
<a
#rla="routerLinkActive"
class="no-min-width px-3"
mat-tab-link
routerLinkActive
[active]="rla.isActive"
[routerLink]="tab.routerLink"
[routerLinkActiveOptions]="{ exact: true }"
>
<ion-icon
[name]="tab.iconName"
[size]="deviceType === 'mobile' ? 'large' : 'small'"
/>
<div class="d-none d-sm-block ml-2">{{ tab.label }}</div>
</a>
}
}
</nav>
<gf-page-tabs [tabs]="tabs" />

3
apps/client/src/styles.scss

@ -489,7 +489,6 @@ ngx-skeleton-loader {
.page {
display: flex;
flex-direction: column;
overflow-y: auto;
padding-bottom: env(safe-area-inset-bottom);
padding-bottom: constant(safe-area-inset-bottom);
@ -508,6 +507,7 @@ ngx-skeleton-loader {
}
&.has-tabs {
gf-page-tabs {
height: calc(100svh - var(--mat-toolbar-standard-height));
.fab-container {
@ -544,6 +544,7 @@ ngx-skeleton-loader {
}
}
}
}
}
.svgMap-tooltip {

1
libs/ui/src/lib/page-tabs/index.ts

@ -0,0 +1 @@
export * from './page-tabs.component';

30
libs/ui/src/lib/page-tabs/page-tabs.component.html

@ -0,0 +1,30 @@
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto">
<router-outlet />
</mat-tab-nav-panel>
<nav
mat-align-tabs="center"
mat-tab-nav-bar
[disablePagination]="true"
[tabPanel]="tabPanel"
>
@for (tab of tabs(); track tab) {
@if (tab.showCondition !== false) {
<a
#rla="routerLinkActive"
class="no-min-width px-3"
mat-tab-link
routerLinkActive
[active]="rla.isActive"
[routerLink]="tab.routerLink"
[routerLinkActiveOptions]="{ exact: true }"
>
<ion-icon
[name]="tab.iconName"
[size]="deviceType === 'mobile' ? 'large' : 'small'"
/>
<div class="d-none d-sm-block ml-2" [innerHTML]="tab.label"></div>
</a>
}
}
</nav>

5
libs/ui/src/lib/page-tabs/page-tabs.component.scss

@ -0,0 +1,5 @@
:host {
display: flex;
flex-direction: column;
width: 100%;
}

23
libs/ui/src/lib/page-tabs/page-tabs.component.ts

@ -0,0 +1,23 @@
import { TabConfiguration } from '@ghostfolio/common/interfaces';
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
import { MatTabsModule } from '@angular/material/tabs';
import { RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone';
import { DeviceDetectorService } from 'ngx-device-detector';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [IonIcon, MatTabsModule, RouterModule],
selector: 'gf-page-tabs',
styleUrls: ['./page-tabs.component.scss'],
templateUrl: './page-tabs.component.html'
})
export class GfPageTabsComponent {
public deviceType: string;
public readonly tabs = input.required<TabConfiguration[]>();
public constructor(deviceService: DeviceDetectorService) {
this.deviceType = deviceService.getDeviceInfo().deviceType;
}
}
Loading…
Cancel
Save