Compare commits

...

34 Commits

Author SHA1 Message Date
sercan
90891eb201 Merge remote-tracking branch 'origin/demo' into starter 2021-06-15 08:36:32 +03:00
sercan
47d9ddb08c Updated changelog 2021-06-15 08:32:13 +03:00
sercan
4da3612d22 Updated changelog and increased the version number 2021-06-14 14:29:58 +03:00
sercan
403a949d4a (apps/ecommerce/inventory) Small mobile experience tweaks 2021-06-14 12:25:04 +03:00
sercan
5b78a68116 (apps/ecommerce/inventory) Better image containment on row details 2021-06-14 12:22:51 +03:00
sercan
214116e10d (apps/ecommerce/inventory) Replaced the mat-table with a custom grid for better mobile experience and better performance, improved the mobile experience 2021-06-14 12:03:17 +03:00
sercan
5962c80e8d (docs) Added "target" docs to navigation 2021-06-14 08:53:01 +03:00
sercan
ff086b1ed0 (fuse/navigation) Added "target" for setting the target attribute on outgoing links. Thanks @danielehrhardt for the original PR, closes #154 2021-06-14 08:52:29 +03:00
sercan
efdfa6418a (core) Go back to the 'classy' layout by default 2021-06-10 14:56:21 +03:00
sercan
c1c9904b9d (layouts/common/search) Improved the autocomplete design 2021-06-10 14:56:00 +03:00
sercan
39650d3cc9 (layouts) Use navigation service data for horizontal navigation 2021-06-10 10:13:43 +03:00
sercan
bafa9adc01 (ui/page-layouts) Added tabbed version of Simple Fullwidth page layout 2021-06-09 11:41:39 +03:00
sercan
bb9023f9df (fuse/navigation) Fixed: First children of collapsable items don't have proper spacing at the top 2021-06-09 10:32:26 +03:00
sercan
66096718e0 (docs) Updated the docs to reflect the latest changes 2021-06-09 10:22:18 +03:00
sercan
945d0a2240 (fuse/fullscreen) Added [tooltip] & [iconTpl] inputs for customizing the Fullscreen trigger button 2021-06-08 18:29:49 +03:00
sercan
9005f08ac7 (app.resolver) Use services to request the initial data
(layouts) Common components of layouts now requests their data directly from their service rather than getting it from route data
(core) New navigation service to request and store the navigation data
2021-06-08 17:29:45 +03:00
sercan
89f5a4ec69 (core/user) Renamed user.model to user.types for better consistency 2021-06-07 12:18:39 +03:00
sercan
ca7b4c7e5d (ui/advanced-search) Removed unused MatIconModule import 2021-06-07 11:41:29 +03:00
sercan
bb57ec2324 (ui/advanced-search) Added an example search form that uses query parameters for Advanced Search forms 2021-06-07 11:40:33 +03:00
sercan
11ad2c89df (apps/file-manager) Added support for nested folder views 2021-06-05 13:57:39 +03:00
sercan
fc1e7b02b0 (data/navigation) Fixed the "Invoice" icon, added missing dashboard links to the "futuristicNavigation" data 2021-06-04 22:28:53 +03:00
sercan
446bfe4139 (ui/angular-material) Added a component list that redirects to the related page of the official docs 2021-06-04 22:21:47 +03:00
sercan
6c7201b77a Merge remote-tracking branch 'origin/demo' into starter 2021-06-03 13:28:30 +03:00
sercan
2c5cd60c0a (general) Updated version numbers and changelog 2021-06-03 13:25:07 +03:00
sercan
decb238f73 (dependencies) Updated various dependencies to their latest versions
(fuse/highlight) Updated the import path
2021-06-03 13:18:05 +03:00
sercan
ab3ad4fd2f (apps/scrumboard) Dark mode fixes and tweaks 2021-06-03 11:27:51 +03:00
sercan
c2dd77d7a3 (angular.json) Removed "e2e" entry, fixed the styles file path for "test" 2021-06-02 12:45:12 +03:00
sercan
a78b087a68 (apps/scrumboard) New version of the Scrumboard app 2021-06-02 11:42:22 +03:00
sercan
84d40427a1 (apps/ecommerce) Small tweaks
(apps/mailbox) Small tweaks
2021-06-02 11:41:47 +03:00
sercan
f295fd9061 (fuse/autogrow) BREAKING: Removed fuseAutogrow in favor of matTextareaAutosize since all of its problems solved, use [matTextareaAutosize] without any vertical padding on the textarea itself. 2021-05-31 17:14:03 +03:00
sercan
b98cfc1d37 (Angular Material) Increased default MatDialog border radius to 16px for better consistency 2021-05-31 16:12:08 +03:00
sercan
0ba5677c01 (Dependencies) Updated Angular & Angular Material to v12.0.2 2021-05-31 10:49:51 +03:00
sercan
90f869e7b9 Merge remote-tracking branch 'origin/demo' into starter 2021-05-31 10:46:26 +03:00
sercan
96ef1281ae (Angular Material) Fixed: Density setting is not working for dark themes 2021-05-31 10:45:29 +03:00
114 changed files with 2321 additions and 1905 deletions

View File

@@ -120,7 +120,7 @@
"src/assets"
],
"styles": [
"src/styles.scss"
"src/styles/styles.scss"
],
"scripts": []
}
@@ -133,18 +133,6 @@
"src/**/*.html"
]
}
},
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "fuse:serve"
},
"configurations": {
"production": {
"devServerTarget": "fuse:serve:production"
}
}
}
}
}

1987
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "@fuse/demo",
"version": "13.0.2",
"version": "13.1.0",
"license": "https://themeforest.net/licenses/standard",
"private": true,
"scripts": {
@@ -12,17 +12,17 @@
"e2e": "ng e2e"
},
"dependencies": {
"@angular/animations": "12.0.0",
"@angular/cdk": "12.0.0",
"@angular/common": "12.0.0",
"@angular/compiler": "12.0.0",
"@angular/core": "12.0.0",
"@angular/forms": "12.0.0",
"@angular/material": "12.0.0",
"@angular/material-moment-adapter": "12.0.0",
"@angular/platform-browser": "12.0.0",
"@angular/platform-browser-dynamic": "12.0.0",
"@angular/router": "12.0.0",
"@angular/animations": "12.0.4",
"@angular/cdk": "12.0.4",
"@angular/common": "12.0.4",
"@angular/compiler": "12.0.4",
"@angular/core": "12.0.4",
"@angular/forms": "12.0.4",
"@angular/material": "12.0.4",
"@angular/material-moment-adapter": "12.0.4",
"@angular/platform-browser": "12.0.4",
"@angular/platform-browser-dynamic": "12.0.4",
"@angular/router": "12.0.4",
"@fullcalendar/angular": "4.4.5-beta",
"@fullcalendar/core": "4.4.2",
"@fullcalendar/daygrid": "4.4.2",
@@ -31,62 +31,60 @@
"@fullcalendar/moment": "4.4.2",
"@fullcalendar/rrule": "4.4.2",
"@fullcalendar/timegrid": "4.4.2",
"@ngneat/transloco": "2.20.1",
"apexcharts": "3.26.3",
"@ngneat/transloco": "2.21.0",
"apexcharts": "3.27.1",
"crypto-js": "3.3.0",
"highlight.js": "10.7.2",
"highlight.js": "11.0.1",
"lodash-es": "4.17.21",
"moment": "2.29.1",
"ng-apexcharts": "1.5.10",
"ngx-markdown": "12.0.0",
"ng-apexcharts": "1.5.12",
"ngx-markdown": "12.0.1",
"ngx-quill": "14.0.0",
"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.0",
"@angular-eslint/builder": "12.0.0",
"@angular-eslint/eslint-plugin": "12.0.0",
"@angular-eslint/eslint-plugin-template": "12.0.0",
"@angular-eslint/schematics": "12.0.0",
"@angular-eslint/template-parser": "12.0.0",
"@angular/cli": "12.0.0",
"@angular/compiler-cli": "12.0.0",
"@angular/language-service": "12.0.0",
"@tailwindcss/aspect-ratio": "0.2.0",
"@tailwindcss/line-clamp": "0.2.0",
"@tailwindcss/typography": "0.4.0",
"@angular-devkit/build-angular": "12.0.4",
"@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.4",
"@angular/compiler-cli": "12.0.4",
"@angular/language-service": "12.0.4",
"@tailwindcss/aspect-ratio": "0.2.1",
"@tailwindcss/line-clamp": "0.2.1",
"@tailwindcss/typography": "0.4.1",
"@types/chroma-js": "2.1.3",
"@types/crypto-js": "3.1.47",
"@types/highlight.js": "10.1.0",
"@types/jasmine": "3.6.11",
"@types/lodash": "4.14.169",
"@types/lodash": "4.14.170",
"@types/lodash-es": "4.17.4",
"@types/node": "12.20.13",
"@typescript-eslint/eslint-plugin": "4.24.0",
"@typescript-eslint/parser": "4.24.0",
"autoprefixer": "10.2.5",
"@types/node": "12.20.15",
"@typescript-eslint/eslint-plugin": "4.26.1",
"@typescript-eslint/parser": "4.26.1",
"autoprefixer": "10.2.6",
"chroma-js": "2.1.2",
"eslint": "7.26.0",
"eslint-plugin-import": "2.23.2",
"eslint-plugin-jsdoc": "34.8.2",
"eslint": "7.28.0",
"eslint-plugin-import": "2.23.4",
"eslint-plugin-jsdoc": "35.2.0",
"eslint-plugin-prefer-arrow": "1.2.3",
"jasmine-core": "3.7.1",
"jasmine-spec-reporter": "5.0.2",
"karma": "6.3.2",
"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",
"protractor": "7.0.0",
"tailwindcss": "2.1.2",
"postcss": "8.3.3",
"tailwindcss": "2.1.4",
"typescript": "4.2.4"
}
}

View File

@@ -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>

View File

@@ -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;

View File

@@ -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

View File

@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import * as hljs from 'highlight.js';
import hljs from 'highlight.js';
@Injectable({
providedIn: 'root'

View File

@@ -19,7 +19,8 @@
<a
class="fuse-horizontal-navigation-item"
*ngIf="item.link && item.externalLink && !item.function && !item.disabled"
[href]="item.link">
[href]="item.link"
[target]="item.target || '_self'">
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
</a>
@@ -49,6 +50,7 @@
class="fuse-horizontal-navigation-item"
*ngIf="item.link && item.externalLink && item.function && !item.disabled"
[href]="item.link"
[target]="item.target || '_self'"
(click)="item.function(item)"
mat-menu-item>
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>

View File

@@ -17,6 +17,12 @@ export interface FuseNavigationItem
disabled?: boolean;
link?: string;
externalLink?: boolean;
target?:
| '_blank'
| '_self'
| '_parent'
| '_top'
| string;
exactMatch?: boolean;
isActiveMatchOptions?: IsActiveMatchOptions;
function?: (item: FuseNavigationItem) => void;

View File

@@ -19,7 +19,8 @@
<a
class="fuse-vertical-navigation-item"
*ngIf="item.link && item.externalLink && !item.function && !item.disabled"
[href]="item.link">
[href]="item.link"
[target]="item.target || '_self'">
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
</a>
@@ -49,6 +50,7 @@
class="fuse-vertical-navigation-item"
*ngIf="item.link && item.externalLink && item.function && !item.disabled"
[href]="item.link"
[target]="item.target || '_self'"
(click)="item.function(item)">
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
</a>

View File

@@ -335,6 +335,7 @@ fuse-vertical-navigation {
}
> .fuse-vertical-navigation-item-children {
margin-top: 6px;
> *:last-child {
padding-bottom: 6px;

View File

@@ -1,114 +0,0 @@
import { ChangeDetectorRef, Directive, ElementRef, HostBinding, HostListener, Input, NgZone, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core';
import { Subject } from 'rxjs';
@Directive({
selector: 'textarea[fuseAutogrow]',
exportAs: 'fuseAutogrow'
})
export class FuseAutogrowDirective implements OnChanges, OnInit, OnDestroy
{
// eslint-disable-next-line @angular-eslint/no-input-rename
@Input('fuseAutogrowVerticalPadding') padding: number = 8;
@HostBinding('rows') private _rows: number = 1;
private _height: string = 'auto';
private _unsubscribeAll: Subject<any> = new Subject<any>();
/**
* Constructor
*/
constructor(
private _elementRef: ElementRef,
private _changeDetectorRef: ChangeDetectorRef,
private _ngZone: NgZone
)
{
}
// -----------------------------------------------------------------------------------------------------
// @ Accessors
// -----------------------------------------------------------------------------------------------------
/**
* Host binding for component inline styles
*/
@HostBinding('style') get styleList(): any
{
return {
'height' : this._height,
'overflow': 'hidden',
'resize' : 'none'
};
}
// -----------------------------------------------------------------------------------------------------
// @ Decorated methods
// -----------------------------------------------------------------------------------------------------
/**
* Resize on 'input' and 'ngModelChange' events
*
* @private
*/
@HostListener('input')
@HostListener('ngModelChange')
private _resize(): void
{
// This doesn't need to trigger Angular's change detection by itself
this._ngZone.runOutsideAngular(() => {
setTimeout(() => {
// Set the height to 'auto' so we can correctly read the scrollHeight
this._height = 'auto';
// Detect the changes so the height is applied
this._changeDetectorRef.detectChanges();
// Get the scrollHeight and subtract the vertical padding
this._height = `${this._elementRef.nativeElement.scrollHeight - this.padding}px`;
// Detect the changes one more time to apply the final height
this._changeDetectorRef.detectChanges();
});
});
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On changes
*
* @param changes
*/
ngOnChanges(changes: SimpleChanges): void
{
// Padding
if ( 'fuseAutogrowVerticalPadding' in changes )
{
// Resize
this._resize();
}
}
/**
* On init
*/
ngOnInit(): void
{
// Resize for the first time
this._resize();
}
/**
* On destroy
*/
ngOnDestroy(): void
{
// Unsubscribe from all subscriptions
this._unsubscribeAll.next();
this._unsubscribeAll.complete();
}
}

View File

@@ -1,14 +0,0 @@
import { NgModule } from '@angular/core';
import { FuseAutogrowDirective } from '@fuse/directives/autogrow/autogrow.directive';
@NgModule({
declarations: [
FuseAutogrowDirective
],
exports : [
FuseAutogrowDirective
]
})
export class FuseAutogrowModule
{
}

View File

@@ -1 +0,0 @@
export * from '@fuse/directives/autogrow/public-api';

View File

@@ -1,2 +0,0 @@
export * from '@fuse/directives/autogrow/autogrow.directive';
export * from '@fuse/directives/autogrow/autogrow.module';

View File

@@ -410,6 +410,13 @@
font-weight: 500 !important;
}
/* ----------------------------------------------------------------------------------------------------- */
/* @ Dialog
/* ----------------------------------------------------------------------------------------------------- */
.mat-dialog-container {
border-radius: 16px !important;
}
/* ----------------------------------------------------------------------------------------------------- */
/* @ Drawer
/* ----------------------------------------------------------------------------------------------------- */
@@ -683,8 +690,8 @@
align-self: stretch;
min-height: 36px;
height: auto;
margin: 10px 0;
padding: 4px 6px 4px 0 !important;
margin: 14px 0;
padding: 0 6px 0 0;
transform: none;
}

View File

@@ -1,21 +1,24 @@
@use '~@angular/material' as mat;
@use "sass:map";
/** Include the core Angular Material styles */
/* Include the core Angular Material styles */
@include mat.core();
/** Configure the Angular Material typography */
@include mat.all-component-typographies(
mat.define-typography-config(
$font-family: theme('fontFamily.sans'),
$title: mat.define-typography-level(1.25rem, 2rem, 600),
$body-2: mat.define-typography-level(0.875rem, 1.5rem, 600),
$button: mat.define-typography-level(0.875rem, 0.875rem, 500),
$input: mat.define-typography-level(0.875rem, 1.2857142857, 400) // line-height: 20px
)
);
/* Create a base theme without color.
This will globally set the density and typography for all future color themes. */
@include mat.all-component-themes((
color: null,
density: -2,
typography: mat.define-typography-config(
$font-family: theme('fontFamily.sans'),
$title: mat.define-typography-level(1.25rem, 2rem, 600),
$body-2: mat.define-typography-level(0.875rem, 1.5rem, 600),
$button: mat.define-typography-level(0.875rem, 0.875rem, 500),
$input: mat.define-typography-level(0.875rem, 1.2857142857, 400) /* line-height: 20px */
)
));
/** Prepare the Background and Foreground maps */
/* Prepare the Background and Foreground maps */
$background-light: (
status-bar: #CBD5E1, /* blueGray.300 */
app-bar: #FFFFFF,
@@ -90,7 +93,7 @@ $foreground-dark: (
slider-off-active: #94A3B8 /* blueGray.400 */
);
/** Generate Primary, Accent and Warn palettes */
/* Generate Primary, Accent and Warn palettes */
$palettes: ();
@each $name in (primary, accent, warn) {
$palettes: map.merge($palettes, (#{$name}: (
@@ -126,7 +129,7 @@ $palettes: ();
)));
}
/** Generate Angular Material themes. Since we are using CSS Custom Properties,
/* Generate Angular Material themes. Since we are using CSS Custom Properties,
we don't have to generate a separate Angular Material theme for each color
set. We can just create one light and one dark theme and then switch the
CSS Custom Properties to dynamically switch the colors. */
@@ -144,11 +147,11 @@ body .light {
is-dark: map.get(map.get($base-light-theme, color), is-dark),
foreground: $foreground-light,
background: $background-light
),
density: -2
)
);
@include mat.all-component-themes($light-theme);
/* Use all-component-colors to only generate the colors */
@include mat.all-component-colors($light-theme);
}
body.dark,
@@ -165,9 +168,9 @@ body .dark {
is-dark: map.get(map.get($base-dark-theme, color), is-dark),
foreground: $foreground-dark,
background: $background-dark
),
density: -2
)
);
/* Use all-component-colors to only generate the colors */
@include mat.all-component-colors($dark-theme);
}

View File

@@ -1,3 +1,3 @@
import { Version } from '@fuse/version/version';
export const FUSE_VERSION = new Version('13.0.2').full;
export const FUSE_VERSION = new Version('13.1.0').full;

View File

@@ -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()
]);
}
}

View File

@@ -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;
}

View 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);
})
);
}
}

View File

@@ -0,0 +1,9 @@
import { FuseNavigationItem } from '@fuse/components/navigation';
export interface Navigation
{
compact: FuseNavigationItem[];
default: FuseNavigationItem[];
futuristic: FuseNavigationItem[];
horizontal: FuseNavigationItem[];
}

View File

@@ -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);
})
);

View File

@@ -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;

View File

@@ -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
{
}

View File

@@ -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
*/

View File

@@ -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);
})
);
}
/**

View File

@@ -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
*/

View File

@@ -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);
})
);
}
/**

View File

@@ -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>

View File

@@ -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);
});
});
}

View File

@@ -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 -->

View File

@@ -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
*/

View File

@@ -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);
})
);
}
/**

View File

@@ -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;

View File

@@ -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
{
}

View File

@@ -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">
@@ -63,13 +63,13 @@
</ng-container>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<languages></languages>
<fuse-fullscreen></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>

View File

@@ -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$

View File

@@ -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 : [

View File

@@ -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>
@@ -46,13 +46,13 @@
</ng-container>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<languages></languages>
<fuse-fullscreen></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>

View File

@@ -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$

View File

@@ -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 : [

View File

@@ -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>
@@ -52,13 +52,13 @@
</ng-container>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<languages></languages>
<fuse-fullscreen></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>

View File

@@ -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$

View File

@@ -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 : [

View File

@@ -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">
@@ -55,13 +55,13 @@
</ng-container>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<languages></languages>
<fuse-fullscreen></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>

View File

@@ -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$

View File

@@ -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 : [

View File

@@ -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>
@@ -36,13 +36,13 @@
</button>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<languages></languages>
<fuse-fullscreen></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>

View File

@@ -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$

View File

@@ -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 : [

View File

@@ -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>
@@ -66,11 +66,11 @@
</button>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<languages></languages>
<fuse-fullscreen></fuse-fullscreen>
<search [appearance]="'bar'"></search>
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>
<messages [messages]="data.messages"></messages>
<shortcuts></shortcuts>
<messages></messages>
</div>
</div>

View File

@@ -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$

View File

@@ -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 : [

View File

@@ -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>
@@ -31,13 +31,13 @@
</button>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<languages></languages>
<fuse-fullscreen></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>

View File

@@ -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$

View File

@@ -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 : [

View File

@@ -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>
@@ -40,13 +40,13 @@
</div>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<languages></languages>
<fuse-fullscreen></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>

View File

@@ -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$

View File

@@ -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 : [

View File

@@ -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
@@ -45,12 +45,12 @@
</button>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<languages></languages>
<fuse-fullscreen></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>

View File

@@ -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$

View File

@@ -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 : [

View File

@@ -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>
@@ -32,13 +32,13 @@
</button>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<languages></languages>
<fuse-fullscreen></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>

View File

@@ -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$

View File

@@ -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 : [

View File

@@ -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
}
];
});

View File

@@ -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
}
];

View File

@@ -0,0 +1,454 @@
import { Injectable } from '@angular/core';
import { assign, cloneDeep } from 'lodash-es';
import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api';
import { boards as boardsData, cards as cardsData, labels as labelsData, lists as listsData, members as membersData } from 'app/mock-api/apps/scrumboard/data';
@Injectable({
providedIn: 'root'
})
export class ScrumboardMockApi
{
// Private
private _boards: any[] = boardsData;
private _cards: any[] = cardsData;
private _labels: any[] = labelsData;
private _lists: any[] = listsData;
private _members: any[] = membersData;
/**
* Constructor
*/
constructor(private _fuseMockApiService: FuseMockApiService)
{
// Register Mock API handlers
this.registerHandlers();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Register Mock API handlers
*/
registerHandlers(): void
{
// -----------------------------------------------------------------------------------------------------
// @ Boards - GET
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onGet('api/apps/scrumboard/boards')
.reply(({request}) => {
// Clone the boards
let boards = cloneDeep(this._boards);
// Go through the boards and inject the members
boards = boards.map(board => ({
...board,
members: board.members.map(boardMember => this._members.find(member => boardMember === member.id))
}));
return [
200,
boards
];
});
// -----------------------------------------------------------------------------------------------------
// @ Board - GET
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onGet('api/apps/scrumboard/board')
.reply(({request}) => {
// Get the id
const id = request.params.get('id');
// Find the board
const board = this._boards.find(item => item.id === id);
// Attach the board lists
board.lists = this._lists.filter(item => item.boardId === id).sort((a, b) => a.position - b.position);
// Grab all cards that belong to this board and attach labels to them
let cards = this._cards.filter(item => item.boardId === id);
cards = cards.map(card => (
{
...card,
labels: card.labels.map(cardLabelId => this._labels.find(label => label.id === cardLabelId))
}
));
// Attach the board cards into corresponding lists
board.lists.forEach((list, index, array) => {
array[index].cards = cards.filter(item => item.boardId === id && item.listId === list.id).sort((a, b) => a.position - b.position);
});
// Attach the board labels
board.labels = this._labels.filter(item => item.boardId === id);
return [
200,
cloneDeep(board)
];
});
// -----------------------------------------------------------------------------------------------------
// @ List - POST
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onPost('api/apps/scrumboard/board/list')
.reply(({request}) => {
// Get the list
const newList = cloneDeep(request.body.list);
// Generate a new GUID
newList.id = FuseMockApiUtils.guid();
// Store the new list
this._lists.push(newList);
return [
200,
newList
];
});
// -----------------------------------------------------------------------------------------------------
// @ List - PATCH
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onPatch('api/apps/scrumboard/board/list')
.reply(({request}) => {
// Get the list
const list = cloneDeep(request.body.list);
// Prepare the updated list
let updatedList = null;
// Find the list and update it
this._lists.forEach((item, index, lists) => {
if ( item.id === list.id )
{
// Update the list
lists[index] = assign({}, lists[index], list);
// Store the updated list
updatedList = lists[index];
}
});
return [
200,
updatedList
];
});
// -----------------------------------------------------------------------------------------------------
// @ Lists - PATCH
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onPatch('api/apps/scrumboard/board/lists')
.reply(({request}) => {
// Get the lists
const lists = cloneDeep(request.body.lists);
// Prepare the updated lists
const updatedLists = [];
// Go through the lists
lists.forEach((item) => {
// Find the list
const index = this._lists.findIndex(list => item.id === list.id);
// Update the list
this._lists[index] = assign({}, this._lists[index], item);
// Store in the updated lists
updatedLists.push(item);
});
return [
200,
updatedLists
];
});
// -----------------------------------------------------------------------------------------------------
// @ List - DELETE
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onDelete('api/apps/scrumboard/board/list')
.reply(({request}) => {
// Get the id
const id = request.params.get('id');
// Find the list and delete it
const index = this._lists.findIndex(item => item.id === id);
this._lists.splice(index, 1);
// Filter out the cards that belonged to the list to delete them
this._cards = this._cards.filter(card => card.listId !== id);
return [
200,
true
];
});
// -----------------------------------------------------------------------------------------------------
// @ Card - PUT
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onPut('api/apps/scrumboard/board/card')
.reply(({request}) => {
// Get the card
const newCard = cloneDeep(request.body.card);
// Generate a new GUID
newCard.id = FuseMockApiUtils.guid();
// Unshift the new card
this._cards.push(newCard);
return [
200,
newCard
];
});
// -----------------------------------------------------------------------------------------------------
// @ Card - PATCH
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onPatch('api/apps/scrumboard/board/card')
.reply(({request}) => {
// Get the id and card
const id = request.body.id;
const card = cloneDeep(request.body.card);
// Prepare the updated card
let updatedCard = null;
// Go through the labels and leave only ids of them
card.labels = card.labels.map(itemLabel => itemLabel.id);
// Find the card and update it
this._cards.forEach((item, index, cards) => {
if ( item.id === id )
{
// Update the card
cards[index] = assign({}, cards[index], card);
// Store the updated card
updatedCard = cloneDeep(cards[index]);
}
});
// Attach the labels of the card
updatedCard.labels = updatedCard.labels.map(cardLabelId => this._labels.find(label => label.id === cardLabelId));
return [
200,
updatedCard
];
});
// -----------------------------------------------------------------------------------------------------
// @ Cards - PATCH
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onPatch('api/apps/scrumboard/board/cards')
.reply(({request}) => {
// Get the cards
const cards = cloneDeep(request.body.cards);
// Prepare the updated cards
const updatedCards = [];
// Go through the cards
cards.forEach((item) => {
// Find the card
const index = this._cards.findIndex(card => item.id === card.id);
// Go through the labels and leave only ids of them
item.labels = item.labels.map(itemLabel => itemLabel.id);
// Update the card
this._cards[index] = assign({}, this._cards[index], item);
// Attach the labels of the card
item.labels = item.labels.map(cardLabelId => this._labels.find(label => label.id === cardLabelId));
// Store in the updated cards
updatedCards.push(item);
});
return [
200,
updatedCards
];
});
// -----------------------------------------------------------------------------------------------------
// @ Card - DELETE
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onDelete('api/apps/scrumboard/board/card')
.reply(({request}) => {
// Get the id
const id = request.params.get('id');
// Find the card and delete it
const index = this._cards.findIndex(item => item.id === id);
this._cards.splice(index, 1);
return [
200,
true
];
});
// -----------------------------------------------------------------------------------------------------
// @ Card Positions - PATCH
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onPatch('api/apps/scrumboard/board/card/positions')
.reply(({request}) => {
// Get the cards
const cards = request.body.cards;
// Go through the cards
this._cards.forEach((card) => {
// Find this card's index within the cards array that comes with the request
// and assign that index as the new position number for the card
card.position = cards.findIndex(item => item.id === card.id && item.listId === card.listId && item.boardId === card.boardId);
});
// Clone the cards
const updatedCards = cloneDeep(this._cards);
return [
200,
updatedCards
];
});
// -----------------------------------------------------------------------------------------------------
// @ Labels - GET
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onGet('api/apps/scrumboard/board/labels')
.reply(({request}) => {
// Get the board id
const boardId = request.params.get('boardId');
// Filter the labels
const labels = this._labels.filter(item => item.boardId === boardId);
return [
200,
cloneDeep(labels)
];
});
// -----------------------------------------------------------------------------------------------------
// @ Label - PUT
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onPut('api/apps/scrumboard/board/label')
.reply(({request}) => {
// Get the label
const newLabel = cloneDeep(request.body.label);
// Generate a new GUID
newLabel.id = FuseMockApiUtils.guid();
// Unshift the new label
this._labels.unshift(newLabel);
return [
200,
newLabel
];
});
// -----------------------------------------------------------------------------------------------------
// @ Label - PATCH
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onPatch('api/apps/scrumboard/board/label')
.reply(({request}) => {
// Get the id and label
const id = request.body.id;
const label = cloneDeep(request.body.label);
// Prepare the updated label
let updatedLabel = null;
// Find the label and update it
this._labels.forEach((item, index, labels) => {
if ( item.id === id )
{
// Update the label
labels[index] = assign({}, labels[index], label);
// Store the updated label
updatedLabel = labels[index];
}
});
return [
200,
updatedLabel
];
});
// -----------------------------------------------------------------------------------------------------
// @ Label - DELETE
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onDelete('api/apps/scrumboard/board/label')
.reply(({request}) => {
// Get the id
const id = request.params.get('id');
// Find the label and delete it
const index = this._labels.findIndex(item => item.id === id);
this._labels.splice(index, 1);
// Get the cards that have the label
const cardsWithLabel = this._cards.filter(card => card.labels.indexOf(id) > -1);
// Iterate through them and remove the label
cardsWithLabel.forEach((card) => {
card.tags.splice(card.tags.indexOf(id), 1);
});
return [
200,
true
];
});
}
}

View File

@@ -0,0 +1,334 @@
/* eslint-disable */
import * as moment from 'moment';
export const boards = [
{
id : '2c82225f-2a6c-45d3-b18a-1132712a4234',
title : 'Admin Dashboard',
description : 'Roadmap for the new project',
icon : 'heroicons_outline:template',
lastActivity: moment().startOf('day').subtract(1, 'day').toISOString(),
members : [
'9c510cf3-460d-4a8c-b3be-bcc3db578c08',
'baa88231-0ee6-4028-96d5-7f187e0f4cd5',
'18bb18f3-ea7d-4465-8913-e8c9adf6f568'
]
},
{
id : '0168b519-3dab-4b46-b2ea-0e678e38a583',
title : 'Weekly Planning',
description : 'Job related tasks for the week',
icon : 'heroicons_outline:calendar',
lastActivity: moment().startOf('day').subtract(2, 'days').toISOString(),
members : [
'79ebb9ee-1e57-4706-810c-03edaec8f56d',
'319ecb5b-f99c-4ee4-81b2-3aeffd1d4735',
'5bf7ed5b-8b04-46b7-b364-005958b7d82e',
'd1f612e6-3e3b-481f-a8a9-f917e243b06e',
'fe0fec0d-002b-406f-87ab-47eb87ba577c',
'23a47d2c-c6cb-40cc-af87-e946a9df5028',
'6726643d-e8dc-42fa-83a6-b4ec06921a6b',
'0d1eb062-13d5-4286-b8d4-e0bea15f3d56'
]
},
{
id : 'bc7db965-3c4f-4233-abf5-69bd70c3c175',
title : 'Personal Tasks',
description : 'Personal tasks around the house',
icon : 'heroicons_outline:home',
lastActivity: moment().startOf('day').subtract(1, 'week').toISOString(),
members : [
'6f6a1c34-390b-4b2e-97c8-ff0e0d787839'
]
}
];
export const lists = [
{
id : 'a2df7786-519c-485a-a85f-c09a61cc5f37',
boardId : '2c82225f-2a6c-45d3-b18a-1132712a4234',
position: 65536,
title : 'To do'
},
{
id : '83ca2a34-65af-49c0-a42e-94a34003fcf2',
boardId : '2c82225f-2a6c-45d3-b18a-1132712a4234',
position: 131072,
title : 'In progress'
},
{
id : 'a85ea483-f8f7-42d9-a314-3fed6aac22ab',
boardId : '2c82225f-2a6c-45d3-b18a-1132712a4234',
position: 196608,
title : 'In review'
},
{
id : '34cbef38-5687-4813-bd66-141a6df6d832',
boardId : '2c82225f-2a6c-45d3-b18a-1132712a4234',
position: 262144,
title : 'Completed'
}
];
export const cards = [
{
id : 'e74e66e9-fe0f-441e-a8ce-28ed6eccc48d',
boardId : '2c82225f-2a6c-45d3-b18a-1132712a4234',
listId : 'a2df7786-519c-485a-a85f-c09a61cc5f37',
position : 65536,
title : 'Example that showcase all of the available bits on the card with a fairly long title compared to other cards',
description: 'Example that showcase all of the available bits on the card with a fairly long title compared to other cards. Example that showcase all of the available bits on the card with a fairly long title compared to other cards.',
labels : [
'e0175175-2784-48f1-a519-a1d2e397c9b3',
'51779701-818a-4a53-bc16-137c3bd7a564',
'e8364d69-9595-46ce-a0f9-ce428632a0ac',
'caff9c9b-a198-4564-b1f4-8b3df1d345bb',
'f9eeb436-13a3-4208-a239-0d555960a567'
],
dueDate : moment().subtract(10, 'days').startOf('day').toISOString()
},
{
id : 'ed58add1-45a7-41db-887d-3ca7ee7f2719',
boardId : '2c82225f-2a6c-45d3-b18a-1132712a4234',
listId : 'a2df7786-519c-485a-a85f-c09a61cc5f37',
position: 131072,
title : 'Do a research about most needed admin applications',
labels : [
'e0175175-2784-48f1-a519-a1d2e397c9b3'
],
dueDate : null
},
{
id : 'cd6897cb-acfd-4016-8b53-3f66a5b5fc68',
boardId : '2c82225f-2a6c-45d3-b18a-1132712a4234',
listId : 'a2df7786-519c-485a-a85f-c09a61cc5f37',
position: 196608,
title : 'Implement the Project dashboard',
labels : [
'caff9c9b-a198-4564-b1f4-8b3df1d345bb'
],
dueDate : moment().startOf('day').toISOString()
},
{
id : '6da8747f-b474-4c9a-9eba-5ef212285500',
boardId : '2c82225f-2a6c-45d3-b18a-1132712a4234',
listId : 'a2df7786-519c-485a-a85f-c09a61cc5f37',
position: 262144,
title : 'Implement the Analytics dashboard',
labels : [
'caff9c9b-a198-4564-b1f4-8b3df1d345bb'
],
dueDate : moment().subtract(1, 'day').startOf('day').toISOString()
},
{
id : '94fb1dee-dd83-4cca-acdd-02e96d3cc4f1',
boardId : '2c82225f-2a6c-45d3-b18a-1132712a4234',
listId : '83ca2a34-65af-49c0-a42e-94a34003fcf2',
position: 65536,
title : 'Analytics dashboard design',
labels : [
'e8364d69-9595-46ce-a0f9-ce428632a0ac'
],
dueDate : null
},
{
id : 'fc16f7d8-957d-43ed-ba85-20f99b5ce011',
boardId : '2c82225f-2a6c-45d3-b18a-1132712a4234',
listId : '83ca2a34-65af-49c0-a42e-94a34003fcf2',
position: 131072,
title : 'Project dashboard design',
labels : [
'e8364d69-9595-46ce-a0f9-ce428632a0ac'
],
dueDate : null
},
{
id : 'c0b32f1f-64ec-4f8d-8b11-a8dc809df331',
boardId : '2c82225f-2a6c-45d3-b18a-1132712a4234',
listId : 'a85ea483-f8f7-42d9-a314-3fed6aac22ab',
position: 65536,
title : 'JWT Auth implementation',
labels : [
'caff9c9b-a198-4564-b1f4-8b3df1d345bb'
],
dueDate : null
},
{
id : '532c2747-be79-464a-9897-6a682bf22b64',
boardId : '2c82225f-2a6c-45d3-b18a-1132712a4234',
listId : '34cbef38-5687-4813-bd66-141a6df6d832',
position: 65536,
title : 'Create low fidelity wireframes',
labels : [],
dueDate : null
},
{
id : '1d908efe-c830-476e-9e87-d06e30d89bc2',
boardId : '2c82225f-2a6c-45d3-b18a-1132712a4234',
listId : '34cbef38-5687-4813-bd66-141a6df6d832',
position: 131072,
title : 'Create high fidelity wireframes',
labels : [],
dueDate : moment().subtract(10, 'day').startOf('day').toISOString()
},
{
id : 'b1da11ed-7896-4826-962d-4b7b718896d4',
boardId : '2c82225f-2a6c-45d3-b18a-1132712a4234',
listId : '34cbef38-5687-4813-bd66-141a6df6d832',
position: 196608,
title : 'Collect information about most used admin layouts',
labels : [
'e0175175-2784-48f1-a519-a1d2e397c9b3'
],
dueDate : null
},
{
id : '3b7f3ceb-107f-42bc-a204-c268c9a56cb4',
boardId : '2c82225f-2a6c-45d3-b18a-1132712a4234',
listId : '34cbef38-5687-4813-bd66-141a6df6d832',
position: 262144,
title : 'Do a research about latest UI trends',
labels : [
'e0175175-2784-48f1-a519-a1d2e397c9b3'
],
dueDate : null
},
{
id : 'cd7f01c5-a941-4076-8cef-37da0354e643',
boardId : '2c82225f-2a6c-45d3-b18a-1132712a4234',
listId : '34cbef38-5687-4813-bd66-141a6df6d832',
position: 327680,
title : 'Learn more about UX',
labels : [
'e0175175-2784-48f1-a519-a1d2e397c9b3'
],
dueDate : null
}
];
export const labels = [
{
id : 'e0175175-2784-48f1-a519-a1d2e397c9b3',
boardId: '2c82225f-2a6c-45d3-b18a-1132712a4234',
title : 'Research'
},
{
id : '51779701-818a-4a53-bc16-137c3bd7a564',
boardId: '2c82225f-2a6c-45d3-b18a-1132712a4234',
title : 'Wireframing'
},
{
id : 'e8364d69-9595-46ce-a0f9-ce428632a0ac',
boardId: '2c82225f-2a6c-45d3-b18a-1132712a4234',
title : 'Design'
},
{
id : 'caff9c9b-a198-4564-b1f4-8b3df1d345bb',
boardId: '2c82225f-2a6c-45d3-b18a-1132712a4234',
title : 'Development'
},
{
id : 'f9eeb436-13a3-4208-a239-0d555960a567',
boardId: '2c82225f-2a6c-45d3-b18a-1132712a4234',
title : 'Bug'
}
];
export const members = [
{
id : '6f6a1c34-390b-4b2e-97c8-ff0e0d787839',
name : 'Angeline Vinson',
avatar: 'assets/images/avatars/female-01.jpg'
},
{
id : '4ce4be48-c8c0-468d-9df8-ddfda14cdb37',
name : 'Roseann Greer',
avatar: 'assets/images/avatars/female-02.jpg'
},
{
id : '9c510cf3-460d-4a8c-b3be-bcc3db578c08',
name : 'Lorraine Barnett',
avatar: 'assets/images/avatars/female-03.jpg'
},
{
id : '7ec887d9-b01a-4057-b5dc-aaed18637cc1',
name : 'Middleton Bradford',
avatar: 'assets/images/avatars/male-01.jpg'
},
{
id : '74975a82-addb-427b-9b43-4d2e03331b68',
name : 'Sue Hays',
avatar: 'assets/images/avatars/female-04.jpg'
},
{
id : '18bb18f3-ea7d-4465-8913-e8c9adf6f568',
name : 'Keith Neal',
avatar: 'assets/images/avatars/male-02.jpg'
},
{
id : 'baa88231-0ee6-4028-96d5-7f187e0f4cd5',
name : 'Wilkins Gilmore',
avatar: 'assets/images/avatars/male-03.jpg'
},
{
id : '0d1eb062-13d5-4286-b8d4-e0bea15f3d56',
name : 'Baldwin Stein',
avatar: 'assets/images/avatars/male-04.jpg'
},
{
id : '5bf7ed5b-8b04-46b7-b364-005958b7d82e',
name : 'Bobbie Cohen',
avatar: 'assets/images/avatars/female-05.jpg'
},
{
id : '93b1a72b-e2db-4f77-82d6-272047433508',
name : 'Melody Peters',
avatar: 'assets/images/avatars/female-06.jpg'
},
{
id : 'd1f612e6-3e3b-481f-a8a9-f917e243b06e',
name : 'Marquez Ryan',
avatar: 'assets/images/avatars/male-05.jpg'
},
{
id : '79ebb9ee-1e57-4706-810c-03edaec8f56d',
name : 'Roberta Briggs',
avatar: 'assets/images/avatars/female-07.jpg'
},
{
id : '6726643d-e8dc-42fa-83a6-b4ec06921a6b',
name : 'Robbie Buckley',
avatar: 'assets/images/avatars/female-08.jpg'
},
{
id : '8af617d7-898e-4992-beda-d5ac1d7ceda4',
name : 'Garcia Whitney',
avatar: 'assets/images/avatars/male-06.jpg'
},
{
id : 'bcff44c4-9943-4adc-9049-08b1d922a658',
name : 'Spencer Pate',
avatar: 'assets/images/avatars/male-07.jpg'
},
{
id : '54160ca2-29c9-4475-88a1-31a9307ad913',
name : 'Monica Mcdaniel',
avatar: 'assets/images/avatars/female-09.jpg'
},
{
id : '51286603-3a43-444e-9242-f51fe57d5363',
name : 'Mcmillan Durham',
avatar: 'assets/images/avatars/male-08.jpg'
},
{
id : '319ecb5b-f99c-4ee4-81b2-3aeffd1d4735',
name : 'Jeoine Hebert',
avatar: 'assets/images/avatars/female-10.jpg'
},
{
id : 'fe0fec0d-002b-406f-87ab-47eb87ba577c',
name : 'Susanna Kline',
avatar: 'assets/images/avatars/female-11.jpg'
},
{
id : '23a47d2c-c6cb-40cc-af87-e946a9df5028',
name : 'Suzette Singleton',
avatar: 'assets/images/avatars/female-12.jpg'
}
];

View File

@@ -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

View File

@@ -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];
});
}
}

View File

@@ -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

View File

@@ -16,6 +16,7 @@ import { NotesMockApi } from 'app/mock-api/apps/notes/api';
import { NotificationsMockApi } from 'app/mock-api/common/notifications/api';
import { ProjectMockApi } from 'app/mock-api/dashboards/project/api';
import { SearchMockApi } from 'app/mock-api/common/search/api';
import { ScrumboardMockApi } from 'app/mock-api/apps/scrumboard/api';
import { ShortcutsMockApi } from 'app/mock-api/common/shortcuts/api';
import { TasksMockApi } from 'app/mock-api/apps/tasks/api';
import { UserMockApi } from 'app/mock-api/common/user/api';
@@ -39,6 +40,7 @@ export const mockApiServices = [
NotificationsMockApi,
ProjectMockApi,
SearchMockApi,
ScrumboardMockApi,
ShortcutsMockApi,
TasksMockApi,
UserMockApi

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1019 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 933 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 647 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Some files were not shown because too many files have changed in this diff Show More