mirror of https://github.com/ghostfolio/ghostfolio
committed by
GitHub
25 changed files with 204 additions and 451 deletions
@ -1,30 +1 @@ |
|||||
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto"> |
<gf-page-tabs [tabs]="tabs" /> |
||||
<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> |
|
||||
|
|||||
@ -1,30 +1 @@ |
|||||
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto"> |
<gf-page-tabs [tabs]="tabs" /> |
||||
<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> |
|
||||
|
|||||
@ -1,30 +1 @@ |
|||||
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto"> |
<gf-page-tabs [tabs]="tabs" /> |
||||
<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> |
|
||||
|
|||||
@ -1,30 +1 @@ |
|||||
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto"> |
<gf-page-tabs [tabs]="tabs" /> |
||||
<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> |
|
||||
|
|||||
@ -1,30 +1 @@ |
|||||
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto"> |
<gf-page-tabs [tabs]="tabs" /> |
||||
<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> |
|
||||
|
|||||
@ -1,30 +1 @@ |
|||||
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto"> |
<gf-page-tabs [tabs]="tabs" /> |
||||
<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> |
|
||||
|
|||||
@ -1,30 +1 @@ |
|||||
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto"> |
<gf-page-tabs [tabs]="tabs" /> |
||||
<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> |
|
||||
|
|||||
@ -1,30 +1 @@ |
|||||
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto"> |
<gf-page-tabs [tabs]="tabs" /> |
||||
<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> |
|
||||
|
|||||
@ -0,0 +1,2 @@ |
|||||
|
export * from './interfaces/interfaces'; |
||||
|
export * from './page-tabs.component'; |
||||
@ -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> |
||||
@ -0,0 +1,70 @@ |
|||||
|
@use '@angular/material' as mat; |
||||
|
|
||||
|
:host { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
height: calc(100svh - var(--mat-toolbar-standard-height)); |
||||
|
width: 100%; |
||||
|
|
||||
|
@include mat.tabs-overrides( |
||||
|
( |
||||
|
active-indicator-height: 0, |
||||
|
divider-height: 0, |
||||
|
label-text-tracking: normal |
||||
|
) |
||||
|
); |
||||
|
|
||||
|
.fab-container { |
||||
|
@media (max-width: 575.98px) { |
||||
|
bottom: 5rem; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
::ng-deep { |
||||
|
.mat-mdc-tab-nav-panel { |
||||
|
padding: 2rem 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@media (max-width: 575.98px) { |
||||
|
@include mat.tabs-overrides( |
||||
|
( |
||||
|
container-height: 3rem |
||||
|
) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
@media (min-width: 576px) { |
||||
|
flex-direction: row-reverse; |
||||
|
|
||||
|
@include mat.tabs-overrides( |
||||
|
( |
||||
|
container-height: 2rem |
||||
|
) |
||||
|
); |
||||
|
|
||||
|
::ng-deep { |
||||
|
.mat-mdc-tab-header { |
||||
|
background-color: rgba(var(--palette-foreground-base), 0.02); |
||||
|
padding: 2rem 0; |
||||
|
width: 14rem; |
||||
|
|
||||
|
.mat-mdc-tab-links { |
||||
|
flex-direction: column; |
||||
|
|
||||
|
.mat-mdc-tab-link { |
||||
|
justify-content: flex-start; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
:host-context(.theme-dark) { |
||||
|
@media (min-width: 576px) { |
||||
|
.mat-mdc-tab-header { |
||||
|
background-color: rgba(var(--palette-foreground-base-dark), 0.02); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
import { |
||||
|
ChangeDetectionStrategy, |
||||
|
Component, |
||||
|
inject, |
||||
|
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'; |
||||
|
|
||||
|
import { TabConfiguration } from './interfaces/interfaces'; |
||||
|
|
||||
|
@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[]>(); |
||||
|
|
||||
|
private readonly deviceService = inject(DeviceDetectorService); |
||||
|
|
||||
|
public constructor() { |
||||
|
this.deviceType = this.deviceService.getDeviceInfo().deviceType; |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue