Compare commits

..

31 Commits

Author SHA1 Message Date
sercan
466bf50de4 Increased the version number
Updated the changelog
2021-05-24 14:32:45 +03:00
sercan
95bc7dc4db (apps/ecommerce/inventory) Performance improvements, decreased the mockApi delay 2021-05-24 09:22:18 +03:00
sercan
cfca19dc68 (mockApi) Removed typings from data files 2021-05-23 07:11:58 +03:00
sercan
a0c20f8d59 (pages/settings) Fixed: Settings container component width is not filling the container 2021-05-22 21:14:42 +03:00
sercan
df9f2256cd Increased the version number
Updated the changelog
2021-05-21 12:02:05 +03:00
sercan
6bcd04b799 (eslint) Fixed linting issues 2021-05-21 11:48:42 +03:00
sercan
3c0e326113 (dependencies) Updated various packages to their latest versions 2021-05-21 11:40:50 +03:00
sercan
c7158377f7 Revert "(dependencies) Updated Angular & Angular Material to v12.0.1"
This reverts commit 105575d4
2021-05-20 22:46:40 +03:00
sercan
105575d40e (dependencies) Updated Angular & Angular Material to v12.0.1 2021-05-20 22:23:25 +03:00
sercan
f470313d72 (pages/activities) Couple data tweaks 2021-05-20 16:51:40 +03:00
sercan
60e9c65505 (pages/activities) Couple data and style tweaks 2021-05-20 16:48:38 +03:00
sercan
3b727fe859 (pages/activities) Added Activities page (timeline) 2021-05-20 15:30:14 +03:00
sercan
4694bb401d (layout/common) Added trackBy functions to ngFor loops in common components 2021-05-19 22:43:16 +03:00
sercan
ee86dc6245 (tailwind) Use TAILWIND_MODE environment variable to activate purge on build 2021-05-19 14:45:30 +03:00
sercan
3d09241c64 (fuse/animations) Fixed: Barrel exports
(FuseMasonry) Fixed: Barrel exports
(FuseUtilsService) Fixed: Barrel exports
(FuseValidators) Fixed: Barrel exports
2021-05-19 14:37:38 +03:00
sercan
e499c06884 (apps/mailbox) Small tweak on resolver's comment 2021-05-19 13:38:10 +03:00
sercan
eca618c95b (FuseNavigation) Fixed: If [routerLinkActiveOptions] is "undefined" initially, router throws an error and stops working 2021-05-19 13:37:37 +03:00
sercan
8524df013a (fuse/tailwind) Fixed: Barrel exports are wrong for FuseTailwindService 2021-05-19 10:57:40 +03:00
sercan
e4df408abe (FuseNavigation) Added support for new "isActiveMatchOptions" for Basic navigation items; https://github.com/angular/angular/pull/40303
(docs) Updated FuseNavigation documentation
2021-05-18 16:09:31 +03:00
sercan
fd859a8663 (comments) Fixed: The word 'data' replaced with 'mock-api' by mistake in the past causing a lot of comments to make no sense 2021-05-18 15:18:44 +03:00
sercan
59960af7a5 (MultiLang) Added multi language support using @ngneat/transloco
(docs) Added docs about multi language
2021-05-18 15:11:57 +03:00
sercan
74c4dc2ad8 (app.module.ts) Small tweaks on comments 2021-05-18 14:34:46 +03:00
sercan
f76f38b812 (FuseVerticalNavigation) Added missing return types 2021-05-18 14:12:38 +03:00
sercan
5c40e99518 (FuseNavigation) Use the generic return type for "getComponent"
(docs) Updated FuseNavigation docs
2021-05-18 13:10:39 +03:00
sercan
c1ca701e92 (FuseNavigation) Added a generic return type for "getComponent" method on FuseNavigationService 2021-05-18 13:08:02 +03:00
sercan
e00dda98bc (core) Separated the "auth" and "icon registry" to their own modules to keep the CoreModule simple 2021-05-18 11:44:42 +03:00
sercan
9edc62f703 (eslint) Activate explicit return types on functions and methods 2021-05-18 11:42:36 +03:00
sercan
f9c8e16778 (fuse/mock-api) Added a return type to the factory function 2021-05-17 15:21:08 +03:00
sercan
4a30e3482c (eslint) Removed e2e tsconfig path as there is no default e2e solution included into Angular since v12.0.0 2021-05-16 16:22:40 +03:00
sercan
837f444cc9 (overrides/angular-material) Use @apply whenever it's possible 2021-05-16 15:55:17 +03:00
sercan
d0876eb80c (overrides) Change the text and arrow color of mat-select on focus when it's used as a prefix or suffix in mat-form-field 2021-05-16 15:54:55 +03:00
139 changed files with 1798 additions and 811 deletions

View File

@@ -16,8 +16,7 @@
],
"parserOptions": {
"project": [
"tsconfig.json",
"e2e/tsconfig.json"
"tsconfig.json"
],
"createDefaultProgram": true
},
@@ -44,6 +43,7 @@
}
],
"@typescript-eslint/dot-notation": "off",
"@typescript-eslint/explicit-function-return-type": "error",
"@typescript-eslint/explicit-member-accessibility": [
"off",
{

View File

@@ -2,6 +2,9 @@
// @ 3rd party credits
// -----------------------------------------------------------------------------------------------------
// Flags
https://github.com/Yummygum/flagpack-core
// Icons
Material - https://material.io/tools/icons
Feather - https://feathericons.com/

538
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.0",
"version": "13.0.2",
"license": "https://themeforest.net/licenses/standard",
"private": true,
"scripts": {
@@ -31,13 +31,14 @@
"@fullcalendar/moment": "4.4.2",
"@fullcalendar/rrule": "4.4.2",
"@fullcalendar/timegrid": "4.4.2",
"apexcharts": "3.26.2",
"@ngneat/transloco": "2.20.1",
"apexcharts": "3.26.3",
"crypto-js": "3.3.0",
"highlight.js": "10.7.2",
"lodash-es": "4.17.21",
"moment": "2.29.1",
"ng-apexcharts": "1.5.9",
"ngx-markdown": "11.1.3",
"ng-apexcharts": "1.5.10",
"ngx-markdown": "12.0.0",
"ngx-quill": "14.0.0",
"perfect-scrollbar": "1.5.1",
"quill": "1.3.7",
@@ -67,13 +68,13 @@
"@types/lodash": "4.14.169",
"@types/lodash-es": "4.17.4",
"@types/node": "12.20.13",
"@typescript-eslint/eslint-plugin": "4.23.0",
"@typescript-eslint/parser": "4.23.0",
"@typescript-eslint/eslint-plugin": "4.24.0",
"@typescript-eslint/parser": "4.24.0",
"autoprefixer": "10.2.5",
"chroma-js": "2.1.1",
"chroma-js": "2.1.2",
"eslint": "7.26.0",
"eslint-plugin-import": "2.23.0",
"eslint-plugin-jsdoc": "34.2.2",
"eslint-plugin-import": "2.23.2",
"eslint-plugin-jsdoc": "34.8.2",
"eslint-plugin-prefer-arrow": "1.2.3",
"jasmine-core": "3.7.1",
"jasmine-spec-reporter": "5.0.2",
@@ -83,7 +84,7 @@
"karma-jasmine": "4.0.1",
"karma-jasmine-html-reporter": "1.6.0",
"lodash": "4.17.21",
"postcss": "8.2.15",
"postcss": "8.3.0",
"protractor": "7.0.0",
"tailwindcss": "2.1.2",
"typescript": "4.2.4"

View File

@@ -1 +1 @@
export * from './public-api';
export * from '@fuse/animations/public-api';

View File

@@ -1,8 +1,8 @@
import { expandCollapse } from './expand-collapse';
import { fadeIn, fadeInBottom, fadeInLeft, fadeInRight, fadeInTop, fadeOut, fadeOutBottom, fadeOutLeft, fadeOutRight, fadeOutTop } from './fade';
import { shake } from './shake';
import { slideInBottom, slideInLeft, slideInRight, slideInTop, slideOutBottom, slideOutLeft, slideOutRight, slideOutTop } from './slide';
import { zoomIn, zoomOut } from './zoom';
import { expandCollapse } from '@fuse/animations/expand-collapse';
import { fadeIn, fadeInBottom, fadeInLeft, fadeInRight, fadeInTop, fadeOut, fadeOutBottom, fadeOutLeft, fadeOutRight, fadeOutTop } from '@fuse/animations/fade';
import { shake } from '@fuse/animations/shake';
import { slideInBottom, slideInLeft, slideInRight, slideInTop, slideOutBottom, slideOutLeft, slideOutRight, slideOutTop } from '@fuse/animations/slide';
import { zoomIn, zoomOut } from '@fuse/animations/zoom';
export const fuseAnimations = [
expandCollapse,

View File

@@ -61,9 +61,9 @@ export class FuseDateRangeComponent implements ControlValueAccessor, OnInit, OnD
private _viewContainerRef: ViewContainerRef
)
{
this._onChange = () => {
this._onChange = (): void => {
};
this._onTouched = () => {
this._onTouched = (): void => {
};
this.dateFormat = 'DD/MM/YYYY';
this.timeFormat = '12';
@@ -361,7 +361,7 @@ export class FuseDateRangeComponent implements ControlValueAccessor, OnInit, OnD
this._unsubscribeAll.complete();
// @ TODO: Workaround until "angular/issues/20007" resolved
this.writeValue = () => {
this.writeValue = (): void => {
};
}

View File

@@ -1 +1 @@
export * from '@fuse/components/card/public-api';
export * from '@fuse/components/masonry/public-api';

View File

@@ -11,7 +11,7 @@
[ngClass]="{'fuse-horizontal-navigation-item-active-forced': item.active}"
[routerLink]="[item.link]"
[routerLinkActive]="'fuse-horizontal-navigation-item-active'"
[routerLinkActiveOptions]="{exact: item.exactMatch || false}">
[routerLinkActiveOptions]="isActiveMatchOptions">
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
</div>
@@ -39,7 +39,7 @@
[ngClass]="{'fuse-horizontal-navigation-item-active-forced': item.active}"
[routerLink]="[item.link]"
[routerLinkActive]="'fuse-horizontal-navigation-item-active'"
[routerLinkActiveOptions]="{exact: item.exactMatch || false}"
[routerLinkActiveOptions]="isActiveMatchOptions"
(click)="item.function(item)">
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
</div>

View File

@@ -1,9 +1,11 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
import { IsActiveMatchOptions } from '@angular/router';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseHorizontalNavigationComponent } from '@fuse/components/navigation/horizontal/horizontal.component';
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types';
import { FuseUtilsService } from '@fuse/services/utils/utils.service';
@Component({
selector : 'fuse-horizontal-navigation-basic-item',
@@ -16,6 +18,7 @@ export class FuseHorizontalNavigationBasicItemComponent implements OnInit, OnDes
@Input() item: FuseNavigationItem;
@Input() name: string;
isActiveMatchOptions: IsActiveMatchOptions;
private _fuseHorizontalNavigationComponent: FuseHorizontalNavigationComponent;
private _unsubscribeAll: Subject<any> = new Subject<any>();
@@ -24,9 +27,15 @@ export class FuseHorizontalNavigationBasicItemComponent implements OnInit, OnDes
*/
constructor(
private _changeDetectorRef: ChangeDetectorRef,
private _fuseNavigationService: FuseNavigationService
private _fuseNavigationService: FuseNavigationService,
private _fuseUtilsService: FuseUtilsService
)
{
// Set the equivalent of {exact: false} as default for active match options.
// We are not assigning the item.isActiveMatchOptions directly to the
// [routerLinkActiveOptions] because if it's "undefined" initially, the router
// will throw an error and stop working.
this.isActiveMatchOptions = this._fuseUtilsService.subsetMatchOptions;
}
// -----------------------------------------------------------------------------------------------------
@@ -38,9 +47,20 @@ export class FuseHorizontalNavigationBasicItemComponent implements OnInit, OnDes
*/
ngOnInit(): void
{
// Set the "isActiveMatchOptions" either from item's
// "isActiveMatchOptions" or the equivalent form of
// item's "exactMatch" option
this.isActiveMatchOptions =
this.item.isActiveMatchOptions ?? this.item.exactMatch
? this._fuseUtilsService.exactMatchOptions
: this._fuseUtilsService.subsetMatchOptions;
// Get the parent navigation component
this._fuseHorizontalNavigationComponent = this._fuseNavigationService.getComponent(this.name);
// Mark for check
this._changeDetectorRef.markForCheck();
// Subscribe to onRefreshed on the navigation component
this._fuseHorizontalNavigationComponent.onRefreshed.pipe(
takeUntil(this._unsubscribeAll)

View File

@@ -46,7 +46,7 @@ export class FuseNavigationService
*
* @param name
*/
getComponent(name: string): any
getComponent<T>(name: string): T
{
return this._componentRegistry.get(name);
}

View File

@@ -1,3 +1,5 @@
import { IsActiveMatchOptions } from '@angular/router';
export interface FuseNavigationItem
{
id?: string;
@@ -16,6 +18,7 @@ export interface FuseNavigationItem
link?: string;
externalLink?: boolean;
exactMatch?: boolean;
isActiveMatchOptions?: IsActiveMatchOptions;
function?: (item: FuseNavigationItem) => void;
classes?: {
title?: string;

View File

@@ -11,7 +11,7 @@
[ngClass]="{'fuse-vertical-navigation-item-active-forced': item.active}"
[routerLink]="[item.link]"
[routerLinkActive]="'fuse-vertical-navigation-item-active'"
[routerLinkActiveOptions]="{exact: item.exactMatch || false}">
[routerLinkActiveOptions]="isActiveMatchOptions">
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
</a>
@@ -39,7 +39,7 @@
[ngClass]="{'fuse-vertical-navigation-item-active-forced': item.active}"
[routerLink]="[item.link]"
[routerLinkActive]="'fuse-vertical-navigation-item-active'"
[routerLinkActiveOptions]="{exact: item.exactMatch || false}"
[routerLinkActiveOptions]="isActiveMatchOptions"
(click)="item.function(item)">
<ng-container *ngTemplateOutlet="itemTemplate"></ng-container>
</a>

View File

@@ -1,4 +1,5 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
import { IsActiveMatchOptions } from '@angular/router';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseVerticalNavigationComponent } from '@fuse/components/navigation/vertical/vertical.component';
@@ -17,6 +18,7 @@ export class FuseVerticalNavigationBasicItemComponent implements OnInit, OnDestr
@Input() item: FuseNavigationItem;
@Input() name: string;
isActiveMatchOptions: IsActiveMatchOptions;
private _fuseVerticalNavigationComponent: FuseVerticalNavigationComponent;
private _unsubscribeAll: Subject<any> = new Subject<any>();
@@ -29,6 +31,11 @@ export class FuseVerticalNavigationBasicItemComponent implements OnInit, OnDestr
private _fuseUtilsService: FuseUtilsService
)
{
// Set the equivalent of {exact: false} as default for active match options.
// We are not assigning the item.isActiveMatchOptions directly to the
// [routerLinkActiveOptions] because if it's "undefined" initially, the router
// will throw an error and stop working.
this.isActiveMatchOptions = this._fuseUtilsService.subsetMatchOptions;
}
// -----------------------------------------------------------------------------------------------------
@@ -40,9 +47,20 @@ export class FuseVerticalNavigationBasicItemComponent implements OnInit, OnDestr
*/
ngOnInit(): void
{
// Set the "isActiveMatchOptions" either from item's
// "isActiveMatchOptions" or the equivalent form of
// item's "exactMatch" option
this.isActiveMatchOptions =
this.item.isActiveMatchOptions ?? this.item.exactMatch
? this._fuseUtilsService.exactMatchOptions
: this._fuseUtilsService.subsetMatchOptions;
// Get the parent navigation component
this._fuseVerticalNavigationComponent = this._fuseNavigationService.getComponent(this.name);
// Mark for check
this._changeDetectorRef.markForCheck();
// Subscribe to onRefreshed on the navigation component
this._fuseVerticalNavigationComponent.onRefreshed.pipe(
takeUntil(this._unsubscribeAll)

View File

@@ -73,10 +73,10 @@ export class FuseVerticalNavigationComponent implements OnChanges, OnInit, After
private _fuseUtilsService: FuseUtilsService
)
{
this._handleAsideOverlayClick = () => {
this._handleAsideOverlayClick = (): void => {
this.closeAside();
};
this._handleOverlayClick = () => {
this._handleOverlayClick = (): void => {
this.close();
};
}

View File

@@ -389,7 +389,7 @@ export class FuseScrollbarDirective implements OnChanges, OnInit, OnDestroy
const cosParameter = (oldValue - value) / 2;
const step = (newTimestamp: number) => {
const step = (newTimestamp: number): void => {
scrollCount += Math.PI / (speed / (newTimestamp - oldTimestamp));
newValue = Math.round(value + cosParameter + cosParameter * Math.cos(scrollCount));

View File

@@ -51,7 +51,7 @@ export class FuseMockApiInterceptor implements HttpInterceptor
delay(handler.delay ?? this._defaultDelay ?? 0),
switchMap((response) => {
// If there is no response mock-api,
// If there is no response data,
// throw an error response
if ( !response )
{
@@ -64,7 +64,7 @@ export class FuseMockApiInterceptor implements HttpInterceptor
return throwError(response);
}
// Parse the response mock-api
// Parse the response data
const data = {
status: response[0],
body : response[1]

View File

@@ -29,7 +29,7 @@ export class FuseMockApiModule
{
provide : APP_INITIALIZER,
deps : [...mockApiServices],
useFactory: () => () => null,
useFactory: () => (): any => null,
multi : true
},
{

View File

@@ -1 +1 @@
export * from '@fuse/services/media-watcher/public-api';
export * from '@fuse/services/tailwind/public-api';

View File

@@ -1,2 +1,2 @@
export * from '@fuse/services/media-watcher/media-watcher.module';
export * from '@fuse/services/media-watcher/media-watcher.service';
export * from '@fuse/services/tailwind/tailwind.module';
export * from '@fuse/services/tailwind/tailwind.service';

View File

@@ -1 +1 @@
export * from '@fuse/services/config/public-api';
export * from '@fuse/services/utils/public-api';

View File

@@ -1,4 +1,5 @@
import { Injectable } from '@angular/core';
import { IsActiveMatchOptions } from '@angular/router';
@Injectable({
providedIn: 'root'
@@ -12,6 +13,36 @@ export class FuseUtilsService
{
}
// -----------------------------------------------------------------------------------------------------
// @ Accessors
// -----------------------------------------------------------------------------------------------------
/**
* Get the equivalent "IsActiveMatchOptions" options for "exact = true".
*/
get exactMatchOptions(): IsActiveMatchOptions
{
return {
paths : 'exact',
fragment : 'ignored',
matrixParams: 'ignored',
queryParams : 'exact'
};
}
/**
* Get the equivalent "IsActiveMatchOptions" options for "exact = false".
*/
get subsetMatchOptions(): IsActiveMatchOptions
{
return {
paths : 'subset',
fragment : 'ignored',
matrixParams: 'ignored',
queryParams : 'subset'
};
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------

View File

@@ -178,11 +178,7 @@
/* Add hover and focus style on all buttons */
.mat-button-focus-overlay {
@apply bg-gray-400 bg-opacity-20 #{'!important'};
.dark & {
background-color: rgba(0, 0, 0, 0.05) !important;
}
@apply bg-gray-400 bg-opacity-20 dark:bg-black dark:bg-opacity-5 #{'!important'};
}
/* On palette colored buttons, use a darker color */
@@ -253,11 +249,7 @@
/* Add hover and focus styles */
.mat-button-focus-overlay {
@apply bg-gray-400 bg-opacity-20 #{'!important'};
.dark & {
background-color: rgba(0, 0, 0, 0.05) !important;
}
@apply bg-gray-400 bg-opacity-20 dark:bg-black dark:bg-opacity-5 #{'!important'};
}
/* On primary colored buttons, use the primary color as focus overlay */
@@ -330,19 +322,11 @@
/* Border color */
&:not(.mat-button-disabled) {
@apply border-gray-300 #{'!important'};
.dark & {
@apply border-gray-500 #{'!important'};
}
@apply border-gray-300 dark:border-gray-500 #{'!important'};
}
&.mat-button-disabled {
@apply border-gray-200 #{'!important'};
.dark & {
@apply border-gray-600 #{'!important'};
}
@apply border-gray-200 dark:border-gray-600 #{'!important'};
}
}
@@ -542,13 +526,7 @@
border-radius: 6px;
padding: 0 16px;
border-width: 1px;
background-color: white;
@apply border-gray-300 shadow-sm #{'!important'};
.dark & {
background-color: rgba(0, 0, 0, 0.05) !important;
@apply border-gray-500 #{'!important'};
}
@apply shadow-sm bg-white border-gray-300 dark:bg-black dark:bg-opacity-5 dark:border-gray-500 #{'!important'};
.mat-form-field-prefix {
@@ -633,12 +611,28 @@
@apply icon-size-6;
}
/* Make mat-select usable as */
/* prefix and suffix */
/* Make mat-select usable as prefix and suffix */
.mat-select {
display: flex;
align-items: center;
&:focus {
.mat-select-trigger {
.mat-select-value {
@apply text-primary #{'!important'};
}
.mat-select-arrow-wrapper {
.mat-select-arrow {
border-top-color: var(--fuse-primary) !important;
}
}
}
}
.mat-select-trigger {
display: flex;
align-items: center;
@@ -663,6 +657,7 @@
.mat-select-arrow {
min-height: 0;
@apply text-gray-500 dark:text-gray-400 #{'!important'};
}
}
}
@@ -1032,11 +1027,7 @@
.mat-form-field-prefix,
.mat-form-field-suffix {
@apply border-gray-300 bg-default #{'!important'};
.dark & {
@apply border-gray-500 #{'!important'};
}
@apply bg-default border-gray-300 dark:border-gray-500 #{'!important'};
}
}
}

View File

@@ -1 +1 @@
export * from './public-api';
export * from '@fuse/validators/public-api';

View File

@@ -1 +1 @@
export * from './validators';
export * from '@fuse/validators/validators';

View File

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

View File

@@ -27,18 +27,18 @@ const routerConfig: ExtraOptions = {
BrowserAnimationsModule,
RouterModule.forRoot(appRoutes, routerConfig),
// Fuse & Fuse Mock API
// Fuse, FuseConfig & FuseMockAPI
FuseModule,
FuseConfigModule.forRoot(appConfig),
FuseMockApiModule.forRoot(mockApiServices),
// Core
// Core module of your application
CoreModule,
// Layout
// Layout module of your application
LayoutModule,
// 3rd party modules
// 3rd party modules that require global configuration via forRoot
MarkdownModule.forRoot({})
],
bootstrap : [

View File

@@ -6,6 +6,7 @@ import { InitialDataResolver } from 'app/app.resolvers';
// @formatter:off
/* eslint-disable max-len */
/* eslint-disable @typescript-eslint/explicit-function-return-type */
export const appRoutes: Route[] = [
// Redirect empty path to '/dashboards/project'
@@ -97,6 +98,9 @@ export const appRoutes: Route[] = [
// Pages
{path: 'pages', children: [
// Activities
{path: 'activities', loadChildren: () => import('app/modules/admin/pages/activities/activities.module').then(m => m.ActivitiesModule)},
// Authentication
{path: 'authentication', loadChildren: () => import('app/modules/admin/pages/authentication/authentication.module').then(m => m.AuthenticationModule)},

View File

@@ -0,0 +1,21 @@
import { NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { AuthService } from 'app/core/auth/auth.service';
import { AuthInterceptor } from 'app/core/auth/auth.interceptor';
@NgModule({
imports : [
HttpClientModule
],
providers: [
AuthService,
{
provide : HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi : true
}
]
})
export class AuthModule
{
}

View File

@@ -1,21 +1,13 @@
import { NgModule, Optional, SkipSelf } from '@angular/core';
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { DomSanitizer } from '@angular/platform-browser';
import { MatIconRegistry } from '@angular/material/icon';
import { AuthService } from 'app/core/auth/auth.service';
import { AuthInterceptor } from 'app/core/auth/auth.interceptor';
import { AuthModule } from 'app/core/auth/auth.module';
import { IconsModule } from 'app/core/icons/icons.module';
import { TranslocoCoreModule } from 'app/core/transloco/transloco.module';
@NgModule({
imports : [
HttpClientModule
],
providers: [
AuthService,
{
provide : HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi : true
}
imports: [
AuthModule,
IconsModule,
TranslocoCoreModule
]
})
export class CoreModule
@@ -24,8 +16,6 @@ export class CoreModule
* Constructor
*/
constructor(
private _domSanitizer: DomSanitizer,
private _matIconRegistry: MatIconRegistry,
@Optional() @SkipSelf() parentModule?: CoreModule
)
{
@@ -34,14 +24,5 @@ export class CoreModule
{
throw new Error('CoreModule has already been loaded. Import this module in the AppModule only.');
}
// Register icon sets
this._matIconRegistry.addSvgIconSet(this._domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/material-twotone.svg'));
this._matIconRegistry.addSvgIconSetInNamespace('mat_outline', this._domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/material-outline.svg'));
this._matIconRegistry.addSvgIconSetInNamespace('mat_solid', this._domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/material-solid.svg'));
this._matIconRegistry.addSvgIconSetInNamespace('iconsmind', this._domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/iconsmind.svg'));
this._matIconRegistry.addSvgIconSetInNamespace('feather', this._domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/feather.svg'));
this._matIconRegistry.addSvgIconSetInNamespace('heroicons_outline', this._domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/heroicons-outline.svg'));
this._matIconRegistry.addSvgIconSetInNamespace('heroicons_solid', this._domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/heroicons-solid.svg'));
}
}

View File

@@ -0,0 +1,25 @@
import { NgModule } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { MatIconRegistry } from '@angular/material/icon';
@NgModule()
export class IconsModule
{
/**
* Constructor
*/
constructor(
private _domSanitizer: DomSanitizer,
private _matIconRegistry: MatIconRegistry
)
{
// Register icon sets
this._matIconRegistry.addSvgIconSet(this._domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/material-twotone.svg'));
this._matIconRegistry.addSvgIconSetInNamespace('mat_outline', this._domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/material-outline.svg'));
this._matIconRegistry.addSvgIconSetInNamespace('mat_solid', this._domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/material-solid.svg'));
this._matIconRegistry.addSvgIconSetInNamespace('iconsmind', this._domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/iconsmind.svg'));
this._matIconRegistry.addSvgIconSetInNamespace('feather', this._domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/feather.svg'));
this._matIconRegistry.addSvgIconSetInNamespace('heroicons_outline', this._domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/heroicons-outline.svg'));
this._matIconRegistry.addSvgIconSetInNamespace('heroicons_solid', this._domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/heroicons-solid.svg'));
}
}

View File

@@ -0,0 +1,32 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Translation, TranslocoLoader } from '@ngneat/transloco';
@Injectable({
providedIn: 'root'
})
export class TranslocoHttpLoader implements TranslocoLoader
{
/**
* Constructor
*/
constructor(
private _httpClient: HttpClient)
{
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Get translation
*
* @param lang
*/
getTranslation(lang: string): Observable<Translation>
{
return this._httpClient.get<Translation>(`/assets/i18n/${lang}.json`);
}
}

View File

@@ -0,0 +1,50 @@
import { Translation, TRANSLOCO_CONFIG, TRANSLOCO_LOADER, translocoConfig, TranslocoModule, TranslocoService } from '@ngneat/transloco';
import { APP_INITIALIZER, NgModule } from '@angular/core';
import { environment } from 'environments/environment';
import { TranslocoHttpLoader } from 'app/core/transloco/transloco.http-loader';
@NgModule({
exports : [
TranslocoModule
],
providers: [
{
// Provide the default Transloco configuration
provide : TRANSLOCO_CONFIG,
useValue: translocoConfig({
availableLangs : [
{
id : 'en',
label: 'English'
},
{
id : 'tr',
label: 'Turkish'
}
],
defaultLang : 'en',
reRenderOnLangChange: true,
prodMode : environment.production
})
},
{
// Provide the default Transloco loader
provide : TRANSLOCO_LOADER,
useClass: TranslocoHttpLoader
},
{
// Preload the default language before the app starts to prevent empty/jumping content
provide : APP_INITIALIZER,
deps : [TranslocoService],
useFactory: (translocoService: TranslocoService): any => (): Promise<Translation> => {
const defaultLang = translocoService.getDefaultLang();
translocoService.setActiveLang(defaultLang);
return translocoService.load(defaultLang).toPromise();
},
multi : true
}
]
})
export class TranslocoCoreModule
{
}

View File

@@ -0,0 +1,35 @@
<!-- Button -->
<button
mat-icon-button
[matMenuTriggerFor]="languages">
<ng-container *ngTemplateOutlet="flagImage; context: {$implicit: activeLang}"></ng-container>
</button>
<!-- Language menu -->
<mat-menu
[xPosition]="'before'"
#languages="matMenu">
<ng-container *ngFor="let lang of availableLangs; trackBy: trackByFn">
<button
mat-menu-item
(click)="setActiveLang(lang.id)">
<span class="flex items-center">
<ng-container *ngTemplateOutlet="flagImage; context: {$implicit: lang.id}"></ng-container>
<span class="ml-3">{{lang.label}}</span>
</span>
</button>
</ng-container>
</mat-menu>
<!-- Flag image template -->
<ng-template
let-lang
#flagImage>
<span class="relative w-6 shadow rounded-sm overflow-hidden">
<span class="absolute inset-0 ring-1 ring-inset ring-black ring-opacity-10"></span>
<img
class="w-full"
[src]="'assets/images/flags/' + flagCodes[lang].toUpperCase() + '.svg'"
[alt]="'Flag image for ' + lang">
</span>
</ng-template>

View File

@@ -0,0 +1,153 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { take } from 'rxjs/operators';
import { AvailableLangs, TranslocoService } from '@ngneat/transloco';
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
@Component({
selector : 'language',
templateUrl : './language.component.html',
encapsulation : ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
exportAs : 'language'
})
export class LanguageComponent implements OnInit, OnDestroy
{
availableLangs: AvailableLangs;
activeLang: string;
flagCodes: any;
/**
* Constructor
*/
constructor(
private _changeDetectorRef: ChangeDetectorRef,
private _fuseNavigationService: FuseNavigationService,
private _translocoService: TranslocoService
)
{
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On init
*/
ngOnInit(): void
{
// Get the available languages from transloco
this.availableLangs = this._translocoService.getAvailableLangs();
// Subscribe to language changes
this._translocoService.langChanges$.subscribe((activeLang) => {
// Get the active lang
this.activeLang = activeLang;
// Update the navigation
this._updateNavigation(activeLang);
});
// Set the country iso codes for languages for flags
this.flagCodes = {
'en': 'us',
'tr': 'tr'
};
}
/**
* On destroy
*/
ngOnDestroy(): void
{
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Set the active lang
*
* @param lang
*/
setActiveLang(lang: string): void
{
// Set the active lang
this._translocoService.setActiveLang(lang);
}
/**
* Track by function for ngFor loops
*
* @param index
* @param item
*/
trackByFn(index: number, item: any): any
{
return item.id || index;
}
// -----------------------------------------------------------------------------------------------------
// @ Private methods
// -----------------------------------------------------------------------------------------------------
/**
* Update the navigation
*
* @param lang
* @private
*/
private _updateNavigation(lang: string): void
{
// For the demonstration purposes, we will only update the Dashboard names
// from the navigation but you can do a full swap and change the entire
// navigation data.
//
// You can import the data from a file or request it from your backend,
// it's up to you.
// Get the component -> navigation data -> item
const navComponent = this._fuseNavigationService.getComponent<FuseVerticalNavigationComponent>('mainNavigation');
// Return if the navigation component does not exist
if ( !navComponent )
{
return null;
}
// Get the flat navigation data
const navigation = navComponent.navigation;
// Get the Project dashboard item and update its title
const projectDashboardItem = this._fuseNavigationService.getItem('dashboards.project', navigation);
if ( projectDashboardItem )
{
this._translocoService.selectTranslate('Project').pipe(take(1))
.subscribe((translation) => {
// Set the title
projectDashboardItem.title = translation;
// Refresh the navigation component
navComponent.refresh();
});
}
// Get the Analytics dashboard item and update its title
const analyticsDashboardItem = this._fuseNavigationService.getItem('dashboards.analytics', navigation);
if ( analyticsDashboardItem )
{
this._translocoService.selectTranslate('Analytics').pipe(take(1))
.subscribe((translation) => {
// Set the title
analyticsDashboardItem.title = translation;
// Refresh the navigation component
navComponent.refresh();
});
}
}
}

View File

@@ -0,0 +1,24 @@
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 { SharedModule } from 'app/shared/shared.module';
@NgModule({
declarations: [
LanguageComponent
],
imports : [
MatButtonModule,
MatIconModule,
MatMenuModule,
SharedModule
],
exports : [
LanguageComponent
]
})
export class LanguageModule
{
}

View File

@@ -46,7 +46,7 @@
<!-- Content -->
<div class="relative flex flex-col flex-auto sm:max-h-120 divide-y overflow-y-auto bg-card">
<!-- Messages -->
<ng-container *ngFor="let message of messages">
<ng-container *ngFor="let message of messages; trackBy: trackByFn">
<div
class="flex group hover:bg-gray-50 dark:hover:bg-black dark:hover:bg-opacity-5"
[ngClass]="{'unread': !message.read}">

View File

@@ -155,6 +155,17 @@ export class MessagesComponent implements OnInit, OnChanges, OnDestroy
this._messagesService.delete(message.id).subscribe();
}
/**
* Track by function for ngFor loops
*
* @param index
* @param item
*/
trackByFn(index: number, item: any): any
{
return item.id || index;
}
// -----------------------------------------------------------------------------------------------------
// @ Private methods
// -----------------------------------------------------------------------------------------------------

View File

@@ -46,7 +46,7 @@
<!-- Content -->
<div class="relative flex flex-col flex-auto sm:max-h-120 divide-y overflow-y-auto bg-card">
<!-- Notifications -->
<ng-container *ngFor="let notification of notifications">
<ng-container *ngFor="let notification of notifications; trackBy: trackByFn">
<div
class="flex group hover:bg-gray-50 dark:hover:bg-black dark:hover:bg-opacity-5"
[ngClass]="{'unread': !notification.read}">

View File

@@ -155,6 +155,17 @@ export class NotificationsComponent implements OnChanges, OnInit, OnDestroy
this._notificationsService.delete(notification.id).subscribe();
}
/**
* Track by function for ngFor loops
*
* @param index
* @param item
*/
trackByFn(index: number, item: any): any
{
return item.id || index;
}
// -----------------------------------------------------------------------------------------------------
// @ Private methods
// -----------------------------------------------------------------------------------------------------

View File

@@ -31,7 +31,7 @@
*ngIf="results && !results.length">
No results found!
</mat-option>
<ng-container *ngFor="let result of results">
<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">
@@ -73,7 +73,7 @@
*ngIf="results && !results.length">
No results found!
</mat-option>
<ng-container *ngFor="let result of results">
<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">

View File

@@ -200,4 +200,15 @@ export class SearchComponent implements OnChanges, OnInit, OnDestroy
// Close the search
this.opened = false;
}
/**
* Track by function for ngFor loops
*
* @param index
* @param item
*/
trackByFn(index: number, item: any): any
{
return item.id || index;
}
}

View File

@@ -1,6 +1,6 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { Overlay } from '@angular/cdk/overlay';
import { BlockScrollStrategy, Overlay } from '@angular/cdk/overlay';
import { MAT_AUTOCOMPLETE_SCROLL_STRATEGY, MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatButtonModule } from '@angular/material/button';
import { MatFormFieldModule } from '@angular/material/form-field';
@@ -28,7 +28,7 @@ import { SearchComponent } from 'app/layout/common/search/search.component';
providers : [
{
provide : MAT_AUTOCOMPLETE_SCROLL_STRATEGY,
useFactory: (overlay: Overlay) => () => overlay.scrollStrategies.block(),
useFactory: (overlay: Overlay) => (): BlockScrollStrategy => overlay.scrollStrategies.block(),
deps : [Overlay]
}
]

View File

@@ -94,7 +94,7 @@
<!-- Shortcuts -->
<div class="grid grid-cols-2 grid-flow-row">
<!-- Shortcut -->
<ng-container *ngFor="let shortcut of shortcuts">
<ng-container *ngFor="let shortcut of shortcuts; trackBy: trackByFn">
<div class="relative group flex flex-col overflow-hidden bg-card border-r border-b even:border-r-0 hover:bg-gray-50 dark:hover:bg-black dark:hover:bg-opacity-5">
<ng-container *ngIf="mode === 'modify'">
<div

View File

@@ -176,7 +176,7 @@ export class ShortcutsComponent implements OnChanges, OnInit, OnDestroy
*/
save(): void
{
// Get the mock-api from the form
// Get the data from the form
const shortcut = this.shortcutForm.value;
// If there is an id, update it...
@@ -199,7 +199,7 @@ export class ShortcutsComponent implements OnChanges, OnInit, OnDestroy
*/
delete(): void
{
// Get the mock-api from the form
// Get the data from the form
const shortcut = this.shortcutForm.value;
// Delete
@@ -209,6 +209,17 @@ export class ShortcutsComponent implements OnChanges, OnInit, OnDestroy
this.mode = 'modify';
}
/**
* Track by function for ngFor loops
*
* @param index
* @param item
*/
trackByFn(index: number, item: any): any
{
return item.id || index;
}
// -----------------------------------------------------------------------------------------------------
// @ Private methods
// -----------------------------------------------------------------------------------------------------

View File

@@ -217,7 +217,7 @@ export class LayoutComponent implements OnInit, OnDestroy
const paths = route.pathFromRoot;
paths.forEach((path) => {
// Check if there is a 'layout' mock-api
// Check if there is a 'layout' data
if ( path.routeConfig && path.routeConfig.data && path.routeConfig.data.layout )
{
// Set the layout

View File

@@ -63,6 +63,7 @@
</ng-container>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<fuse-fullscreen></fuse-fullscreen>
<search [appearance]="'bar'"></search>
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>

View File

@@ -3,7 +3,7 @@ import { ActivatedRoute, Data, Router } from '@angular/router';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
import { FuseNavigationService } from '@fuse/components/navigation';
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
import { InitialData } from 'app/app.types';
@Component({
@@ -50,7 +50,7 @@ export class CenteredLayoutComponent implements OnInit, OnDestroy
*/
ngOnInit(): void
{
// Subscribe to the resolved route mock-api
// Subscribe to the resolved route data
this._activatedRoute.data.subscribe((data: Data) => {
this.data = data.initialData;
});
@@ -87,7 +87,7 @@ export class CenteredLayoutComponent implements OnInit, OnDestroy
toggleNavigation(name: string): void
{
// Get the navigation
const navigation = this._fuseNavigationService.getComponent(name);
const navigation = this._fuseNavigationService.getComponent<FuseVerticalNavigationComponent>(name);
if ( navigation )
{

View File

@@ -7,6 +7,7 @@ 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 { 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';
@@ -28,6 +29,7 @@ import { CenteredLayoutComponent } from 'app/layout/layouts/horizontal/centered/
MatMenuModule,
FuseFullscreenModule,
FuseNavigationModule,
LanguageModule,
MessagesModule,
NotificationsModule,
SearchModule,

View File

@@ -46,6 +46,7 @@
</ng-container>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<fuse-fullscreen></fuse-fullscreen>
<search [appearance]="'bar'"></search>
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>

View File

@@ -3,7 +3,7 @@ import { ActivatedRoute, Data, Router } from '@angular/router';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
import { FuseNavigationService } from '@fuse/components/navigation';
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
import { InitialData } from 'app/app.types';
@Component({
@@ -50,7 +50,7 @@ export class EnterpriseLayoutComponent implements OnInit, OnDestroy
*/
ngOnInit(): void
{
// Subscribe to the resolved route mock-api
// Subscribe to the resolved route data
this._activatedRoute.data.subscribe((data: Data) => {
this.data = data.initialData;
});
@@ -87,7 +87,7 @@ export class EnterpriseLayoutComponent implements OnInit, OnDestroy
toggleNavigation(name: string): void
{
// Get the navigation
const navigation = this._fuseNavigationService.getComponent(name);
const navigation = this._fuseNavigationService.getComponent<FuseVerticalNavigationComponent>(name);
if ( navigation )
{

View File

@@ -7,6 +7,7 @@ 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 { 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';
@@ -28,6 +29,7 @@ import { EnterpriseLayoutComponent } from 'app/layout/layouts/horizontal/enterpr
MatMenuModule,
FuseFullscreenModule,
FuseNavigationModule,
LanguageModule,
MessagesModule,
NotificationsModule,
SearchModule,

View File

@@ -52,6 +52,7 @@
</ng-container>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<fuse-fullscreen></fuse-fullscreen>
<search [appearance]="'bar'"></search>
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>

View File

@@ -3,7 +3,7 @@ import { ActivatedRoute, Data, Router } from '@angular/router';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
import { FuseNavigationService } from '@fuse/components/navigation';
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
import { InitialData } from 'app/app.types';
@Component({
@@ -50,7 +50,7 @@ export class MaterialLayoutComponent implements OnInit, OnDestroy
*/
ngOnInit(): void
{
// Subscribe to the resolved route mock-api
// Subscribe to the resolved route data
this._activatedRoute.data.subscribe((data: Data) => {
this.data = data.initialData;
});
@@ -87,7 +87,7 @@ export class MaterialLayoutComponent implements OnInit, OnDestroy
toggleNavigation(name: string): void
{
// Get the navigation
const navigation = this._fuseNavigationService.getComponent(name);
const navigation = this._fuseNavigationService.getComponent<FuseVerticalNavigationComponent>(name);
if ( navigation )
{

View File

@@ -7,6 +7,7 @@ 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 { 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';
@@ -28,6 +29,7 @@ import { MaterialLayoutComponent } from 'app/layout/layouts/horizontal/material/
MatMenuModule,
FuseFullscreenModule,
FuseNavigationModule,
LanguageModule,
MessagesModule,
NotificationsModule,
SearchModule,

View File

@@ -55,6 +55,7 @@
</ng-container>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<fuse-fullscreen></fuse-fullscreen>
<search [appearance]="'bar'"></search>
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>

View File

@@ -3,7 +3,7 @@ import { ActivatedRoute, Data, Router } from '@angular/router';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
import { FuseNavigationService } from '@fuse/components/navigation';
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
import { InitialData } from 'app/app.types';
@Component({
@@ -50,7 +50,7 @@ export class ModernLayoutComponent implements OnInit, OnDestroy
*/
ngOnInit(): void
{
// Subscribe to the resolved route mock-api
// Subscribe to the resolved route data
this._activatedRoute.data.subscribe((data: Data) => {
this.data = data.initialData;
});
@@ -87,7 +87,7 @@ export class ModernLayoutComponent implements OnInit, OnDestroy
toggleNavigation(name: string): void
{
// Get the navigation
const navigation = this._fuseNavigationService.getComponent(name);
const navigation = this._fuseNavigationService.getComponent<FuseVerticalNavigationComponent>(name);
if ( navigation )
{

View File

@@ -7,6 +7,7 @@ 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 { 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';
@@ -28,6 +29,7 @@ import { ModernLayoutComponent } from 'app/layout/layouts/horizontal/modern/mode
MatMenuModule,
FuseFullscreenModule,
FuseNavigationModule,
LanguageModule,
MessagesModule,
NotificationsModule,
SearchModule,

View File

@@ -36,6 +36,7 @@
</button>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<fuse-fullscreen></fuse-fullscreen>
<search [appearance]="'bar'"></search>
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>

View File

@@ -3,7 +3,7 @@ import { ActivatedRoute, Data, Router } from '@angular/router';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
import { FuseNavigationService } from '@fuse/components/navigation';
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
import { InitialData } from 'app/app.types';
@Component({
@@ -50,7 +50,7 @@ export class ClassicLayoutComponent implements OnInit, OnDestroy
*/
ngOnInit(): void
{
// Subscribe to the resolved route mock-api
// Subscribe to the resolved route data
this._activatedRoute.data.subscribe((data: Data) => {
this.data = data.initialData;
});
@@ -87,7 +87,7 @@ export class ClassicLayoutComponent implements OnInit, OnDestroy
toggleNavigation(name: string): void
{
// Get the navigation
const navigation = this._fuseNavigationService.getComponent(name);
const navigation = this._fuseNavigationService.getComponent<FuseVerticalNavigationComponent>(name);
if ( navigation )
{

View File

@@ -7,6 +7,7 @@ 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 { 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';
@@ -28,6 +29,7 @@ import { ClassicLayoutComponent } from 'app/layout/layouts/vertical/classic/clas
MatMenuModule,
FuseFullscreenModule,
FuseNavigationModule,
LanguageModule,
MessagesModule,
NotificationsModule,
SearchModule,

View File

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

View File

@@ -3,7 +3,7 @@ import { ActivatedRoute, Data, Router } from '@angular/router';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
import { FuseNavigationService } from '@fuse/components/navigation';
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
import { InitialData } from 'app/app.types';
@Component({
@@ -50,7 +50,7 @@ export class ClassyLayoutComponent implements OnInit, OnDestroy
*/
ngOnInit(): void
{
// Subscribe to the resolved route mock-api
// Subscribe to the resolved route data
this._activatedRoute.data.subscribe((data: Data) => {
this.data = data.initialData;
});
@@ -87,7 +87,7 @@ export class ClassyLayoutComponent implements OnInit, OnDestroy
toggleNavigation(name: string): void
{
// Get the navigation
const navigation = this._fuseNavigationService.getComponent(name);
const navigation = this._fuseNavigationService.getComponent<FuseVerticalNavigationComponent>(name);
if ( navigation )
{

View File

@@ -7,6 +7,7 @@ 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 { 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';
@@ -28,6 +29,7 @@ import { ClassyLayoutComponent } from 'app/layout/layouts/vertical/classy/classy
MatMenuModule,
FuseFullscreenModule,
FuseNavigationModule,
LanguageModule,
MessagesModule,
NotificationsModule,
SearchModule,

View File

@@ -31,6 +31,7 @@
</button>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<fuse-fullscreen></fuse-fullscreen>
<search [appearance]="'bar'"></search>
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>

View File

@@ -3,7 +3,7 @@ import { ActivatedRoute, Data, Router } from '@angular/router';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
import { FuseNavigationService } from '@fuse/components/navigation';
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
import { InitialData } from 'app/app.types';
@Component({
@@ -50,7 +50,7 @@ export class CompactLayoutComponent implements OnInit, OnDestroy
*/
ngOnInit(): void
{
// Subscribe to the resolved route mock-api
// Subscribe to the resolved route data
this._activatedRoute.data.subscribe((data: Data) => {
this.data = data.initialData;
});
@@ -87,7 +87,7 @@ export class CompactLayoutComponent implements OnInit, OnDestroy
toggleNavigation(name: string): void
{
// Get the navigation
const navigation = this._fuseNavigationService.getComponent(name);
const navigation = this._fuseNavigationService.getComponent<FuseVerticalNavigationComponent>(name);
if ( navigation )
{

View File

@@ -7,6 +7,7 @@ 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 { 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';
@@ -28,6 +29,7 @@ import { CompactLayoutComponent } from 'app/layout/layouts/vertical/compact/comp
MatMenuModule,
FuseFullscreenModule,
FuseNavigationModule,
LanguageModule,
MessagesModule,
NotificationsModule,
SearchModule,

View File

@@ -40,6 +40,7 @@
</div>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<fuse-fullscreen></fuse-fullscreen>
<search [appearance]="'bar'"></search>
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>

View File

@@ -3,7 +3,7 @@ import { ActivatedRoute, Data, Router } from '@angular/router';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
import { FuseNavigationService } from '@fuse/components/navigation';
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
import { InitialData } from 'app/app.types';
@Component({
@@ -51,7 +51,7 @@ export class DenseLayoutComponent implements OnInit, OnDestroy
*/
ngOnInit(): void
{
// Subscribe to the resolved route mock-api
// Subscribe to the resolved route data
this._activatedRoute.data.subscribe((data: Data) => {
this.data = data.initialData;
});
@@ -88,7 +88,7 @@ export class DenseLayoutComponent implements OnInit, OnDestroy
toggleNavigation(name: string): void
{
// Get the navigation
const navigation = this._fuseNavigationService.getComponent(name);
const navigation = this._fuseNavigationService.getComponent<FuseVerticalNavigationComponent>(name);
if ( navigation )
{

View File

@@ -7,6 +7,7 @@ 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 { 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';
@@ -28,6 +29,7 @@ import { DenseLayoutComponent } from 'app/layout/layouts/vertical/dense/dense.co
MatMenuModule,
FuseFullscreenModule,
FuseNavigationModule,
LanguageModule,
MessagesModule,
NotificationsModule,
SearchModule,

View File

@@ -45,6 +45,7 @@
</button>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<fuse-fullscreen></fuse-fullscreen>
<search [appearance]="'bar'"></search>
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>

View File

@@ -3,7 +3,7 @@ import { ActivatedRoute, Data, Router } from '@angular/router';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
import { FuseNavigationService } from '@fuse/components/navigation';
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
import { InitialData } from 'app/app.types';
@Component({
@@ -50,7 +50,7 @@ export class FuturisticLayoutComponent implements OnInit, OnDestroy
*/
ngOnInit(): void
{
// Subscribe to the resolved route mock-api
// Subscribe to the resolved route data
this._activatedRoute.data.subscribe((data: Data) => {
this.data = data.initialData;
});
@@ -87,7 +87,7 @@ export class FuturisticLayoutComponent implements OnInit, OnDestroy
toggleNavigation(name: string): void
{
// Get the navigation
const navigation = this._fuseNavigationService.getComponent(name);
const navigation = this._fuseNavigationService.getComponent<FuseVerticalNavigationComponent>(name);
if ( navigation )
{

View File

@@ -7,6 +7,7 @@ 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 { 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';
@@ -28,6 +29,7 @@ import { FuturisticLayoutComponent } from 'app/layout/layouts/vertical/futuristi
MatMenuModule,
FuseFullscreenModule,
FuseNavigationModule,
LanguageModule,
MessagesModule,
NotificationsModule,
SearchModule,

View File

@@ -32,6 +32,7 @@
</button>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-2">
<language></language>
<fuse-fullscreen></fuse-fullscreen>
<search [appearance]="'bar'"></search>
<shortcuts [shortcuts]="data.shortcuts"></shortcuts>

View File

@@ -3,7 +3,7 @@ import { ActivatedRoute, Data, Router } from '@angular/router';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
import { FuseNavigationService } from '@fuse/components/navigation';
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
import { InitialData } from 'app/app.types';
@Component({
@@ -50,7 +50,7 @@ export class ThinLayoutComponent implements OnInit, OnDestroy
*/
ngOnInit(): void
{
// Subscribe to the resolved route mock-api
// Subscribe to the resolved route data
this._activatedRoute.data.subscribe((data: Data) => {
this.data = data.initialData;
});
@@ -87,7 +87,7 @@ export class ThinLayoutComponent implements OnInit, OnDestroy
toggleNavigation(name: string): void
{
// Get the navigation
const navigation = this._fuseNavigationService.getComponent(name);
const navigation = this._fuseNavigationService.getComponent<FuseVerticalNavigationComponent>(name);
if ( navigation )
{

View File

@@ -7,6 +7,7 @@ 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 { 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';
@@ -28,6 +29,7 @@ import { ThinLayoutComponent } from 'app/layout/layouts/vertical/thin/thin.compo
MatMenuModule,
FuseFullscreenModule,
FuseNavigationModule,
LanguageModule,
MessagesModule,
NotificationsModule,
SearchModule,

View File

@@ -295,12 +295,12 @@ export class ContactsMockApi
const reader = new FileReader();
// Resolve the promise on success
reader.onload = () => {
reader.onload = (): void => {
resolve(reader.result);
};
// Reject the promise on error
reader.onerror = (e) => {
reader.onerror = (e): void => {
reject(e);
};

View File

@@ -50,7 +50,7 @@ export class ECommerceInventoryMockApi
// @ Products - GET
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onGet('api/apps/ecommerce/inventory/products', 625)
.onGet('api/apps/ecommerce/inventory/products', 300)
.reply(({request}) => {
// Get available queries

View File

@@ -1,8 +1,7 @@
/* eslint-disable */
import * as moment from 'moment';
import { Message } from 'app/layout/common/messages/messages.types';
export const messages: Message[] = [
export const messages = [
{
id : '832276cc-c5e9-4fcc-8e23-d38e2e267bc9',
image : 'assets/images/avatars/male-01.jpg',

View File

@@ -151,6 +151,13 @@ export const defaultNavigation: FuseNavigationItem[] = [
type : 'group',
icon : 'heroicons_outline:document',
children: [
{
id : 'pages.activities',
title: 'Activities',
type : 'basic',
icon : 'heroicons_outline:menu-alt-2',
link : '/pages/activities'
},
{
id : 'pages.authentication',
title : 'Authentication',
@@ -920,7 +927,7 @@ export const defaultNavigation: FuseNavigationItem[] = [
icon : 'heroicons_outline:speakerphone',
link : '/docs/changelog',
badge: {
title : '13.0.0',
title : '13.0.2',
classes: 'px-2 bg-yellow-300 text-black rounded-full'
}
},

View File

@@ -1,8 +1,7 @@
/* eslint-disable */
import * as moment from 'moment';
import { Notification } from 'app/layout/common/notifications/notifications.types';
export const notifications: Notification[] = [
export const notifications = [
{
id : '493190c9-5b61-4912-afe5-78c21f1044d7',
icon : 'heroicons_outline:star',

View File

@@ -1,7 +1,5 @@
/* eslint-disable */
import { Shortcut } from 'app/layout/common/shortcuts/shortcuts.types';
export const shortcuts: Shortcut[] = [
export const shortcuts = [
{
id : 'a1ae91d3-e2cb-459b-9be9-a184694f548b',
label : 'Changelog',

View File

@@ -1,5 +1,5 @@
/* eslint-disable */
export const user: any = {
export const user = {
id : 'cfaad35d-07a3-4447-a6c3-d8c3d54fd5df',
name : 'Brian Hughes',
email : 'hughes.brian@company.com',

View File

@@ -1,4 +1,5 @@
import { AcademyMockApi } from 'app/mock-api/apps/academy/api';
import { ActivitiesMockApi } from 'app/mock-api/pages/activities/api';
import { AnalyticsMockApi } from 'app/mock-api/dashboards/analytics/api';
import { AuthMockApi } from 'app/mock-api/common/auth/api';
import { CalendarMockApi } from 'app/mock-api/apps/calendar/api';
@@ -21,6 +22,7 @@ import { UserMockApi } from 'app/mock-api/common/user/api';
export const mockApiServices = [
AcademyMockApi,
ActivitiesMockApi,
AnalyticsMockApi,
AuthMockApi,
CalendarMockApi,

View File

@@ -0,0 +1,38 @@
import { Injectable } from '@angular/core';
import { cloneDeep } from 'lodash-es';
import { FuseMockApiService } from '@fuse/lib/mock-api';
import { activities as activitiesData } from 'app/mock-api/pages/activities/data';
@Injectable({
providedIn: 'root'
})
export class ActivitiesMockApi
{
private _activities: any = activitiesData;
/**
* Constructor
*/
constructor(private _fuseMockApiService: FuseMockApiService)
{
// Register Mock API handlers
this.registerHandlers();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Register Mock API handlers
*/
registerHandlers(): void
{
// -----------------------------------------------------------------------------------------------------
// @ Activities - GET
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onGet('api/pages/activities')
.reply(() => [200, cloneDeep(this._activities)]);
}
}

View File

@@ -0,0 +1,88 @@
/* eslint-disable */
import * as moment from 'moment';
export const activities = [
{
id : '493190c9-5b61-4912-afe5-78c21f1044d7',
icon : 'heroicons_solid:star',
description : 'Your submission has been accepted',
date : moment().subtract(25, 'minutes').toISOString(), // 25 minutes ago
extraContent: `<div class="font-bold">Congratulations for your acceptance!</div><br>
<div>Hi Brian,<br>Your submission has been accepted and you are ready to move into the next phase. Once you are ready, reach out to me and we will ...</div>`
},
{
id : '6e3e97e5-effc-4fb7-b730-52a151f0b641',
image : 'assets/images/avatars/male-04.jpg',
description : '<strong>Leo Gill</strong> added you to <strong>Top Secret Project</strong> group and assigned you as a <strong>Project Manager</strong>',
date : moment().subtract(50, 'minutes').toISOString(), // 50 minutes ago
linkedContent: 'Top Secret Project',
link : '/dashboards/project',
useRouter : true
},
{
id : 'b91ccb58-b06c-413b-b389-87010e03a120',
icon : 'heroicons_solid:mail',
description : 'You have 15 unread mails across 3 mailboxes',
date : moment().subtract(3, 'hours').toISOString(), // 3 hours ago
linkedContent: 'Mailbox',
link : '/apps/mailbox',
useRouter : true
},
{
id : '541416c9-84a7-408a-8d74-27a43c38d797',
icon : 'heroicons_solid:refresh',
description : 'Your <strong>Docker container</strong> is ready to publish',
date : moment().subtract(5, 'hours').toISOString(), // 5 hours ago
linkedContent: 'Download the container',
link : '.',
useRouter : true
},
{
id : 'ef7b95a7-8e8b-4616-9619-130d9533add9',
image : 'assets/images/avatars/male-06.jpg',
description : '<strong>Roger Murray</strong> accepted your friend request',
date : moment().subtract(7, 'hours').toISOString(), // 7 hours ago
extraContent: `You have <span class="font-semibold">8</span> mutual friends.`
},
{
id : 'eb8aa470-635e-461d-88e1-23d9ea2a5665',
image : 'assets/images/avatars/female-04.jpg',
description: '<strong>Sophie Stone</strong> sent you a direct message',
date : moment().subtract(9, 'hours').toISOString() // 9 hours ago
},
{
id : 'b85c2338-cc98-4140-bbf8-c226ce4e395e',
icon : 'heroicons_solid:mail',
description : 'You have 3 new mails',
date : moment().subtract(1, 'day').toISOString(), // 1 day ago
extraContent : `<ol class="list-decimal list-inside space-y-2">
<li class="font-medium">Please review and sign the attached agreement</li>
<li class="font-medium">Delivery address confirmation</li>
<li class="font-medium">Previous clients and their invoices</li>
</ol>`,
linkedContent: 'Mailbox',
link : '/apps/mailbox',
useRouter : true
},
{
id : 'fd0f01b4-f3de-4333-add5-cd86850279f8',
image : 'assets/images/avatars/female-02.jpg',
description : '<strong>Tina Harris</strong> started a chat with you',
date : moment().subtract(1, 'day').toISOString(), // 1 day ago,
linkedContent: 'Go to Chat (Tina Harris)',
link : '/apps/chat/5636c0ba-fa47-42ca-9160-27340583041e',
useRouter : true
},
{
id : '8f8e1bf9-4661-4939-9e43-390957b60f42',
icon : 'heroicons_solid:star',
description: 'Your submission has been accepted and you are ready to sign-up for the final assigment which will be ready in 2 days',
date : moment().subtract(3, 'days').toISOString() // 3 days ago
},
{
id : '30af917b-7a6a-45d1-822f-9e7ad7f8bf69',
icon : 'heroicons_solid:refresh',
description: 'Your Vagrant container is ready to download',
date : moment().subtract(4, 'day').toISOString() // 4 days ago
}
];

View File

@@ -243,8 +243,8 @@ export class CalendarComponent implements OnInit, AfterViewInit, OnDestroy
day : 'numeric',
omitCommas: true
},
columnHeaderHtml : date => `<span class="fc-weekday">${moment(date).format('ddd')}</span>
<span class="fc-date">${moment(date).format('D')}</span>`,
columnHeaderHtml : (date): string => `<span class="fc-weekday">${moment(date).format('ddd')}</span>
<span class="fc-date">${moment(date).format('D')}</span>`,
slotDuration : '01:00:00',
slotLabelFormat : this.eventTimeFormat
},
@@ -271,7 +271,7 @@ export class CalendarComponent implements OnInit, AfterViewInit, OnDestroy
this.viewTitle = this._fullCalendarApi.view.title;
// Get the view's current start and end dates, add/subtract
// 60 days to create a ~150 days period to fetch the mock-api for
// 60 days to create a ~150 days period to fetch the data for
const viewStart = moment(this._fullCalendarApi.view.currentStart).subtract(60, 'days');
const viewEnd = moment(this._fullCalendarApi.view.currentEnd).add(60, 'days');

View File

@@ -265,7 +265,7 @@ export class CalendarService
// Return if remaining days is bigger than the number
// of days to prefetch. This means we were already been
// there and fetched the events mock-api so no need for doing
// there and fetched the events data so no need for doing
// it again.
if ( remainingDays >= this._numberOfDaysToPrefetch )
{
@@ -292,7 +292,7 @@ export class CalendarService
// Return if remaining days is bigger than the number
// of days to prefetch. This means we were already been
// there and fetched the events mock-api so no need for doing
// there and fetched the events data so no need for doing
// it again.
if ( remainingDays >= this._numberOfDaysToPrefetch )
{

View File

@@ -221,6 +221,14 @@
mat-cell
*matCellDef="let product"
[attr.colspan]="productsTableColumns.length">
<ng-container *ngIf="selectedProduct?.id === product.id">
<ng-container *ngTemplateOutlet="rowDetailsTemplate; context: {$implicit: product}"></ng-container>
</ng-container>
</td>
<ng-template
#rowDetailsTemplate
let-product>
<div
class="shadow-lg overflow-hidden"
[@expandCollapse]="selectedProduct?.id === product.id ? 'expanded' : 'collapsed'">
@@ -403,7 +411,7 @@
<!-- Tags -->
<ng-container *ngIf="selectedProduct && selectedProduct.tags.length">
<span class="font-semibold">Tags</span>
<div class="mt-1 rounded-md border shadow-sm overflow-hidden">
<div class="mt-1 rounded-md border border-gray-300 shadow-sm overflow-hidden">
<!-- Header -->
<div class="flex items-center my-2 mx-3">
<div class="flex items-center flex-auto min-w-0">
@@ -525,7 +533,7 @@
</form>
</div>
</div>
</td>
</ng-template>
</ng-container>
<tr

View File

@@ -239,9 +239,6 @@ export class InventoryListComponent implements OnInit, AfterViewInit, OnDestroy
// Set the selected product
this.selectedProduct = product;
// Mark for check
this._changeDetectorRef.markForCheck();
// Fill the form
this.selectedProductForm.patchValue(product);
@@ -484,7 +481,7 @@ export class InventoryListComponent implements OnInit, AfterViewInit, OnDestroy
}
/**
* Update the selected product using the form mock-api
* Update the selected product using the form data
*/
updateSelectedProduct(): void
{
@@ -503,7 +500,7 @@ export class InventoryListComponent implements OnInit, AfterViewInit, OnDestroy
}
/**
* Delete the selected product using the form mock-api
* Delete the selected product using the form data
*/
deleteSelectedProduct(): void
{

View File

@@ -155,11 +155,11 @@ export class MailboxMailsResolver implements Resolve<any>
.pipe(
finalize(() => {
// Reset the mail every time mails list changes,
// if there is no selected mail. This will ensure
// that the mail will be reset while navigating
// between the folders/filters/labels but it won't
// reset on page reload if we are reading a mail.
// If there is no selected mail, reset the mail every
// time mail list changes. This will ensure that the
// mail will be reset while navigating between the
// folders/filters/labels but it won't reset on page
// reload if we are reading a mail.
// Try to get the current activated route
let currentRoute = route;

View File

@@ -2,7 +2,7 @@ import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseNavigationItem, FuseNavigationService } from '@fuse/components/navigation';
import { FuseNavigationItem, FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
import { MailboxService } from 'app/modules/admin/apps/mailbox/mailbox.service';
import { MailboxComposeComponent } from 'app/modules/admin/apps/mailbox/compose/compose.component';
import { labelColorDefs } from 'app/modules/admin/apps/mailbox/mailbox.constants';
@@ -122,7 +122,7 @@ export class MailboxSidebarComponent implements OnInit, OnDestroy
*/
private _generateFoldersMenuLinks(): void
{
// Reset the folders menu mock-api
// Reset the folders menu data
this._foldersMenuData = [];
// Iterate through the folders
@@ -146,11 +146,11 @@ export class MailboxSidebarComponent implements OnInit, OnDestroy
};
}
// Push the menu item to the folders menu mock-api
// Push the menu item to the folders menu data
this._foldersMenuData.push(menuItem);
});
// Update the menu mock-api
// Update the menu data
this._updateMenuData();
}
@@ -177,7 +177,7 @@ export class MailboxSidebarComponent implements OnInit, OnDestroy
});
});
// Update the menu mock-api
// Update the menu data
this._updateMenuData();
}
@@ -207,7 +207,7 @@ export class MailboxSidebarComponent implements OnInit, OnDestroy
});
});
// Update the menu mock-api
// Update the menu data
this._updateMenuData();
}
@@ -226,12 +226,12 @@ export class MailboxSidebarComponent implements OnInit, OnDestroy
link : '/apps/mailbox/settings'
});
// Update the menu mock-api
// Update the menu data
this._updateMenuData();
}
/**
* Update the menu mock-api
* Update the menu data
*
* @private
*/
@@ -278,8 +278,8 @@ export class MailboxSidebarComponent implements OnInit, OnDestroy
// Get the inbox folder
const inboxFolder = this.folders.find(folder => folder.slug === 'inbox');
// Get the component -> navigation mock-api -> item
const mainNavigationComponent = this._fuseNavigationService.getComponent('mainNavigation');
// Get the component -> navigation data -> item
const mainNavigationComponent = this._fuseNavigationService.getComponent<FuseVerticalNavigationComponent>('mainNavigation');
// If the main navigation component exists...
if ( mainNavigationComponent )

View File

@@ -330,12 +330,12 @@ export class NotesDetailsComponent implements OnInit, OnDestroy
const reader = new FileReader();
// Resolve the promise on success
reader.onload = () => {
reader.onload = (): void => {
resolve(reader.result);
};
// Reject the promise on error
reader.onerror = (e) => {
reader.onerror = (e): void => {
reject(e);
};

View File

@@ -10,7 +10,7 @@ import { MatMenuModule } from '@angular/material/menu';
import { MatRippleModule } from '@angular/material/core';
import { MatSidenavModule } from '@angular/material/sidenav';
import { FuseAutogrowModule } from '@fuse/directives/autogrow';
import { FuseMasonryModule } from '@fuse/components/masonry/masonry.module';
import { FuseMasonryModule } from '@fuse/components/masonry';
import { SharedModule } from 'app/shared/shared.module';
import { NotesComponent } from 'app/modules/admin/apps/notes/notes.component';
import { NotesDetailsComponent } from 'app/modules/admin/apps/notes/details/details.component';

View File

@@ -6,7 +6,7 @@ import { MatDrawer } from '@angular/material/sidenav';
import { fromEvent, Subject } from 'rxjs';
import { filter, takeUntil } from 'rxjs/operators';
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
import { FuseNavigationService } from '@fuse/components/navigation';
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
import { Tag, Task } from 'app/modules/admin/apps/tasks/tasks.types';
import { TasksService } from 'app/modules/admin/apps/tasks/tasks.service';
@@ -83,7 +83,7 @@ export class TasksListComponent implements OnInit, OnDestroy
setTimeout(() => {
// Get the component -> navigation data -> item
const mainNavigationComponent = this._fuseNavigationService.getComponent('mainNavigation');
const mainNavigationComponent = this._fuseNavigationService.getComponent<FuseVerticalNavigationComponent>('mainNavigation');
// If the main navigation component exists...
if ( mainNavigationComponent )

View File

@@ -70,10 +70,10 @@ export class AnalyticsComponent implements OnInit, OnDestroy
window['Apex'] = {
chart: {
events: {
mounted: (chart: any, options?: any) => {
mounted: (chart: any, options?: any): void => {
this._fixSvgFill(chart.el);
},
updated: (chart: any, options?: any) => {
updated: (chart: any, options?: any): void => {
this._fixSvgFill(chart.el);
}
}
@@ -234,8 +234,8 @@ export class AnalyticsComponent implements OnInit, OnDestroy
axisBorder: {
show: false
},
min : min => min - 750,
max : max => max + 250,
min : (min): number => min - 750,
max : (max): number => max + 250,
tickAmount: 5,
show : false
}
@@ -274,7 +274,7 @@ export class AnalyticsComponent implements OnInit, OnDestroy
},
yaxis : {
labels: {
formatter: val => val.toString()
formatter: (val): string => val.toString()
}
}
};
@@ -312,7 +312,7 @@ export class AnalyticsComponent implements OnInit, OnDestroy
},
yaxis : {
labels: {
formatter: val => val.toString()
formatter: (val): string => val.toString()
}
}
};
@@ -350,7 +350,7 @@ export class AnalyticsComponent implements OnInit, OnDestroy
},
yaxis : {
labels: {
formatter: val => val.toString()
formatter: (val): string => val.toString()
}
}
};
@@ -426,8 +426,8 @@ export class AnalyticsComponent implements OnInit, OnDestroy
colors: 'var(--fuse-text-secondary)'
}
},
max : max => max + 250,
min : min => min - 250,
max : (max): number => max + 250,
min : (min): number => min - 250,
show : false,
tickAmount: 5
}
@@ -481,11 +481,11 @@ export class AnalyticsComponent implements OnInit, OnDestroy
custom : ({
seriesIndex,
w
}) => `<div class="flex items-center h-8 min-h-8 max-h-8 px-3">
<div class="w-3 h-3 rounded-full" style="background-color: ${w.config.colors[seriesIndex]};"></div>
<div class="ml-2 text-md leading-none">${w.config.labels[seriesIndex]}:</div>
<div class="ml-2 text-md font-bold leading-none">${w.config.series[seriesIndex]}%</div>
</div>`
}): string => `<div class="flex items-center h-8 min-h-8 max-h-8 px-3">
<div class="w-3 h-3 rounded-full" style="background-color: ${w.config.colors[seriesIndex]};"></div>
<div class="ml-2 text-md leading-none">${w.config.labels[seriesIndex]}:</div>
<div class="ml-2 text-md font-bold leading-none">${w.config.series[seriesIndex]}%</div>
</div>`
}
};
@@ -537,11 +537,11 @@ export class AnalyticsComponent implements OnInit, OnDestroy
custom : ({
seriesIndex,
w
}) => `<div class="flex items-center h-8 min-h-8 max-h-8 px-3">
<div class="w-3 h-3 rounded-full" style="background-color: ${w.config.colors[seriesIndex]};"></div>
<div class="ml-2 text-md leading-none">${w.config.labels[seriesIndex]}:</div>
<div class="ml-2 text-md font-bold leading-none">${w.config.series[seriesIndex]}%</div>
</div>`
}): string => `<div class="flex items-center h-8 min-h-8 max-h-8 px-3">
<div class="w-3 h-3 rounded-full" style="background-color: ${w.config.colors[seriesIndex]};"></div>
<div class="ml-2 text-md leading-none">${w.config.labels[seriesIndex]}:</div>
<div class="ml-2 text-md font-bold leading-none">${w.config.series[seriesIndex]}%</div>
</div>`
}
};
@@ -593,11 +593,11 @@ export class AnalyticsComponent implements OnInit, OnDestroy
custom : ({
seriesIndex,
w
}) => `<div class="flex items-center h-8 min-h-8 max-h-8 px-3">
<div class="w-3 h-3 rounded-full" style="background-color: ${w.config.colors[seriesIndex]};"></div>
<div class="ml-2 text-md leading-none">${w.config.labels[seriesIndex]}:</div>
<div class="ml-2 text-md font-bold leading-none">${w.config.series[seriesIndex]}%</div>
</div>`
}): string => `<div class="flex items-center h-8 min-h-8 max-h-8 px-3">
<div class="w-3 h-3 rounded-full" style="background-color: ${w.config.colors[seriesIndex]};"></div>
<div class="ml-2 text-md leading-none">${w.config.labels[seriesIndex]}:</div>
<div class="ml-2 text-md font-bold leading-none">${w.config.series[seriesIndex]}%</div>
</div>`
}
};
@@ -649,11 +649,11 @@ export class AnalyticsComponent implements OnInit, OnDestroy
custom : ({
seriesIndex,
w
}) => `<div class="flex items-center h-8 min-h-8 max-h-8 px-3">
<div class="w-3 h-3 rounded-full" style="background-color: ${w.config.colors[seriesIndex]};"></div>
<div class="ml-2 text-md leading-none">${w.config.labels[seriesIndex]}:</div>
<div class="ml-2 text-md font-bold leading-none">${w.config.series[seriesIndex]}%</div>
</div>`
}): string => `<div class="flex items-center h-8 min-h-8 max-h-8 px-3">
<div class="w-3 h-3 rounded-full" style="background-color: ${w.config.colors[seriesIndex]};"></div>
<div class="ml-2 text-md leading-none">${w.config.labels[seriesIndex]}:</div>
<div class="ml-2 text-md font-bold leading-none">${w.config.series[seriesIndex]}%</div>
</div>`
}
};
}

View File

@@ -12,7 +12,9 @@
src="assets/images/avatars/brian-hughes.jpg">
</div>
<div class="flex flex-col min-w-0 ml-4">
<div class="text-2xl md:text-5xl font-semibold tracking-tight leading-7 md:leading-10 truncate">Welcome back, Brian!</div>
<ng-container *transloco="let t">
<div class="text-2xl md:text-5xl font-semibold tracking-tight leading-7 md:leading-snug truncate">{{t('welcome-back')}}, Brian!</div>
</ng-container>
<div class="flex items-center">
<mat-icon
class="icon-size-5"

View File

@@ -58,10 +58,10 @@ export class ProjectComponent implements OnInit, OnDestroy
window['Apex'] = {
chart: {
events: {
mounted: (chart: any, options?: any) => {
mounted: (chart: any, options?: any): void => {
this._fixSvgFill(chart.el);
},
updated: (chart: any, options?: any) => {
updated: (chart: any, options?: any): void => {
this._fixSvgFill(chart.el);
}
}
@@ -327,7 +327,7 @@ export class ProjectComponent implements OnInit, OnDestroy
categories: this.data.budgetDistribution.categories
},
yaxis : {
max : (max: number) => parseInt((max + 10).toFixed(0), 10),
max : (max: number): number => parseInt((max + 10).toFixed(0), 10),
tickAmount: 7
}
};
@@ -360,7 +360,7 @@ export class ProjectComponent implements OnInit, OnDestroy
},
yaxis : {
labels: {
formatter: val => `$${val}`
formatter: (val): string => `$${val}`
}
}
};
@@ -393,7 +393,7 @@ export class ProjectComponent implements OnInit, OnDestroy
},
yaxis : {
labels: {
formatter: val => `$${val}`
formatter: (val): string => `$${val}`
}
}
};
@@ -426,7 +426,7 @@ export class ProjectComponent implements OnInit, OnDestroy
},
yaxis : {
labels: {
formatter: val => `$${val}`
formatter: (val): string => `$${val}`
}
}
};

View File

@@ -10,6 +10,7 @@ import { MatSidenavModule } from '@angular/material/sidenav';
import { MatSortModule } from '@angular/material/sort';
import { MatTableModule } from '@angular/material/table';
import { MatTabsModule } from '@angular/material/tabs';
import { TranslocoModule } from '@ngneat/transloco';
import { NgApexchartsModule } from 'ng-apexcharts';
import { SharedModule } from 'app/shared/shared.module';
import { ProjectComponent } from 'app/modules/admin/dashboards/project/project.component';
@@ -32,6 +33,7 @@ import { projectRoutes } from 'app/modules/admin/dashboards/project/project.rout
MatTableModule,
MatTabsModule,
NgApexchartsModule,
TranslocoModule,
SharedModule
]
})

View File

@@ -11,6 +11,53 @@ export class ChangelogComponent
{
changelog: any[] = [
// v13.0.2
{
version : 'v13.0.2',
releaseDate: 'May 24, 2021',
changes : [
{
type: 'Changed',
list: [
'(mockApi) Removed typings from data files',
'(apps/ecommerce/inventory) Performance improvements, decreased the mockApi delay',
'(pages/settings) Fixed: Settings container component width is not filling the container'
]
}
]
},
// v13.0.1
{
version : 'v13.0.1',
releaseDate: 'May 21, 2021',
changes : [
{
type: 'Added',
list: [
'(i18n) Added multi language support using @ngneat/transloco',
'(pages) Added Activities page (timeline)',
'(FuseNavigation) Added support for new "isActiveMatchOptions" for Basic navigation items; https://github.com/angular/angular/pull/40303'
]
},
{
type: 'Changed',
list: [
'(dependencies) Updated various packages to their latest versions',
'(tailwind) Use TAILWIND_MODE environment variable to activate purge on build',
'(overrides/angular-material) Changed the text and arrow color of mat-select on focus when it\'s used as a prefix or suffix in mat-form-field',
'(overrides/angular-material) Use @apply whenever it\'s possible',
'(eslint) Removed e2e tsconfig path as there is no default e2e solution included into Angular since v12.0.0',
'(eslint) Activated explicit return types on functions and methods',
'(core) Separated the "auth" and "icon registry" to their own modules to keep the CoreModule simple',
'(FuseNavigation) Added a generic return type for "getComponent" method on FuseNavigationService',
'(FuseNavigation) Use the generic return type for "getComponent"',
'(fuse) Fixed barrel exports',
'(layout/common) Added trackBy functions to ngFor loops in common components',
'(docs) Updated docs'
]
}
]
},
// v13.0.0
{
version : 'v13.0.0',

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