mirror of
https://github.com/richard-loafle/fuse-angular.git
synced 2026-01-12 02:47:10 +00:00
Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56c4eb0356 | ||
|
|
a8a4f2b18d | ||
|
|
36c8727616 | ||
|
|
5ea37aed99 | ||
|
|
cbce71f155 | ||
|
|
ed47050232 | ||
|
|
c86a538d41 | ||
|
|
f369206ef8 | ||
|
|
1659d4babd | ||
|
|
fa37f99d33 | ||
|
|
331968ac5b | ||
|
|
27274c84d6 | ||
|
|
4b8a101a3e | ||
|
|
8080a85d40 | ||
|
|
36784c405f | ||
|
|
8f4f7886d5 | ||
|
|
d693a08136 | ||
|
|
0c0ef40de3 | ||
|
|
f4d737d3a3 | ||
|
|
47d9ddb08c | ||
|
|
4da3612d22 | ||
|
|
403a949d4a | ||
|
|
5b78a68116 | ||
|
|
214116e10d | ||
|
|
5962c80e8d | ||
|
|
ff086b1ed0 | ||
|
|
efdfa6418a | ||
|
|
c1c9904b9d | ||
|
|
39650d3cc9 | ||
|
|
bafa9adc01 | ||
|
|
bb9023f9df | ||
|
|
66096718e0 | ||
|
|
945d0a2240 | ||
|
|
9005f08ac7 | ||
|
|
89f5a4ec69 | ||
|
|
ca7b4c7e5d | ||
|
|
bb57ec2324 | ||
|
|
11ad2c89df | ||
|
|
fc1e7b02b0 | ||
|
|
446bfe4139 |
4038
package-lock.json
generated
4038
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
71
package.json
71
package.json
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"name": "@fuse/demo",
|
||||
"version": "13.0.3",
|
||||
"version": "13.2.0",
|
||||
"description": "Fuse - Angular Admin Template and Starter Project",
|
||||
"author": "https://themeforest.net/user/srcn",
|
||||
"license": "https://themeforest.net/licenses/standard",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -12,17 +14,17 @@
|
||||
"e2e": "ng e2e"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/animations": "12.0.2",
|
||||
"@angular/cdk": "12.0.2",
|
||||
"@angular/common": "12.0.2",
|
||||
"@angular/compiler": "12.0.2",
|
||||
"@angular/core": "12.0.2",
|
||||
"@angular/forms": "12.0.2",
|
||||
"@angular/material": "12.0.2",
|
||||
"@angular/material-moment-adapter": "12.0.2",
|
||||
"@angular/platform-browser": "12.0.2",
|
||||
"@angular/platform-browser-dynamic": "12.0.2",
|
||||
"@angular/router": "12.0.2",
|
||||
"@angular/animations": "12.1.1",
|
||||
"@angular/cdk": "12.1.1",
|
||||
"@angular/common": "12.1.1",
|
||||
"@angular/compiler": "12.1.1",
|
||||
"@angular/core": "12.1.1",
|
||||
"@angular/forms": "12.1.1",
|
||||
"@angular/material": "12.1.1",
|
||||
"@angular/material-moment-adapter": "12.1.1",
|
||||
"@angular/platform-browser": "12.1.1",
|
||||
"@angular/platform-browser-dynamic": "12.1.1",
|
||||
"@angular/router": "12.1.1",
|
||||
"@fullcalendar/angular": "4.4.5-beta",
|
||||
"@fullcalendar/core": "4.4.2",
|
||||
"@fullcalendar/daygrid": "4.4.2",
|
||||
@@ -32,32 +34,31 @@
|
||||
"@fullcalendar/rrule": "4.4.2",
|
||||
"@fullcalendar/timegrid": "4.4.2",
|
||||
"@ngneat/transloco": "2.21.0",
|
||||
"apexcharts": "3.26.3",
|
||||
"apexcharts": "3.27.1",
|
||||
"crypto-js": "3.3.0",
|
||||
"highlight.js": "11.0.0",
|
||||
"highlight.js": "11.0.1",
|
||||
"lodash-es": "4.17.21",
|
||||
"moment": "2.29.1",
|
||||
"ng-apexcharts": "1.5.10",
|
||||
"ng-apexcharts": "1.5.12",
|
||||
"ngx-markdown": "12.0.1",
|
||||
"ngx-quill": "14.0.0",
|
||||
"ngx-quill": "14.1.1",
|
||||
"perfect-scrollbar": "1.5.1",
|
||||
"quill": "1.3.7",
|
||||
"rrule": "2.6.8",
|
||||
"rxjs": "6.6.7",
|
||||
"tslib": "2.2.0",
|
||||
"tslib": "2.3.0",
|
||||
"web-animations-js": "2.3.2",
|
||||
"zone.js": "0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "12.0.2",
|
||||
"@angular-eslint/builder": "12.1.0",
|
||||
"@angular-eslint/eslint-plugin": "12.1.0",
|
||||
"@angular-eslint/eslint-plugin-template": "12.1.0",
|
||||
"@angular-eslint/schematics": "12.1.0",
|
||||
"@angular-eslint/template-parser": "12.1.0",
|
||||
"@angular/cli": "12.0.2",
|
||||
"@angular/compiler-cli": "12.0.2",
|
||||
"@angular/language-service": "12.0.2",
|
||||
"@angular-devkit/build-angular": "12.1.0",
|
||||
"@angular-eslint/builder": "12.2.0",
|
||||
"@angular-eslint/eslint-plugin": "12.2.0",
|
||||
"@angular-eslint/eslint-plugin-template": "12.2.0",
|
||||
"@angular-eslint/schematics": "12.2.0",
|
||||
"@angular-eslint/template-parser": "12.2.0",
|
||||
"@angular/cli": "12.1.0",
|
||||
"@angular/compiler-cli": "12.1.1",
|
||||
"@tailwindcss/aspect-ratio": "0.2.1",
|
||||
"@tailwindcss/line-clamp": "0.2.1",
|
||||
"@tailwindcss/typography": "0.4.1",
|
||||
@@ -67,24 +68,24 @@
|
||||
"@types/jasmine": "3.6.11",
|
||||
"@types/lodash": "4.14.170",
|
||||
"@types/lodash-es": "4.17.4",
|
||||
"@types/node": "12.20.14",
|
||||
"@typescript-eslint/eslint-plugin": "4.26.0",
|
||||
"@typescript-eslint/parser": "4.26.0",
|
||||
"@types/node": "12.20.15",
|
||||
"@typescript-eslint/eslint-plugin": "4.28.1",
|
||||
"@typescript-eslint/parser": "4.28.1",
|
||||
"autoprefixer": "10.2.6",
|
||||
"chroma-js": "2.1.2",
|
||||
"eslint": "7.27.0",
|
||||
"eslint": "7.29.0",
|
||||
"eslint-plugin-import": "2.23.4",
|
||||
"eslint-plugin-jsdoc": "35.1.2",
|
||||
"eslint-plugin-jsdoc": "35.4.1",
|
||||
"eslint-plugin-prefer-arrow": "1.2.3",
|
||||
"jasmine-core": "3.7.1",
|
||||
"karma": "6.3.3",
|
||||
"karma": "6.3.4",
|
||||
"karma-chrome-launcher": "3.1.0",
|
||||
"karma-coverage": "2.0.3",
|
||||
"karma-jasmine": "4.0.1",
|
||||
"karma-jasmine-html-reporter": "1.6.0",
|
||||
"lodash": "4.17.21",
|
||||
"postcss": "8.3.0",
|
||||
"tailwindcss": "2.1.4",
|
||||
"typescript": "4.2.4"
|
||||
"postcss": "8.3.5",
|
||||
"tailwindcss": "2.2.4",
|
||||
"typescript": "4.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,6 +341,13 @@ export class FuseDrawerComponent implements OnChanges, OnInit, OnDestroy
|
||||
animate('300ms cubic-bezier(0.25, 0.8, 0.25, 1)', style({opacity: 1}))
|
||||
]).create(this._overlay);
|
||||
|
||||
// Once the animation is done...
|
||||
this._player.onDone(() => {
|
||||
|
||||
// Destroy the player
|
||||
this._player.destroy();
|
||||
});
|
||||
|
||||
// Play the animation
|
||||
this._player.play();
|
||||
|
||||
@@ -373,6 +380,9 @@ export class FuseDrawerComponent implements OnChanges, OnInit, OnDestroy
|
||||
// Once the animation is done...
|
||||
this._player.onDone(() => {
|
||||
|
||||
// Destroy the player
|
||||
this._player.destroy();
|
||||
|
||||
// If the backdrop still exists...
|
||||
if ( this._overlay )
|
||||
{
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
<!-- Button -->
|
||||
<button
|
||||
mat-icon-button
|
||||
[matTooltip]="'Toggle Fullscreen'"
|
||||
[matTooltip]="tooltip || 'Toggle Fullscreen'"
|
||||
(click)="toggleFullscreen()">
|
||||
<mat-icon [svgIcon]="'heroicons_outline:arrows-expand'"></mat-icon>
|
||||
<ng-container [ngTemplateOutlet]="iconTpl || defaultIconTpl"></ng-container>
|
||||
</button>
|
||||
|
||||
<!-- Default icon -->
|
||||
<ng-template #defaultIconTpl>
|
||||
<mat-icon [svgIcon]="'heroicons_outline:arrows-expand'"></mat-icon>
|
||||
</ng-template>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ChangeDetectionStrategy, Component, Inject, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, Inject, Input, OnInit, TemplateRef, ViewEncapsulation } from '@angular/core';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { FSDocument, FSDocumentElement } from '@fuse/components/fullscreen/fullscreen.types';
|
||||
|
||||
@@ -11,6 +11,8 @@ import { FSDocument, FSDocumentElement } from '@fuse/components/fullscreen/fulls
|
||||
})
|
||||
export class FuseFullscreenComponent implements OnInit
|
||||
{
|
||||
@Input() iconTpl: TemplateRef<any>;
|
||||
@Input() tooltip: string;
|
||||
private _fsDoc: FSDocument;
|
||||
private _fsDocEl: FSDocumentElement;
|
||||
private _isFullscreen: boolean = false;
|
||||
|
||||
@@ -3,15 +3,17 @@ import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { FuseFullscreenComponent } from '@fuse/components/fullscreen/fullscreen.component';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
FuseFullscreenComponent
|
||||
],
|
||||
imports : [
|
||||
imports: [
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
MatTooltipModule
|
||||
MatTooltipModule,
|
||||
CommonModule
|
||||
],
|
||||
exports : [
|
||||
FuseFullscreenComponent
|
||||
|
||||
@@ -5,69 +5,83 @@
|
||||
[ngClass]="item.classes?.wrapper">
|
||||
|
||||
<!-- Item with an internal link -->
|
||||
<div
|
||||
class="fuse-horizontal-navigation-item"
|
||||
*ngIf="item.link && !item.externalLink && !item.function && !item.disabled"
|
||||
[ngClass]="{'fuse-horizontal-navigation-item-active-forced': item.active}"
|
||||
[routerLink]="[item.link]"
|
||||
[routerLinkActive]="'fuse-horizontal-navigation-item-active'"
|
||||
[routerLinkActiveOptions]="isActiveMatchOptions">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</div>
|
||||
<ng-container *ngIf="item.link && !item.externalLink && !item.function && !item.disabled">
|
||||
<div
|
||||
class="fuse-horizontal-navigation-item"
|
||||
[ngClass]="{'fuse-horizontal-navigation-item-active-forced': item.active}"
|
||||
[routerLink]="[item.link]"
|
||||
[routerLinkActive]="'fuse-horizontal-navigation-item-active'"
|
||||
[routerLinkActiveOptions]="isActiveMatchOptions"
|
||||
[matTooltip]="item.tooltip || ''">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<!-- Item with an external link -->
|
||||
<a
|
||||
class="fuse-horizontal-navigation-item"
|
||||
*ngIf="item.link && item.externalLink && !item.function && !item.disabled"
|
||||
[href]="item.link">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</a>
|
||||
<ng-container *ngIf="item.link && item.externalLink && !item.function && !item.disabled">
|
||||
<a
|
||||
class="fuse-horizontal-navigation-item"
|
||||
[href]="item.link"
|
||||
[target]="item.target || '_self'"
|
||||
[matTooltip]="item.tooltip || ''">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</a>
|
||||
</ng-container>
|
||||
|
||||
<!-- Item with a function -->
|
||||
<div
|
||||
class="fuse-horizontal-navigation-item"
|
||||
*ngIf="!item.link && item.function && !item.disabled"
|
||||
[ngClass]="{'fuse-horizontal-navigation-item-active-forced': item.active}"
|
||||
(click)="item.function(item)">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</div>
|
||||
<ng-container *ngIf="!item.link && item.function && !item.disabled">
|
||||
<div
|
||||
class="fuse-horizontal-navigation-item"
|
||||
[ngClass]="{'fuse-horizontal-navigation-item-active-forced': item.active}"
|
||||
[matTooltip]="item.tooltip || ''"
|
||||
(click)="item.function(item)">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<!-- Item with an internal link and function -->
|
||||
<div
|
||||
class="fuse-horizontal-navigation-item"
|
||||
*ngIf="item.link && !item.externalLink && item.function && !item.disabled"
|
||||
[ngClass]="{'fuse-horizontal-navigation-item-active-forced': item.active}"
|
||||
[routerLink]="[item.link]"
|
||||
[routerLinkActive]="'fuse-horizontal-navigation-item-active'"
|
||||
[routerLinkActiveOptions]="isActiveMatchOptions"
|
||||
(click)="item.function(item)">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</div>
|
||||
<ng-container *ngIf="item.link && !item.externalLink && item.function && !item.disabled">
|
||||
<div
|
||||
class="fuse-horizontal-navigation-item"
|
||||
[ngClass]="{'fuse-horizontal-navigation-item-active-forced': item.active}"
|
||||
[routerLink]="[item.link]"
|
||||
[routerLinkActive]="'fuse-horizontal-navigation-item-active'"
|
||||
[routerLinkActiveOptions]="isActiveMatchOptions"
|
||||
[matTooltip]="item.tooltip || ''"
|
||||
(click)="item.function(item)">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<!-- Item with an external link and function -->
|
||||
<a
|
||||
class="fuse-horizontal-navigation-item"
|
||||
*ngIf="item.link && item.externalLink && item.function && !item.disabled"
|
||||
[href]="item.link"
|
||||
(click)="item.function(item)"
|
||||
mat-menu-item>
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</a>
|
||||
<ng-container *ngIf="item.link && item.externalLink && item.function && !item.disabled">
|
||||
<a
|
||||
class="fuse-horizontal-navigation-item"
|
||||
[href]="item.link"
|
||||
[target]="item.target || '_self'"
|
||||
[matTooltip]="item.tooltip || ''"
|
||||
(click)="item.function(item)"
|
||||
mat-menu-item>
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</a>
|
||||
</ng-container>
|
||||
|
||||
<!-- Item with a no link and no function -->
|
||||
<div
|
||||
class="fuse-horizontal-navigation-item"
|
||||
*ngIf="!item.link && !item.function && !item.disabled"
|
||||
[ngClass]="{'fuse-horizontal-navigation-item-active-forced': item.active}">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</div>
|
||||
<ng-container *ngIf="!item.link && !item.function && !item.disabled">
|
||||
<div
|
||||
class="fuse-horizontal-navigation-item"
|
||||
[ngClass]="{'fuse-horizontal-navigation-item-active-forced': item.active}"
|
||||
[matTooltip]="item.tooltip || ''">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<!-- Item is disabled -->
|
||||
<div
|
||||
class="fuse-horizontal-navigation-item fuse-horizontal-navigation-item-disabled"
|
||||
*ngIf="item.disabled">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</div>
|
||||
<ng-container *ngIf="item.disabled">
|
||||
<div class="fuse-horizontal-navigation-item fuse-horizontal-navigation-item-disabled">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -75,11 +89,12 @@
|
||||
<ng-template #itemTemplate>
|
||||
|
||||
<!-- Icon -->
|
||||
<mat-icon
|
||||
class="fuse-horizontal-navigation-item-icon"
|
||||
[ngClass]="item.classes?.icon"
|
||||
*ngIf="item.icon"
|
||||
[svgIcon]="item.icon"></mat-icon>
|
||||
<ng-container *ngIf="item.icon">
|
||||
<mat-icon
|
||||
class="fuse-horizontal-navigation-item-icon"
|
||||
[ngClass]="item.classes?.icon"
|
||||
[svgIcon]="item.icon"></mat-icon>
|
||||
</ng-container>
|
||||
|
||||
<!-- Title & Subtitle -->
|
||||
<div class="fuse-horizontal-navigation-item-title-wrapper">
|
||||
@@ -88,24 +103,24 @@
|
||||
{{item.title}}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="fuse-horizontal-navigation-item-subtitle text-hint"
|
||||
*ngIf="item.subtitle">
|
||||
<span [ngClass]="item.classes?.subtitle">
|
||||
{{item.subtitle}}
|
||||
</span>
|
||||
</div>
|
||||
<ng-container *ngIf="item.subtitle">
|
||||
<div class="fuse-horizontal-navigation-item-subtitle text-hint">
|
||||
<span [ngClass]="item.classes?.subtitle">
|
||||
{{item.subtitle}}
|
||||
</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<!-- Badge -->
|
||||
<div
|
||||
class="fuse-horizontal-navigation-item-badge"
|
||||
*ngIf="item.badge">
|
||||
<div
|
||||
class="fuse-horizontal-navigation-item-badge-content"
|
||||
[ngClass]="item.badge.classes">
|
||||
{{item.badge.title}}
|
||||
<ng-container *ngIf="item.badge">
|
||||
<div class="fuse-horizontal-navigation-item-badge">
|
||||
<div
|
||||
class="fuse-horizontal-navigation-item-badge-content"
|
||||
[ngClass]="item.badge.classes">
|
||||
{{item.badge.title}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
</ng-template>
|
||||
|
||||
@@ -1,59 +1,63 @@
|
||||
<div
|
||||
*ngIf="!child"
|
||||
[ngClass]="{'fuse-horizontal-navigation-menu-active': trigger.menuOpen,
|
||||
<ng-container *ngIf="!child">
|
||||
<div
|
||||
[ngClass]="{'fuse-horizontal-navigation-menu-active': trigger.menuOpen,
|
||||
'fuse-horizontal-navigation-menu-active-forced': item.active}"
|
||||
[matMenuTriggerFor]="matMenu"
|
||||
(onMenuOpen)="triggerChangeDetection()"
|
||||
(onMenuClose)="triggerChangeDetection()"
|
||||
#trigger="matMenuTrigger">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate; context: {$implicit: item}"></ng-container>
|
||||
</div>
|
||||
[matMenuTriggerFor]="matMenu"
|
||||
(onMenuOpen)="triggerChangeDetection()"
|
||||
(onMenuClose)="triggerChangeDetection()"
|
||||
#trigger="matMenuTrigger">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate; context: {$implicit: item}"></ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<mat-menu
|
||||
class="fuse-horizontal-navigation-menu-panel"
|
||||
[overlapTrigger]="false"
|
||||
#matMenu="matMenu">
|
||||
|
||||
<ng-container *ngFor="let item of item.children">
|
||||
<ng-container *ngFor="let item of item.children; trackBy: trackByFn">
|
||||
|
||||
<!-- Skip the hidden items -->
|
||||
<ng-container *ngIf="(item.hidden && !item.hidden(item)) || !item.hidden">
|
||||
|
||||
<!-- Basic -->
|
||||
<div
|
||||
class="fuse-horizontal-navigation-menu-item"
|
||||
*ngIf="item.type === 'basic'"
|
||||
[disabled]="item.disabled"
|
||||
mat-menu-item>
|
||||
<fuse-horizontal-navigation-basic-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-horizontal-navigation-basic-item>
|
||||
</div>
|
||||
<ng-container *ngIf="item.type === 'basic'">
|
||||
<div
|
||||
class="fuse-horizontal-navigation-menu-item"
|
||||
[disabled]="item.disabled"
|
||||
mat-menu-item>
|
||||
<fuse-horizontal-navigation-basic-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-horizontal-navigation-basic-item>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<!-- Branch: aside, collapsable, group -->
|
||||
<div
|
||||
class="fuse-horizontal-navigation-menu-item"
|
||||
*ngIf="item.type === 'aside' || item.type === 'collapsable' || item.type === 'group'"
|
||||
[disabled]="item.disabled"
|
||||
[matMenuTriggerFor]="branch.matMenu"
|
||||
mat-menu-item>
|
||||
<ng-container *ngTemplateOutlet="itemTemplate; context: {$implicit: item}"></ng-container>
|
||||
<fuse-horizontal-navigation-branch-item
|
||||
[child]="true"
|
||||
[item]="item"
|
||||
[name]="name"
|
||||
#branch></fuse-horizontal-navigation-branch-item>
|
||||
</div>
|
||||
<ng-container *ngIf="item.type === 'aside' || item.type === 'collapsable' || item.type === 'group'">
|
||||
<div
|
||||
class="fuse-horizontal-navigation-menu-item"
|
||||
[disabled]="item.disabled"
|
||||
[matMenuTriggerFor]="branch.matMenu"
|
||||
mat-menu-item>
|
||||
<ng-container *ngTemplateOutlet="itemTemplate; context: {$implicit: item}"></ng-container>
|
||||
<fuse-horizontal-navigation-branch-item
|
||||
[child]="true"
|
||||
[item]="item"
|
||||
[name]="name"
|
||||
#branch></fuse-horizontal-navigation-branch-item>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<!-- Divider -->
|
||||
<div
|
||||
class="fuse-horizontal-navigation-menu-item"
|
||||
*ngIf="item.type === 'divider'"
|
||||
mat-menu-item>
|
||||
<fuse-horizontal-navigation-divider-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-horizontal-navigation-divider-item>
|
||||
</div>
|
||||
<ng-container *ngIf="item.type === 'divider'">
|
||||
<div
|
||||
class="fuse-horizontal-navigation-menu-item"
|
||||
mat-menu-item>
|
||||
<fuse-horizontal-navigation-divider-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-horizontal-navigation-divider-item>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
|
||||
@@ -74,14 +78,16 @@
|
||||
<div
|
||||
class="fuse-horizontal-navigation-item"
|
||||
[ngClass]="{'fuse-horizontal-navigation-item-disabled': item.disabled,
|
||||
'fuse-horizontal-navigation-item-active-forced': item.active}">
|
||||
'fuse-horizontal-navigation-item-active-forced': item.active}"
|
||||
[matTooltip]="item.tooltip || ''">
|
||||
|
||||
<!-- Icon -->
|
||||
<mat-icon
|
||||
class="fuse-horizontal-navigation-item-icon"
|
||||
[ngClass]="item.classes?.icon"
|
||||
*ngIf="item.icon"
|
||||
[svgIcon]="item.icon"></mat-icon>
|
||||
<ng-container *ngIf="item.icon">
|
||||
<mat-icon
|
||||
class="fuse-horizontal-navigation-item-icon"
|
||||
[ngClass]="item.classes?.icon"
|
||||
[svgIcon]="item.icon"></mat-icon>
|
||||
</ng-container>
|
||||
|
||||
<!-- Title & Subtitle -->
|
||||
<div class="fuse-horizontal-navigation-item-title-wrapper">
|
||||
@@ -90,25 +96,25 @@
|
||||
{{item.title}}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="fuse-horizontal-navigation-item-subtitle text-hint"
|
||||
*ngIf="item.subtitle">
|
||||
<span [ngClass]="item.classes?.subtitle">
|
||||
{{item.subtitle}}
|
||||
</span>
|
||||
</div>
|
||||
<ng-container *ngIf="item.subtitle">
|
||||
<div class="fuse-horizontal-navigation-item-subtitle text-hint">
|
||||
<span [ngClass]="item.classes?.subtitle">
|
||||
{{item.subtitle}}
|
||||
</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<!-- Badge -->
|
||||
<div
|
||||
class="fuse-horizontal-navigation-item-badge"
|
||||
*ngIf="item.badge">
|
||||
<div
|
||||
class="fuse-horizontal-navigation-item-badge-content"
|
||||
[ngClass]="item.badge.classes">
|
||||
{{item.badge.title}}
|
||||
<ng-container *ngIf="item.badge">
|
||||
<div class="fuse-horizontal-navigation-item-badge">
|
||||
<div
|
||||
class="fuse-horizontal-navigation-item-badge-content"
|
||||
[ngClass]="item.badge.classes">
|
||||
{{item.badge.title}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -81,4 +81,15 @@ export class FuseHorizontalNavigationBranchItemComponent implements OnInit, OnDe
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
}
|
||||
|
||||
/**
|
||||
* Track by function for ngFor loops
|
||||
*
|
||||
* @param index
|
||||
* @param item
|
||||
*/
|
||||
trackByFn(index: number, item: any): any
|
||||
{
|
||||
return item.id || index;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +1,33 @@
|
||||
<div class="fuse-horizontal-navigation-wrapper">
|
||||
|
||||
<ng-container *ngFor="let item of navigation">
|
||||
<ng-container *ngFor="let item of navigation; trackBy: trackByFn">
|
||||
|
||||
<!-- Skip the hidden items -->
|
||||
<ng-container *ngIf="(item.hidden && !item.hidden(item)) || !item.hidden">
|
||||
|
||||
<!-- Basic -->
|
||||
<fuse-horizontal-navigation-basic-item
|
||||
class="fuse-horizontal-navigation-menu-item"
|
||||
*ngIf="item.type === 'basic'"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-horizontal-navigation-basic-item>
|
||||
<ng-container *ngIf="item.type === 'basic'">
|
||||
<fuse-horizontal-navigation-basic-item
|
||||
class="fuse-horizontal-navigation-menu-item"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-horizontal-navigation-basic-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Branch: aside, collapsable, group -->
|
||||
<fuse-horizontal-navigation-branch-item
|
||||
class="fuse-horizontal-navigation-menu-item"
|
||||
*ngIf="item.type === 'aside' || item.type === 'collapsable' || item.type === 'group'"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-horizontal-navigation-branch-item>
|
||||
<ng-container *ngIf="item.type === 'aside' || item.type === 'collapsable' || item.type === 'group'">
|
||||
<fuse-horizontal-navigation-branch-item
|
||||
class="fuse-horizontal-navigation-menu-item"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-horizontal-navigation-branch-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Spacer -->
|
||||
<fuse-horizontal-navigation-spacer-item
|
||||
class="fuse-horizontal-navigation-menu-item"
|
||||
*ngIf="item.type === 'spacer'"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-horizontal-navigation-spacer-item>
|
||||
<ng-container *ngIf="item.type === 'spacer'">
|
||||
<fuse-horizontal-navigation-spacer-item
|
||||
class="fuse-horizontal-navigation-menu-item"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-horizontal-navigation-spacer-item>
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
|
||||
|
||||
@@ -15,8 +15,15 @@ export interface FuseNavigationItem
|
||||
hidden?: (item: FuseNavigationItem) => boolean;
|
||||
active?: boolean;
|
||||
disabled?: boolean;
|
||||
tooltip?: string;
|
||||
link?: string;
|
||||
externalLink?: boolean;
|
||||
target?:
|
||||
| '_blank'
|
||||
| '_self'
|
||||
| '_parent'
|
||||
| '_top'
|
||||
| string;
|
||||
exactMatch?: boolean;
|
||||
isActiveMatchOptions?: IsActiveMatchOptions;
|
||||
function?: (item: FuseNavigationItem) => void;
|
||||
|
||||
@@ -7,14 +7,16 @@
|
||||
class="fuse-vertical-navigation-item"
|
||||
[ngClass]="{'fuse-vertical-navigation-item-active': active,
|
||||
'fuse-vertical-navigation-item-disabled': item.disabled,
|
||||
'fuse-vertical-navigation-item-active-forced': item.active}">
|
||||
'fuse-vertical-navigation-item-active-forced': item.active}"
|
||||
[matTooltip]="item.tooltip || ''">
|
||||
|
||||
<!-- Icon -->
|
||||
<mat-icon
|
||||
class="fuse-vertical-navigation-item-icon"
|
||||
[ngClass]="item.classes?.icon"
|
||||
*ngIf="item.icon"
|
||||
[svgIcon]="item.icon"></mat-icon>
|
||||
<ng-container *ngIf="item.icon">
|
||||
<mat-icon
|
||||
class="fuse-vertical-navigation-item-icon"
|
||||
[ngClass]="item.classes?.icon"
|
||||
[svgIcon]="item.icon"></mat-icon>
|
||||
</ng-container>
|
||||
|
||||
<!-- Title & Subtitle -->
|
||||
<div class="fuse-vertical-navigation-item-title-wrapper">
|
||||
@@ -23,25 +25,25 @@
|
||||
{{item.title}}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="fuse-vertical-navigation-item-subtitle"
|
||||
*ngIf="item.subtitle">
|
||||
<span [ngClass]="item.classes?.subtitle">
|
||||
{{item.subtitle}}
|
||||
</span>
|
||||
</div>
|
||||
<ng-container *ngIf="item.subtitle">
|
||||
<div class="fuse-vertical-navigation-item-subtitle">
|
||||
<span [ngClass]="item.classes?.subtitle">
|
||||
{{item.subtitle}}
|
||||
</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<!-- Badge -->
|
||||
<div
|
||||
class="fuse-vertical-navigation-item-badge"
|
||||
*ngIf="item.badge">
|
||||
<div
|
||||
class="fuse-vertical-navigation-item-badge-content"
|
||||
[ngClass]="item.badge.classes">
|
||||
{{item.badge.title}}
|
||||
<ng-container *ngIf="item.badge">
|
||||
<div class="fuse-vertical-navigation-item-badge">
|
||||
<div
|
||||
class="fuse-vertical-navigation-item-badge-content"
|
||||
[ngClass]="item.badge.classes">
|
||||
{{item.badge.title}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -57,35 +59,40 @@
|
||||
<ng-container *ngIf="(item.hidden && !item.hidden(item)) || !item.hidden">
|
||||
|
||||
<!-- Basic -->
|
||||
<fuse-vertical-navigation-basic-item
|
||||
*ngIf="item.type === 'basic'"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-basic-item>
|
||||
<ng-container *ngIf="item.type === 'basic'">
|
||||
<fuse-vertical-navigation-basic-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-basic-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Collapsable -->
|
||||
<fuse-vertical-navigation-collapsable-item
|
||||
*ngIf="item.type === 'collapsable'"
|
||||
[item]="item"
|
||||
[name]="name"
|
||||
[autoCollapse]="autoCollapse"></fuse-vertical-navigation-collapsable-item>
|
||||
<ng-container *ngIf="item.type === 'collapsable'">
|
||||
<fuse-vertical-navigation-collapsable-item
|
||||
[item]="item"
|
||||
[name]="name"
|
||||
[autoCollapse]="autoCollapse"></fuse-vertical-navigation-collapsable-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Divider -->
|
||||
<fuse-vertical-navigation-divider-item
|
||||
*ngIf="item.type === 'divider'"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-divider-item>
|
||||
<ng-container *ngIf="item.type === 'divider'">
|
||||
<fuse-vertical-navigation-divider-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-divider-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Group -->
|
||||
<fuse-vertical-navigation-group-item
|
||||
*ngIf="item.type === 'group'"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-group-item>
|
||||
<ng-container *ngIf="item.type === 'group'">
|
||||
<fuse-vertical-navigation-group-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-group-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Spacer -->
|
||||
<fuse-vertical-navigation-spacer-item
|
||||
*ngIf="item.type === 'spacer'"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-spacer-item>
|
||||
<ng-container *ngIf="item.type === 'spacer'">
|
||||
<fuse-vertical-navigation-spacer-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-spacer-item>
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
|
||||
|
||||
@@ -5,68 +5,84 @@
|
||||
[ngClass]="item.classes?.wrapper">
|
||||
|
||||
<!-- Item with an internal link -->
|
||||
<a
|
||||
class="fuse-vertical-navigation-item"
|
||||
*ngIf="item.link && !item.externalLink && !item.function && !item.disabled"
|
||||
[ngClass]="{'fuse-vertical-navigation-item-active-forced': item.active}"
|
||||
[routerLink]="[item.link]"
|
||||
[routerLinkActive]="'fuse-vertical-navigation-item-active'"
|
||||
[routerLinkActiveOptions]="isActiveMatchOptions">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</a>
|
||||
<ng-container *ngIf="item.link && !item.externalLink && !item.function && !item.disabled">
|
||||
<a
|
||||
class="fuse-vertical-navigation-item"
|
||||
[ngClass]="{'fuse-vertical-navigation-item-active-forced': item.active}"
|
||||
[routerLink]="[item.link]"
|
||||
[routerLinkActive]="'fuse-vertical-navigation-item-active'"
|
||||
[routerLinkActiveOptions]="isActiveMatchOptions"
|
||||
[matTooltip]="item.tooltip || ''">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</a>
|
||||
</ng-container>
|
||||
|
||||
<!-- Item with an external link -->
|
||||
<a
|
||||
class="fuse-vertical-navigation-item"
|
||||
*ngIf="item.link && item.externalLink && !item.function && !item.disabled"
|
||||
[href]="item.link">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</a>
|
||||
<ng-container *ngIf="item.link && item.externalLink && !item.function && !item.disabled">
|
||||
<a
|
||||
class="fuse-vertical-navigation-item"
|
||||
[href]="item.link"
|
||||
[target]="item.target || '_self'"
|
||||
[matTooltip]="item.tooltip || ''">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</a>
|
||||
</ng-container>
|
||||
|
||||
<!-- Item with a function -->
|
||||
<div
|
||||
class="fuse-vertical-navigation-item"
|
||||
*ngIf="!item.link && item.function && !item.disabled"
|
||||
[ngClass]="{'fuse-vertical-navigation-item-active-forced': item.active}"
|
||||
(click)="item.function(item)">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</div>
|
||||
<ng-container *ngIf="!item.link && item.function && !item.disabled">
|
||||
<div
|
||||
class="fuse-vertical-navigation-item"
|
||||
[ngClass]="{'fuse-vertical-navigation-item-active-forced': item.active}"
|
||||
[matTooltip]="item.tooltip || ''"
|
||||
(click)="item.function(item)">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<!-- Item with an internal link and function -->
|
||||
<a
|
||||
class="fuse-vertical-navigation-item"
|
||||
*ngIf="item.link && !item.externalLink && item.function && !item.disabled"
|
||||
[ngClass]="{'fuse-vertical-navigation-item-active-forced': item.active}"
|
||||
[routerLink]="[item.link]"
|
||||
[routerLinkActive]="'fuse-vertical-navigation-item-active'"
|
||||
[routerLinkActiveOptions]="isActiveMatchOptions"
|
||||
(click)="item.function(item)">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</a>
|
||||
<ng-container *ngIf="item.link && !item.externalLink && item.function && !item.disabled">
|
||||
<a
|
||||
class="fuse-vertical-navigation-item"
|
||||
[ngClass]="{'fuse-vertical-navigation-item-active-forced': item.active}"
|
||||
[routerLink]="[item.link]"
|
||||
[routerLinkActive]="'fuse-vertical-navigation-item-active'"
|
||||
[routerLinkActiveOptions]="isActiveMatchOptions"
|
||||
[matTooltip]="item.tooltip || ''"
|
||||
(click)="item.function(item)">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</a>
|
||||
</ng-container>
|
||||
|
||||
<!-- Item with an external link and function -->
|
||||
<a
|
||||
class="fuse-vertical-navigation-item"
|
||||
*ngIf="item.link && item.externalLink && item.function && !item.disabled"
|
||||
[href]="item.link"
|
||||
(click)="item.function(item)">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</a>
|
||||
<ng-container *ngIf="item.link && item.externalLink && item.function && !item.disabled">
|
||||
<a
|
||||
class="fuse-vertical-navigation-item"
|
||||
[href]="item.link"
|
||||
[target]="item.target || '_self'"
|
||||
[matTooltip]="item.tooltip || ''"
|
||||
(click)="item.function(item)">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</a>
|
||||
</ng-container>
|
||||
|
||||
<!-- Item with a no link and no function -->
|
||||
<div
|
||||
class="fuse-vertical-navigation-item"
|
||||
*ngIf="!item.link && !item.function && !item.disabled"
|
||||
[ngClass]="{'fuse-vertical-navigation-item-active-forced': item.active}">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</div>
|
||||
<ng-container *ngIf="!item.link && !item.function && !item.disabled">
|
||||
<div
|
||||
class="fuse-vertical-navigation-item"
|
||||
[ngClass]="{'fuse-vertical-navigation-item-active-forced': item.active}"
|
||||
[matTooltip]="item.tooltip || ''">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<!-- Item is disabled -->
|
||||
<div
|
||||
class="fuse-vertical-navigation-item fuse-vertical-navigation-item-disabled"
|
||||
*ngIf="item.disabled">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</div>
|
||||
<ng-container *ngIf="item.disabled">
|
||||
<div
|
||||
class="fuse-vertical-navigation-item fuse-vertical-navigation-item-disabled"
|
||||
[matTooltip]="item.tooltip || ''">
|
||||
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -74,11 +90,12 @@
|
||||
<ng-template #itemTemplate>
|
||||
|
||||
<!-- Icon -->
|
||||
<mat-icon
|
||||
class="fuse-vertical-navigation-item-icon"
|
||||
[ngClass]="item.classes?.icon"
|
||||
*ngIf="item.icon"
|
||||
[svgIcon]="item.icon"></mat-icon>
|
||||
<ng-container *ngIf="item.icon">
|
||||
<mat-icon
|
||||
class="fuse-vertical-navigation-item-icon"
|
||||
[ngClass]="item.classes?.icon"
|
||||
[svgIcon]="item.icon"></mat-icon>
|
||||
</ng-container>
|
||||
|
||||
<!-- Title & Subtitle -->
|
||||
<div class="fuse-vertical-navigation-item-title-wrapper">
|
||||
@@ -87,24 +104,24 @@
|
||||
{{item.title}}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="fuse-vertical-navigation-item-subtitle"
|
||||
*ngIf="item.subtitle">
|
||||
<span [ngClass]="item.classes?.subtitle">
|
||||
{{item.subtitle}}
|
||||
</span>
|
||||
</div>
|
||||
<ng-container *ngIf="item.subtitle">
|
||||
<div class="fuse-vertical-navigation-item-subtitle">
|
||||
<span [ngClass]="item.classes?.subtitle">
|
||||
{{item.subtitle}}
|
||||
</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<!-- Badge -->
|
||||
<div
|
||||
class="fuse-vertical-navigation-item-badge"
|
||||
*ngIf="item.badge">
|
||||
<div
|
||||
class="fuse-vertical-navigation-item-badge-content"
|
||||
[ngClass]="item.badge.classes">
|
||||
{{item.badge.title}}
|
||||
<ng-container *ngIf="item.badge">
|
||||
<div class="fuse-vertical-navigation-item-badge">
|
||||
<div
|
||||
class="fuse-vertical-navigation-item-badge-content"
|
||||
[ngClass]="item.badge.classes">
|
||||
{{item.badge.title}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
</ng-template>
|
||||
|
||||
@@ -6,14 +6,16 @@
|
||||
<div
|
||||
class="fuse-vertical-navigation-item"
|
||||
[ngClass]="{'fuse-vertical-navigation-item-disabled': item.disabled}"
|
||||
[matTooltip]="item.tooltip || ''"
|
||||
(click)="toggleCollapsable()">
|
||||
|
||||
<!-- Icon -->
|
||||
<mat-icon
|
||||
class="fuse-vertical-navigation-item-icon"
|
||||
[ngClass]="item.classes?.icon"
|
||||
*ngIf="item.icon"
|
||||
[svgIcon]="item.icon"></mat-icon>
|
||||
<ng-container *ngIf="item.icon">
|
||||
<mat-icon
|
||||
class="fuse-vertical-navigation-item-icon"
|
||||
[ngClass]="item.classes?.icon"
|
||||
[svgIcon]="item.icon"></mat-icon>
|
||||
</ng-container>
|
||||
|
||||
<!-- Title & Subtitle -->
|
||||
<div class="fuse-vertical-navigation-item-title-wrapper">
|
||||
@@ -22,25 +24,25 @@
|
||||
{{item.title}}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="fuse-vertical-navigation-item-subtitle"
|
||||
*ngIf="item.subtitle">
|
||||
<span [ngClass]="item.classes?.subtitle">
|
||||
{{item.subtitle}}
|
||||
</span>
|
||||
</div>
|
||||
<ng-container *ngIf="item.subtitle">
|
||||
<div class="fuse-vertical-navigation-item-subtitle">
|
||||
<span [ngClass]="item.classes?.subtitle">
|
||||
{{item.subtitle}}
|
||||
</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<!-- Badge -->
|
||||
<div
|
||||
class="fuse-vertical-navigation-item-badge"
|
||||
*ngIf="item.badge">
|
||||
<div
|
||||
class="fuse-vertical-navigation-item-badge-content"
|
||||
[ngClass]="item.badge.classes">
|
||||
{{item.badge.title}}
|
||||
<ng-container *ngIf="item.badge">
|
||||
<div class="fuse-vertical-navigation-item-badge">
|
||||
<div
|
||||
class="fuse-vertical-navigation-item-badge-content"
|
||||
[ngClass]="item.badge.classes">
|
||||
{{item.badge.title}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<!-- Arrow -->
|
||||
<mat-icon
|
||||
@@ -62,35 +64,40 @@
|
||||
<ng-container *ngIf="(item.hidden && !item.hidden(item)) || !item.hidden">
|
||||
|
||||
<!-- Basic -->
|
||||
<fuse-vertical-navigation-basic-item
|
||||
*ngIf="item.type === 'basic'"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-basic-item>
|
||||
<ng-container *ngIf="item.type === 'basic'">
|
||||
<fuse-vertical-navigation-basic-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-basic-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Collapsable -->
|
||||
<fuse-vertical-navigation-collapsable-item
|
||||
*ngIf="item.type === 'collapsable'"
|
||||
[item]="item"
|
||||
[name]="name"
|
||||
[autoCollapse]="autoCollapse"></fuse-vertical-navigation-collapsable-item>
|
||||
<ng-container *ngIf="item.type === 'collapsable'">
|
||||
<fuse-vertical-navigation-collapsable-item
|
||||
[item]="item"
|
||||
[name]="name"
|
||||
[autoCollapse]="autoCollapse"></fuse-vertical-navigation-collapsable-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Divider -->
|
||||
<fuse-vertical-navigation-divider-item
|
||||
*ngIf="item.type === 'divider'"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-divider-item>
|
||||
<ng-container *ngIf="item.type === 'divider'">
|
||||
<fuse-vertical-navigation-divider-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-divider-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Group -->
|
||||
<fuse-vertical-navigation-group-item
|
||||
*ngIf="item.type === 'group'"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-group-item>
|
||||
<ng-container *ngIf="item.type === 'group'">
|
||||
<fuse-vertical-navigation-group-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-group-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Spacer -->
|
||||
<fuse-vertical-navigation-spacer-item
|
||||
*ngIf="item.type === 'spacer'"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-spacer-item>
|
||||
<ng-container *ngIf="item.type === 'spacer'">
|
||||
<fuse-vertical-navigation-spacer-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-spacer-item>
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
|
||||
|
||||
@@ -7,11 +7,12 @@
|
||||
<div class="fuse-vertical-navigation-item">
|
||||
|
||||
<!-- Icon -->
|
||||
<mat-icon
|
||||
class="fuse-vertical-navigation-item-icon"
|
||||
[ngClass]="item.classes?.icon"
|
||||
*ngIf="item.icon"
|
||||
[svgIcon]="item.icon"></mat-icon>
|
||||
<ng-container *ngIf="item.icon">
|
||||
<mat-icon
|
||||
class="fuse-vertical-navigation-item-icon"
|
||||
[ngClass]="item.classes?.icon"
|
||||
[svgIcon]="item.icon"></mat-icon>
|
||||
</ng-container>
|
||||
|
||||
<!-- Title & Subtitle -->
|
||||
<div class="fuse-vertical-navigation-item-title-wrapper">
|
||||
@@ -20,25 +21,25 @@
|
||||
{{item.title}}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="fuse-vertical-navigation-item-subtitle"
|
||||
*ngIf="item.subtitle">
|
||||
<span [ngClass]="item.classes?.subtitle">
|
||||
{{item.subtitle}}
|
||||
</span>
|
||||
</div>
|
||||
<ng-container *ngIf="item.subtitle">
|
||||
<div class="fuse-vertical-navigation-item-subtitle">
|
||||
<span [ngClass]="item.classes?.subtitle">
|
||||
{{item.subtitle}}
|
||||
</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<!-- Badge -->
|
||||
<div
|
||||
class="fuse-vertical-navigation-item-badge"
|
||||
*ngIf="item.badge">
|
||||
<div
|
||||
class="fuse-vertical-navigation-item-badge-content"
|
||||
[ngClass]="item.badge.classes">
|
||||
{{item.badge.title}}
|
||||
<ng-container *ngIf="item.badge">
|
||||
<div class="fuse-vertical-navigation-item-badge">
|
||||
<div
|
||||
class="fuse-vertical-navigation-item-badge-content"
|
||||
[ngClass]="item.badge.classes">
|
||||
{{item.badge.title}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -50,35 +51,40 @@
|
||||
<ng-container *ngIf="(item.hidden && !item.hidden(item)) || !item.hidden">
|
||||
|
||||
<!-- Basic -->
|
||||
<fuse-vertical-navigation-basic-item
|
||||
*ngIf="item.type === 'basic'"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-basic-item>
|
||||
<ng-container *ngIf="item.type === 'basic'">
|
||||
<fuse-vertical-navigation-basic-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-basic-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Collapsable -->
|
||||
<fuse-vertical-navigation-collapsable-item
|
||||
*ngIf="item.type === 'collapsable'"
|
||||
[item]="item"
|
||||
[name]="name"
|
||||
[autoCollapse]="autoCollapse"></fuse-vertical-navigation-collapsable-item>
|
||||
<ng-container *ngIf="item.type === 'collapsable'">
|
||||
<fuse-vertical-navigation-collapsable-item
|
||||
[item]="item"
|
||||
[name]="name"
|
||||
[autoCollapse]="autoCollapse"></fuse-vertical-navigation-collapsable-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Divider -->
|
||||
<fuse-vertical-navigation-divider-item
|
||||
*ngIf="item.type === 'divider'"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-divider-item>
|
||||
<ng-container *ngIf="item.type === 'divider'">
|
||||
<fuse-vertical-navigation-divider-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-divider-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Group -->
|
||||
<fuse-vertical-navigation-group-item
|
||||
*ngIf="item.type === 'group'"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-group-item>
|
||||
<ng-container *ngIf="item.type === 'group'">
|
||||
<fuse-vertical-navigation-group-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-group-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Spacer -->
|
||||
<fuse-vertical-navigation-spacer-item
|
||||
*ngIf="item.type === 'spacer'"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-spacer-item>
|
||||
<ng-container *ngIf="item.type === 'spacer'">
|
||||
<fuse-vertical-navigation-spacer-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-spacer-item>
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
|
||||
|
||||
@@ -335,6 +335,7 @@ fuse-vertical-navigation {
|
||||
}
|
||||
|
||||
> .fuse-vertical-navigation-item-children {
|
||||
margin-top: 6px;
|
||||
|
||||
> *:last-child {
|
||||
padding-bottom: 6px;
|
||||
|
||||
@@ -24,46 +24,52 @@
|
||||
<ng-container *ngIf="(item.hidden && !item.hidden(item)) || !item.hidden">
|
||||
|
||||
<!-- Aside -->
|
||||
<fuse-vertical-navigation-aside-item
|
||||
*ngIf="item.type === 'aside'"
|
||||
[item]="item"
|
||||
[name]="name"
|
||||
[activeItemId]="activeAsideItemId"
|
||||
[autoCollapse]="autoCollapse"
|
||||
[skipChildren]="true"
|
||||
(click)="toggleAside(item)"></fuse-vertical-navigation-aside-item>
|
||||
<ng-container *ngIf="item.type === 'aside'">
|
||||
<fuse-vertical-navigation-aside-item
|
||||
[item]="item"
|
||||
[name]="name"
|
||||
[activeItemId]="activeAsideItemId"
|
||||
[autoCollapse]="autoCollapse"
|
||||
[skipChildren]="true"
|
||||
(click)="toggleAside(item)"></fuse-vertical-navigation-aside-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Basic -->
|
||||
<fuse-vertical-navigation-basic-item
|
||||
*ngIf="item.type === 'basic'"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-basic-item>
|
||||
<ng-container *ngIf="item.type === 'basic'">
|
||||
<fuse-vertical-navigation-basic-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-basic-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Collapsable -->
|
||||
<fuse-vertical-navigation-collapsable-item
|
||||
*ngIf="item.type === 'collapsable'"
|
||||
[item]="item"
|
||||
[name]="name"
|
||||
[autoCollapse]="autoCollapse"></fuse-vertical-navigation-collapsable-item>
|
||||
<ng-container *ngIf="item.type === 'collapsable'">
|
||||
<fuse-vertical-navigation-collapsable-item
|
||||
[item]="item"
|
||||
[name]="name"
|
||||
[autoCollapse]="autoCollapse"></fuse-vertical-navigation-collapsable-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Divider -->
|
||||
<fuse-vertical-navigation-divider-item
|
||||
*ngIf="item.type === 'divider'"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-divider-item>
|
||||
<ng-container *ngIf="item.type === 'divider'">
|
||||
<fuse-vertical-navigation-divider-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-divider-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Group -->
|
||||
<fuse-vertical-navigation-group-item
|
||||
*ngIf="item.type === 'group'"
|
||||
[item]="item"
|
||||
[name]="name"
|
||||
[autoCollapse]="autoCollapse"></fuse-vertical-navigation-group-item>
|
||||
<ng-container *ngIf="item.type === 'group'">
|
||||
<fuse-vertical-navigation-group-item
|
||||
[item]="item"
|
||||
[name]="name"
|
||||
[autoCollapse]="autoCollapse"></fuse-vertical-navigation-group-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- Spacer -->
|
||||
<fuse-vertical-navigation-spacer-item
|
||||
*ngIf="item.type === 'spacer'"
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-spacer-item>
|
||||
<ng-container *ngIf="item.type === 'spacer'">
|
||||
<fuse-vertical-navigation-spacer-item
|
||||
[item]="item"
|
||||
[name]="name"></fuse-vertical-navigation-spacer-item>
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
|
||||
@@ -84,31 +90,33 @@
|
||||
</div>
|
||||
|
||||
<!-- Aside -->
|
||||
<div
|
||||
class="fuse-vertical-navigation-aside-wrapper"
|
||||
*ngIf="activeAsideItemId"
|
||||
fuseScrollbar
|
||||
[fuseScrollbarOptions]="{wheelPropagation: false, suppressScrollX: true}"
|
||||
[@fadeInLeft]="position === 'left'"
|
||||
[@fadeInRight]="position === 'right'"
|
||||
[@fadeOutLeft]="position === 'left'"
|
||||
[@fadeOutRight]="position === 'right'">
|
||||
<ng-container *ngIf="activeAsideItemId">
|
||||
<div
|
||||
class="fuse-vertical-navigation-aside-wrapper"
|
||||
fuseScrollbar
|
||||
[fuseScrollbarOptions]="{wheelPropagation: false, suppressScrollX: true}"
|
||||
[@fadeInLeft]="position === 'left'"
|
||||
[@fadeInRight]="position === 'right'"
|
||||
[@fadeOutLeft]="position === 'left'"
|
||||
[@fadeOutRight]="position === 'right'">
|
||||
|
||||
<!-- Items -->
|
||||
<ng-container *ngFor="let item of navigation; trackBy: trackByFn">
|
||||
<!-- Items -->
|
||||
<ng-container *ngFor="let item of navigation; trackBy: trackByFn">
|
||||
|
||||
<!-- Skip the hidden items -->
|
||||
<ng-container *ngIf="(item.hidden && !item.hidden(item)) || !item.hidden">
|
||||
<!-- Skip the hidden items -->
|
||||
<ng-container *ngIf="(item.hidden && !item.hidden(item)) || !item.hidden">
|
||||
|
||||
<!-- Aside -->
|
||||
<fuse-vertical-navigation-aside-item
|
||||
*ngIf="item.type === 'aside' && item.id === activeAsideItemId"
|
||||
[item]="item"
|
||||
[name]="name"
|
||||
[autoCollapse]="autoCollapse"></fuse-vertical-navigation-aside-item>
|
||||
<!-- Aside -->
|
||||
<ng-container *ngIf="item.type === 'aside' && item.id === activeAsideItemId">
|
||||
<fuse-vertical-navigation-aside-item
|
||||
[item]="item"
|
||||
[name]="name"
|
||||
[autoCollapse]="autoCollapse"></fuse-vertical-navigation-aside-item>
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
@@ -374,6 +374,10 @@ export class FuseVerticalNavigationComponent implements OnChanges, OnInit, After
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Forcefully close the navigation and aside in case they are opened
|
||||
this.close();
|
||||
this.closeAside();
|
||||
|
||||
// Deregister the navigation component from the registry
|
||||
this._fuseNavigationService.deregisterComponent(this.name);
|
||||
|
||||
|
||||
@@ -136,11 +136,8 @@
|
||||
.mat-flat-button,
|
||||
.mat-raised-button,
|
||||
.mat-stroked-button {
|
||||
|
||||
.fuse-mat-rounded & {
|
||||
padding: 0 20px;
|
||||
border-radius: 9999px;
|
||||
}
|
||||
padding: 0 20px !important;
|
||||
border-radius: 9999px !important;
|
||||
}
|
||||
|
||||
/* Target all buttons */
|
||||
@@ -334,6 +331,8 @@
|
||||
/* @ Button Toggle
|
||||
/* ----------------------------------------------------------------------------------------------------- */
|
||||
.mat-button-toggle-group {
|
||||
border: none !important;
|
||||
@apply space-x-1;
|
||||
|
||||
&.mat-button-toggle-group-appearance-standard {
|
||||
|
||||
@@ -341,36 +340,27 @@
|
||||
background-clip: padding-box;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Rounded design */
|
||||
.fuse-mat-rounded {
|
||||
|
||||
.mat-button-toggle-group {
|
||||
.mat-button-toggle {
|
||||
border-radius: 9999px;
|
||||
overflow: hidden;
|
||||
border: none !important;
|
||||
@apply space-x-1;
|
||||
font-weight: 500;
|
||||
|
||||
.mat-button-toggle {
|
||||
border-radius: 9999px;
|
||||
overflow: hidden;
|
||||
border: none !important;
|
||||
font-weight: 500;
|
||||
|
||||
&.mat-button-toggle-checked {
|
||||
|
||||
.mat-button-toggle-label-content {
|
||||
@apply text-default #{'!important'};
|
||||
}
|
||||
}
|
||||
&.mat-button-toggle-checked {
|
||||
|
||||
.mat-button-toggle-label-content {
|
||||
padding: 0 20px;
|
||||
@apply text-secondary;
|
||||
@apply text-default #{'!important'};
|
||||
}
|
||||
}
|
||||
|
||||
.mat-ripple {
|
||||
border-radius: 9999px;
|
||||
}
|
||||
.mat-button-toggle-label-content {
|
||||
padding: 0 20px;
|
||||
@apply text-secondary;
|
||||
}
|
||||
|
||||
.mat-ripple {
|
||||
border-radius: 9999px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1329,62 +1319,55 @@
|
||||
opacity: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-tab-header {
|
||||
border-bottom: none !important;
|
||||
|
||||
.mat-tab-label-container {
|
||||
padding: 0 24px;
|
||||
|
||||
.mat-tab-list {
|
||||
|
||||
.mat-tab-labels {
|
||||
|
||||
.mat-tab-label {
|
||||
min-width: 0 !important;
|
||||
height: 40px !important;
|
||||
padding: 0 20px !important;
|
||||
border-radius: 9999px !important;
|
||||
@apply text-secondary;
|
||||
|
||||
&.mat-tab-label-active {
|
||||
@apply bg-gray-700 bg-opacity-10 dark:bg-gray-50 dark:bg-opacity-10 #{'!important'};
|
||||
@apply text-default #{'!important'};
|
||||
}
|
||||
|
||||
+ .mat-tab-label {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.mat-tab-label-content {
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mat-ink-bar {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mat-tab-body-content {
|
||||
padding: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-tab-label {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
/* Rounded design */
|
||||
.fuse-mat-rounded {
|
||||
|
||||
.mat-tab-group {
|
||||
|
||||
.mat-tab-header {
|
||||
border-bottom: none !important;
|
||||
|
||||
.mat-tab-label-container {
|
||||
padding: 0 24px;
|
||||
|
||||
.mat-tab-list {
|
||||
|
||||
.mat-tab-labels {
|
||||
|
||||
.mat-tab-label {
|
||||
min-width: 0 !important;
|
||||
height: 40px !important;
|
||||
padding: 0 20px !important;
|
||||
border-radius: 9999px !important;
|
||||
@apply text-secondary;
|
||||
|
||||
&.mat-tab-label-active {
|
||||
@apply bg-gray-700 bg-opacity-10 dark:bg-gray-50 dark:bg-opacity-10 #{'!important'};
|
||||
@apply text-default #{'!important'};
|
||||
}
|
||||
|
||||
+ .mat-tab-label {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.mat-tab-label-content {
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mat-ink-bar {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mat-tab-body-content {
|
||||
padding: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------------------- */
|
||||
/* @ Textarea
|
||||
/* ----------------------------------------------------------------------------------------------------- */
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import { Version } from '@fuse/version/version';
|
||||
|
||||
export const FUSE_VERSION = new Version('13.0.3').full;
|
||||
export const FUSE_VERSION = new Version('13.2.0').full;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||
import { forkJoin, Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { InitialData } from 'app/app.types';
|
||||
import { MessagesService } from 'app/layout/common/messages/messages.service';
|
||||
import { NavigationService } from 'app/core/navigation/navigation.service';
|
||||
import { NotificationsService } from 'app/layout/common/notifications/notifications.service';
|
||||
import { ShortcutsService } from 'app/layout/common/shortcuts/shortcuts.service';
|
||||
import { UserService } from 'app/core/user/user.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -13,7 +15,13 @@ export class InitialDataResolver implements Resolve<any>
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(private _httpClient: HttpClient)
|
||||
constructor(
|
||||
private _messagesService: MessagesService,
|
||||
private _navigationService: NavigationService,
|
||||
private _notificationsService: NotificationsService,
|
||||
private _shortcutsService: ShortcutsService,
|
||||
private _userService: UserService
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -27,29 +35,15 @@ export class InitialDataResolver implements Resolve<any>
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<InitialData>
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any>
|
||||
{
|
||||
// Fork join multiple API endpoint calls to wait all of them to finish
|
||||
return forkJoin([
|
||||
this._httpClient.get<any>('api/common/messages'),
|
||||
this._httpClient.get<any>('api/common/navigation'),
|
||||
this._httpClient.get<any>('api/common/notifications'),
|
||||
this._httpClient.get<any>('api/common/shortcuts'),
|
||||
this._httpClient.get<any>('api/common/user')
|
||||
]).pipe(
|
||||
map(([messages, navigation, notifications, shortcuts, user]) => ({
|
||||
messages,
|
||||
navigation: {
|
||||
compact : navigation.compact,
|
||||
default : navigation.default,
|
||||
futuristic: navigation.futuristic,
|
||||
horizontal: navigation.horizontal
|
||||
},
|
||||
notifications,
|
||||
shortcuts,
|
||||
user
|
||||
})
|
||||
)
|
||||
);
|
||||
this._navigationService.get(),
|
||||
this._messagesService.getAll(),
|
||||
this._notificationsService.getAll(),
|
||||
this._shortcutsService.getAll(),
|
||||
this._userService.get()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,6 +149,9 @@ export const appRoutes: Route[] = [
|
||||
// TailwindCSS
|
||||
{path: 'tailwindcss', loadChildren: () => import('app/modules/admin/ui/tailwindcss/tailwindcss.module').then(m => m.TailwindCSSModule)},
|
||||
|
||||
// Advanced search
|
||||
{path: 'advanced-search', loadChildren: () => import('app/modules/admin/ui/advanced-search/advanced-search.module').then(m => m.AdvancedSearchModule)},
|
||||
|
||||
// Animations
|
||||
{path: 'animations', loadChildren: () => import('app/modules/admin/ui/animations/animations.module').then(m => m.AnimationsModule)},
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import { FuseNavigationItem } from '@fuse/components/navigation';
|
||||
import { Message } from 'app/layout/common/messages/messages.types';
|
||||
import { Notification } from 'app/layout/common/notifications/notifications.types';
|
||||
import { Shortcut } from 'app/layout/common/shortcuts/shortcuts.types';
|
||||
import { User } from 'app/core/user/user.model';
|
||||
|
||||
export interface InitialData
|
||||
{
|
||||
messages: Message[];
|
||||
navigation: {
|
||||
compact: FuseNavigationItem[];
|
||||
default: FuseNavigationItem[];
|
||||
futuristic: FuseNavigationItem[];
|
||||
horizontal: FuseNavigationItem[];
|
||||
};
|
||||
notifications: Notification[];
|
||||
shortcuts: Shortcut[];
|
||||
user: User;
|
||||
}
|
||||
48
src/app/core/navigation/navigation.service.ts
Normal file
48
src/app/core/navigation/navigation.service.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable, ReplaySubject } from 'rxjs';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class NavigationService
|
||||
{
|
||||
private _navigation: ReplaySubject<Navigation> = new ReplaySubject<Navigation>(1);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(private _httpClient: HttpClient)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Accessors
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Getter for navigation
|
||||
*/
|
||||
get navigation$(): Observable<Navigation>
|
||||
{
|
||||
return this._navigation.asObservable();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get all navigation data
|
||||
*/
|
||||
get(): Observable<Navigation>
|
||||
{
|
||||
return this._httpClient.get<Navigation>('api/common/navigation').pipe(
|
||||
tap((navigation) => {
|
||||
this._navigation.next(navigation);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
9
src/app/core/navigation/navigation.types.ts
Normal file
9
src/app/core/navigation/navigation.types.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { FuseNavigationItem } from '@fuse/components/navigation';
|
||||
|
||||
export interface Navigation
|
||||
{
|
||||
compact: FuseNavigationItem[];
|
||||
default: FuseNavigationItem[];
|
||||
futuristic: FuseNavigationItem[];
|
||||
horizontal: FuseNavigationItem[];
|
||||
}
|
||||
@@ -27,6 +27,6 @@ export class TranslocoHttpLoader implements TranslocoLoader
|
||||
*/
|
||||
getTranslation(lang: string): Observable<Translation>
|
||||
{
|
||||
return this._httpClient.get<Translation>(`/assets/i18n/${lang}.json`);
|
||||
return this._httpClient.get<Translation>(`./assets/i18n/${lang}.json`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable, ReplaySubject } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { User } from 'app/core/user/user.model';
|
||||
import { map, tap } from 'rxjs/operators';
|
||||
import { User } from 'app/core/user/user.types';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -42,6 +42,18 @@ export class UserService
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get the current logged in user data
|
||||
*/
|
||||
get(): Observable<User>
|
||||
{
|
||||
return this._httpClient.get<User>('api/common/user').pipe(
|
||||
tap((user) => {
|
||||
this._user.next(user);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the user
|
||||
*
|
||||
@@ -51,7 +63,6 @@ export class UserService
|
||||
{
|
||||
return this._httpClient.patch<User>('api/common/user', {user}).pipe(
|
||||
map((response) => {
|
||||
// Execute the observable
|
||||
this._user.next(response);
|
||||
})
|
||||
);
|
||||
|
||||
@@ -4,13 +4,13 @@ import { AvailableLangs, TranslocoService } from '@ngneat/transloco';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
|
||||
@Component({
|
||||
selector : 'language',
|
||||
templateUrl : './language.component.html',
|
||||
selector : 'languages',
|
||||
templateUrl : './languages.component.html',
|
||||
encapsulation : ViewEncapsulation.None,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
exportAs : 'language'
|
||||
exportAs : 'languages'
|
||||
})
|
||||
export class LanguageComponent implements OnInit, OnDestroy
|
||||
export class LanguagesComponent implements OnInit, OnDestroy
|
||||
{
|
||||
availableLangs: AvailableLangs;
|
||||
activeLang: string;
|
||||
@@ -2,12 +2,12 @@ import { NgModule } from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { LanguageComponent } from 'app/layout/common/language/language.component';
|
||||
import { LanguagesComponent } from 'app/layout/common/languages/languages.component';
|
||||
import { SharedModule } from 'app/shared/shared.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
LanguageComponent
|
||||
LanguagesComponent
|
||||
],
|
||||
imports : [
|
||||
MatButtonModule,
|
||||
@@ -16,9 +16,9 @@ import { SharedModule } from 'app/shared/shared.module';
|
||||
SharedModule
|
||||
],
|
||||
exports : [
|
||||
LanguageComponent
|
||||
LanguagesComponent
|
||||
]
|
||||
})
|
||||
export class LanguageModule
|
||||
export class LanguagesModule
|
||||
{
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, TemplateRef, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit, TemplateRef, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core';
|
||||
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
|
||||
import { TemplatePortal } from '@angular/cdk/portal';
|
||||
import { MatButton } from '@angular/material/button';
|
||||
@@ -14,12 +14,12 @@ import { MessagesService } from 'app/layout/common/messages/messages.service';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
exportAs : 'messages'
|
||||
})
|
||||
export class MessagesComponent implements OnInit, OnChanges, OnDestroy
|
||||
export class MessagesComponent implements OnInit, OnDestroy
|
||||
{
|
||||
@Input() messages: Message[];
|
||||
@ViewChild('messagesOrigin') private _messagesOrigin: MatButton;
|
||||
@ViewChild('messagesPanel') private _messagesPanel: TemplateRef<any>;
|
||||
|
||||
messages: Message[];
|
||||
unreadCount: number = 0;
|
||||
private _overlayRef: OverlayRef;
|
||||
private _unsubscribeAll: Subject<any> = new Subject<any>();
|
||||
@@ -40,21 +40,6 @@ export class MessagesComponent implements OnInit, OnChanges, OnDestroy
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On changes
|
||||
*
|
||||
* @param changes
|
||||
*/
|
||||
ngOnChanges(changes: SimpleChanges): void
|
||||
{
|
||||
// Messages
|
||||
if ( 'messages' in changes )
|
||||
{
|
||||
// Store the messages on the service
|
||||
this._messagesService.store(changes.messages.currentValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
@@ -182,7 +167,7 @@ export class MessagesComponent implements OnInit, OnChanges, OnDestroy
|
||||
scrollStrategy : this._overlay.scrollStrategies.block(),
|
||||
positionStrategy: this._overlay.position()
|
||||
.flexibleConnectedTo(this._messagesOrigin._elementRef.nativeElement)
|
||||
.withLockedPosition()
|
||||
.withLockedPosition(true)
|
||||
.withPush(true)
|
||||
.withPositions([
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable, ReplaySubject } from 'rxjs';
|
||||
import { Message } from 'app/layout/common/messages/messages.types';
|
||||
import { map, switchMap, take } from 'rxjs/operators';
|
||||
import { map, switchMap, take, tap } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -35,17 +35,15 @@ export class MessagesService
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Store messages on the service
|
||||
*
|
||||
* @param messages
|
||||
* Get all messages
|
||||
*/
|
||||
store(messages: Message[]): Observable<Message[]>
|
||||
getAll(): Observable<Message[]>
|
||||
{
|
||||
// Load the messages
|
||||
this._messages.next(messages);
|
||||
|
||||
// Return the messages
|
||||
return this.messages$;
|
||||
return this._httpClient.get<Message[]>('api/common/messages').pipe(
|
||||
tap((messages) => {
|
||||
this._messages.next(messages);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, TemplateRef, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit, TemplateRef, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core';
|
||||
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
|
||||
import { TemplatePortal } from '@angular/cdk/portal';
|
||||
import { MatButton } from '@angular/material/button';
|
||||
@@ -14,12 +14,12 @@ import { NotificationsService } from 'app/layout/common/notifications/notificati
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
exportAs : 'notifications'
|
||||
})
|
||||
export class NotificationsComponent implements OnChanges, OnInit, OnDestroy
|
||||
export class NotificationsComponent implements OnInit, OnDestroy
|
||||
{
|
||||
@Input() notifications: Notification[];
|
||||
@ViewChild('notificationsOrigin') private _notificationsOrigin: MatButton;
|
||||
@ViewChild('notificationsPanel') private _notificationsPanel: TemplateRef<any>;
|
||||
|
||||
notifications: Notification[];
|
||||
unreadCount: number = 0;
|
||||
private _overlayRef: OverlayRef;
|
||||
private _unsubscribeAll: Subject<any> = new Subject<any>();
|
||||
@@ -40,21 +40,6 @@ export class NotificationsComponent implements OnChanges, OnInit, OnDestroy
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On changes
|
||||
*
|
||||
* @param changes
|
||||
*/
|
||||
ngOnChanges(changes: SimpleChanges): void
|
||||
{
|
||||
// Notifications
|
||||
if ( 'notifications' in changes )
|
||||
{
|
||||
// Store the notifications on the service
|
||||
this._notificationsService.store(changes.notifications.currentValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
@@ -182,7 +167,7 @@ export class NotificationsComponent implements OnChanges, OnInit, OnDestroy
|
||||
scrollStrategy : this._overlay.scrollStrategies.block(),
|
||||
positionStrategy: this._overlay.position()
|
||||
.flexibleConnectedTo(this._notificationsOrigin._elementRef.nativeElement)
|
||||
.withLockedPosition()
|
||||
.withLockedPosition(true)
|
||||
.withPush(true)
|
||||
.withPositions([
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable, ReplaySubject } from 'rxjs';
|
||||
import { Notification } from 'app/layout/common/notifications/notifications.types';
|
||||
import { map, switchMap, take } from 'rxjs/operators';
|
||||
import { map, switchMap, take, tap } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -35,17 +35,15 @@ export class NotificationsService
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Store notifications on the service
|
||||
*
|
||||
* @param notifications
|
||||
* Get all notifications
|
||||
*/
|
||||
store(notifications: Notification[]): Observable<Notification[]>
|
||||
getAll(): Observable<Notification[]>
|
||||
{
|
||||
// Load the notifications
|
||||
this._notifications.next(notifications);
|
||||
|
||||
// Return the notifications
|
||||
return this.notifications$;
|
||||
return this._httpClient.get<Notification[]>('api/common/notifications').pipe(
|
||||
tap((notifications) => {
|
||||
this._notifications.next(notifications);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
(click)="open()">
|
||||
<mat-icon [svgIcon]="'heroicons_outline:search'"></mat-icon>
|
||||
</button>
|
||||
|
||||
<div
|
||||
class="absolute inset-0 flex items-center flex-shrink-0 z-99 bg-card"
|
||||
*ngIf="opened"
|
||||
@@ -23,22 +22,36 @@
|
||||
(keydown)="onKeydown($event)"
|
||||
#barSearchInput>
|
||||
<mat-autocomplete
|
||||
class="max-h-128 border-t rounded-b shadow-md"
|
||||
class="max-h-128 sm:px-2 border-t rounded-b shadow-md"
|
||||
[disableRipple]="true"
|
||||
#matAutocomplete="matAutocomplete">
|
||||
<mat-option
|
||||
class="h-14 px-6 py-0 sm:px-8 text-md pointer-events-none text-secondary bg-transparent"
|
||||
*ngIf="results && !results.length">
|
||||
class="py-0 px-6 text-md pointer-events-none text-secondary bg-transparent"
|
||||
*ngIf="resultSets && !resultSets.length">
|
||||
No results found!
|
||||
</mat-option>
|
||||
<ng-container *ngFor="let result of results; trackBy: trackByFn">
|
||||
<mat-option
|
||||
class="group relative h-14 px-6 py-0 sm:px-8 text-md"
|
||||
[routerLink]="result.link">
|
||||
<ng-container
|
||||
[ngTemplateOutlet]="searchResult"
|
||||
[ngTemplateOutletContext]="{$implicit: result}"></ng-container>
|
||||
</mat-option>
|
||||
<ng-container *ngFor="let resultSet of resultSets; trackBy: trackByFn">
|
||||
<mat-optgroup class="flex items-center mt-2 px-2">
|
||||
<span class="text-sm font-semibold tracking-wider text-secondary">{{resultSet.label.toUpperCase()}}</span>
|
||||
</mat-optgroup>
|
||||
<ng-container *ngFor="let result of resultSet.results; trackBy: trackByFn">
|
||||
<mat-option
|
||||
class="group relative mb-1 py-0 px-6 text-md rounded-md hover:bg-gray-100 dark:hover:bg-hover"
|
||||
[routerLink]="result.link">
|
||||
<!-- Contacts -->
|
||||
<ng-container *ngIf="resultSet.id === 'contacts'">
|
||||
<ng-container *ngTemplateOutlet="contactResult; context: {$implicit: result}"></ng-container>
|
||||
</ng-container>
|
||||
<!-- Pages -->
|
||||
<ng-container *ngIf="resultSet.id === 'pages'">
|
||||
<ng-container *ngTemplateOutlet="pageResult; context: {$implicit: result}"></ng-container>
|
||||
</ng-container>
|
||||
<!-- Tasks -->
|
||||
<ng-container *ngIf="resultSet.id === 'tasks'">
|
||||
<ng-container *ngTemplateOutlet="taskResult; context: {$implicit: result}"></ng-container>
|
||||
</ng-container>
|
||||
</mat-option>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</mat-autocomplete>
|
||||
<button
|
||||
@@ -69,62 +82,89 @@
|
||||
[disableRipple]="true"
|
||||
#matAutocomplete="matAutocomplete">
|
||||
<mat-option
|
||||
class="h-14 px-5 py-0 text-md pointer-events-none text-secondary bg-transparent"
|
||||
*ngIf="results && !results.length">
|
||||
class="py-0 px-6 text-md pointer-events-none text-secondary bg-transparent"
|
||||
*ngIf="resultSets && !resultSets.length">
|
||||
No results found!
|
||||
</mat-option>
|
||||
<ng-container *ngFor="let result of results; trackBy: trackByFn">
|
||||
<mat-option
|
||||
class="group relative h-14 px-5 py-0 text-md"
|
||||
[routerLink]="result.link">
|
||||
<ng-container
|
||||
[ngTemplateOutlet]="searchResult"
|
||||
[ngTemplateOutletContext]="{$implicit: result}"></ng-container>
|
||||
</mat-option>
|
||||
<ng-container *ngFor="let resultSet of resultSets; trackBy: trackByFn">
|
||||
<mat-optgroup class="flex items-center mt-2 px-2">
|
||||
<span class="text-sm font-semibold tracking-wider text-secondary">{{resultSet.label.toUpperCase()}}</span>
|
||||
</mat-optgroup>
|
||||
<ng-container *ngFor="let result of resultSet.results; trackBy: trackByFn">
|
||||
<mat-option
|
||||
class="group relative mb-1 py-0 px-6 text-md rounded-md hover:bg-gray-100 dark:hover:bg-hover"
|
||||
[routerLink]="result.link">
|
||||
<!-- Contacts -->
|
||||
<ng-container *ngIf="resultSet.id === 'contacts'">
|
||||
<ng-container *ngTemplateOutlet="contactResult; context: {$implicit: result}"></ng-container>
|
||||
</ng-container>
|
||||
<!-- Pages -->
|
||||
<ng-container *ngIf="resultSet.id === 'pages'">
|
||||
<ng-container *ngTemplateOutlet="pageResult; context: {$implicit: result}"></ng-container>
|
||||
</ng-container>
|
||||
<!-- Tasks -->
|
||||
<ng-container *ngIf="resultSet.id === 'tasks'">
|
||||
<ng-container *ngTemplateOutlet="taskResult; context: {$implicit: result}"></ng-container>
|
||||
</ng-container>
|
||||
</mat-option>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</mat-autocomplete>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<!-- Contact result template -->
|
||||
<ng-template
|
||||
#searchResult
|
||||
#contactResult
|
||||
let-result>
|
||||
|
||||
<!-- Hover indicator -->
|
||||
<div class="absolute inset-y-0 left-0 hidden w-1 bg-primary group-hover:flex"></div>
|
||||
|
||||
<!-- Contact result -->
|
||||
<ng-container *ngIf="result.resultType === 'contact'">
|
||||
<div class="flex items-center">
|
||||
<div class="px-1.5 py-1 mr-4 text-xs font-semibold leading-normal rounded text-indigo-50 bg-indigo-600">Contact</div>
|
||||
<div class="overflow-hidden overflow-ellipsis">
|
||||
<span [innerHTML]="result.title"></span>
|
||||
</div>
|
||||
<div class="flex flex-shrink-0 items-center justify-center w-8 h-8 ml-auto rounded-full overflow-hidden bg-primary-100 dark:bg-black dark:bg-opacity-5">
|
||||
<img
|
||||
*ngIf="result.avatar"
|
||||
[src]="result.avatar">
|
||||
<mat-icon
|
||||
class="m-0 icon-size-5 text-primary"
|
||||
*ngIf="!result.avatar"
|
||||
[svgIcon]="'heroicons_outline:user-circle'"></mat-icon>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="flex flex-shrink-0 items-center justify-center w-8 h-8 rounded-full overflow-hidden bg-primary-100 dark:bg-primary-800">
|
||||
<img
|
||||
*ngIf="result.avatar"
|
||||
[src]="result.avatar">
|
||||
<mat-icon
|
||||
class="m-0 icon-size-5 text-primary dark:text-primary-400"
|
||||
*ngIf="!result.avatar"
|
||||
[svgIcon]="'heroicons_outline:user-circle'"></mat-icon>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<!-- Page result -->
|
||||
<ng-container *ngIf="result.resultType === 'page'">
|
||||
<div class="flex items-center">
|
||||
<div class="px-1.5 py-1 mr-4 text-xs font-semibold leading-normal rounded text-teal-50 bg-teal-600">Page</div>
|
||||
<div class="flex flex-col overflow-hidden overflow-ellipsis">
|
||||
<span
|
||||
class="overflow-hidden overflow-ellipsis whitespace-nowrap leading-normal"
|
||||
[innerHTML]="result.title"></span>
|
||||
<span
|
||||
class="mt-1 text-secondary overflow-hidden overflow-ellipsis whitespace-nowrap leading-normal text-sm no-underline"
|
||||
[routerLink]="result.link">{{result.link}}</span>
|
||||
</div>
|
||||
<div class="ml-3 truncate">
|
||||
<span [innerHTML]="result.name"></span>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<!-- Page result template -->
|
||||
<ng-template
|
||||
#pageResult
|
||||
let-result>
|
||||
<div class="flex flex-col">
|
||||
<div
|
||||
class="truncate leading-normal"
|
||||
[innerHTML]="result.title"></div>
|
||||
<div class="truncate leading-normal text-sm text-secondary">
|
||||
{{result.link}}
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<!-- Task result template -->
|
||||
<ng-template
|
||||
#taskResult
|
||||
let-result>
|
||||
<div class="flex items-center">
|
||||
<ng-container *ngIf="result.completed">
|
||||
<mat-icon
|
||||
class="mr-0 text-primary dark:text-primary-400"
|
||||
[svgIcon]="'heroicons_outline:check-circle'"></mat-icon>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!result.completed">
|
||||
<mat-icon
|
||||
class="mr-0 text-hint"
|
||||
[svgIcon]="'heroicons_outline:check-circle'"></mat-icon>
|
||||
</ng-container>
|
||||
<div
|
||||
class="ml-3 truncate leading-normal"
|
||||
[ngClass]="{'line-through text-hint': result.completed}"
|
||||
[innerHTML]="result.title"></div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
@@ -20,7 +20,7 @@ export class SearchComponent implements OnChanges, OnInit, OnDestroy
|
||||
@Output() search: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
opened: boolean = false;
|
||||
results: any[];
|
||||
resultSets: any[];
|
||||
searchControl: FormControl = new FormControl();
|
||||
private _unsubscribeAll: Subject<any> = new Subject<any>();
|
||||
|
||||
@@ -104,12 +104,12 @@ export class SearchComponent implements OnChanges, OnInit, OnDestroy
|
||||
takeUntil(this._unsubscribeAll),
|
||||
map((value) => {
|
||||
|
||||
// Set the search results to null if there is no value or
|
||||
// Set the resultSets to null if there is no value or
|
||||
// the length of the value is smaller than the minLength
|
||||
// so the autocomplete panel can be closed
|
||||
if ( !value || value.length < this.minLength )
|
||||
{
|
||||
this.results = null;
|
||||
this.resultSets = null;
|
||||
}
|
||||
|
||||
// Continue
|
||||
@@ -121,13 +121,13 @@ export class SearchComponent implements OnChanges, OnInit, OnDestroy
|
||||
)
|
||||
.subscribe((value) => {
|
||||
this._httpClient.post('api/common/search', {query: value})
|
||||
.subscribe((response: any) => {
|
||||
.subscribe((resultSets: any) => {
|
||||
|
||||
// Store the results
|
||||
this.results = response.results;
|
||||
// Store the result sets
|
||||
this.resultSets = resultSets;
|
||||
|
||||
// Execute the event
|
||||
this.search.next(this.results);
|
||||
this.search.next(resultSets);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -21,7 +21,15 @@
|
||||
[svgIcon]="'heroicons_solid:x'"></mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="text-lg font-medium leading-10">Shortcuts</div>
|
||||
<div class="flex items-center text-lg font-medium leading-10">
|
||||
<span class="">Shortcuts</span>
|
||||
<ng-container *ngIf="mode !== 'view'">
|
||||
<span class="ml-1">
|
||||
<ng-container *ngIf="mode === 'add'">- Add new</ng-container>
|
||||
<ng-container *ngIf="mode === 'modify' || mode === 'edit'">- Editing</ng-container>
|
||||
</span>
|
||||
</ng-container>
|
||||
</div>
|
||||
<div class="ml-auto">
|
||||
|
||||
<!-- View mode -->
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, TemplateRef, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit, TemplateRef, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
|
||||
import { TemplatePortal } from '@angular/cdk/portal';
|
||||
@@ -15,14 +15,14 @@ import { ShortcutsService } from 'app/layout/common/shortcuts/shortcuts.service'
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
exportAs : 'shortcuts'
|
||||
})
|
||||
export class ShortcutsComponent implements OnChanges, OnInit, OnDestroy
|
||||
export class ShortcutsComponent implements OnInit, OnDestroy
|
||||
{
|
||||
@Input() shortcuts: Shortcut[];
|
||||
@ViewChild('shortcutsOrigin') private _shortcutsOrigin: MatButton;
|
||||
@ViewChild('shortcutsPanel') private _shortcutsPanel: TemplateRef<any>;
|
||||
|
||||
mode: 'view' | 'modify' | 'add' | 'edit' = 'view';
|
||||
shortcutForm: FormGroup;
|
||||
shortcuts: Shortcut[];
|
||||
private _overlayRef: OverlayRef;
|
||||
private _unsubscribeAll: Subject<any> = new Subject<any>();
|
||||
|
||||
@@ -43,21 +43,6 @@ export class ShortcutsComponent implements OnChanges, OnInit, OnDestroy
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On changes
|
||||
*
|
||||
* @param changes
|
||||
*/
|
||||
ngOnChanges(changes: SimpleChanges): void
|
||||
{
|
||||
// Shortcuts
|
||||
if ( 'shortcuts' in changes )
|
||||
{
|
||||
// Store the shortcuts on the service
|
||||
this._shortcutsService.store(changes.shortcuts.currentValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
@@ -236,7 +221,7 @@ export class ShortcutsComponent implements OnChanges, OnInit, OnDestroy
|
||||
scrollStrategy : this._overlay.scrollStrategies.block(),
|
||||
positionStrategy: this._overlay.position()
|
||||
.flexibleConnectedTo(this._shortcutsOrigin._elementRef.nativeElement)
|
||||
.withLockedPosition()
|
||||
.withLockedPosition(true)
|
||||
.withPush(true)
|
||||
.withPositions([
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable, ReplaySubject } from 'rxjs';
|
||||
import { map, switchMap, take } from 'rxjs/operators';
|
||||
import { map, switchMap, take, tap } from 'rxjs/operators';
|
||||
import { Shortcut } from 'app/layout/common/shortcuts/shortcuts.types';
|
||||
|
||||
@Injectable({
|
||||
@@ -35,17 +35,15 @@ export class ShortcutsService
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Store shortcuts on the service
|
||||
*
|
||||
* @param shortcuts
|
||||
* Get all messages
|
||||
*/
|
||||
store(shortcuts: Shortcut[]): Observable<Shortcut[]>
|
||||
getAll(): Observable<Shortcut[]>
|
||||
{
|
||||
// Load the shortcuts
|
||||
this._shortcuts.next(shortcuts);
|
||||
|
||||
// Return the shortcuts
|
||||
return this.shortcuts$;
|
||||
return this._httpClient.get<Shortcut[]>('api/common/shortcuts').pipe(
|
||||
tap((shortcuts) => {
|
||||
this._shortcuts.next(shortcuts);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,17 +3,17 @@ import { Router } from '@angular/router';
|
||||
import { BooleanInput } from '@angular/cdk/coercion';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { User } from 'app/core/user/user.model';
|
||||
import { User } from 'app/core/user/user.types';
|
||||
import { UserService } from 'app/core/user/user.service';
|
||||
|
||||
@Component({
|
||||
selector : 'user-menu',
|
||||
templateUrl : './user-menu.component.html',
|
||||
selector : 'user',
|
||||
templateUrl : './user.component.html',
|
||||
encapsulation : ViewEncapsulation.None,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
exportAs : 'userMenu'
|
||||
exportAs : 'user'
|
||||
})
|
||||
export class UserMenuComponent implements OnInit, OnDestroy
|
||||
export class UserComponent implements OnInit, OnDestroy
|
||||
{
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
static ngAcceptInputType_showAvatar: BooleanInput;
|
||||
@@ -3,12 +3,12 @@ import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatDividerModule } from '@angular/material/divider';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { UserMenuComponent } from 'app/layout/common/user-menu/user-menu.component';
|
||||
import { UserComponent } from 'app/layout/common/user/user.component';
|
||||
import { SharedModule } from 'app/shared/shared.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
UserMenuComponent
|
||||
UserComponent
|
||||
],
|
||||
imports : [
|
||||
MatButtonModule,
|
||||
@@ -18,9 +18,9 @@ import { SharedModule } from 'app/shared/shared.module';
|
||||
SharedModule
|
||||
],
|
||||
exports : [
|
||||
UserMenuComponent
|
||||
UserComponent
|
||||
]
|
||||
})
|
||||
export class UserMenuModule
|
||||
export class UserModule
|
||||
{
|
||||
}
|
||||
@@ -54,7 +54,7 @@
|
||||
</div>
|
||||
|
||||
<fuse-drawer
|
||||
class="w-100 min-w-100"
|
||||
class="w-screen min-w-screen sm:w-100 sm:min-w-100"
|
||||
fixed
|
||||
transparentOverlay
|
||||
[mode]="'over'"
|
||||
@@ -74,17 +74,17 @@
|
||||
|
||||
<!-- Theme -->
|
||||
<div class="text-md font-semibold text-secondary">THEME</div>
|
||||
<div class="grid grid-cols-3 gap-3 mt-6">
|
||||
<div class="grid grid-cols-2 sm:grid-cols-3 gap-3 mt-6">
|
||||
<ng-container *ngFor="let theme of themes">
|
||||
<div
|
||||
class="flex items-center px-4 py-3 rounded-full cursor-pointer ring-inset ring-primary bg-hover"
|
||||
class="flex items-center justify-center px-4 py-3 rounded-full cursor-pointer ring-inset ring-primary bg-hover"
|
||||
[class.ring-2]="config.theme === theme[0]"
|
||||
(click)="setTheme(theme[0])">
|
||||
<div
|
||||
class="w-4 h-4 rounded-full"
|
||||
class="flex-0 w-3 h-3 rounded-full"
|
||||
[style.background-color]="theme[1].primary"></div>
|
||||
<div
|
||||
class="ml-2.5 font-medium leading-5"
|
||||
class="ml-2.5 font-medium leading-5 truncate"
|
||||
[class.text-secondary]="config.theme !== theme[0]">
|
||||
{{theme[0] | titlecase}}
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
class="dark bg-gray-900 print:hidden"
|
||||
[mode]="'over'"
|
||||
[name]="'mainNavigation'"
|
||||
[navigation]="data.navigation.default"
|
||||
[navigation]="navigation.default"
|
||||
[opened]="false">
|
||||
<!-- Navigation header hook -->
|
||||
<ng-container fuseVerticalNavigationContentHeader>
|
||||
@@ -50,7 +50,7 @@
|
||||
<fuse-horizontal-navigation
|
||||
class="mr-2"
|
||||
[name]="'mainNavigation'"
|
||||
[navigation]="data.navigation.horizontal"></fuse-horizontal-navigation>
|
||||
[navigation]="navigation.horizontal"></fuse-horizontal-navigation>
|
||||
</ng-container>
|
||||
<!-- Navigation toggle button -->
|
||||
<ng-container *ngIf="isScreenSmall">
|
||||
@@ -62,14 +62,14 @@
|
||||
</button>
|
||||
</ng-container>
|
||||
<!-- Components -->
|
||||
<div class="flex items-center pl-2 ml-auto space-x-2">
|
||||
<language></language>
|
||||
<fuse-fullscreen></fuse-fullscreen>
|
||||
<div class="flex items-center pl-2 ml-auto space-x-1 sm:space-x-2">
|
||||
<languages></languages>
|
||||
<fuse-fullscreen class="hidden md:block"></fuse-fullscreen>
|
||||
<search [appearance]="'bar'"></search>
|
||||
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>
|
||||
<messages [messages]="data.messages"></messages>
|
||||
<notifications [notifications]="data.notifications"></notifications>
|
||||
<user-menu></user-menu>
|
||||
<shortcuts></shortcuts>
|
||||
<messages></messages>
|
||||
<notifications></notifications>
|
||||
<user></user>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -4,7 +4,8 @@ import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { InitialData } from 'app/app.types';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
import { NavigationService } from 'app/core/navigation/navigation.service';
|
||||
|
||||
@Component({
|
||||
selector : 'centered-layout',
|
||||
@@ -13,7 +14,7 @@ import { InitialData } from 'app/app.types';
|
||||
})
|
||||
export class CenteredLayoutComponent implements OnInit, OnDestroy
|
||||
{
|
||||
data: InitialData;
|
||||
navigation: Navigation;
|
||||
isScreenSmall: boolean;
|
||||
private _unsubscribeAll: Subject<any> = new Subject<any>();
|
||||
|
||||
@@ -23,6 +24,7 @@ export class CenteredLayoutComponent implements OnInit, OnDestroy
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute,
|
||||
private _router: Router,
|
||||
private _navigationService: NavigationService,
|
||||
private _fuseMediaWatcherService: FuseMediaWatcherService,
|
||||
private _fuseNavigationService: FuseNavigationService
|
||||
)
|
||||
@@ -50,10 +52,12 @@ export class CenteredLayoutComponent implements OnInit, OnDestroy
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to the resolved route data
|
||||
this._activatedRoute.data.subscribe((data: Data) => {
|
||||
this.data = data.initialData;
|
||||
});
|
||||
// Subscribe to navigation data
|
||||
this._navigationService.navigation$
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((navigation: Navigation) => {
|
||||
this.navigation = navigation;
|
||||
});
|
||||
|
||||
// Subscribe to media changes
|
||||
this._fuseMediaWatcherService.onMediaChange$
|
||||
|
||||
@@ -7,12 +7,12 @@ import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { FuseFullscreenModule } from '@fuse/components/fullscreen';
|
||||
import { FuseNavigationModule } from '@fuse/components/navigation';
|
||||
import { LanguageModule } from 'app/layout/common/language/language.module';
|
||||
import { LanguagesModule } from 'app/layout/common/languages/languages.module';
|
||||
import { MessagesModule } from 'app/layout/common/messages/messages.module';
|
||||
import { NotificationsModule } from 'app/layout/common/notifications/notifications.module';
|
||||
import { SearchModule } from 'app/layout/common/search/search.module';
|
||||
import { ShortcutsModule } from 'app/layout/common/shortcuts/shortcuts.module';
|
||||
import { UserMenuModule } from 'app/layout/common/user-menu/user-menu.module';
|
||||
import { UserModule } from 'app/layout/common/user/user.module';
|
||||
import { SharedModule } from 'app/shared/shared.module';
|
||||
import { CenteredLayoutComponent } from 'app/layout/layouts/horizontal/centered/centered.component';
|
||||
|
||||
@@ -29,12 +29,12 @@ import { CenteredLayoutComponent } from 'app/layout/layouts/horizontal/centered/
|
||||
MatMenuModule,
|
||||
FuseFullscreenModule,
|
||||
FuseNavigationModule,
|
||||
LanguageModule,
|
||||
LanguagesModule,
|
||||
MessagesModule,
|
||||
NotificationsModule,
|
||||
SearchModule,
|
||||
ShortcutsModule,
|
||||
UserMenuModule,
|
||||
UserModule,
|
||||
SharedModule
|
||||
],
|
||||
exports : [
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
class="dark bg-gray-900 print:hidden"
|
||||
[mode]="'over'"
|
||||
[name]="'mainNavigation'"
|
||||
[navigation]="data.navigation.default"
|
||||
[navigation]="navigation.default"
|
||||
[opened]="false">
|
||||
<!-- Navigation header hook -->
|
||||
<ng-container fuseVerticalNavigationContentHeader>
|
||||
@@ -45,14 +45,14 @@
|
||||
</button>
|
||||
</ng-container>
|
||||
<!-- Components -->
|
||||
<div class="flex items-center pl-2 ml-auto space-x-2">
|
||||
<language></language>
|
||||
<fuse-fullscreen></fuse-fullscreen>
|
||||
<div class="flex items-center pl-2 ml-auto space-x-1 sm:space-x-2">
|
||||
<languages></languages>
|
||||
<fuse-fullscreen class="hidden md:block"></fuse-fullscreen>
|
||||
<search [appearance]="'bar'"></search>
|
||||
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>
|
||||
<messages [messages]="data.messages"></messages>
|
||||
<notifications [notifications]="data.notifications"></notifications>
|
||||
<user-menu></user-menu>
|
||||
<shortcuts></shortcuts>
|
||||
<messages></messages>
|
||||
<notifications></notifications>
|
||||
<user></user>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -63,7 +63,7 @@
|
||||
<fuse-horizontal-navigation
|
||||
class="-mx-4"
|
||||
[name]="'mainNavigation'"
|
||||
[navigation]="data.navigation.horizontal"></fuse-horizontal-navigation>
|
||||
[navigation]="navigation.horizontal"></fuse-horizontal-navigation>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Data, Router } from '@angular/router';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { InitialData } from 'app/app.types';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
import { NavigationService } from 'app/core/navigation/navigation.service';
|
||||
|
||||
@Component({
|
||||
selector : 'enterprise-layout',
|
||||
@@ -13,8 +14,8 @@ import { InitialData } from 'app/app.types';
|
||||
})
|
||||
export class EnterpriseLayoutComponent implements OnInit, OnDestroy
|
||||
{
|
||||
data: InitialData;
|
||||
isScreenSmall: boolean;
|
||||
navigation: Navigation;
|
||||
private _unsubscribeAll: Subject<any> = new Subject<any>();
|
||||
|
||||
/**
|
||||
@@ -23,6 +24,7 @@ export class EnterpriseLayoutComponent implements OnInit, OnDestroy
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute,
|
||||
private _router: Router,
|
||||
private _navigationService: NavigationService,
|
||||
private _fuseMediaWatcherService: FuseMediaWatcherService,
|
||||
private _fuseNavigationService: FuseNavigationService
|
||||
)
|
||||
@@ -50,10 +52,12 @@ export class EnterpriseLayoutComponent implements OnInit, OnDestroy
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to the resolved route data
|
||||
this._activatedRoute.data.subscribe((data: Data) => {
|
||||
this.data = data.initialData;
|
||||
});
|
||||
// Subscribe to navigation data
|
||||
this._navigationService.navigation$
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((navigation: Navigation) => {
|
||||
this.navigation = navigation;
|
||||
});
|
||||
|
||||
// Subscribe to media changes
|
||||
this._fuseMediaWatcherService.onMediaChange$
|
||||
|
||||
@@ -7,12 +7,12 @@ import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { FuseFullscreenModule } from '@fuse/components/fullscreen';
|
||||
import { FuseNavigationModule } from '@fuse/components/navigation';
|
||||
import { LanguageModule } from 'app/layout/common/language/language.module';
|
||||
import { LanguagesModule } from 'app/layout/common/languages/languages.module';
|
||||
import { MessagesModule } from 'app/layout/common/messages/messages.module';
|
||||
import { NotificationsModule } from 'app/layout/common/notifications/notifications.module';
|
||||
import { SearchModule } from 'app/layout/common/search/search.module';
|
||||
import { ShortcutsModule } from 'app/layout/common/shortcuts/shortcuts.module';
|
||||
import { UserMenuModule } from 'app/layout/common/user-menu/user-menu.module';
|
||||
import { UserModule } from 'app/layout/common/user/user.module';
|
||||
import { SharedModule } from 'app/shared/shared.module';
|
||||
import { EnterpriseLayoutComponent } from 'app/layout/layouts/horizontal/enterprise/enterprise.component';
|
||||
|
||||
@@ -29,12 +29,12 @@ import { EnterpriseLayoutComponent } from 'app/layout/layouts/horizontal/enterpr
|
||||
MatMenuModule,
|
||||
FuseFullscreenModule,
|
||||
FuseNavigationModule,
|
||||
LanguageModule,
|
||||
LanguagesModule,
|
||||
MessagesModule,
|
||||
NotificationsModule,
|
||||
SearchModule,
|
||||
ShortcutsModule,
|
||||
UserMenuModule,
|
||||
UserModule,
|
||||
SharedModule
|
||||
],
|
||||
exports : [
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
class="dark bg-gray-900 print:hidden"
|
||||
[mode]="'over'"
|
||||
[name]="'mainNavigation'"
|
||||
[navigation]="data.navigation.default"
|
||||
[navigation]="navigation.default"
|
||||
[opened]="false">
|
||||
<!-- Navigation header hook -->
|
||||
<ng-container fuseVerticalNavigationContentHeader>
|
||||
@@ -51,14 +51,14 @@
|
||||
</button>
|
||||
</ng-container>
|
||||
<!-- Components -->
|
||||
<div class="flex items-center pl-2 ml-auto space-x-2">
|
||||
<language></language>
|
||||
<fuse-fullscreen></fuse-fullscreen>
|
||||
<div class="flex items-center pl-2 ml-auto space-x-1 sm:space-x-2">
|
||||
<languages></languages>
|
||||
<fuse-fullscreen class="hidden md:block"></fuse-fullscreen>
|
||||
<search [appearance]="'bar'"></search>
|
||||
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>
|
||||
<messages [messages]="data.messages"></messages>
|
||||
<notifications [notifications]="data.notifications"></notifications>
|
||||
<user-menu></user-menu>
|
||||
<shortcuts></shortcuts>
|
||||
<messages></messages>
|
||||
<notifications></notifications>
|
||||
<user></user>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Bottom bar -->
|
||||
@@ -66,7 +66,7 @@
|
||||
<div class="relative flex flex-auto flex-0 items-center h-16 px-4">
|
||||
<fuse-horizontal-navigation
|
||||
[name]="'mainNavigation'"
|
||||
[navigation]="data.navigation.horizontal"></fuse-horizontal-navigation>
|
||||
[navigation]="navigation.horizontal"></fuse-horizontal-navigation>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Data, Router } from '@angular/router';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { InitialData } from 'app/app.types';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
import { NavigationService } from 'app/core/navigation/navigation.service';
|
||||
|
||||
@Component({
|
||||
selector : 'material-layout',
|
||||
@@ -13,8 +14,8 @@ import { InitialData } from 'app/app.types';
|
||||
})
|
||||
export class MaterialLayoutComponent implements OnInit, OnDestroy
|
||||
{
|
||||
data: InitialData;
|
||||
isScreenSmall: boolean;
|
||||
navigation: Navigation;
|
||||
private _unsubscribeAll: Subject<any> = new Subject<any>();
|
||||
|
||||
/**
|
||||
@@ -23,6 +24,7 @@ export class MaterialLayoutComponent implements OnInit, OnDestroy
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute,
|
||||
private _router: Router,
|
||||
private _navigationService: NavigationService,
|
||||
private _fuseMediaWatcherService: FuseMediaWatcherService,
|
||||
private _fuseNavigationService: FuseNavigationService
|
||||
)
|
||||
@@ -50,10 +52,12 @@ export class MaterialLayoutComponent implements OnInit, OnDestroy
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to the resolved route data
|
||||
this._activatedRoute.data.subscribe((data: Data) => {
|
||||
this.data = data.initialData;
|
||||
});
|
||||
// Subscribe to navigation data
|
||||
this._navigationService.navigation$
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((navigation: Navigation) => {
|
||||
this.navigation = navigation;
|
||||
});
|
||||
|
||||
// Subscribe to media changes
|
||||
this._fuseMediaWatcherService.onMediaChange$
|
||||
|
||||
@@ -7,12 +7,12 @@ import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { FuseFullscreenModule } from '@fuse/components/fullscreen';
|
||||
import { FuseNavigationModule } from '@fuse/components/navigation';
|
||||
import { LanguageModule } from 'app/layout/common/language/language.module';
|
||||
import { LanguagesModule } from 'app/layout/common/languages/languages.module';
|
||||
import { MessagesModule } from 'app/layout/common/messages/messages.module';
|
||||
import { NotificationsModule } from 'app/layout/common/notifications/notifications.module';
|
||||
import { SearchModule } from 'app/layout/common/search/search.module';
|
||||
import { ShortcutsModule } from 'app/layout/common/shortcuts/shortcuts.module';
|
||||
import { UserMenuModule } from 'app/layout/common/user-menu/user-menu.module';
|
||||
import { UserModule } from 'app/layout/common/user/user.module';
|
||||
import { SharedModule } from 'app/shared/shared.module';
|
||||
import { MaterialLayoutComponent } from 'app/layout/layouts/horizontal/material/material.component';
|
||||
|
||||
@@ -29,12 +29,12 @@ import { MaterialLayoutComponent } from 'app/layout/layouts/horizontal/material/
|
||||
MatMenuModule,
|
||||
FuseFullscreenModule,
|
||||
FuseNavigationModule,
|
||||
LanguageModule,
|
||||
LanguagesModule,
|
||||
MessagesModule,
|
||||
NotificationsModule,
|
||||
SearchModule,
|
||||
ShortcutsModule,
|
||||
UserMenuModule,
|
||||
UserModule,
|
||||
SharedModule
|
||||
],
|
||||
exports : [
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
class="dark bg-gray-900 print:hidden"
|
||||
[mode]="'over'"
|
||||
[name]="'mainNavigation'"
|
||||
[navigation]="data.navigation.default"
|
||||
[navigation]="navigation.default"
|
||||
[opened]="false">
|
||||
<!-- Navigation header hook -->
|
||||
<ng-container fuseVerticalNavigationContentHeader>
|
||||
@@ -43,7 +43,7 @@
|
||||
<fuse-horizontal-navigation
|
||||
class="mr-2"
|
||||
[name]="'mainNavigation'"
|
||||
[navigation]="data.navigation.horizontal"></fuse-horizontal-navigation>
|
||||
[navigation]="navigation.horizontal"></fuse-horizontal-navigation>
|
||||
</ng-container>
|
||||
<!-- Navigation toggle button -->
|
||||
<ng-container *ngIf="isScreenSmall">
|
||||
@@ -54,14 +54,14 @@
|
||||
</button>
|
||||
</ng-container>
|
||||
<!-- Components -->
|
||||
<div class="flex items-center pl-2 ml-auto space-x-2">
|
||||
<language></language>
|
||||
<fuse-fullscreen></fuse-fullscreen>
|
||||
<div class="flex items-center pl-2 ml-auto space-x-1 sm:space-x-2">
|
||||
<languages></languages>
|
||||
<fuse-fullscreen class="hidden md:block"></fuse-fullscreen>
|
||||
<search [appearance]="'bar'"></search>
|
||||
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>
|
||||
<messages [messages]="data.messages"></messages>
|
||||
<notifications [notifications]="data.notifications"></notifications>
|
||||
<user-menu></user-menu>
|
||||
<shortcuts></shortcuts>
|
||||
<messages></messages>
|
||||
<notifications></notifications>
|
||||
<user></user>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Data, Router } from '@angular/router';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { InitialData } from 'app/app.types';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
import { NavigationService } from 'app/core/navigation/navigation.service';
|
||||
|
||||
@Component({
|
||||
selector : 'modern-layout',
|
||||
@@ -13,8 +14,8 @@ import { InitialData } from 'app/app.types';
|
||||
})
|
||||
export class ModernLayoutComponent implements OnInit, OnDestroy
|
||||
{
|
||||
data: InitialData;
|
||||
isScreenSmall: boolean;
|
||||
navigation: Navigation;
|
||||
private _unsubscribeAll: Subject<any> = new Subject<any>();
|
||||
|
||||
/**
|
||||
@@ -23,6 +24,7 @@ export class ModernLayoutComponent implements OnInit, OnDestroy
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute,
|
||||
private _router: Router,
|
||||
private _navigationService: NavigationService,
|
||||
private _fuseMediaWatcherService: FuseMediaWatcherService,
|
||||
private _fuseNavigationService: FuseNavigationService
|
||||
)
|
||||
@@ -50,10 +52,12 @@ export class ModernLayoutComponent implements OnInit, OnDestroy
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to the resolved route data
|
||||
this._activatedRoute.data.subscribe((data: Data) => {
|
||||
this.data = data.initialData;
|
||||
});
|
||||
// Subscribe to navigation data
|
||||
this._navigationService.navigation$
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((navigation: Navigation) => {
|
||||
this.navigation = navigation;
|
||||
});
|
||||
|
||||
// Subscribe to media changes
|
||||
this._fuseMediaWatcherService.onMediaChange$
|
||||
|
||||
@@ -7,12 +7,12 @@ import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { FuseFullscreenModule } from '@fuse/components/fullscreen';
|
||||
import { FuseNavigationModule } from '@fuse/components/navigation';
|
||||
import { LanguageModule } from 'app/layout/common/language/language.module';
|
||||
import { LanguagesModule } from 'app/layout/common/languages/languages.module';
|
||||
import { MessagesModule } from 'app/layout/common/messages/messages.module';
|
||||
import { NotificationsModule } from 'app/layout/common/notifications/notifications.module';
|
||||
import { SearchModule } from 'app/layout/common/search/search.module';
|
||||
import { ShortcutsModule } from 'app/layout/common/shortcuts/shortcuts.module';
|
||||
import { UserMenuModule } from 'app/layout/common/user-menu/user-menu.module';
|
||||
import { UserModule } from 'app/layout/common/user/user.module';
|
||||
import { SharedModule } from 'app/shared/shared.module';
|
||||
import { ModernLayoutComponent } from 'app/layout/layouts/horizontal/modern/modern.component';
|
||||
|
||||
@@ -29,12 +29,12 @@ import { ModernLayoutComponent } from 'app/layout/layouts/horizontal/modern/mode
|
||||
MatMenuModule,
|
||||
FuseFullscreenModule,
|
||||
FuseNavigationModule,
|
||||
LanguageModule,
|
||||
LanguagesModule,
|
||||
MessagesModule,
|
||||
NotificationsModule,
|
||||
SearchModule,
|
||||
ShortcutsModule,
|
||||
UserMenuModule,
|
||||
UserModule,
|
||||
SharedModule
|
||||
],
|
||||
exports : [
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
class="dark bg-gray-900 print:hidden"
|
||||
[mode]="isScreenSmall ? 'over' : 'side'"
|
||||
[name]="'mainNavigation'"
|
||||
[navigation]="data.navigation.default"
|
||||
[navigation]="navigation.default"
|
||||
[opened]="!isScreenSmall">
|
||||
<!-- Navigation header hook -->
|
||||
<ng-container fuseVerticalNavigationContentHeader>
|
||||
@@ -35,14 +35,14 @@
|
||||
<mat-icon [svgIcon]="'heroicons_outline:menu'"></mat-icon>
|
||||
</button>
|
||||
<!-- Components -->
|
||||
<div class="flex items-center pl-2 ml-auto space-x-2">
|
||||
<language></language>
|
||||
<fuse-fullscreen></fuse-fullscreen>
|
||||
<div class="flex items-center pl-2 ml-auto space-x-1 sm:space-x-2">
|
||||
<languages></languages>
|
||||
<fuse-fullscreen class="hidden md:block"></fuse-fullscreen>
|
||||
<search [appearance]="'bar'"></search>
|
||||
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>
|
||||
<messages [messages]="data.messages"></messages>
|
||||
<notifications [notifications]="data.notifications"></notifications>
|
||||
<user-menu></user-menu>
|
||||
<shortcuts></shortcuts>
|
||||
<messages></messages>
|
||||
<notifications></notifications>
|
||||
<user></user>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Data, Router } from '@angular/router';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { InitialData } from 'app/app.types';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
import { NavigationService } from 'app/core/navigation/navigation.service';
|
||||
|
||||
@Component({
|
||||
selector : 'classic-layout',
|
||||
@@ -13,8 +14,8 @@ import { InitialData } from 'app/app.types';
|
||||
})
|
||||
export class ClassicLayoutComponent implements OnInit, OnDestroy
|
||||
{
|
||||
data: InitialData;
|
||||
isScreenSmall: boolean;
|
||||
navigation: Navigation;
|
||||
private _unsubscribeAll: Subject<any> = new Subject<any>();
|
||||
|
||||
/**
|
||||
@@ -23,6 +24,7 @@ export class ClassicLayoutComponent implements OnInit, OnDestroy
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute,
|
||||
private _router: Router,
|
||||
private _navigationService: NavigationService,
|
||||
private _fuseMediaWatcherService: FuseMediaWatcherService,
|
||||
private _fuseNavigationService: FuseNavigationService
|
||||
)
|
||||
@@ -50,10 +52,12 @@ export class ClassicLayoutComponent implements OnInit, OnDestroy
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to the resolved route data
|
||||
this._activatedRoute.data.subscribe((data: Data) => {
|
||||
this.data = data.initialData;
|
||||
});
|
||||
// Subscribe to navigation data
|
||||
this._navigationService.navigation$
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((navigation: Navigation) => {
|
||||
this.navigation = navigation;
|
||||
});
|
||||
|
||||
// Subscribe to media changes
|
||||
this._fuseMediaWatcherService.onMediaChange$
|
||||
|
||||
@@ -7,12 +7,12 @@ import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { FuseFullscreenModule } from '@fuse/components/fullscreen';
|
||||
import { FuseNavigationModule } from '@fuse/components/navigation';
|
||||
import { LanguageModule } from 'app/layout/common/language/language.module';
|
||||
import { LanguagesModule } from 'app/layout/common/languages/languages.module';
|
||||
import { MessagesModule } from 'app/layout/common/messages/messages.module';
|
||||
import { NotificationsModule } from 'app/layout/common/notifications/notifications.module';
|
||||
import { SearchModule } from 'app/layout/common/search/search.module';
|
||||
import { ShortcutsModule } from 'app/layout/common/shortcuts/shortcuts.module';
|
||||
import { UserMenuModule } from 'app/layout/common/user-menu/user-menu.module';
|
||||
import { UserModule } from 'app/layout/common/user/user.module';
|
||||
import { SharedModule } from 'app/shared/shared.module';
|
||||
import { ClassicLayoutComponent } from 'app/layout/layouts/vertical/classic/classic.component';
|
||||
|
||||
@@ -29,12 +29,12 @@ import { ClassicLayoutComponent } from 'app/layout/layouts/vertical/classic/clas
|
||||
MatMenuModule,
|
||||
FuseFullscreenModule,
|
||||
FuseNavigationModule,
|
||||
LanguageModule,
|
||||
LanguagesModule,
|
||||
MessagesModule,
|
||||
NotificationsModule,
|
||||
SearchModule,
|
||||
ShortcutsModule,
|
||||
UserMenuModule,
|
||||
UserModule,
|
||||
SharedModule
|
||||
],
|
||||
exports : [
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
class="dark bg-gray-900 print:hidden"
|
||||
[mode]="isScreenSmall ? 'over' : 'side'"
|
||||
[name]="'mainNavigation'"
|
||||
[navigation]="data.navigation.default"
|
||||
[navigation]="navigation.default"
|
||||
[opened]="!isScreenSmall">
|
||||
<!-- Navigation header hook -->
|
||||
<ng-container fuseVerticalNavigationContentHeader>
|
||||
@@ -16,8 +16,8 @@
|
||||
</div>
|
||||
<!-- Components -->
|
||||
<div class="flex items-center ml-auto">
|
||||
<notifications [notifications]="data.notifications"></notifications>
|
||||
<user-menu [showAvatar]="false"></user-menu>
|
||||
<notifications></notifications>
|
||||
<user [showAvatar]="false"></user>
|
||||
</div>
|
||||
</div>
|
||||
<!-- User -->
|
||||
@@ -25,20 +25,20 @@
|
||||
<div class="relative w-24 h-24">
|
||||
<img
|
||||
class="w-full h-full rounded-full"
|
||||
*ngIf="data.user.avatar"
|
||||
[src]="data.user.avatar"
|
||||
*ngIf="user.avatar"
|
||||
[src]="user.avatar"
|
||||
alt="User avatar">
|
||||
<mat-icon
|
||||
class="icon-size-24"
|
||||
*ngIf="!data.user.avatar"
|
||||
*ngIf="!user.avatar"
|
||||
[svgIcon]="'heroicons_solid:user-circle'"></mat-icon>
|
||||
</div>
|
||||
<div class="flex flex-col items-center justify-center w-full mt-6">
|
||||
<div class="w-full whitespace-nowrap overflow-ellipsis overflow-hidden text-center leading-normal font-medium">
|
||||
{{data.user.name}}
|
||||
{{user.name}}
|
||||
</div>
|
||||
<div class="w-full mt-0.5 whitespace-nowrap overflow-ellipsis overflow-hidden text-center text-md leading-normal font-medium text-secondary">
|
||||
{{data.user.email}}
|
||||
{{user.email}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -65,12 +65,12 @@
|
||||
<mat-icon [svgIcon]="'heroicons_outline:menu'"></mat-icon>
|
||||
</button>
|
||||
<!-- Components -->
|
||||
<div class="flex items-center pl-2 ml-auto space-x-2">
|
||||
<language></language>
|
||||
<fuse-fullscreen></fuse-fullscreen>
|
||||
<div class="flex items-center pl-2 ml-auto space-x-1 sm:space-x-2">
|
||||
<languages></languages>
|
||||
<fuse-fullscreen class="hidden md:block"></fuse-fullscreen>
|
||||
<search [appearance]="'bar'"></search>
|
||||
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>
|
||||
<messages [messages]="data.messages"></messages>
|
||||
<shortcuts></shortcuts>
|
||||
<messages></messages>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Data, Router } from '@angular/router';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { InitialData } from 'app/app.types';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
import { NavigationService } from 'app/core/navigation/navigation.service';
|
||||
import { User } from 'app/core/user/user.types';
|
||||
import { UserService } from 'app/core/user/user.service';
|
||||
|
||||
@Component({
|
||||
selector : 'classy-layout',
|
||||
@@ -13,8 +16,9 @@ import { InitialData } from 'app/app.types';
|
||||
})
|
||||
export class ClassyLayoutComponent implements OnInit, OnDestroy
|
||||
{
|
||||
data: InitialData;
|
||||
isScreenSmall: boolean;
|
||||
navigation: Navigation;
|
||||
user: User;
|
||||
private _unsubscribeAll: Subject<any> = new Subject<any>();
|
||||
|
||||
/**
|
||||
@@ -23,6 +27,8 @@ export class ClassyLayoutComponent implements OnInit, OnDestroy
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute,
|
||||
private _router: Router,
|
||||
private _navigationService: NavigationService,
|
||||
private _userService: UserService,
|
||||
private _fuseMediaWatcherService: FuseMediaWatcherService,
|
||||
private _fuseNavigationService: FuseNavigationService
|
||||
)
|
||||
@@ -50,10 +56,19 @@ export class ClassyLayoutComponent implements OnInit, OnDestroy
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to the resolved route data
|
||||
this._activatedRoute.data.subscribe((data: Data) => {
|
||||
this.data = data.initialData;
|
||||
});
|
||||
// Subscribe to navigation data
|
||||
this._navigationService.navigation$
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((navigation: Navigation) => {
|
||||
this.navigation = navigation;
|
||||
});
|
||||
|
||||
// Subscribe to the user service
|
||||
this._userService.user$
|
||||
.pipe((takeUntil(this._unsubscribeAll)))
|
||||
.subscribe((user: User) => {
|
||||
this.user = user;
|
||||
});
|
||||
|
||||
// Subscribe to media changes
|
||||
this._fuseMediaWatcherService.onMediaChange$
|
||||
|
||||
@@ -7,12 +7,12 @@ import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { FuseNavigationModule } from '@fuse/components/navigation';
|
||||
import { FuseFullscreenModule } from '@fuse/components/fullscreen/fullscreen.module';
|
||||
import { LanguageModule } from 'app/layout/common/language/language.module';
|
||||
import { LanguagesModule } from 'app/layout/common/languages/languages.module';
|
||||
import { MessagesModule } from 'app/layout/common/messages/messages.module';
|
||||
import { NotificationsModule } from 'app/layout/common/notifications/notifications.module';
|
||||
import { SearchModule } from 'app/layout/common/search/search.module';
|
||||
import { ShortcutsModule } from 'app/layout/common/shortcuts/shortcuts.module';
|
||||
import { UserMenuModule } from 'app/layout/common/user-menu/user-menu.module';
|
||||
import { UserModule } from 'app/layout/common/user/user.module';
|
||||
import { SharedModule } from 'app/shared/shared.module';
|
||||
import { ClassyLayoutComponent } from 'app/layout/layouts/vertical/classy/classy.component';
|
||||
|
||||
@@ -29,12 +29,12 @@ import { ClassyLayoutComponent } from 'app/layout/layouts/vertical/classy/classy
|
||||
MatMenuModule,
|
||||
FuseFullscreenModule,
|
||||
FuseNavigationModule,
|
||||
LanguageModule,
|
||||
LanguagesModule,
|
||||
MessagesModule,
|
||||
NotificationsModule,
|
||||
SearchModule,
|
||||
ShortcutsModule,
|
||||
UserMenuModule,
|
||||
UserModule,
|
||||
SharedModule
|
||||
],
|
||||
exports : [
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[appearance]="'compact'"
|
||||
[mode]="isScreenSmall ? 'over' : 'side'"
|
||||
[name]="'mainNavigation'"
|
||||
[navigation]="data.navigation.compact"
|
||||
[navigation]="navigation.compact"
|
||||
[opened]="!isScreenSmall">
|
||||
<!-- Navigation header hook -->
|
||||
<ng-container fuseVerticalNavigationContentHeader>
|
||||
@@ -30,14 +30,14 @@
|
||||
<mat-icon [svgIcon]="'heroicons_outline:menu'"></mat-icon>
|
||||
</button>
|
||||
<!-- Components -->
|
||||
<div class="flex items-center pl-2 ml-auto space-x-2">
|
||||
<language></language>
|
||||
<fuse-fullscreen></fuse-fullscreen>
|
||||
<div class="flex items-center pl-2 ml-auto space-x-1 sm:space-x-2">
|
||||
<languages></languages>
|
||||
<fuse-fullscreen class="hidden md:block"></fuse-fullscreen>
|
||||
<search [appearance]="'bar'"></search>
|
||||
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>
|
||||
<messages [messages]="data.messages"></messages>
|
||||
<notifications [notifications]="data.notifications"></notifications>
|
||||
<user-menu></user-menu>
|
||||
<shortcuts></shortcuts>
|
||||
<messages></messages>
|
||||
<notifications></notifications>
|
||||
<user></user>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Data, Router } from '@angular/router';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { InitialData } from 'app/app.types';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
import { NavigationService } from 'app/core/navigation/navigation.service';
|
||||
|
||||
@Component({
|
||||
selector : 'compact-layout',
|
||||
@@ -13,8 +14,8 @@ import { InitialData } from 'app/app.types';
|
||||
})
|
||||
export class CompactLayoutComponent implements OnInit, OnDestroy
|
||||
{
|
||||
data: InitialData;
|
||||
isScreenSmall: boolean;
|
||||
navigation: Navigation;
|
||||
private _unsubscribeAll: Subject<any> = new Subject<any>();
|
||||
|
||||
/**
|
||||
@@ -23,6 +24,7 @@ export class CompactLayoutComponent implements OnInit, OnDestroy
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute,
|
||||
private _router: Router,
|
||||
private _navigationService: NavigationService,
|
||||
private _fuseMediaWatcherService: FuseMediaWatcherService,
|
||||
private _fuseNavigationService: FuseNavigationService
|
||||
)
|
||||
@@ -50,10 +52,12 @@ export class CompactLayoutComponent implements OnInit, OnDestroy
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to the resolved route data
|
||||
this._activatedRoute.data.subscribe((data: Data) => {
|
||||
this.data = data.initialData;
|
||||
});
|
||||
// Subscribe to navigation data
|
||||
this._navigationService.navigation$
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((navigation: Navigation) => {
|
||||
this.navigation = navigation;
|
||||
});
|
||||
|
||||
// Subscribe to media changes
|
||||
this._fuseMediaWatcherService.onMediaChange$
|
||||
|
||||
@@ -7,12 +7,12 @@ import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { FuseFullscreenModule } from '@fuse/components/fullscreen';
|
||||
import { FuseNavigationModule } from '@fuse/components/navigation';
|
||||
import { LanguageModule } from 'app/layout/common/language/language.module';
|
||||
import { LanguagesModule } from 'app/layout/common/languages/languages.module';
|
||||
import { MessagesModule } from 'app/layout/common/messages/messages.module';
|
||||
import { NotificationsModule } from 'app/layout/common/notifications/notifications.module';
|
||||
import { SearchModule } from 'app/layout/common/search/search.module';
|
||||
import { ShortcutsModule } from 'app/layout/common/shortcuts/shortcuts.module';
|
||||
import { UserMenuModule } from 'app/layout/common/user-menu/user-menu.module';
|
||||
import { UserModule } from 'app/layout/common/user/user.module';
|
||||
import { SharedModule } from 'app/shared/shared.module';
|
||||
import { CompactLayoutComponent } from 'app/layout/layouts/vertical/compact/compact.component';
|
||||
|
||||
@@ -29,12 +29,12 @@ import { CompactLayoutComponent } from 'app/layout/layouts/vertical/compact/comp
|
||||
MatMenuModule,
|
||||
FuseFullscreenModule,
|
||||
FuseNavigationModule,
|
||||
LanguageModule,
|
||||
LanguagesModule,
|
||||
MessagesModule,
|
||||
NotificationsModule,
|
||||
SearchModule,
|
||||
ShortcutsModule,
|
||||
UserMenuModule,
|
||||
UserModule,
|
||||
SharedModule
|
||||
],
|
||||
exports : [
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[appearance]="navigationAppearance"
|
||||
[mode]="isScreenSmall ? 'over' : 'side'"
|
||||
[name]="'mainNavigation'"
|
||||
[navigation]="data.navigation.default"
|
||||
[navigation]="navigation.default"
|
||||
[opened]="!isScreenSmall">
|
||||
<!-- Navigation header hook -->
|
||||
<ng-container fuseVerticalNavigationContentHeader>
|
||||
@@ -39,14 +39,14 @@
|
||||
</button>
|
||||
</div>
|
||||
<!-- Components -->
|
||||
<div class="flex items-center pl-2 ml-auto space-x-2">
|
||||
<language></language>
|
||||
<fuse-fullscreen></fuse-fullscreen>
|
||||
<div class="flex items-center pl-2 ml-auto space-x-1 sm:space-x-2">
|
||||
<languages></languages>
|
||||
<fuse-fullscreen class="hidden md:block"></fuse-fullscreen>
|
||||
<search [appearance]="'bar'"></search>
|
||||
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>
|
||||
<messages [messages]="data.messages"></messages>
|
||||
<notifications [notifications]="data.notifications"></notifications>
|
||||
<user-menu></user-menu>
|
||||
<shortcuts></shortcuts>
|
||||
<messages></messages>
|
||||
<notifications></notifications>
|
||||
<user></user>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Data, Router } from '@angular/router';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { InitialData } from 'app/app.types';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
import { NavigationService } from 'app/core/navigation/navigation.service';
|
||||
|
||||
@Component({
|
||||
selector : 'dense-layout',
|
||||
@@ -13,8 +14,8 @@ import { InitialData } from 'app/app.types';
|
||||
})
|
||||
export class DenseLayoutComponent implements OnInit, OnDestroy
|
||||
{
|
||||
data: InitialData;
|
||||
isScreenSmall: boolean;
|
||||
navigation: Navigation;
|
||||
navigationAppearance: 'default' | 'dense' = 'dense';
|
||||
private _unsubscribeAll: Subject<any> = new Subject<any>();
|
||||
|
||||
@@ -24,6 +25,7 @@ export class DenseLayoutComponent implements OnInit, OnDestroy
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute,
|
||||
private _router: Router,
|
||||
private _navigationService: NavigationService,
|
||||
private _fuseMediaWatcherService: FuseMediaWatcherService,
|
||||
private _fuseNavigationService: FuseNavigationService
|
||||
)
|
||||
@@ -51,10 +53,12 @@ export class DenseLayoutComponent implements OnInit, OnDestroy
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to the resolved route data
|
||||
this._activatedRoute.data.subscribe((data: Data) => {
|
||||
this.data = data.initialData;
|
||||
});
|
||||
// Subscribe to navigation data
|
||||
this._navigationService.navigation$
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((navigation: Navigation) => {
|
||||
this.navigation = navigation;
|
||||
});
|
||||
|
||||
// Subscribe to media changes
|
||||
this._fuseMediaWatcherService.onMediaChange$
|
||||
|
||||
@@ -7,12 +7,12 @@ import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { FuseFullscreenModule } from '@fuse/components/fullscreen';
|
||||
import { FuseNavigationModule } from '@fuse/components/navigation';
|
||||
import { LanguageModule } from 'app/layout/common/language/language.module';
|
||||
import { LanguagesModule } from 'app/layout/common/languages/languages.module';
|
||||
import { MessagesModule } from 'app/layout/common/messages/messages.module';
|
||||
import { NotificationsModule } from 'app/layout/common/notifications/notifications.module';
|
||||
import { SearchModule } from 'app/layout/common/search/search.module';
|
||||
import { ShortcutsModule } from 'app/layout/common/shortcuts/shortcuts.module';
|
||||
import { UserMenuModule } from 'app/layout/common/user-menu/user-menu.module';
|
||||
import { UserModule } from 'app/layout/common/user/user.module';
|
||||
import { SharedModule } from 'app/shared/shared.module';
|
||||
import { DenseLayoutComponent } from 'app/layout/layouts/vertical/dense/dense.component';
|
||||
|
||||
@@ -29,12 +29,12 @@ import { DenseLayoutComponent } from 'app/layout/layouts/vertical/dense/dense.co
|
||||
MatMenuModule,
|
||||
FuseFullscreenModule,
|
||||
FuseNavigationModule,
|
||||
LanguageModule,
|
||||
LanguagesModule,
|
||||
MessagesModule,
|
||||
NotificationsModule,
|
||||
SearchModule,
|
||||
ShortcutsModule,
|
||||
UserMenuModule,
|
||||
UserModule,
|
||||
SharedModule
|
||||
],
|
||||
exports : [
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
class="dark bg-indigo-800 text-white print:hidden"
|
||||
[mode]="isScreenSmall ? 'over' : 'side'"
|
||||
[name]="'mainNavigation'"
|
||||
[navigation]="data.navigation.futuristic"
|
||||
[navigation]="navigation.futuristic"
|
||||
[opened]="!isScreenSmall">
|
||||
<!-- Navigation header hook -->
|
||||
<ng-container fuseVerticalNavigationHeader>
|
||||
@@ -18,10 +18,10 @@
|
||||
<ng-container fuseVerticalNavigationFooter>
|
||||
<!-- User -->
|
||||
<div class="flex items-center w-full px-6 py-8 border-t">
|
||||
<user-menu></user-menu>
|
||||
<user></user>
|
||||
<div class="flex flex-col w-full ml-4 overflow-hidden">
|
||||
<div class="w-full whitespace-nowrap overflow-ellipsis overflow-hidden leading-normal text-current opacity-80">
|
||||
{{data.user.name}}
|
||||
{{user.name}}
|
||||
</div>
|
||||
<div class="w-full mt-0.5 whitespace-nowrap text-sm overflow-ellipsis overflow-hidden leading-normal text-current opacity-50">
|
||||
brian.hughes@company.com
|
||||
@@ -44,13 +44,13 @@
|
||||
<mat-icon [svgIcon]="'heroicons_outline:menu'"></mat-icon>
|
||||
</button>
|
||||
<!-- Components -->
|
||||
<div class="flex items-center pl-2 ml-auto space-x-2">
|
||||
<language></language>
|
||||
<fuse-fullscreen></fuse-fullscreen>
|
||||
<div class="flex items-center pl-2 ml-auto space-x-1 sm:space-x-2">
|
||||
<languages></languages>
|
||||
<fuse-fullscreen class="hidden md:block"></fuse-fullscreen>
|
||||
<search [appearance]="'bar'"></search>
|
||||
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>
|
||||
<messages [messages]="data.messages"></messages>
|
||||
<notifications [notifications]="data.notifications"></notifications>
|
||||
<shortcuts></shortcuts>
|
||||
<messages></messages>
|
||||
<notifications></notifications>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Data, Router } from '@angular/router';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { InitialData } from 'app/app.types';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
import { NavigationService } from 'app/core/navigation/navigation.service';
|
||||
import { User } from 'app/core/user/user.types';
|
||||
import { UserService } from 'app/core/user/user.service';
|
||||
|
||||
@Component({
|
||||
selector : 'futuristic-layout',
|
||||
@@ -13,8 +16,9 @@ import { InitialData } from 'app/app.types';
|
||||
})
|
||||
export class FuturisticLayoutComponent implements OnInit, OnDestroy
|
||||
{
|
||||
data: InitialData;
|
||||
isScreenSmall: boolean;
|
||||
navigation: Navigation;
|
||||
user: User;
|
||||
private _unsubscribeAll: Subject<any> = new Subject<any>();
|
||||
|
||||
/**
|
||||
@@ -23,6 +27,8 @@ export class FuturisticLayoutComponent implements OnInit, OnDestroy
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute,
|
||||
private _router: Router,
|
||||
private _navigationService: NavigationService,
|
||||
private _userService: UserService,
|
||||
private _fuseMediaWatcherService: FuseMediaWatcherService,
|
||||
private _fuseNavigationService: FuseNavigationService
|
||||
)
|
||||
@@ -50,10 +56,19 @@ export class FuturisticLayoutComponent implements OnInit, OnDestroy
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to the resolved route data
|
||||
this._activatedRoute.data.subscribe((data: Data) => {
|
||||
this.data = data.initialData;
|
||||
});
|
||||
// Subscribe to navigation data
|
||||
this._navigationService.navigation$
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((navigation: Navigation) => {
|
||||
this.navigation = navigation;
|
||||
});
|
||||
|
||||
// Subscribe to the user service
|
||||
this._userService.user$
|
||||
.pipe((takeUntil(this._unsubscribeAll)))
|
||||
.subscribe((user: User) => {
|
||||
this.user = user;
|
||||
});
|
||||
|
||||
// Subscribe to media changes
|
||||
this._fuseMediaWatcherService.onMediaChange$
|
||||
|
||||
@@ -7,12 +7,12 @@ import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { FuseFullscreenModule } from '@fuse/components/fullscreen';
|
||||
import { FuseNavigationModule } from '@fuse/components/navigation';
|
||||
import { LanguageModule } from 'app/layout/common/language/language.module';
|
||||
import { LanguagesModule } from 'app/layout/common/languages/languages.module';
|
||||
import { MessagesModule } from 'app/layout/common/messages/messages.module';
|
||||
import { NotificationsModule } from 'app/layout/common/notifications/notifications.module';
|
||||
import { SearchModule } from 'app/layout/common/search/search.module';
|
||||
import { ShortcutsModule } from 'app/layout/common/shortcuts/shortcuts.module';
|
||||
import { UserMenuModule } from 'app/layout/common/user-menu/user-menu.module';
|
||||
import { UserModule } from 'app/layout/common/user/user.module';
|
||||
import { SharedModule } from 'app/shared/shared.module';
|
||||
import { FuturisticLayoutComponent } from 'app/layout/layouts/vertical/futuristic/futuristic.component';
|
||||
|
||||
@@ -29,12 +29,12 @@ import { FuturisticLayoutComponent } from 'app/layout/layouts/vertical/futuristi
|
||||
MatMenuModule,
|
||||
FuseFullscreenModule,
|
||||
FuseNavigationModule,
|
||||
LanguageModule,
|
||||
LanguagesModule,
|
||||
MessagesModule,
|
||||
NotificationsModule,
|
||||
SearchModule,
|
||||
ShortcutsModule,
|
||||
UserMenuModule,
|
||||
UserModule,
|
||||
SharedModule
|
||||
],
|
||||
exports : [
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[appearance]="'thin'"
|
||||
[mode]="isScreenSmall ? 'over' : 'side'"
|
||||
[name]="'mainNavigation'"
|
||||
[navigation]="data.navigation.compact"
|
||||
[navigation]="navigation.compact"
|
||||
[opened]="!isScreenSmall">
|
||||
<!-- Navigation header hook -->
|
||||
<ng-container fuseVerticalNavigationContentHeader>
|
||||
@@ -31,14 +31,14 @@
|
||||
<mat-icon [svgIcon]="'heroicons_outline:menu'"></mat-icon>
|
||||
</button>
|
||||
<!-- Components -->
|
||||
<div class="flex items-center pl-2 ml-auto space-x-2">
|
||||
<language></language>
|
||||
<fuse-fullscreen></fuse-fullscreen>
|
||||
<div class="flex items-center pl-2 ml-auto space-x-1 sm:space-x-2">
|
||||
<languages></languages>
|
||||
<fuse-fullscreen class="hidden md:block"></fuse-fullscreen>
|
||||
<search [appearance]="'bar'"></search>
|
||||
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>
|
||||
<messages [messages]="data.messages"></messages>
|
||||
<notifications [notifications]="data.notifications"></notifications>
|
||||
<user-menu></user-menu>
|
||||
<shortcuts></shortcuts>
|
||||
<messages></messages>
|
||||
<notifications></notifications>
|
||||
<user></user>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Data, Router } from '@angular/router';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { InitialData } from 'app/app.types';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
import { NavigationService } from 'app/core/navigation/navigation.service';
|
||||
|
||||
@Component({
|
||||
selector : 'thin-layout',
|
||||
@@ -13,8 +14,8 @@ import { InitialData } from 'app/app.types';
|
||||
})
|
||||
export class ThinLayoutComponent implements OnInit, OnDestroy
|
||||
{
|
||||
data: InitialData;
|
||||
isScreenSmall: boolean;
|
||||
navigation: Navigation;
|
||||
private _unsubscribeAll: Subject<any> = new Subject<any>();
|
||||
|
||||
/**
|
||||
@@ -23,6 +24,7 @@ export class ThinLayoutComponent implements OnInit, OnDestroy
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute,
|
||||
private _router: Router,
|
||||
private _navigationService: NavigationService,
|
||||
private _fuseMediaWatcherService: FuseMediaWatcherService,
|
||||
private _fuseNavigationService: FuseNavigationService
|
||||
)
|
||||
@@ -50,10 +52,12 @@ export class ThinLayoutComponent implements OnInit, OnDestroy
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to the resolved route data
|
||||
this._activatedRoute.data.subscribe((data: Data) => {
|
||||
this.data = data.initialData;
|
||||
});
|
||||
// Subscribe to navigation data
|
||||
this._navigationService.navigation$
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((navigation: Navigation) => {
|
||||
this.navigation = navigation;
|
||||
});
|
||||
|
||||
// Subscribe to media changes
|
||||
this._fuseMediaWatcherService.onMediaChange$
|
||||
|
||||
@@ -7,12 +7,12 @@ import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { FuseFullscreenModule } from '@fuse/components/fullscreen';
|
||||
import { FuseNavigationModule } from '@fuse/components/navigation';
|
||||
import { LanguageModule } from 'app/layout/common/language/language.module';
|
||||
import { LanguagesModule } from 'app/layout/common/languages/languages.module';
|
||||
import { MessagesModule } from 'app/layout/common/messages/messages.module';
|
||||
import { NotificationsModule } from 'app/layout/common/notifications/notifications.module';
|
||||
import { SearchModule } from 'app/layout/common/search/search.module';
|
||||
import { ShortcutsModule } from 'app/layout/common/shortcuts/shortcuts.module';
|
||||
import { UserMenuModule } from 'app/layout/common/user-menu/user-menu.module';
|
||||
import { UserModule } from 'app/layout/common/user/user.module';
|
||||
import { SharedModule } from 'app/shared/shared.module';
|
||||
import { ThinLayoutComponent } from 'app/layout/layouts/vertical/thin/thin.component';
|
||||
|
||||
@@ -29,12 +29,12 @@ import { ThinLayoutComponent } from 'app/layout/layouts/vertical/thin/thin.compo
|
||||
MatMenuModule,
|
||||
FuseFullscreenModule,
|
||||
FuseNavigationModule,
|
||||
LanguageModule,
|
||||
LanguagesModule,
|
||||
MessagesModule,
|
||||
NotificationsModule,
|
||||
SearchModule,
|
||||
ShortcutsModule,
|
||||
UserMenuModule,
|
||||
UserModule,
|
||||
SharedModule
|
||||
],
|
||||
exports : [
|
||||
|
||||
@@ -33,10 +33,18 @@ export class FileManagerMockApi
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
this._fuseMockApiService
|
||||
.onGet('api/apps/file-manager')
|
||||
.reply(() => {
|
||||
.reply(({request}) => {
|
||||
|
||||
// Clone the items
|
||||
const items = cloneDeep(this._items);
|
||||
let items = cloneDeep(this._items);
|
||||
|
||||
// See if a folder id exist
|
||||
const folderId = request.params.get('folderId') ?? null;
|
||||
|
||||
// Filter the items by folder id. If folder id is null,
|
||||
// that means we want to root items which have folder id
|
||||
// of null
|
||||
items = items.filter(item => item.folderId === folderId);
|
||||
|
||||
// Separate the items by folders and files
|
||||
const folders = items.filter(item => item.type === 'folder');
|
||||
@@ -46,11 +54,38 @@ export class FileManagerMockApi
|
||||
folders.sort((a, b) => a.name.localeCompare(b.name));
|
||||
files.sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
// Figure out the path and attach it to the response
|
||||
// Prepare the empty paths array
|
||||
const pathItems = cloneDeep(this._items);
|
||||
const path = [];
|
||||
|
||||
// Prepare the current folder
|
||||
let currentFolder = null;
|
||||
|
||||
// Get the current folder and add it as the first entry
|
||||
if ( folderId )
|
||||
{
|
||||
currentFolder = pathItems.find(item => item.id === folderId);
|
||||
path.push(currentFolder);
|
||||
}
|
||||
|
||||
// Start traversing and storing the folders as a path array
|
||||
// until we hit null on the folder id
|
||||
while ( currentFolder?.folderId )
|
||||
{
|
||||
currentFolder = pathItems.find(item => item.id === currentFolder.folderId);
|
||||
if ( currentFolder )
|
||||
{
|
||||
path.unshift(currentFolder);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
200,
|
||||
{
|
||||
folders,
|
||||
files
|
||||
files,
|
||||
path
|
||||
}
|
||||
];
|
||||
});
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
export const items = [
|
||||
{
|
||||
id : 'cd6897cb-acfd-4016-8b53-3f66a5b5fc68',
|
||||
folderId : null,
|
||||
name : 'Personal',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'April 24, 2018',
|
||||
@@ -13,6 +14,7 @@ export const items = [
|
||||
},
|
||||
{
|
||||
id : '6da8747f-b474-4c9a-9eba-5ef212285500',
|
||||
folderId : null,
|
||||
name : 'Photos',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'November 01, 2021',
|
||||
@@ -24,6 +26,7 @@ export const items = [
|
||||
},
|
||||
{
|
||||
id : 'ed58add1-45a7-41db-887d-3ca7ee7f2719',
|
||||
folderId : null,
|
||||
name : 'Work',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'May 8, 2020',
|
||||
@@ -35,6 +38,7 @@ export const items = [
|
||||
},
|
||||
{
|
||||
id : '5cb66e32-d1ac-4b9a-8c34-5991ce25add2',
|
||||
folderId : null,
|
||||
name : 'Contract #123',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'January 14, 2021',
|
||||
@@ -46,6 +50,7 @@ export const items = [
|
||||
},
|
||||
{
|
||||
id : '3ffc3d84-8f2d-4929-903a-ef6fc21657a7',
|
||||
folderId : null,
|
||||
name : 'Estimated budget',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'December 14, 2020',
|
||||
@@ -57,6 +62,7 @@ export const items = [
|
||||
},
|
||||
{
|
||||
id : '157adb9a-14f8-4559-ac93-8be893c9f80a',
|
||||
folderId : null,
|
||||
name : 'DMCA notice #42',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'May 8, 2021',
|
||||
@@ -68,6 +74,7 @@ export const items = [
|
||||
},
|
||||
{
|
||||
id : '4f64597a-df7e-461c-ad60-f33e5f7e0747',
|
||||
folderId : null,
|
||||
name : 'Invoices',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'January 12, 2020',
|
||||
@@ -79,6 +86,7 @@ export const items = [
|
||||
},
|
||||
{
|
||||
id : 'e445c445-57b2-4476-8c62-b068e3774b8e',
|
||||
folderId : null,
|
||||
name : 'Crash logs',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'June 8, 2020',
|
||||
@@ -90,6 +98,7 @@ export const items = [
|
||||
},
|
||||
{
|
||||
id : 'b482f93e-7847-4614-ad48-b78b78309f81',
|
||||
folderId : null,
|
||||
name : 'System logs',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'June 8, 2020',
|
||||
@@ -101,6 +110,7 @@ export const items = [
|
||||
},
|
||||
{
|
||||
id : 'ec07a98d-2e5b-422c-a9b2-b5d1c0e263f5',
|
||||
folderId : null,
|
||||
name : 'Personal projects',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'March 18, 2020',
|
||||
@@ -112,6 +122,7 @@ export const items = [
|
||||
},
|
||||
{
|
||||
id : 'ae908d59-07da-4dd8-aba0-124e50289295',
|
||||
folderId : null,
|
||||
name : 'Biometric portrait',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'August 29, 2020',
|
||||
@@ -123,6 +134,7 @@ export const items = [
|
||||
},
|
||||
{
|
||||
id : '4038a5b6-5b1a-432d-907c-e037aeb817a8',
|
||||
folderId : null,
|
||||
name : 'Scanned image 20201012-1',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'September 13, 2020',
|
||||
@@ -134,6 +146,7 @@ export const items = [
|
||||
},
|
||||
{
|
||||
id : '630d2e9a-d110-47a0-ac03-256073a0f56d',
|
||||
folderId : null,
|
||||
name : 'Scanned image 20201012-2',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'September 14, 2020',
|
||||
@@ -145,6 +158,7 @@ export const items = [
|
||||
},
|
||||
{
|
||||
id : '1417d5ed-b616-4cff-bfab-286677b69d79',
|
||||
folderId : null,
|
||||
name : 'Prices',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'April 07, 2020',
|
||||
@@ -156,6 +170,7 @@ export const items = [
|
||||
},
|
||||
{
|
||||
id : 'bd2817c7-6751-40dc-b252-b6b5634c0689',
|
||||
folderId : null,
|
||||
name : 'Shopping list',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'March 26, 2021',
|
||||
@@ -167,6 +182,7 @@ export const items = [
|
||||
},
|
||||
{
|
||||
id : '14fb47c9-6eeb-4070-919c-07c8133285d1',
|
||||
folderId : null,
|
||||
name : 'Summer budget',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'June 02, 2020',
|
||||
@@ -175,5 +191,67 @@ export const items = [
|
||||
type : 'XLS',
|
||||
contents : null,
|
||||
description: null
|
||||
},
|
||||
|
||||
{
|
||||
id : '894e8514-03d3-4f5e-bb28-f6c092501fae',
|
||||
folderId : 'cd6897cb-acfd-4016-8b53-3f66a5b5fc68',
|
||||
name : 'A personal file',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'June 02, 2020',
|
||||
modifiedAt : 'June 02, 2020',
|
||||
size : '943 KB',
|
||||
type : 'XLS',
|
||||
contents : null,
|
||||
description: null
|
||||
},
|
||||
{
|
||||
id : '74010810-16cf-441d-a1aa-c9fb620fceea',
|
||||
folderId : 'cd6897cb-acfd-4016-8b53-3f66a5b5fc68',
|
||||
name : 'A personal folder',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'November 01, 2021',
|
||||
modifiedAt : 'November 01, 2021',
|
||||
size : '3015 MB',
|
||||
type : 'folder',
|
||||
contents : '907 files',
|
||||
description: 'Personal photos; selfies, family, vacation and etc.'
|
||||
},
|
||||
{
|
||||
id : 'a8c73e5a-8114-436d-ab54-d900b50b3762',
|
||||
folderId : '74010810-16cf-441d-a1aa-c9fb620fceea',
|
||||
name : 'A personal file within the personal folder',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'June 02, 2020',
|
||||
modifiedAt : 'June 02, 2020',
|
||||
size : '943 KB',
|
||||
type : 'XLS',
|
||||
contents : null,
|
||||
description: null
|
||||
},
|
||||
|
||||
{
|
||||
id : '12d851a8-4f60-473e-8a59-abe4b422ea99',
|
||||
folderId : '6da8747f-b474-4c9a-9eba-5ef212285500',
|
||||
name : 'Photos file',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'June 02, 2020',
|
||||
modifiedAt : 'June 02, 2020',
|
||||
size : '943 KB',
|
||||
type : 'XLS',
|
||||
contents : null,
|
||||
description: null
|
||||
},
|
||||
{
|
||||
id : '2836766d-27e1-4f40-a31a-5a8419105e7e',
|
||||
folderId : 'ed58add1-45a7-41db-887d-3ca7ee7f2719',
|
||||
name : 'Work file',
|
||||
createdBy : 'Brian Hughes',
|
||||
createdAt : 'June 02, 2020',
|
||||
modifiedAt : 'June 02, 2020',
|
||||
size : '943 KB',
|
||||
type : 'XLS',
|
||||
contents : null,
|
||||
description: null
|
||||
}
|
||||
];
|
||||
|
||||
@@ -596,7 +596,7 @@ export const defaultNavigation: FuseNavigationItem[] = [
|
||||
id : 'pages.invoice',
|
||||
title : 'Invoice',
|
||||
type : 'collapsable',
|
||||
icon : 'heroicons_outline:exclamation-circle',
|
||||
icon : 'heroicons_outline:calculator',
|
||||
children: [
|
||||
{
|
||||
id : 'pages.invoice.printable',
|
||||
@@ -682,10 +682,10 @@ export const defaultNavigation: FuseNavigationItem[] = [
|
||||
icon : 'heroicons_outline:collection',
|
||||
children: [
|
||||
{
|
||||
id : 'user-interface.angular-material',
|
||||
title: 'Angular Material',
|
||||
id : 'user-interface.material-components',
|
||||
title: 'Material components',
|
||||
type : 'basic',
|
||||
icon : 'heroicons_outline:shield-check',
|
||||
icon : 'heroicons_outline:chip',
|
||||
link : '/ui/angular-material'
|
||||
},
|
||||
{
|
||||
@@ -695,6 +695,13 @@ export const defaultNavigation: FuseNavigationItem[] = [
|
||||
icon : 'heroicons_outline:sparkles',
|
||||
link : '/ui/tailwindcss'
|
||||
},
|
||||
{
|
||||
id : 'user-interface.advanced-search',
|
||||
title: 'Advanced search',
|
||||
type : 'basic',
|
||||
icon : 'heroicons_outline:search-circle',
|
||||
link : '/ui/advanced-search'
|
||||
},
|
||||
{
|
||||
id : 'user-interface.animations',
|
||||
title: 'Animations',
|
||||
@@ -861,10 +868,16 @@ export const defaultNavigation: FuseNavigationItem[] = [
|
||||
type : 'collapsable',
|
||||
children: [
|
||||
{
|
||||
id : 'user-interface.page-layouts.simple.fullwidth',
|
||||
title: 'Fullwidth',
|
||||
id : 'user-interface.page-layouts.simple.fullwidth-1',
|
||||
title: 'Fullwidth #1',
|
||||
type : 'basic',
|
||||
link : '/ui/page-layouts/simple/fullwidth'
|
||||
link : '/ui/page-layouts/simple/fullwidth-1'
|
||||
},
|
||||
{
|
||||
id : 'user-interface.page-layouts.simple.fullwidth-2',
|
||||
title: 'Fullwidth #2',
|
||||
type : 'basic',
|
||||
link : '/ui/page-layouts/simple/fullwidth-2'
|
||||
},
|
||||
{
|
||||
id : 'user-interface.page-layouts.simple.left-sidebar-1',
|
||||
@@ -933,7 +946,7 @@ export const defaultNavigation: FuseNavigationItem[] = [
|
||||
icon : 'heroicons_outline:speakerphone',
|
||||
link : '/docs/changelog',
|
||||
badge: {
|
||||
title : '13.0.3',
|
||||
title : '13.2.0',
|
||||
classes: 'px-2 bg-yellow-300 text-black rounded-full'
|
||||
}
|
||||
},
|
||||
@@ -1122,6 +1135,7 @@ export const compactNavigation: FuseNavigationItem[] = [
|
||||
{
|
||||
id : 'dashboards',
|
||||
title : 'Dashboards',
|
||||
tooltip : 'Dashboards',
|
||||
type : 'aside',
|
||||
icon : 'heroicons_outline:home',
|
||||
children: [] // This will be filled from defaultNavigation so we don't have to manage multiple sets of the same navigation
|
||||
@@ -1129,6 +1143,7 @@ export const compactNavigation: FuseNavigationItem[] = [
|
||||
{
|
||||
id : 'apps',
|
||||
title : 'Apps',
|
||||
tooltip : 'Apps',
|
||||
type : 'aside',
|
||||
icon : 'heroicons_outline:qrcode',
|
||||
children: [] // This will be filled from defaultNavigation so we don't have to manage multiple sets of the same navigation
|
||||
@@ -1136,6 +1151,7 @@ export const compactNavigation: FuseNavigationItem[] = [
|
||||
{
|
||||
id : 'pages',
|
||||
title : 'Pages',
|
||||
tooltip : 'Pages',
|
||||
type : 'aside',
|
||||
icon : 'heroicons_outline:document-duplicate',
|
||||
children: [] // This will be filled from defaultNavigation so we don't have to manage multiple sets of the same navigation
|
||||
@@ -1143,6 +1159,7 @@ export const compactNavigation: FuseNavigationItem[] = [
|
||||
{
|
||||
id : 'user-interface',
|
||||
title : 'UI',
|
||||
tooltip : 'UI',
|
||||
type : 'aside',
|
||||
icon : 'heroicons_outline:collection',
|
||||
children: [] // This will be filled from defaultNavigation so we don't have to manage multiple sets of the same navigation
|
||||
@@ -1150,147 +1167,24 @@ export const compactNavigation: FuseNavigationItem[] = [
|
||||
{
|
||||
id : 'navigation-features',
|
||||
title : 'Navigation',
|
||||
tooltip : 'Navigation',
|
||||
type : 'aside',
|
||||
icon : 'heroicons_outline:menu',
|
||||
children: [] // This will be filled from defaultNavigation so we don't have to manage multiple sets of the same navigation
|
||||
}
|
||||
];
|
||||
export const futuristicNavigation: FuseNavigationItem[] = [
|
||||
{
|
||||
id : 'dashboards',
|
||||
title : 'DASHBOARDS',
|
||||
type : 'group',
|
||||
children: [] // This will be filled from defaultNavigation so we don't have to manage multiple sets of the same navigation
|
||||
},
|
||||
{
|
||||
id : 'apps',
|
||||
title : 'APPS',
|
||||
type : 'group',
|
||||
children: [
|
||||
{
|
||||
id : 'apps.dashboards.analytics',
|
||||
title: 'Analytics',
|
||||
type : 'basic',
|
||||
icon : 'heroicons_outline:chart-pie',
|
||||
link : '/dashboards/analytics'
|
||||
},
|
||||
{
|
||||
id : 'apps.dashboards.project',
|
||||
title: 'Project',
|
||||
type : 'basic',
|
||||
icon : 'heroicons_outline:clipboard-check',
|
||||
link : '/dashboards/project'
|
||||
},
|
||||
{
|
||||
id : 'apps.academy',
|
||||
title: 'Academy',
|
||||
type : 'basic',
|
||||
icon : 'heroicons_outline:academic-cap',
|
||||
link : '/apps/academy'
|
||||
},
|
||||
{
|
||||
id : 'apps.calendar',
|
||||
title: 'Calendar',
|
||||
type : 'basic',
|
||||
icon : 'heroicons_outline:calendar',
|
||||
link : '/apps/calendar'
|
||||
},
|
||||
{
|
||||
id : 'apps.chat',
|
||||
title: 'Chat',
|
||||
type : 'basic',
|
||||
icon : 'heroicons_outline:chat-alt',
|
||||
link : '/apps/chat'
|
||||
},
|
||||
{
|
||||
id : 'apps.contacts',
|
||||
title: 'Contacts',
|
||||
type : 'basic',
|
||||
icon : 'heroicons_outline:user-group',
|
||||
link : '/apps/contacts'
|
||||
},
|
||||
{
|
||||
id : 'apps.ecommerce',
|
||||
title : 'ECommerce',
|
||||
type : 'collapsable',
|
||||
icon : 'heroicons_outline:shopping-cart',
|
||||
children: [
|
||||
{
|
||||
id : 'apps.ecommerce.inventory',
|
||||
title: 'Inventory',
|
||||
type : 'basic',
|
||||
link : '/apps/ecommerce/inventory'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id : 'apps.file-manager',
|
||||
title: 'File manager',
|
||||
type : 'basic',
|
||||
icon : 'heroicons_outline:shopping-cart',
|
||||
link : '/apps/file-manager'
|
||||
},
|
||||
{
|
||||
id : 'apps.help-center',
|
||||
title : 'Help center',
|
||||
type : 'collapsable',
|
||||
icon : 'heroicons_outline:support',
|
||||
link : '/apps/help-center',
|
||||
children: [
|
||||
{
|
||||
id : 'apps.help-center.home',
|
||||
title : 'Home',
|
||||
type : 'basic',
|
||||
link : '/apps/help-center',
|
||||
exactMatch: true
|
||||
},
|
||||
{
|
||||
id : 'apps.help-center.faqs',
|
||||
title: 'FAQs',
|
||||
type : 'basic',
|
||||
link : '/apps/help-center/faqs'
|
||||
},
|
||||
{
|
||||
id : 'apps.help-center.guides',
|
||||
title: 'Guides',
|
||||
type : 'basic',
|
||||
link : '/apps/help-center/guides'
|
||||
},
|
||||
{
|
||||
id : 'apps.help-center.support',
|
||||
title: 'Support',
|
||||
type : 'basic',
|
||||
link : '/apps/help-center/support'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id : 'apps.mailbox',
|
||||
title: 'Mailbox',
|
||||
type : 'basic',
|
||||
icon : 'heroicons_outline:mail',
|
||||
link : '/apps/mailbox',
|
||||
badge: {
|
||||
title : '27',
|
||||
classes: 'px-2 bg-black bg-opacity-25 text-white rounded-full'
|
||||
}
|
||||
},
|
||||
{
|
||||
id : 'apps.notes',
|
||||
title: 'Notes',
|
||||
type : 'basic',
|
||||
icon : 'heroicons_outline:pencil-alt',
|
||||
link : '/apps/notes'
|
||||
},
|
||||
{
|
||||
id : 'apps.scrumboard',
|
||||
title: 'Scrumboard',
|
||||
type : 'basic',
|
||||
icon : 'heroicons_outline:view-boards',
|
||||
link : '/apps/scrumboard'
|
||||
},
|
||||
{
|
||||
id : 'apps.tasks',
|
||||
title: 'Tasks',
|
||||
type : 'basic',
|
||||
icon : 'heroicons_outline:check-circle',
|
||||
link : '/apps/tasks'
|
||||
}
|
||||
]
|
||||
children: [] // This will be filled from defaultNavigation so we don't have to manage multiple sets of the same navigation
|
||||
},
|
||||
{
|
||||
id : 'others',
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as moment from 'moment';
|
||||
export const notifications = [
|
||||
{
|
||||
id : '493190c9-5b61-4912-afe5-78c21f1044d7',
|
||||
icon : 'heroicons_outline:star',
|
||||
icon : 'heroicons_solid:star',
|
||||
title : 'Daily challenges',
|
||||
description: 'Your submission has been accepted',
|
||||
time : moment().subtract(25, 'minutes').toISOString(), // 25 minutes ago
|
||||
@@ -21,7 +21,7 @@ export const notifications = [
|
||||
},
|
||||
{
|
||||
id : 'b91ccb58-b06c-413b-b389-87010e03a120',
|
||||
icon : 'heroicons_outline:mail',
|
||||
icon : 'heroicons_solid:mail',
|
||||
title : 'Mailbox',
|
||||
description: 'You have 15 unread mails across 3 mailboxes',
|
||||
time : moment().subtract(3, 'hours').toISOString(), // 3 hours ago
|
||||
@@ -31,7 +31,7 @@ export const notifications = [
|
||||
},
|
||||
{
|
||||
id : '541416c9-84a7-408a-8d74-27a43c38d797',
|
||||
icon : 'heroicons_outline:refresh',
|
||||
icon : 'heroicons_solid:refresh',
|
||||
title : 'Cron jobs',
|
||||
description: 'Your <em>Docker container</em> is ready to publish',
|
||||
time : moment().subtract(5, 'hours').toISOString(), // 5 hours ago
|
||||
@@ -59,7 +59,7 @@ export const notifications = [
|
||||
},
|
||||
{
|
||||
id : 'b85c2338-cc98-4140-bbf8-c226ce4e395e',
|
||||
icon : 'heroicons_outline:mail',
|
||||
icon : 'heroicons_solid:mail',
|
||||
title : 'Mailbox',
|
||||
description: 'You have 3 new mails',
|
||||
time : moment().subtract(1, 'day').toISOString(), // 1 day ago
|
||||
@@ -69,7 +69,7 @@ export const notifications = [
|
||||
},
|
||||
{
|
||||
id : '8f8e1bf9-4661-4939-9e43-390957b60f42',
|
||||
icon : 'heroicons_outline:star',
|
||||
icon : 'heroicons_solid:star',
|
||||
title : 'Daily challenges',
|
||||
description: 'Your submission has been accepted and you are ready to sign-up for the final assigment which will be ready in 2 days',
|
||||
time : moment().subtract(3, 'days').toISOString(), // 3 days ago
|
||||
@@ -79,7 +79,7 @@ export const notifications = [
|
||||
},
|
||||
{
|
||||
id : '30af917b-7a6a-45d1-822f-9e7ad7f8bf69',
|
||||
icon : 'heroicons_outline:refresh',
|
||||
icon : 'heroicons_solid:refresh',
|
||||
title : 'Cron jobs',
|
||||
description: 'Your Vagrant container is ready to download',
|
||||
time : moment().subtract(4, 'day').toISOString(), // 4 days ago
|
||||
|
||||
@@ -4,6 +4,7 @@ import { FuseNavigationItem, FuseNavigationService } from '@fuse/components/navi
|
||||
import { FuseMockApiService } from '@fuse/lib/mock-api';
|
||||
import { defaultNavigation } from 'app/mock-api/common/navigation/data';
|
||||
import { contacts } from 'app/mock-api/apps/contacts/data';
|
||||
import { tasks } from 'app/mock-api/apps/tasks/data';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -12,6 +13,7 @@ export class SearchMockApi
|
||||
{
|
||||
private readonly _defaultNavigation: FuseNavigationItem[] = defaultNavigation;
|
||||
private readonly _contacts: any[] = contacts;
|
||||
private readonly _tasks: any[] = tasks;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -54,58 +56,75 @@ export class SearchMockApi
|
||||
return [200, {results: []}];
|
||||
}
|
||||
|
||||
// Filter the navigation
|
||||
const navigationResults = cloneDeep(flatNavigation).filter(item => (item.title?.toLowerCase().includes(query) || (item.subtitle && item.subtitle.includes(query))));
|
||||
|
||||
// Filter the contacts
|
||||
const contactsResults = cloneDeep(this._contacts).filter(user => user.name.toLowerCase().includes(query));
|
||||
const contactsResults = cloneDeep(this._contacts)
|
||||
.filter(contact => contact.name.toLowerCase().includes(query));
|
||||
|
||||
// Create the results array
|
||||
// Filter the navigation
|
||||
const pagesResults = cloneDeep(flatNavigation)
|
||||
.filter(page => (page.title?.toLowerCase().includes(query) || (page.subtitle && page.subtitle.includes(query))));
|
||||
|
||||
// Filter the tasks
|
||||
const tasksResults = cloneDeep(this._tasks)
|
||||
.filter(task => task.title.toLowerCase().includes(query));
|
||||
|
||||
// Prepare the results array
|
||||
const results = [];
|
||||
|
||||
// If there are navigation results...
|
||||
if ( navigationResults.length > 0 )
|
||||
{
|
||||
// Normalize the results while marking the found chars
|
||||
navigationResults.forEach((result: any) => {
|
||||
|
||||
// Normalize
|
||||
result['hint'] = result.link;
|
||||
result['resultType'] = 'page';
|
||||
|
||||
// Mark the found chars
|
||||
const re = new RegExp('(' + query.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + ')', 'ig');
|
||||
result.title = result.title.replace(re, '<mark>$1</mark>');
|
||||
});
|
||||
|
||||
// Add the results
|
||||
results.push(...navigationResults);
|
||||
}
|
||||
|
||||
// If there are contacts results...
|
||||
if ( contactsResults.length > 0 )
|
||||
{
|
||||
// Normalize the results while marking the found chars
|
||||
// Normalize the results
|
||||
contactsResults.forEach((result) => {
|
||||
|
||||
// Normalize
|
||||
result.title = result.name;
|
||||
result.resultType = 'contact';
|
||||
|
||||
// Make the found chars bold
|
||||
const re = new RegExp('(' + query.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + ')', 'ig');
|
||||
result.title = result.title.replace(re, '<mark>$1</mark>');
|
||||
|
||||
// Add a link
|
||||
result.link = '/apps/contacts/' + result.id;
|
||||
});
|
||||
|
||||
// Add the results to the results object
|
||||
results.push(...contactsResults);
|
||||
// Add to the results
|
||||
results.push({
|
||||
id : 'contacts',
|
||||
label : 'Contacts',
|
||||
results: contactsResults
|
||||
});
|
||||
}
|
||||
|
||||
// If there are page results...
|
||||
if ( pagesResults.length > 0 )
|
||||
{
|
||||
// Normalize the results
|
||||
pagesResults.forEach((result: any) => {
|
||||
|
||||
});
|
||||
|
||||
// Add to the results
|
||||
results.push({
|
||||
id : 'pages',
|
||||
label : 'Pages',
|
||||
results: pagesResults
|
||||
});
|
||||
}
|
||||
|
||||
// If there are tasks results...
|
||||
if ( tasksResults.length > 0 )
|
||||
{
|
||||
// Normalize the results
|
||||
tasksResults.forEach((result) => {
|
||||
|
||||
// Add a link
|
||||
result.link = '/apps/tasks/' + result.id;
|
||||
});
|
||||
|
||||
// Add to the results
|
||||
results.push({
|
||||
id : 'tasks',
|
||||
label : 'Tasks',
|
||||
results: tasksResults
|
||||
});
|
||||
}
|
||||
|
||||
// Return the response
|
||||
return [200, {results}];
|
||||
return [200, results];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ export const shortcuts = [
|
||||
{
|
||||
id : 'a1ae91d3-e2cb-459b-9be9-a184694f548b',
|
||||
label : 'Changelog',
|
||||
description: 'Latest version: v1.2',
|
||||
description: 'List of changes',
|
||||
icon : 'heroicons_outline:clipboard-list',
|
||||
link : '/dashboards/project',
|
||||
link : '/docs/changelog',
|
||||
useRouter : true
|
||||
},
|
||||
{
|
||||
@@ -13,7 +13,7 @@ export const shortcuts = [
|
||||
label : 'Documentation',
|
||||
description: 'Getting started',
|
||||
icon : 'heroicons_outline:book-open',
|
||||
link : '/dashboards/project',
|
||||
link : '/docs/guides/getting-started/introduction',
|
||||
useRouter : true
|
||||
},
|
||||
{
|
||||
@@ -21,7 +21,7 @@ export const shortcuts = [
|
||||
label : 'Help center',
|
||||
description: 'FAQs and guides',
|
||||
icon : 'heroicons_outline:support',
|
||||
link : '/pages/help-center',
|
||||
link : '/apps/help-center',
|
||||
useRouter : true
|
||||
},
|
||||
{
|
||||
@@ -29,7 +29,7 @@ export const shortcuts = [
|
||||
label : 'Dashboard',
|
||||
description: 'User analytics',
|
||||
icon : 'heroicons_outline:chart-pie',
|
||||
link : '/dashboards/project',
|
||||
link : '/dashboards/analytics',
|
||||
useRouter : true
|
||||
},
|
||||
{
|
||||
@@ -67,7 +67,7 @@ export const shortcuts = [
|
||||
{
|
||||
id : '0a240ab8-e19d-4503-bf68-20013030d526',
|
||||
label : 'Reload',
|
||||
description: 'Restart the app',
|
||||
description: 'Reload the app',
|
||||
icon : 'heroicons_outline:refresh',
|
||||
link : '/dashboards/project',
|
||||
useRouter : false
|
||||
|
||||
@@ -369,9 +369,9 @@ export class ContactsDetailsComponent implements OnInit, OnDestroy
|
||||
scrollStrategy : this._overlay.scrollStrategies.block(),
|
||||
positionStrategy: this._overlay.position()
|
||||
.flexibleConnectedTo(this._tagsPanelOrigin.nativeElement)
|
||||
.withFlexibleDimensions()
|
||||
.withFlexibleDimensions(true)
|
||||
.withViewportMargin(64)
|
||||
.withLockedPosition()
|
||||
.withLockedPosition(true)
|
||||
.withPositions([
|
||||
{
|
||||
originX : 'start',
|
||||
|
||||
@@ -12,7 +12,6 @@ import { MatRippleModule } from '@angular/material/core';
|
||||
import { MatSortModule } from '@angular/material/sort';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { SharedModule } from 'app/shared/shared.module';
|
||||
import { InventoryComponent } from 'app/modules/admin/apps/ecommerce/inventory/inventory.component';
|
||||
@@ -38,7 +37,6 @@ import { ecommerceRoutes } from 'app/modules/admin/apps/ecommerce/ecommerce.rout
|
||||
MatSortModule,
|
||||
MatSelectModule,
|
||||
MatSlideToggleModule,
|
||||
MatTableModule,
|
||||
MatTooltipModule,
|
||||
SharedModule
|
||||
]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="absolute inset-0 flex flex-col min-w-0 overflow-hidden bg-card dark:bg-transparent">
|
||||
<div class="sm:absolute sm:inset-0 flex flex-col flex-auto min-w-0 sm:overflow-hidden bg-card dark:bg-transparent">
|
||||
|
||||
<!-- Header -->
|
||||
<div class="relative flex flex-col sm:flex-row flex-0 sm:items-center sm:justify-between py-8 px-6 md:px-8 border-b">
|
||||
@@ -39,531 +39,451 @@
|
||||
<div class="flex flex-auto overflow-hidden">
|
||||
|
||||
<!-- Products list -->
|
||||
<div class="flex flex-col flex-auto sm:mb-18 overflow-hidden">
|
||||
|
||||
<ng-container *ngIf="productsCount > 0; else noProducts">
|
||||
|
||||
<!-- Table wrapper -->
|
||||
<div
|
||||
class="overflow-x-auto sm:overflow-y-auto"
|
||||
cdkScrollable>
|
||||
|
||||
<!-- Table -->
|
||||
<table
|
||||
class="w-full min-w-320 table-fixed bg-transparent"
|
||||
[ngClass]="{'pointer-events-none': isLoading}"
|
||||
mat-table
|
||||
matSort
|
||||
[matSortActive]="'name'"
|
||||
[matSortDisableClear]="true"
|
||||
[matSortDirection]="'asc'"
|
||||
[multiTemplateDataRows]="true"
|
||||
[dataSource]="products$"
|
||||
[trackBy]="trackByFn">
|
||||
|
||||
<!-- SKU -->
|
||||
<ng-container matColumnDef="sku">
|
||||
<th
|
||||
class="w-56 pl-26 bg-gray-50 dark:bg-black dark:bg-opacity-5"
|
||||
mat-header-cell
|
||||
*matHeaderCellDef
|
||||
mat-sort-header
|
||||
disableClear>
|
||||
<div class="flex flex-col flex-auto sm:mb-18 overflow-hidden sm:overflow-y-auto">
|
||||
<ng-container *ngIf="(products$ | async) as products">
|
||||
<ng-container *ngIf="products.length > 0; else noProducts">
|
||||
<div class="grid">
|
||||
<!-- Header -->
|
||||
<div
|
||||
class="inventory-grid z-10 sticky top-0 grid gap-4 py-4 px-6 md:px-8 shadow text-md font-semibold text-secondary bg-gray-50 dark:bg-black dark:bg-opacity-5"
|
||||
matSort
|
||||
matSortDisableClear>
|
||||
<div></div>
|
||||
<div
|
||||
class="hidden md:block"
|
||||
[mat-sort-header]="'sku'">
|
||||
SKU
|
||||
</th>
|
||||
<td
|
||||
class="px-8"
|
||||
mat-cell
|
||||
*matCellDef="let product">
|
||||
<div class="flex items-center">
|
||||
<span class="relative flex flex-0 items-center justify-center w-12 h-12 mr-6 rounded overflow-hidden border">
|
||||
<img
|
||||
class="w-8"
|
||||
*ngIf="product.thumbnail"
|
||||
[src]="product.thumbnail">
|
||||
<span
|
||||
class="flex items-center justify-center w-full h-full text-xs font-semibold leading-none text-center uppercase"
|
||||
*ngIf="!product.thumbnail">
|
||||
No Image
|
||||
</span>
|
||||
</span>
|
||||
<span class="truncate">{{product.sku}}</span>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Name -->
|
||||
<ng-container matColumnDef="name">
|
||||
<th
|
||||
class="bg-gray-50 dark:bg-black dark:bg-opacity-5"
|
||||
mat-header-cell
|
||||
*matHeaderCellDef
|
||||
mat-sort-header
|
||||
disableClear>
|
||||
Name
|
||||
</th>
|
||||
<td
|
||||
class="pr-8 truncate"
|
||||
mat-cell
|
||||
*matCellDef="let product">
|
||||
{{product.name}}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Price -->
|
||||
<ng-container matColumnDef="price">
|
||||
<th
|
||||
class="w-40 bg-gray-50 dark:bg-black dark:bg-opacity-5"
|
||||
mat-header-cell
|
||||
*matHeaderCellDef
|
||||
mat-sort-header
|
||||
disableClear>
|
||||
</div>
|
||||
<div [mat-sort-header]="'name'">Name</div>
|
||||
<div
|
||||
class="hidden sm:block"
|
||||
[mat-sort-header]="'price'">
|
||||
Price
|
||||
</th>
|
||||
<td
|
||||
class="pr-4"
|
||||
mat-cell
|
||||
*matCellDef="let product">
|
||||
{{product.price | currency:'USD':'symbol':'1.2-2'}}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Stock -->
|
||||
<ng-container matColumnDef="stock">
|
||||
<th
|
||||
class="w-24 bg-gray-50 dark:bg-black dark:bg-opacity-5"
|
||||
mat-header-cell
|
||||
*matHeaderCellDef
|
||||
mat-sort-header
|
||||
disableClear>
|
||||
</div>
|
||||
<div
|
||||
class="hidden lg:block"
|
||||
[mat-sort-header]="'stock'">
|
||||
Stock
|
||||
</th>
|
||||
<td
|
||||
class="pr-4"
|
||||
mat-cell
|
||||
*matCellDef="let product">
|
||||
<span class="flex items-center">
|
||||
<span class="min-w-4">{{product.stock}}</span>
|
||||
<!-- Low stock -->
|
||||
<span
|
||||
class="flex items-end ml-2 w-1 h-4 bg-red-200 rounded overflow-hidden"
|
||||
*ngIf="product.stock < 20">
|
||||
<span class="flex w-full h-1/3 bg-red-600"></span>
|
||||
</span>
|
||||
<!-- Medium stock -->
|
||||
<span
|
||||
class="flex items-end ml-2 w-1 h-4 bg-orange-200 rounded overflow-hidden"
|
||||
*ngIf="product.stock >= 20 && product.stock < 30">
|
||||
<span class="flex w-full h-2/4 bg-orange-400"></span>
|
||||
</span>
|
||||
<!-- High stock -->
|
||||
<span
|
||||
class="flex items-end ml-2 w-1 h-4 bg-green-100 rounded overflow-hidden"
|
||||
*ngIf="product.stock >= 30">
|
||||
<span class="flex w-full h-full bg-green-400"></span>
|
||||
</span>
|
||||
</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Active -->
|
||||
<ng-container matColumnDef="active">
|
||||
<th
|
||||
class="w-24 bg-gray-50 dark:bg-black dark:bg-opacity-5"
|
||||
mat-header-cell
|
||||
*matHeaderCellDef
|
||||
mat-sort-header
|
||||
disableClear>
|
||||
</div>
|
||||
<div
|
||||
class="hidden lg:block"
|
||||
[mat-sort-header]="'active'">
|
||||
Active
|
||||
</th>
|
||||
<td
|
||||
class="pr-4"
|
||||
mat-cell
|
||||
*matCellDef="let product">
|
||||
<mat-icon
|
||||
class="text-green-400 icon-size-5"
|
||||
*ngIf="product.active"
|
||||
[svgIcon]="'heroicons_solid:check'"></mat-icon>
|
||||
<mat-icon
|
||||
class="text-gray-400 icon-size-5"
|
||||
*ngIf="!product.active"
|
||||
[svgIcon]="'heroicons_solid:x'"></mat-icon>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Details -->
|
||||
<ng-container matColumnDef="details">
|
||||
<th
|
||||
class="w-24 pr-8 bg-gray-50 dark:bg-black dark:bg-opacity-5"
|
||||
mat-header-cell
|
||||
*matHeaderCellDef>
|
||||
Details
|
||||
</th>
|
||||
<td
|
||||
class="pr-8"
|
||||
mat-cell
|
||||
*matCellDef="let product">
|
||||
<button
|
||||
class="min-w-10 min-h-7 h-7 px-2 leading-6"
|
||||
mat-stroked-button
|
||||
(click)="toggleDetails(product.id)">
|
||||
<mat-icon
|
||||
class="icon-size-5"
|
||||
[svgIcon]="selectedProduct?.id === product.id ? 'heroicons_solid:chevron-up' : 'heroicons_solid:chevron-down'"></mat-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Product details row -->
|
||||
<ng-container matColumnDef="productDetails">
|
||||
<td
|
||||
class="p-0 border-b-0"
|
||||
mat-cell
|
||||
*matCellDef="let product"
|
||||
[attr.colspan]="productsTableColumns.length">
|
||||
<ng-container *ngIf="selectedProduct?.id === product.id">
|
||||
<ng-container *ngTemplateOutlet="rowDetailsTemplate; context: {$implicit: product}"></ng-container>
|
||||
</ng-container>
|
||||
</td>
|
||||
|
||||
<ng-template
|
||||
#rowDetailsTemplate
|
||||
let-product>
|
||||
<div
|
||||
class="shadow-lg overflow-hidden"
|
||||
[@expandCollapse]="selectedProduct?.id === product.id ? 'expanded' : 'collapsed'">
|
||||
<div class="flex border-b">
|
||||
<!-- Selected product form -->
|
||||
<form
|
||||
class="flex flex-col w-full"
|
||||
[formGroup]="selectedProductForm">
|
||||
|
||||
<div class="flex p-8">
|
||||
|
||||
<!-- Product images and status -->
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="p-3 border rounded">
|
||||
<ng-container *ngIf="selectedProductForm.get('images').value.length; else noImage">
|
||||
<img
|
||||
class="w-30 min-w-30"
|
||||
[src]="selectedProductForm.get('images').value[selectedProductForm.get('currentImageIndex').value]">
|
||||
</ng-container>
|
||||
<ng-template #noImage>
|
||||
<span class="flex items-center min-h-20 text-lg font-semibold">NO IMAGE</span>
|
||||
</ng-template>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center mt-2"
|
||||
*ngIf="selectedProductForm.get('images').value.length">
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="cycleImages(false)">
|
||||
<mat-icon
|
||||
class="icon-size-5"
|
||||
[svgIcon]="'heroicons_solid:arrow-narrow-left'"></mat-icon>
|
||||
</button>
|
||||
<span class="font-sm mx-2">
|
||||
{{selectedProductForm.get('currentImageIndex').value + 1}} of {{selectedProductForm.get('images').value.length}}
|
||||
</span>
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="cycleImages(true)">
|
||||
<mat-icon
|
||||
class="icon-size-5"
|
||||
[svgIcon]="'heroicons_solid:arrow-narrow-right'"></mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col mt-8">
|
||||
<span class="font-semibold mb-2">Product status</span>
|
||||
<mat-slide-toggle
|
||||
[formControlName]="'active'"
|
||||
[color]="'primary'">
|
||||
{{selectedProductForm.get('active').value === true ? 'Active' : 'Disabled'}}
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-auto">
|
||||
<div class="flex flex-col w-2/4 pl-8">
|
||||
|
||||
<!-- Name -->
|
||||
<mat-form-field class="w-full">
|
||||
<mat-label>Name</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[formControlName]="'name'">
|
||||
</mat-form-field>
|
||||
|
||||
<!-- SKU and Barcode -->
|
||||
<div class="flex">
|
||||
<mat-form-field class="w-1/3 pr-2">
|
||||
<mat-label>SKU</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[formControlName]="'sku'">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-2/3 pl-2">
|
||||
<mat-label>Barcode</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[formControlName]="'barcode'">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<!-- Category, Brand & Vendor -->
|
||||
<div class="flex">
|
||||
<mat-form-field class="w-1/3 pr-2">
|
||||
<mat-label>Category</mat-label>
|
||||
<mat-select [formControlName]="'category'">
|
||||
<ng-container *ngFor="let category of categories">
|
||||
<mat-option [value]="category.id">
|
||||
{{category.name}}
|
||||
</mat-option>
|
||||
</ng-container>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-1/3 px-2">
|
||||
<mat-label>Brand</mat-label>
|
||||
<mat-select [formControlName]="'brand'">
|
||||
<ng-container *ngFor="let brand of brands">
|
||||
<mat-option [value]="brand.id">
|
||||
{{brand.name}}
|
||||
</mat-option>
|
||||
</ng-container>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-1/3 pl-2">
|
||||
<mat-label>Vendor</mat-label>
|
||||
<mat-select [formControlName]="'vendor'">
|
||||
<ng-container *ngFor="let vendor of vendors">
|
||||
<mat-option [value]="vendor.id">
|
||||
{{vendor.name}}
|
||||
</mat-option>
|
||||
</ng-container>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<!-- Stock and Reserved -->
|
||||
<div class="flex">
|
||||
<mat-form-field class="w-1/3 pr-2">
|
||||
<mat-label>Stock</mat-label>
|
||||
<input
|
||||
type="number"
|
||||
matInput
|
||||
[formControlName]="'stock'">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-1/3 pl-2">
|
||||
<mat-label>Reserved</mat-label>
|
||||
<input
|
||||
type="number"
|
||||
matInput
|
||||
[formControlName]="'reserved'">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Cost, Base price, Tax & Price -->
|
||||
<div class="flex flex-col w-1/4 pl-8">
|
||||
<mat-form-field class="w-full">
|
||||
<mat-label>Cost</mat-label>
|
||||
<span matPrefix>$</span>
|
||||
<input
|
||||
matInput
|
||||
[formControlName]="'cost'">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-full">
|
||||
<mat-label>Base Price</mat-label>
|
||||
<span matPrefix>$</span>
|
||||
<input
|
||||
matInput
|
||||
[formControlName]="'basePrice'">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-full">
|
||||
<mat-label>Tax</mat-label>
|
||||
<span matSuffix>%</span>
|
||||
<input
|
||||
type="number"
|
||||
matInput
|
||||
[formControlName]="'taxPercent'">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-full">
|
||||
<mat-label>Price</mat-label>
|
||||
<span matSuffix>$</span>
|
||||
<input
|
||||
matInput
|
||||
[formControlName]="'price'">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<!-- Weight & Tags -->
|
||||
<div class="flex flex-col w-1/4 pl-8">
|
||||
<mat-form-field class="w-full">
|
||||
<mat-label>Weight</mat-label>
|
||||
<span matSuffix>lbs.</span>
|
||||
<input
|
||||
matInput
|
||||
[formControlName]="'weight'">
|
||||
</mat-form-field>
|
||||
|
||||
<!-- Tags -->
|
||||
<ng-container *ngIf="selectedProduct && selectedProduct.tags.length">
|
||||
<span class="font-semibold">Tags</span>
|
||||
<div class="mt-1 rounded-md border border-gray-300 shadow-sm overflow-hidden">
|
||||
<!-- Header -->
|
||||
<div class="flex items-center my-2 mx-3">
|
||||
<div class="flex items-center flex-auto min-w-0">
|
||||
<mat-icon
|
||||
class="icon-size-5"
|
||||
[svgIcon]="'heroicons_solid:search'"></mat-icon>
|
||||
<input
|
||||
class="min-w-0 ml-2 py-1 border-0"
|
||||
type="text"
|
||||
placeholder="Enter tag name"
|
||||
(input)="filterTags($event)"
|
||||
(keydown)="filterTagsInputKeyDown($event)"
|
||||
[maxLength]="50"
|
||||
#newTagInput>
|
||||
</div>
|
||||
<button
|
||||
class="ml-3 w-8 h-8 min-h-8"
|
||||
mat-icon-button
|
||||
(click)="toggleTagsEditMode()">
|
||||
<mat-icon
|
||||
*ngIf="!tagsEditMode"
|
||||
class="icon-size-5"
|
||||
[svgIcon]="'heroicons_solid:pencil-alt'"></mat-icon>
|
||||
<mat-icon
|
||||
*ngIf="tagsEditMode"
|
||||
class="icon-size-5"
|
||||
[svgIcon]="'heroicons_solid:check'"></mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Available tags -->
|
||||
<div class="max-h-40 leading-none overflow-y-auto border-t">
|
||||
<!-- Tags -->
|
||||
<ng-container *ngIf="!tagsEditMode">
|
||||
<ng-container *ngFor="let tag of filteredTags; trackBy: trackByFn">
|
||||
<mat-checkbox
|
||||
class="flex items-center h-10 min-h-10 px-4"
|
||||
[color]="'primary'"
|
||||
[checked]="selectedProduct.tags.includes(tag.id)"
|
||||
(change)="toggleProductTag(tag, $event)">
|
||||
{{tag.title}}
|
||||
</mat-checkbox>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
<!-- Tags editing -->
|
||||
<ng-container *ngIf="tagsEditMode">
|
||||
<div class="p-4 space-y-2">
|
||||
<ng-container *ngFor="let tag of filteredTags; trackBy: trackByFn">
|
||||
<mat-form-field class="fuse-mat-dense fuse-mat-no-subscript w-full">
|
||||
<input
|
||||
matInput
|
||||
[value]="tag.title"
|
||||
(input)="updateTagTitle(tag, $event)">
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="deleteTag(tag)"
|
||||
matSuffix>
|
||||
<mat-icon
|
||||
class="icon-size-5"
|
||||
[svgIcon]="'heroicons_solid:trash'"></mat-icon>
|
||||
</button>
|
||||
</mat-form-field>
|
||||
</ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center h-10 min-h-10 -ml-0.5 pl-4 pr-3 leading-none cursor-pointer border-t hover:bg-gray-50 dark:hover:bg-hover"
|
||||
*ngIf="shouldShowCreateTagButton(newTagInput.value)"
|
||||
(click)="createTag(newTagInput.value); newTagInput.value = ''"
|
||||
matRipple>
|
||||
<mat-icon
|
||||
class="mr-2 icon-size-5"
|
||||
[svgIcon]="'heroicons_solid:plus-circle'"></mat-icon>
|
||||
<div class="break-all">Create "<b>{{newTagInput.value}}</b>"</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="hidden sm:block">Details</div>
|
||||
</div>
|
||||
<!-- Rows -->
|
||||
<ng-container *ngIf="(products$ | async) as products">
|
||||
<ng-container *ngFor="let product of products; trackBy: trackByFn">
|
||||
<div class="inventory-grid grid items-center gap-4 py-3 px-6 md:px-8 border-b">
|
||||
|
||||
<!-- Image -->
|
||||
<div class="flex items-center">
|
||||
<div class="relative flex flex-0 items-center justify-center w-12 h-12 mr-6 rounded overflow-hidden border">
|
||||
<img
|
||||
class="w-8"
|
||||
*ngIf="product.thumbnail"
|
||||
[alt]="'Product thumbnail image'"
|
||||
[src]="product.thumbnail">
|
||||
<div
|
||||
class="flex items-center justify-center w-full h-full text-xs font-semibold leading-none text-center uppercase"
|
||||
*ngIf="!product.thumbnail">
|
||||
NO THUMB
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between w-full border-t px-8 py-4">
|
||||
<button
|
||||
class="-ml-4"
|
||||
mat-button
|
||||
[color]="'warn'"
|
||||
(click)="deleteSelectedProduct()">
|
||||
Delete
|
||||
</button>
|
||||
<div class="flex items-center">
|
||||
<div
|
||||
class="flex items-center mr-4"
|
||||
*ngIf="flashMessage">
|
||||
<ng-container *ngIf="flashMessage === 'success'">
|
||||
<mat-icon
|
||||
class="text-green-500"
|
||||
[svgIcon]="'heroicons_outline:check'"></mat-icon>
|
||||
<span class="ml-2">Product updated</span>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="flashMessage === 'error'">
|
||||
<mat-icon
|
||||
class="text-red-500"
|
||||
[svgIcon]="'heroicons_outline:x'"></mat-icon>
|
||||
<span class="ml-2">An error occurred, try again!</span>
|
||||
</ng-container>
|
||||
</div>
|
||||
<button
|
||||
mat-flat-button
|
||||
[color]="'primary'"
|
||||
(click)="updateSelectedProduct()">
|
||||
Update
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- SKU -->
|
||||
<div class="hidden md:block truncate">
|
||||
{{product.sku}}
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<!-- Name -->
|
||||
<div class="truncate">
|
||||
{{product.name}}
|
||||
</div>
|
||||
|
||||
<!-- Price -->
|
||||
<div class="hidden sm:block">
|
||||
{{product.price | currency:'USD':'symbol':'1.2-2'}}
|
||||
</div>
|
||||
|
||||
<!-- Stock -->
|
||||
<div class="hidden lg:flex items-center">
|
||||
<div class="min-w-4">{{product.stock}}</div>
|
||||
<!-- Low stock -->
|
||||
<div
|
||||
class="flex items-end ml-2 w-1 h-4 bg-red-200 rounded overflow-hidden"
|
||||
*ngIf="product.stock < 20">
|
||||
<div class="flex w-full h-1/3 bg-red-600"></div>
|
||||
</div>
|
||||
<!-- Medium stock -->
|
||||
<div
|
||||
class="flex items-end ml-2 w-1 h-4 bg-orange-200 rounded overflow-hidden"
|
||||
*ngIf="product.stock >= 20 && product.stock < 30">
|
||||
<div class="flex w-full h-2/4 bg-orange-400"></div>
|
||||
</div>
|
||||
<!-- High stock -->
|
||||
<div
|
||||
class="flex items-end ml-2 w-1 h-4 bg-green-100 rounded overflow-hidden"
|
||||
*ngIf="product.stock >= 30">
|
||||
<div class="flex w-full h-full bg-green-400"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Active -->
|
||||
<div class="hidden lg:block">
|
||||
<ng-container *ngIf="product.active">
|
||||
<mat-icon
|
||||
class="text-green-400 icon-size-5"
|
||||
[svgIcon]="'heroicons_solid:check'"></mat-icon>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!product.active">
|
||||
<mat-icon
|
||||
class="text-gray-400 icon-size-5"
|
||||
[svgIcon]="'heroicons_solid:x'"></mat-icon>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<!-- Details button -->
|
||||
<div>
|
||||
<button
|
||||
class="min-w-10 min-h-7 h-7 px-2 leading-6"
|
||||
mat-stroked-button
|
||||
(click)="toggleDetails(product.id)">
|
||||
<mat-icon
|
||||
class="icon-size-5"
|
||||
[svgIcon]="selectedProduct?.id === product.id ? 'heroicons_solid:chevron-up' : 'heroicons_solid:chevron-down'"></mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
<div class="grid">
|
||||
<ng-container *ngIf="selectedProduct?.id === product.id">
|
||||
<ng-container *ngTemplateOutlet="rowDetailsTemplate; context: {$implicit: product}"></ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<tr
|
||||
class="shadow"
|
||||
mat-header-row
|
||||
*matHeaderRowDef="productsTableColumns; sticky: true"></tr>
|
||||
<tr
|
||||
class="h-18 hover:bg-gray-100 dark:hover:bg-hover"
|
||||
mat-row
|
||||
*matRowDef="let product; columns: productsTableColumns;"></tr>
|
||||
<tr
|
||||
class="h-0"
|
||||
mat-row
|
||||
*matRowDef="let row; columns: ['productDetails']"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<mat-paginator
|
||||
class="sm:absolute sm:inset-x-0 sm:bottom-0 border-b sm:border-t sm:border-b-0 z-10 bg-gray-50 dark:bg-transparent"
|
||||
[ngClass]="{'pointer-events-none': isLoading}"
|
||||
[length]="pagination.length"
|
||||
[pageIndex]="pagination.page"
|
||||
[pageSize]="pagination.size"
|
||||
[pageSizeOptions]="[5, 10, 25, 100]"
|
||||
[showFirstLastButtons]="true"></mat-paginator>
|
||||
<mat-paginator
|
||||
class="sm:absolute sm:inset-x-0 sm:bottom-0 border-b sm:border-t sm:border-b-0 z-10 bg-gray-50 dark:bg-transparent"
|
||||
[ngClass]="{'pointer-events-none': isLoading}"
|
||||
[length]="pagination.length"
|
||||
[pageIndex]="pagination.page"
|
||||
[pageSize]="pagination.size"
|
||||
[pageSizeOptions]="[5, 10, 25, 100]"
|
||||
[showFirstLastButtons]="true"></mat-paginator>
|
||||
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
|
||||
<ng-template
|
||||
#rowDetailsTemplate
|
||||
let-product>
|
||||
<div class="shadow-lg overflow-hidden">
|
||||
<div class="flex border-b">
|
||||
<!-- Selected product form -->
|
||||
<form
|
||||
class="flex flex-col w-full"
|
||||
[formGroup]="selectedProductForm">
|
||||
|
||||
<div class="flex flex-col sm:flex-row p-8">
|
||||
|
||||
<!-- Product images and status -->
|
||||
<div class="flex flex-col items-center sm:items-start mb-8 sm:mb-0">
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="w-32 h-44 border rounded overflow-hidden">
|
||||
<ng-container *ngIf="selectedProductForm.get('images').value.length; else noImage">
|
||||
<img
|
||||
class="w-full h-full object-cover"
|
||||
[src]="selectedProductForm.get('images').value[selectedProductForm.get('currentImageIndex').value]">
|
||||
</ng-container>
|
||||
<ng-template #noImage>
|
||||
<span class="flex items-center min-h-20 text-lg font-semibold">NO IMAGE</span>
|
||||
</ng-template>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center mt-2 whitespace-nowrap"
|
||||
*ngIf="selectedProductForm.get('images').value.length">
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="cycleImages(false)">
|
||||
<mat-icon
|
||||
class="icon-size-5"
|
||||
[svgIcon]="'heroicons_solid:arrow-narrow-left'"></mat-icon>
|
||||
</button>
|
||||
<span class="font-sm mx-2">
|
||||
{{selectedProductForm.get('currentImageIndex').value + 1}} of {{selectedProductForm.get('images').value.length}}
|
||||
</span>
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="cycleImages(true)">
|
||||
<mat-icon
|
||||
class="icon-size-5"
|
||||
[svgIcon]="'heroicons_solid:arrow-narrow-right'"></mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col mt-8">
|
||||
<span class="font-semibold mb-2">Product status</span>
|
||||
<mat-slide-toggle
|
||||
[formControlName]="'active'"
|
||||
[color]="'primary'">
|
||||
{{selectedProductForm.get('active').value === true ? 'Active' : 'Disabled'}}
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-auto flex-wrap">
|
||||
<!-- Name, SKU & etc. -->
|
||||
<div class="flex flex-col w-full lg:w-2/4 sm:pl-8">
|
||||
|
||||
<!-- Name -->
|
||||
<mat-form-field class="w-full">
|
||||
<mat-label>Name</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[formControlName]="'name'">
|
||||
</mat-form-field>
|
||||
|
||||
<!-- SKU and Barcode -->
|
||||
<div class="flex">
|
||||
<mat-form-field class="w-1/3 pr-2">
|
||||
<mat-label>SKU</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[formControlName]="'sku'">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-2/3 pl-2">
|
||||
<mat-label>Barcode</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[formControlName]="'barcode'">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<!-- Category, Brand & Vendor -->
|
||||
<div class="flex">
|
||||
<mat-form-field class="w-1/3 pr-2">
|
||||
<mat-label>Category</mat-label>
|
||||
<mat-select [formControlName]="'category'">
|
||||
<ng-container *ngFor="let category of categories">
|
||||
<mat-option [value]="category.id">
|
||||
{{category.name}}
|
||||
</mat-option>
|
||||
</ng-container>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-1/3 px-2">
|
||||
<mat-label>Brand</mat-label>
|
||||
<mat-select [formControlName]="'brand'">
|
||||
<ng-container *ngFor="let brand of brands">
|
||||
<mat-option [value]="brand.id">
|
||||
{{brand.name}}
|
||||
</mat-option>
|
||||
</ng-container>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-1/3 pl-2">
|
||||
<mat-label>Vendor</mat-label>
|
||||
<mat-select [formControlName]="'vendor'">
|
||||
<ng-container *ngFor="let vendor of vendors">
|
||||
<mat-option [value]="vendor.id">
|
||||
{{vendor.name}}
|
||||
</mat-option>
|
||||
</ng-container>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<!-- Stock and Reserved -->
|
||||
<div class="flex">
|
||||
<mat-form-field class="w-1/3 pr-2">
|
||||
<mat-label>Stock</mat-label>
|
||||
<input
|
||||
type="number"
|
||||
matInput
|
||||
[formControlName]="'stock'">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-1/3 pl-2">
|
||||
<mat-label>Reserved</mat-label>
|
||||
<input
|
||||
type="number"
|
||||
matInput
|
||||
[formControlName]="'reserved'">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Cost, Base price, Tax & Price -->
|
||||
<div class="flex flex-col w-full lg:w-1/4 sm:pl-8">
|
||||
<mat-form-field class="w-full">
|
||||
<mat-label>Cost</mat-label>
|
||||
<span matPrefix>$</span>
|
||||
<input
|
||||
matInput
|
||||
[formControlName]="'cost'">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-full">
|
||||
<mat-label>Base Price</mat-label>
|
||||
<span matPrefix>$</span>
|
||||
<input
|
||||
matInput
|
||||
[formControlName]="'basePrice'">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-full">
|
||||
<mat-label>Tax</mat-label>
|
||||
<span matSuffix>%</span>
|
||||
<input
|
||||
type="number"
|
||||
matInput
|
||||
[formControlName]="'taxPercent'">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-full">
|
||||
<mat-label>Price</mat-label>
|
||||
<span matSuffix>$</span>
|
||||
<input
|
||||
matInput
|
||||
[formControlName]="'price'">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<!-- Weight & Tags -->
|
||||
<div class="flex flex-col w-full lg:w-1/4 sm:pl-8">
|
||||
<mat-form-field class="w-full">
|
||||
<mat-label>Weight</mat-label>
|
||||
<span matSuffix>lbs.</span>
|
||||
<input
|
||||
matInput
|
||||
[formControlName]="'weight'">
|
||||
</mat-form-field>
|
||||
|
||||
<!-- Tags -->
|
||||
<span class="mb-px font-medium leading-tight">Tags</span>
|
||||
<div class="mt-1.5 rounded-md border border-gray-300 dark:border-gray-500 shadow-sm overflow-hidden">
|
||||
<!-- Header -->
|
||||
<div class="flex items-center -my-px py-2 px-3">
|
||||
<div class="flex items-center flex-auto min-w-0">
|
||||
<mat-icon
|
||||
class="icon-size-5"
|
||||
[svgIcon]="'heroicons_solid:search'"></mat-icon>
|
||||
<input
|
||||
class="min-w-0 ml-2 py-1 border-0"
|
||||
type="text"
|
||||
placeholder="Enter tag name"
|
||||
(input)="filterTags($event)"
|
||||
(keydown)="filterTagsInputKeyDown($event)"
|
||||
[maxLength]="50"
|
||||
#newTagInput>
|
||||
</div>
|
||||
<button
|
||||
class="ml-3 w-8 h-8 min-h-8"
|
||||
mat-icon-button
|
||||
(click)="toggleTagsEditMode()">
|
||||
<mat-icon
|
||||
*ngIf="!tagsEditMode"
|
||||
class="icon-size-5"
|
||||
[svgIcon]="'heroicons_solid:pencil-alt'"></mat-icon>
|
||||
<mat-icon
|
||||
*ngIf="tagsEditMode"
|
||||
class="icon-size-5"
|
||||
[svgIcon]="'heroicons_solid:check'"></mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Available tags -->
|
||||
<div class="h-44 leading-none overflow-y-auto border-t border-gray-300 dark:border-gray-500">
|
||||
<!-- Tags -->
|
||||
<ng-container *ngIf="!tagsEditMode">
|
||||
<ng-container *ngFor="let tag of filteredTags; trackBy: trackByFn">
|
||||
<mat-checkbox
|
||||
class="flex items-center h-10 min-h-10 px-4"
|
||||
[color]="'primary'"
|
||||
[checked]="selectedProduct.tags.includes(tag.id)"
|
||||
(change)="toggleProductTag(tag, $event)">
|
||||
{{tag.title}}
|
||||
</mat-checkbox>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
<!-- Tags editing -->
|
||||
<ng-container *ngIf="tagsEditMode">
|
||||
<div class="p-4 space-y-2">
|
||||
<ng-container *ngFor="let tag of filteredTags; trackBy: trackByFn">
|
||||
<mat-form-field class="fuse-mat-dense fuse-mat-no-subscript w-full">
|
||||
<input
|
||||
matInput
|
||||
[value]="tag.title"
|
||||
(input)="updateTagTitle(tag, $event)">
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="deleteTag(tag)"
|
||||
matSuffix>
|
||||
<mat-icon
|
||||
class="icon-size-5"
|
||||
[svgIcon]="'heroicons_solid:trash'"></mat-icon>
|
||||
</button>
|
||||
</mat-form-field>
|
||||
</ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
<div
|
||||
class="flex items-center h-10 min-h-10 -ml-0.5 pl-4 pr-3 leading-none cursor-pointer border-t hover:bg-gray-50 dark:hover:bg-hover"
|
||||
*ngIf="shouldShowCreateTagButton(newTagInput.value)"
|
||||
(click)="createTag(newTagInput.value); newTagInput.value = ''"
|
||||
matRipple>
|
||||
<mat-icon
|
||||
class="mr-2 icon-size-5"
|
||||
[svgIcon]="'heroicons_solid:plus-circle'"></mat-icon>
|
||||
<div class="break-all">Create "<b>{{newTagInput.value}}</b>"</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between w-full border-t px-8 py-4">
|
||||
<button
|
||||
class="-ml-4"
|
||||
mat-button
|
||||
[color]="'warn'"
|
||||
(click)="deleteSelectedProduct()">
|
||||
Delete
|
||||
</button>
|
||||
<div class="flex items-center">
|
||||
<div
|
||||
class="flex items-center mr-4"
|
||||
*ngIf="flashMessage">
|
||||
<ng-container *ngIf="flashMessage === 'success'">
|
||||
<mat-icon
|
||||
class="text-green-500"
|
||||
[svgIcon]="'heroicons_outline:check'"></mat-icon>
|
||||
<span class="ml-2">Product updated</span>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="flashMessage === 'error'">
|
||||
<mat-icon
|
||||
class="text-red-500"
|
||||
[svgIcon]="'heroicons_outline:x'"></mat-icon>
|
||||
<span class="ml-2">An error occurred, try again!</span>
|
||||
</ng-container>
|
||||
</div>
|
||||
<button
|
||||
mat-flat-button
|
||||
[color]="'primary'"
|
||||
(click)="updateSelectedProduct()">
|
||||
Update
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #noProducts>
|
||||
<div class="p-8 sm:p-16 border-t text-4xl font-semibold tracking-tight text-center">There are no products!</div>
|
||||
</ng-template>
|
||||
|
||||
@@ -12,6 +12,26 @@ import { InventoryService } from 'app/modules/admin/apps/ecommerce/inventory/inv
|
||||
@Component({
|
||||
selector : 'inventory-list',
|
||||
templateUrl : './inventory.component.html',
|
||||
styles : [
|
||||
/* language=SCSS */
|
||||
`
|
||||
.inventory-grid {
|
||||
grid-template-columns: 48px auto 40px;
|
||||
|
||||
@screen sm {
|
||||
grid-template-columns: 48px auto 112px 72px;
|
||||
}
|
||||
|
||||
@screen md {
|
||||
grid-template-columns: 48px 112px auto 112px 72px;
|
||||
}
|
||||
|
||||
@screen lg {
|
||||
grid-template-columns: 48px 112px auto 112px 96px 96px 72px;
|
||||
}
|
||||
}
|
||||
`
|
||||
],
|
||||
encapsulation : ViewEncapsulation.None,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
animations : fuseAnimations
|
||||
@@ -29,8 +49,6 @@ export class InventoryListComponent implements OnInit, AfterViewInit, OnDestroy
|
||||
flashMessage: 'success' | 'error' | null = null;
|
||||
isLoading: boolean = false;
|
||||
pagination: InventoryPagination;
|
||||
productsCount: number = 0;
|
||||
productsTableColumns: string[] = ['sku', 'name', 'price', 'stock', 'active', 'details'];
|
||||
searchInputControl: FormControl = new FormControl();
|
||||
selectedProduct: InventoryProduct | null = null;
|
||||
selectedProductForm: FormGroup;
|
||||
@@ -121,16 +139,6 @@ export class InventoryListComponent implements OnInit, AfterViewInit, OnDestroy
|
||||
|
||||
// Get the products
|
||||
this.products$ = this._inventoryService.products$;
|
||||
this._inventoryService.products$
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((products: InventoryProduct[]) => {
|
||||
|
||||
// Update the counts
|
||||
this.productsCount = products.length;
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
});
|
||||
|
||||
// Get the tags
|
||||
this._inventoryService.tags$
|
||||
@@ -179,28 +187,41 @@ export class InventoryListComponent implements OnInit, AfterViewInit, OnDestroy
|
||||
*/
|
||||
ngAfterViewInit(): void
|
||||
{
|
||||
// If the user changes the sort order...
|
||||
this._sort.sortChange
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(() => {
|
||||
// Reset back to the first page
|
||||
this._paginator.pageIndex = 0;
|
||||
|
||||
// Close the details
|
||||
this.closeDetails();
|
||||
if ( this._sort && this._paginator )
|
||||
{
|
||||
// Set the initial sort
|
||||
this._sort.sort({
|
||||
id : 'name',
|
||||
start : 'asc',
|
||||
disableClear: true
|
||||
});
|
||||
|
||||
// Get products if sort or page changes
|
||||
merge(this._sort.sortChange, this._paginator.page).pipe(
|
||||
switchMap(() => {
|
||||
this.closeDetails();
|
||||
this.isLoading = true;
|
||||
return this._inventoryService.getProducts(this._paginator.pageIndex, this._paginator.pageSize, this._sort.active, this._sort.direction);
|
||||
}),
|
||||
map(() => {
|
||||
this.isLoading = false;
|
||||
})
|
||||
).subscribe();
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
|
||||
// If the user changes the sort order...
|
||||
this._sort.sortChange
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(() => {
|
||||
// Reset back to the first page
|
||||
this._paginator.pageIndex = 0;
|
||||
|
||||
// Close the details
|
||||
this.closeDetails();
|
||||
});
|
||||
|
||||
// Get products if sort or page changes
|
||||
merge(this._sort.sortChange, this._paginator.page).pipe(
|
||||
switchMap(() => {
|
||||
this.closeDetails();
|
||||
this.isLoading = true;
|
||||
return this._inventoryService.getProducts(this._paginator.pageIndex, this._paginator.pageSize, this._sort.active, this._sort.direction);
|
||||
}),
|
||||
map(() => {
|
||||
this.isLoading = false;
|
||||
})
|
||||
).subscribe();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="flex items-center justify-end">
|
||||
<button
|
||||
mat-icon-button
|
||||
[routerLink]="['../']">
|
||||
[routerLink]="['../../']">
|
||||
<mat-icon [svgIcon]="'heroicons_outline:x'"></mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -22,17 +22,17 @@ export class CanDeactivateFileManagerDetails implements CanDeactivate<FileManage
|
||||
nextRoute = nextRoute.firstChild;
|
||||
}
|
||||
|
||||
// If the next state doesn't contain '/files'
|
||||
// If the next state doesn't contain '/file-manager'
|
||||
// it means we are navigating away from the
|
||||
// tasks app
|
||||
// file manager app
|
||||
if ( !nextState.url.includes('/file-manager') )
|
||||
{
|
||||
// Let it navigate
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we are navigating to another task...
|
||||
if ( nextRoute.paramMap.get('id') )
|
||||
// If we are navigating to another item...
|
||||
if ( nextState.url.includes('/details') )
|
||||
{
|
||||
// Just navigate
|
||||
return true;
|
||||
|
||||
@@ -33,6 +33,54 @@ export class FileManagerItemsResolver implements Resolve<any>
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class FileManagerFolderResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(
|
||||
private _router: Router,
|
||||
private _fileManagerService: FileManagerService
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Item[]>
|
||||
{
|
||||
return this._fileManagerService.getItems(route.paramMap.get('folderId'))
|
||||
.pipe(
|
||||
// Error here means the requested task is not available
|
||||
catchError((error) => {
|
||||
|
||||
// Log the error
|
||||
console.error(error);
|
||||
|
||||
// Get the parent url
|
||||
const parentUrl = state.url.split('/').slice(0, -1).join('/');
|
||||
|
||||
// Navigate to there
|
||||
this._router.navigateByUrl(parentUrl);
|
||||
|
||||
// Throw an error
|
||||
return throwError(error);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
|
||||
@@ -3,13 +3,30 @@ import { CanDeactivateFileManagerDetails } from 'app/modules/admin/apps/file-man
|
||||
import { FileManagerComponent } from 'app/modules/admin/apps/file-manager/file-manager.component';
|
||||
import { FileManagerListComponent } from 'app/modules/admin/apps/file-manager/list/list.component';
|
||||
import { FileManagerDetailsComponent } from 'app/modules/admin/apps/file-manager/details/details.component';
|
||||
import { FileManagerItemResolver, FileManagerItemsResolver } from 'app/modules/admin/apps/file-manager/file-manager.resolvers';
|
||||
import { FileManagerFolderResolver, FileManagerItemResolver, FileManagerItemsResolver } from 'app/modules/admin/apps/file-manager/file-manager.resolvers';
|
||||
|
||||
export const fileManagerRoutes: Route[] = [
|
||||
{
|
||||
path : '',
|
||||
component: FileManagerComponent,
|
||||
children : [
|
||||
{
|
||||
path : 'folders/:folderId',
|
||||
component: FileManagerListComponent,
|
||||
resolve : {
|
||||
item: FileManagerFolderResolver
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path : 'details/:id',
|
||||
component : FileManagerDetailsComponent,
|
||||
resolve : {
|
||||
item: FileManagerItemResolver
|
||||
},
|
||||
canDeactivate: [CanDeactivateFileManagerDetails]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path : '',
|
||||
component: FileManagerListComponent,
|
||||
@@ -18,7 +35,7 @@ export const fileManagerRoutes: Route[] = [
|
||||
},
|
||||
children : [
|
||||
{
|
||||
path : ':id',
|
||||
path : 'details/:id',
|
||||
component : FileManagerDetailsComponent,
|
||||
resolve : {
|
||||
item: FileManagerItemResolver
|
||||
|
||||
@@ -47,9 +47,9 @@ export class FileManagerService
|
||||
/**
|
||||
* Get items
|
||||
*/
|
||||
getItems(): Observable<Item[]>
|
||||
getItems(folderId: string | null = null): Observable<Item[]>
|
||||
{
|
||||
return this._httpClient.get<Items>('api/apps/file-manager').pipe(
|
||||
return this._httpClient.get<Items>('api/apps/file-manager', {params: {folderId}}).pipe(
|
||||
tap((response: any) => {
|
||||
this._items.next(response);
|
||||
})
|
||||
|
||||
@@ -2,11 +2,13 @@ export interface Items
|
||||
{
|
||||
folders: Item[];
|
||||
files: Item[];
|
||||
path: any[];
|
||||
}
|
||||
|
||||
export interface Item
|
||||
{
|
||||
id?: string;
|
||||
folderId?: string;
|
||||
name?: string;
|
||||
createdBy?: string;
|
||||
createdAt?: string;
|
||||
|
||||
@@ -26,7 +26,32 @@
|
||||
<div>
|
||||
<div class="text-4xl font-extrabold tracking-tight leading-none">File Manager</div>
|
||||
<div class="flex items-center mt-0.5 font-medium text-secondary">
|
||||
{{items.folders.length}} folders, {{items.files.length}} files
|
||||
<ng-container *ngIf="!items.path.length">
|
||||
{{items.folders.length}} folders, {{items.files.length}} files
|
||||
</ng-container>
|
||||
<!-- Breadcrumbs -->
|
||||
<ng-container *ngIf="items.path.length">
|
||||
<div class="flex items-center space-x-2">
|
||||
<a
|
||||
class="text-primary cursor-pointer"
|
||||
[routerLink]="['/apps/file-manager']">Home
|
||||
</a>
|
||||
<div class="">/</div>
|
||||
<ng-container *ngFor="let path of items.path; let last = last; trackBy: trackByFn">
|
||||
<ng-container *ngIf="!last">
|
||||
<a
|
||||
class="text-primary cursor-pointer"
|
||||
[routerLink]="['/apps/file-manager/folders/', path.id]">{{path.name}}</a>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="last">
|
||||
<div>{{path.name}}</div>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!last">
|
||||
<div class="">/</div>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Actions -->
|
||||
@@ -42,75 +67,95 @@
|
||||
</div>
|
||||
|
||||
<!-- Items list -->
|
||||
<ng-container *ngIf="items && items.folders.length && items.files.length > 0; else noItems">
|
||||
<div class="p-6 md:p-8">
|
||||
<ng-container *ngIf="items && (items.folders.length > 0 || items.files.length > 0); else noItems">
|
||||
<div class="p-6 md:p-8 space-y-8">
|
||||
<!-- Folders -->
|
||||
<div class="font-medium">Folders</div>
|
||||
<div
|
||||
class="flex flex-wrap -m-2 mt-2">
|
||||
<ng-container *ngFor="let folder of items.folders; trackBy:trackByFn">
|
||||
<ng-container *ngTemplateOutlet="item, context: {$implicit: folder}"></ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<!-- Files -->
|
||||
<div class="font-medium mt-8">Files</div>
|
||||
<div
|
||||
class="flex flex-wrap -m-2 mt-2">
|
||||
<ng-container *ngFor="let file of items.files; trackBy:trackByFn">
|
||||
<ng-container *ngTemplateOutlet="item, context: {$implicit: file}"></ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<!-- Item template -->
|
||||
<ng-template
|
||||
#item
|
||||
let-item>
|
||||
<a
|
||||
class="flex flex-col w-40 h-40 m-2 p-4 shadow rounded-2xl cursor-pointer bg-card"
|
||||
[routerLink]="['./', item.id]">
|
||||
<div class="aspect-w-9 aspect-h-6">
|
||||
<div class="flex items-center justify-center">
|
||||
<!-- Icons -->
|
||||
<ng-container [ngSwitch]="item.type">
|
||||
<!-- Folder -->
|
||||
<ng-container *ngSwitchCase="'folder'">
|
||||
<mat-icon
|
||||
class="icon-size-14 text-hint"
|
||||
[svgIcon]="'iconsmind:folder'"></mat-icon>
|
||||
</ng-container>
|
||||
<!-- File -->
|
||||
<ng-container *ngSwitchDefault>
|
||||
<div class="relative">
|
||||
<mat-icon
|
||||
class="icon-size-14 text-hint"
|
||||
[svgIcon]="'iconsmind:file'"></mat-icon>
|
||||
<div
|
||||
class="absolute left-0 bottom-0 px-1.5 rounded text-sm font-semibold leading-5 text-white"
|
||||
[class.bg-red-600]="item.type === 'PDF'"
|
||||
[class.bg-blue-600]="item.type === 'DOC'"
|
||||
[class.bg-green-600]="item.type === 'XLS'"
|
||||
[class.bg-gray-600]="item.type === 'TXT'"
|
||||
[class.bg-amber-600]="item.type === 'JPG'">
|
||||
{{item.type.toUpperCase()}}
|
||||
</div>
|
||||
<ng-container *ngIf="items.folders.length > 0">
|
||||
<div>
|
||||
<div class="font-medium">Folders</div>
|
||||
<div
|
||||
class="flex flex-wrap -m-2 mt-2">
|
||||
<ng-container *ngFor="let folder of items.folders; trackBy:trackByFn">
|
||||
<div class="relative w-40 h-40 m-2 p-4 shadow rounded-2xl bg-card">
|
||||
<a
|
||||
class="absolute z-20 top-1.5 right-1.5 w-8 h-8 min-h-8"
|
||||
(click)="$event.preventDefault()"
|
||||
[routerLink]="['./details/', folder.id]"
|
||||
mat-icon-button>
|
||||
<mat-icon
|
||||
class="icon-size-5"
|
||||
[svgIcon]="'heroicons_solid:information-circle'"></mat-icon>
|
||||
</a>
|
||||
<a
|
||||
class="z-10 absolute inset-0 flex flex-col p-4 cursor-pointer"
|
||||
[routerLink]="['/apps/file-manager/folders/', folder.id]">
|
||||
<div class="aspect-w-9 aspect-h-6">
|
||||
<div class="flex items-center justify-center">
|
||||
<!-- Icon -->
|
||||
<mat-icon
|
||||
class="icon-size-14 text-hint"
|
||||
[svgIcon]="'iconsmind:folder'"></mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col flex-auto justify-center text-center text-sm font-medium">
|
||||
<div
|
||||
class="truncate"
|
||||
[matTooltip]="folder.name">{{folder.name}}</div>
|
||||
<ng-container *ngIf="folder.contents">
|
||||
<div class="text-secondary truncate">{{folder.contents}}</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col flex-auto justify-center text-center text-sm font-medium">
|
||||
<div
|
||||
class="truncate"
|
||||
[matTooltip]="item.name">{{item.name}}</div>
|
||||
<ng-container *ngIf="item.contents">
|
||||
<div class="text-secondary truncate">{{item.contents}}</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</a>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
|
||||
<!-- Files -->
|
||||
<ng-container *ngIf="items.files.length > 0">
|
||||
<div>
|
||||
<div class="font-medium">Files</div>
|
||||
<div
|
||||
class="flex flex-wrap -m-2 mt-2">
|
||||
<ng-container *ngFor="let file of items.files; trackBy:trackByFn">
|
||||
<a
|
||||
class="flex flex-col w-40 h-40 m-2 p-4 shadow rounded-2xl cursor-pointer bg-card"
|
||||
[routerLink]="['./details/', file.id]">
|
||||
<div class="aspect-w-9 aspect-h-6">
|
||||
<div class="flex items-center justify-center">
|
||||
<!-- Icons -->
|
||||
<div class="relative">
|
||||
<mat-icon
|
||||
class="icon-size-14 text-hint"
|
||||
[svgIcon]="'iconsmind:file'"></mat-icon>
|
||||
<div
|
||||
class="absolute left-0 bottom-0 px-1.5 rounded text-sm font-semibold leading-5 text-white"
|
||||
[class.bg-red-600]="file.type === 'PDF'"
|
||||
[class.bg-blue-600]="file.type === 'DOC'"
|
||||
[class.bg-green-600]="file.type === 'XLS'"
|
||||
[class.bg-gray-600]="file.type === 'TXT'"
|
||||
[class.bg-amber-600]="file.type === 'JPG'">
|
||||
{{file.type.toUpperCase()}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col flex-auto justify-center text-center text-sm font-medium">
|
||||
<div
|
||||
class="truncate"
|
||||
[matTooltip]="file.name">{{file.name}}</div>
|
||||
<ng-container *ngIf="file.contents">
|
||||
<div class="text-secondary truncate">{{file.contents}}</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</a>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<!-- No items template -->
|
||||
<ng-template #noItems>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="flex flex-col flex-auto min-w-0">
|
||||
|
||||
<!-- Header -->
|
||||
<div class="relative pt-8 pb-28 px-4 sm:pt-20 sm:pb-48 sm:px-16 overflow-hidden bg-gray-800 dark">
|
||||
<div class="relative pt-8 pb-28 px-4 sm:pt-20 sm:pb-48 sm:px-16 overflow-hidden bg-gray-800 dark:bg-gray-900 dark">
|
||||
<!-- Background - @formatter:off -->
|
||||
<!-- Rings -->
|
||||
<svg class="absolute inset-0 pointer-events-none"
|
||||
@@ -40,7 +40,7 @@
|
||||
<div class="text-2xl font-semibold">FAQs</div>
|
||||
<div class="md:max-w-40 mt-1 text-secondary">Frequently asked questions and answers</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-center py-4 px-8 text-primary bg-gray-50 dark:bg-transparent dark:border-t">
|
||||
<div class="flex items-center justify-center py-4 px-8 text-primary-500 dark:text-primary-400 bg-gray-50 dark:bg-transparent dark:border-t">
|
||||
<a
|
||||
class="flex items-center"
|
||||
[routerLink]="['faqs']">
|
||||
@@ -58,7 +58,7 @@
|
||||
<div class="text-2xl font-semibold">Guides</div>
|
||||
<div class="md:max-w-40 mt-1 text-secondary">Articles and resources to guide you</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-center py-4 px-8 text-primary-500 bg-gray-50 dark:bg-transparent dark:border-t">
|
||||
<div class="flex items-center justify-center py-4 px-8 text-primary-500 dark:text-primary-400 bg-gray-50 dark:bg-transparent dark:border-t">
|
||||
<a
|
||||
class="flex items-center"
|
||||
[routerLink]="['guides']">
|
||||
@@ -76,7 +76,7 @@
|
||||
<div class="text-2xl font-semibold">Support</div>
|
||||
<div class="md:max-w-40 mt-1 text-secondary">Contact us for more detailed support</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-center py-4 px-8 text-primary-500 bg-gray-50 dark:bg-transparent dark:border-t">
|
||||
<div class="flex items-center justify-center py-4 px-8 text-primary-500 dark:text-primary-400 bg-gray-50 dark:bg-transparent dark:border-t">
|
||||
<a
|
||||
class="flex items-center"
|
||||
[routerLink]="['support']">
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
Contact support
|
||||
</div>
|
||||
<!-- Form -->
|
||||
<div class="mt-8 sm:mt-12 p-6 pb-7 sm:p-10 sm:pb-7 shadow rounded-2xl bg-white">
|
||||
<div class="mt-8 sm:mt-12 p-6 pb-7 sm:p-10 sm:pb-7 shadow rounded-2xl bg-card">
|
||||
<!-- Alert -->
|
||||
<fuse-alert
|
||||
class="mb-8"
|
||||
|
||||
@@ -304,9 +304,9 @@ export class MailboxDetailsComponent implements OnInit, OnDestroy
|
||||
scrollStrategy : this._overlay.scrollStrategies.block(),
|
||||
positionStrategy: this._overlay.position()
|
||||
.flexibleConnectedTo(this._infoDetailsPanelOrigin._elementRef.nativeElement)
|
||||
.withFlexibleDimensions()
|
||||
.withFlexibleDimensions(true)
|
||||
.withViewportMargin(16)
|
||||
.withLockedPosition()
|
||||
.withLockedPosition(true)
|
||||
.withPositions([
|
||||
{
|
||||
originX : 'start',
|
||||
|
||||
@@ -217,9 +217,9 @@ export class TasksDetailsComponent implements OnInit, AfterViewInit, OnDestroy
|
||||
scrollStrategy : this._overlay.scrollStrategies.block(),
|
||||
positionStrategy: this._overlay.position()
|
||||
.flexibleConnectedTo(this._tagsPanelOrigin.nativeElement)
|
||||
.withFlexibleDimensions()
|
||||
.withFlexibleDimensions(true)
|
||||
.withViewportMargin(64)
|
||||
.withLockedPosition()
|
||||
.withLockedPosition(true)
|
||||
.withPositions([
|
||||
{
|
||||
originX : 'start',
|
||||
|
||||
@@ -11,6 +11,88 @@ export class ChangelogComponent
|
||||
{
|
||||
changelog: any[] = [
|
||||
|
||||
// v13.2.0
|
||||
{
|
||||
version : 'v13.2.0',
|
||||
releaseDate: 'July 01, 2021',
|
||||
changes : [
|
||||
{
|
||||
type: 'Added',
|
||||
list: [
|
||||
'(fuse/navigation) "tooltip" property to show tooltips on navigation items using MatTooltip'
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'Changed',
|
||||
list: [
|
||||
'(dependencies) Updated Angular & Angular Material to v12.1.1',
|
||||
'(dependencies) Updated various other packages',
|
||||
'(dev-dependencies) Removed "@angular/language-service" as IDEs and Code editors include them either natively or through plugins',
|
||||
'(Angular Material) Apply rounded styles by default',
|
||||
'(fuse/navigation) Moved *ngIf directives into their own "ng-container" containers',
|
||||
'(layouts) Hide the "fuse-fullscreen" button on smaller devices since they don\'t support fullscreen',
|
||||
'(layout/common) Explicitly define the overlay position strategy properties',
|
||||
'(apps/contacts) Explicitly define the overlay position strategy properties',
|
||||
'(apps/mailbox) Explicitly define the overlay position strategy properties',
|
||||
'(apps/tasks) Explicitly define the overlay position strategy properties',
|
||||
'(tailwindcss) Breaking: Removed 5, 6 & 12 fractional spacing values since they are not used in Demo by default and they are mostly not needed because of Flex and Grid. If you happen to use them, you can manually add them back.',
|
||||
'(docs) Updated docs',
|
||||
'(package.json) Added "description" and "author" fields',
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'Fixed',
|
||||
list: [
|
||||
'(fuse/drawer) Memory leak due to the animation player, thanks to Vadym Pidoplichko for coming up the issue and the solution.',
|
||||
'(fuse/navigation) Vertical navigation blocks scroll if it\'s destroyed while in "over" mode and opened',
|
||||
'(layouts) Header buttons are not fitting on certain layouts',
|
||||
'(layout/settings-drawer) Issues on small screen devices',
|
||||
'(apps/ecommerce/inventory) Tags selector border colors are not correct on dark mode',
|
||||
'(apps/help-center) Small dark mode issues',
|
||||
'(transloco) Language files cannot be loaded if using a base href other than "/"',
|
||||
'(tailwindcss) Dark mode classes are not being purged correctly due to the wrong safelist entry'
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
// v13.1.0
|
||||
{
|
||||
version : 'v13.1.0',
|
||||
releaseDate: 'June 15, 2021',
|
||||
changes : [
|
||||
{
|
||||
type: 'Added',
|
||||
list: [
|
||||
'(fuse/fullscreen) [tooltip] & [iconTpl] inputs for customizing the trigger button',
|
||||
'(fuse/navigation) "target" property for setting the target attribute on external links',
|
||||
'(ui/angular-material) List of available components with links to official docs',
|
||||
'(ui/advanced-search) An example form that uses query parameters for Advanced Search like forms',
|
||||
'(ui/page-layouts) Tabbed version of "Simple Fullwidth" page layout'
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'Changed',
|
||||
list: [
|
||||
'(app.resolver) Use services to request the initial data',
|
||||
'(core) New navigation service to request and store the navigation data',
|
||||
'(core/user) Renamed "user.model" to "user.types" for better consistency',
|
||||
'(layouts) Common components of layouts now requests their data directly from their service rather than getting it from route data',
|
||||
'(layouts/common/search) Improved the autocomplete design',
|
||||
'(apps/ecommerce/inventory) Replaced the mat-table with a custom grid for better performance & improved the mobile experience',
|
||||
'(docs) Updated the docs to reflect the latest changes',
|
||||
'(dependencies) Updated Angular, Angular Material & various other packages'
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'Fixed',
|
||||
list: [
|
||||
'(fuse/navigation) First children of collapsable items don\'t have proper spacing at the top',
|
||||
'(data/navigation) Wrong icon for "Invoice" navigation item',
|
||||
'(data/navigation) Dashboards are missing from "Futuristic" navigation type'
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
// v13.0.3
|
||||
{
|
||||
version : 'v13.0.3',
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
<div class="flex flex-col flex-auto min-w-0">
|
||||
|
||||
<!-- Header -->
|
||||
<div class="flex flex-col sm:flex-row flex-0 sm:items-center sm:justify-between p-6 sm:py-8 sm:px-10 border-b bg-card dark:bg-transparent">
|
||||
<div class="flex-1 min-w-0">
|
||||
<!-- Breadcrumbs -->
|
||||
<div class="flex flex-wrap items-center font-medium">
|
||||
<div>
|
||||
<a class="whitespace-nowrap text-primary-500">Documentation</a>
|
||||
</div>
|
||||
<div class="flex items-center ml-1 whitespace-nowrap">
|
||||
<mat-icon
|
||||
class="icon-size-5 text-secondary"
|
||||
[svgIcon]="'heroicons_solid:chevron-right'"></mat-icon>
|
||||
<a class="ml-1 text-primary-500">Core Features</a>
|
||||
</div>
|
||||
<div class="flex items-center ml-1 whitespace-nowrap">
|
||||
<mat-icon
|
||||
class="icon-size-5 text-secondary"
|
||||
[svgIcon]="'heroicons_solid:chevron-right'"></mat-icon>
|
||||
<span class="ml-1 text-secondary">Components</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Title -->
|
||||
<div class="mt-2">
|
||||
<h2 class="text-3xl md:text-4xl font-extrabold tracking-tight leading-7 sm:leading-10 truncate">
|
||||
Fullscreen
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="-ml-3 sm:ml-0 mb-2 sm:mb-0 order-first sm:order-last"
|
||||
mat-icon-button
|
||||
(click)="toggleDrawer()">
|
||||
<mat-icon [svgIcon]="'heroicons_outline:menu'"></mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="flex-auto max-w-3xl p-6 sm:p-10 prose prose-sm">
|
||||
|
||||
<p>
|
||||
<strong>fuse-fullscreen</strong> is a small component that toggles the fullscreen on and off.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Exported as: </strong><code>fuseFullscreen</code>
|
||||
</p>
|
||||
|
||||
<h2>Module</h2>
|
||||
<textarea
|
||||
fuse-highlight
|
||||
lang="typescript">
|
||||
import { FuseFullscreenModule } from '@fuse/components/fullscreen';
|
||||
</textarea>
|
||||
|
||||
<h2>Usage</h2>
|
||||
<p>
|
||||
Here's the basic usage of the <code>fuse-fullscreen</code>:
|
||||
</p>
|
||||
<!-- @formatter:off -->
|
||||
<textarea fuse-highlight
|
||||
lang="html">
|
||||
<fuse-fullscreen></fuse-fullscreen>
|
||||
</textarea>
|
||||
<!-- @formatter:on -->
|
||||
|
||||
<h2>Properties</h2>
|
||||
<div class="bg-card py-3 px-6 rounded shadow">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="font-mono text-md text-secondary">
|
||||
<div>@Input()</div>
|
||||
<div>iconTpl: TemplateRef<any></div>
|
||||
</td>
|
||||
<td>
|
||||
Template reference for the icon.
|
||||
</td>
|
||||
<td>
|
||||
-
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-mono text-md text-secondary">
|
||||
<div>@Input()</div>
|
||||
<div>tooltip: string</div>
|
||||
</td>
|
||||
<td>
|
||||
Tooltip of the toggle button.
|
||||
</td>
|
||||
<td>
|
||||
'Toggle Fullscreen'
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { CoreFeaturesComponent } from 'app/modules/admin/docs/core-features/core-features.component';
|
||||
|
||||
@Component({
|
||||
selector : 'fullscreen',
|
||||
templateUrl: './fullscreen.component.html',
|
||||
styles : ['']
|
||||
})
|
||||
export class FullscreenComponent
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(private _coreFeaturesComponent: CoreFeaturesComponent)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Toggle the drawer
|
||||
*/
|
||||
toggleDrawer(): void
|
||||
{
|
||||
// Toggle the drawer
|
||||
this._coreFeaturesComponent.matDrawer.toggle();
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,7 @@
|
||||
<textarea
|
||||
fuse-highlight
|
||||
lang="typescript">
|
||||
import { FuseHighlightModule } from '@fuse/components/drawer';
|
||||
import { FuseHighlightModule } from '@fuse/components/highlight';
|
||||
</textarea>
|
||||
|
||||
<h2>Usage</h2>
|
||||
|
||||
@@ -94,8 +94,16 @@
|
||||
hidden?: (item: FuseNavigationItem) => boolean;
|
||||
active?: boolean;
|
||||
disabled?: boolean;
|
||||
tooltip?: string;
|
||||
link?: string;
|
||||
externalLink?: boolean;
|
||||
externalLink?: boolean;
|
||||
target?:
|
||||
| '_blank'
|
||||
| '_self'
|
||||
| '_parent'
|
||||
| '_top'
|
||||
| string;
|
||||
exactMatch?: boolean;
|
||||
isActiveMatchOptions?: IsActiveMatchOptions;
|
||||
function?: (item: FuseNavigationItem) => void;
|
||||
@@ -182,6 +190,14 @@
|
||||
Whether the navigation item is disabled.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-mono text-md text-secondary">
|
||||
<div>tooltip</div>
|
||||
</td>
|
||||
<td>
|
||||
Tooltip to show on item hover. Empty string will remove the tooltip.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-mono text-md text-secondary">
|
||||
<div>link</div>
|
||||
@@ -199,6 +215,14 @@
|
||||
<strong>link</strong> property.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-mono text-md text-secondary">
|
||||
<div>target</div>
|
||||
</td>
|
||||
<td>
|
||||
Sets the <em>target</em> attribute of the external, outgoing link.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-mono text-md text-secondary">
|
||||
<div>exactMatch</div>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user