Finalized standalone components conversion

This commit is contained in:
Sercan Yemen 2023-05-30 09:26:50 +03:00
parent 5d42763f1b
commit e23a21eedf
194 changed files with 24320 additions and 26181 deletions

46298
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,66 +1,66 @@
{
"name": "fuse-angular",
"version": "18.0.0",
"description": "Fuse - Angular Admin Template and Starter Project",
"author": "https://themeforest.net/user/srcn",
"license": "https://themeforest.net/licenses/standard",
"private": true,
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"dependencies": {
"@angular/animations": "16.0.0",
"@angular/cdk": "16.0.0",
"@angular/common": "16.0.0",
"@angular/compiler": "16.0.0",
"@angular/core": "16.0.0",
"@angular/forms": "16.0.0",
"@angular/material": "16.0.0",
"@angular/material-luxon-adapter": "16.0.0",
"@angular/platform-browser": "16.0.0",
"@angular/platform-browser-dynamic": "16.0.0",
"@angular/router": "16.0.0",
"@ngneat/transloco": "4.2.6",
"apexcharts": "3.40.0",
"crypto-js": "3.3.0",
"highlight.js": "11.8.0",
"lodash-es": "4.17.21",
"luxon": "3.3.0",
"ng-apexcharts": "1.7.6",
"ngx-quill": "21.0.0",
"perfect-scrollbar": "1.5.5",
"quill": "1.3.7",
"rxjs": "7.8.1",
"tslib": "2.5.0",
"zone.js": "0.13.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "16.0.0",
"@angular/cli": "16.0.0",
"@angular/compiler-cli": "16.0.0",
"@tailwindcss/typography": "0.5.9",
"@types/chroma-js": "2.4.0",
"@types/crypto-js": "3.1.47",
"@types/highlight.js": "10.1.0",
"@types/jasmine": "4.3.1",
"@types/lodash": "4.14.194",
"@types/lodash-es": "4.17.7",
"@types/luxon": "3.3.0",
"autoprefixer": "10.4.14",
"chroma-js": "2.4.2",
"jasmine-core": "4.6.0",
"karma": "6.4.2",
"karma-chrome-launcher": "3.2.0",
"karma-coverage": "2.2.0",
"karma-jasmine": "5.1.0",
"karma-jasmine-html-reporter": "2.0.0",
"lodash": "4.17.21",
"postcss": "8.4.23",
"tailwindcss": "3.3.2",
"typescript": "4.9.5"
}
}
"name": "fuse-angular",
"version": "18.0.0",
"description": "Fuse - Angular Admin Template and Starter Project",
"author": "https://themeforest.net/user/srcn",
"license": "https://themeforest.net/licenses/standard",
"private": true,
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"dependencies": {
"@angular/animations": "16.0.3",
"@angular/cdk": "16.0.2",
"@angular/common": "16.0.3",
"@angular/compiler": "16.0.3",
"@angular/core": "16.0.3",
"@angular/forms": "16.0.3",
"@angular/material": "16.0.2",
"@angular/material-luxon-adapter": "16.0.2",
"@angular/platform-browser": "16.0.3",
"@angular/platform-browser-dynamic": "16.0.3",
"@angular/router": "16.0.3",
"@ngneat/transloco": "4.2.7",
"apexcharts": "3.40.0",
"crypto-js": "3.3.0",
"highlight.js": "11.8.0",
"lodash-es": "4.17.21",
"luxon": "3.3.0",
"ng-apexcharts": "1.7.6",
"ngx-quill": "22.0.0",
"perfect-scrollbar": "1.5.5",
"quill": "1.3.7",
"rxjs": "7.8.1",
"tslib": "2.5.2",
"zone.js": "0.13.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "16.0.3",
"@angular/cli": "16.0.3",
"@angular/compiler-cli": "16.0.3",
"@tailwindcss/typography": "0.5.9",
"@types/chroma-js": "2.4.0",
"@types/crypto-js": "3.1.47",
"@types/highlight.js": "10.1.0",
"@types/jasmine": "4.3.2",
"@types/lodash": "4.14.195",
"@types/lodash-es": "4.17.7",
"@types/luxon": "3.3.0",
"autoprefixer": "10.4.14",
"chroma-js": "2.4.2",
"jasmine-core": "5.0.0",
"karma": "6.4.2",
"karma-chrome-launcher": "3.2.0",
"karma-coverage": "2.2.0",
"karma-jasmine": "5.1.0",
"karma-jasmine-html-reporter": "2.0.0",
"lodash": "4.17.21",
"postcss": "8.4.24",
"tailwindcss": "3.3.2",
"typescript": "5.0.4"
}
}

View File

@ -1,9 +1,7 @@
import { Injectable } from '@angular/core';
import { Observable, ReplaySubject } from 'rxjs';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class FuseAlertService
{
private readonly _onDismiss: ReplaySubject<string> = new ReplaySubject<string>(1);

View File

@ -1,9 +1,7 @@
import { Injectable } from '@angular/core';
import { FuseDrawerComponent } from '@fuse/components/drawer/drawer.component';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class FuseDrawerService
{
private _componentRegistry: Map<string, FuseDrawerComponent> = new Map<string, FuseDrawerComponent>();

View File

@ -1,9 +1,7 @@
import { Injectable } from '@angular/core';
import hljs from 'highlight.js';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class FuseHighlightService
{
/**

View File

@ -1,9 +1,7 @@
import { Injectable } from '@angular/core';
import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class FuseNavigationService
{
private _componentRegistry: Map<string, any> = new Map<string, any>();

View File

@ -1,51 +0,0 @@
import { NgModule, Optional, SkipSelf } from '@angular/core';
import { MATERIAL_SANITY_CHECKS } from '@angular/material/core';
import { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
import { FuseConfirmationModule } from '@fuse/services/confirmation';
import { FuseLoadingModule } from '@fuse/services/loading';
import { FuseMediaWatcherModule } from '@fuse/services/media-watcher/media-watcher.module';
import { FusePlatformModule } from '@fuse/services/platform/platform.module';
import { FuseSplashScreenModule } from '@fuse/services/splash-screen/splash-screen.module';
import { FuseUtilsModule } from '@fuse/services/utils/utils.module';
@NgModule({
imports : [
FuseConfirmationModule,
FuseLoadingModule,
FuseMediaWatcherModule,
FusePlatformModule,
FuseSplashScreenModule,
FuseUtilsModule,
],
providers: [
{
// Disable 'theme' sanity check
provide : MATERIAL_SANITY_CHECKS,
useValue: {
doctype: true,
theme : false,
version: true,
},
},
{
// Use the 'fill' appearance on Angular Material form fields by default
provide : MAT_FORM_FIELD_DEFAULT_OPTIONS,
useValue: {
appearance: 'fill',
},
},
],
})
export class FuseModule
{
/**
* Constructor
*/
constructor(@Optional() @SkipSelf() parentModule?: FuseModule)
{
if ( parentModule )
{
throw new Error('FuseModule has already been loaded. Import this module in the AppModule only!');
}
}
}

108
src/@fuse/fuse.provider.ts Normal file
View File

@ -0,0 +1,108 @@
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { APP_INITIALIZER, ENVIRONMENT_INITIALIZER, EnvironmentProviders, importProvidersFrom, inject, Provider } from '@angular/core';
import { MATERIAL_SANITY_CHECKS } from '@angular/material/core';
import { MatDialogModule } from '@angular/material/dialog';
import { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
import { FUSE_MOCK_API_DEFAULT_DELAY, mockApiInterceptor } from '@fuse/lib/mock-api';
import { FuseConfig } from '@fuse/services/config';
import { FUSE_CONFIG } from '@fuse/services/config/config.constants';
import { FuseConfirmationService } from '@fuse/services/confirmation';
import { fuseLoadingInterceptor, FuseLoadingService } from '@fuse/services/loading';
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
import { FusePlatformService } from '@fuse/services/platform';
import { FuseSplashScreenService } from '@fuse/services/splash-screen';
import { FuseUtilsService } from '@fuse/services/utils';
export type FuseProviderConfig = {
mockApi?: {
delay?: number;
services?: any[];
},
fuse?: FuseConfig
}
/**
* Fuse provider
*/
export const provideFuse = (config: FuseProviderConfig): Array<Provider | EnvironmentProviders> =>
{
// Base providers
const providers: Array<Provider | EnvironmentProviders> = [
{
// Disable 'theme' sanity check
provide : MATERIAL_SANITY_CHECKS,
useValue: {
doctype: true,
theme : false,
version: true,
},
},
{
// Use the 'fill' appearance on Angular Material form fields by default
provide : MAT_FORM_FIELD_DEFAULT_OPTIONS,
useValue: {
appearance: 'fill',
},
},
{
provide : FUSE_MOCK_API_DEFAULT_DELAY,
useValue: config?.mockApi?.delay ?? 0,
},
{
provide : FUSE_CONFIG,
useValue: config?.fuse ?? {},
},
importProvidersFrom(MatDialogModule),
{
provide : ENVIRONMENT_INITIALIZER,
useValue: () => inject(FuseConfirmationService),
multi : true,
},
provideHttpClient(withInterceptors([fuseLoadingInterceptor])),
{
provide : ENVIRONMENT_INITIALIZER,
useValue: () => inject(FuseLoadingService),
multi : true,
},
{
provide : ENVIRONMENT_INITIALIZER,
useValue: () => inject(FuseMediaWatcherService),
multi : true,
},
{
provide : ENVIRONMENT_INITIALIZER,
useValue: () => inject(FusePlatformService),
multi : true,
},
{
provide : ENVIRONMENT_INITIALIZER,
useValue: () => inject(FuseSplashScreenService),
multi : true,
},
{
provide : ENVIRONMENT_INITIALIZER,
useValue: () => inject(FuseUtilsService),
multi : true,
},
];
// Mock Api services
if ( config?.mockApi?.services )
{
providers.push(
provideHttpClient(withInterceptors([mockApiInterceptor])),
{
provide : APP_INITIALIZER,
deps : [...config.mockApi.services],
useFactory: () => (): any => null,
multi : true,
},
);
}
// Return the providers
return providers;
};

View File

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

View File

@ -1,96 +1,77 @@
import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';
import { HttpErrorResponse, HttpEvent, HttpHandlerFn, HttpRequest, HttpResponse } from '@angular/common/http';
import { inject } from '@angular/core';
import { FUSE_MOCK_API_DEFAULT_DELAY } from '@fuse/lib/mock-api/mock-api.constants';
import { FuseMockApiService } from '@fuse/lib/mock-api/mock-api.service';
import { delay, Observable, of, switchMap, throwError } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class FuseMockApiInterceptor implements HttpInterceptor
export const mockApiInterceptor = (request: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> =>
{
/**
* Constructor
*/
constructor(
@Inject(FUSE_MOCK_API_DEFAULT_DELAY) private _defaultDelay: number,
private _fuseMockApiService: FuseMockApiService,
)
const defaultDelay = inject(FUSE_MOCK_API_DEFAULT_DELAY);
const fuseMockApiService = inject(FuseMockApiService);
// Try to get the request handler
const {
handler,
urlParams,
} = fuseMockApiService.findHandler(request.method.toUpperCase(), request.url);
// Pass through if the request handler does not exist
if ( !handler )
{
return next(request);
}
/**
* Intercept
*
* @param request
* @param next
*/
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
{
// Try to get the request handler
const {
handler,
urlParams,
} = this._fuseMockApiService.findHandler(request.method.toUpperCase(), request.url);
// Set the intercepted request on the handler
handler.request = request;
// Pass through if the request handler does not exist
if ( !handler )
// Set the url params on the handler
handler.urlParams = urlParams;
// Subscribe to the response function observable
return handler.response.pipe(
delay(handler.delay ?? defaultDelay ?? 0),
switchMap((response) =>
{
return next.handle(request);
}
// Set the intercepted request on the handler
handler.request = request;
// Set the url params on the handler
handler.urlParams = urlParams;
// Subscribe to the response function observable
return handler.response.pipe(
delay(handler.delay ?? this._defaultDelay ?? 0),
switchMap((response) =>
// If there is no response data,
// throw an error response
if ( !response )
{
// If there is no response data,
// throw an error response
if ( !response )
{
response = new HttpErrorResponse({
error : 'NOT FOUND',
status : 404,
statusText: 'NOT FOUND',
});
return throwError(response);
}
// Parse the response data
const data = {
status: response[0],
body : response[1],
};
// If the status code is in between 200 and 300,
// return a success response
if ( data.status >= 200 && data.status < 300 )
{
response = new HttpResponse({
body : data.body,
status : data.status,
statusText: 'OK',
});
return of(response);
}
// For other status codes,
// throw an error response
response = new HttpErrorResponse({
error : data.body.error,
status : data.status,
statusText: 'ERROR',
error : 'NOT FOUND',
status : 404,
statusText: 'NOT FOUND',
});
return throwError(response);
}));
}
}
}
// Parse the response data
const data = {
status: response[0],
body : response[1],
};
// If the status code is in between 200 and 300,
// return a success response
if ( data.status >= 200 && data.status < 300 )
{
response = new HttpResponse({
body : data.body,
status : data.status,
statusText: 'OK',
});
return of(response);
}
// For other status codes,
// throw an error response
response = new HttpErrorResponse({
error : data.body.error,
status : data.status,
statusText: 'ERROR',
});
return throwError(response);
}));
};

View File

@ -1,42 +0,0 @@
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { APP_INITIALIZER, ModuleWithProviders, NgModule } from '@angular/core';
import { FUSE_MOCK_API_DEFAULT_DELAY } from '@fuse/lib/mock-api/mock-api.constants';
import { FuseMockApiInterceptor } from '@fuse/lib/mock-api/mock-api.interceptor';
@NgModule({
providers: [
{
provide : HTTP_INTERCEPTORS,
useClass: FuseMockApiInterceptor,
multi : true,
},
],
})
export class FuseMockApiModule
{
/**
* FuseMockApi module default configuration.
*
* @param mockApiServices - Array of services that register mock API handlers
* @param config - Configuration options
* @param config.delay - Default delay value in milliseconds to apply all responses
*/
static forRoot(mockApiServices: any[], config?: { delay?: number }): ModuleWithProviders<FuseMockApiModule>
{
return {
ngModule : FuseMockApiModule,
providers: [
{
provide : APP_INITIALIZER,
deps : [...mockApiServices],
useFactory: () => (): any => null,
multi : true,
},
{
provide : FUSE_MOCK_API_DEFAULT_DELAY,
useValue: config?.delay ?? 0,
},
],
};
}
}

View File

@ -3,9 +3,7 @@ import { FuseMockApiHandler } from '@fuse/lib/mock-api/mock-api.request-handler'
import { FuseMockApiMethods } from '@fuse/lib/mock-api/mock-api.types';
import { compact, fromPairs } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class FuseMockApiService
{
private _handlers: { [key: string]: Map<string, FuseMockApiHandler> } = {

View File

@ -1,5 +1,5 @@
export * from '@fuse/lib/mock-api/mock-api.constants';
export * from '@fuse/lib/mock-api/mock-api.module';
export * from '@fuse/lib/mock-api/mock-api.interceptor';
export * from '@fuse/lib/mock-api/mock-api.service';
export * from '@fuse/lib/mock-api/mock-api.types';
export * from '@fuse/lib/mock-api/mock-api.utils';

View File

@ -1,3 +1,3 @@
import { InjectionToken } from '@angular/core';
export const FUSE_APP_CONFIG = new InjectionToken<any>('FUSE_APP_CONFIG');
export const FUSE_CONFIG = new InjectionToken<any>('FUSE_APP_CONFIG');

View File

@ -1,32 +0,0 @@
import { ModuleWithProviders, NgModule } from '@angular/core';
import { FUSE_APP_CONFIG } from '@fuse/services/config/config.constants';
import { FuseConfigService } from '@fuse/services/config/config.service';
@NgModule()
export class FuseConfigModule
{
/**
* Constructor
*/
constructor(private _fuseConfigService: FuseConfigService)
{
}
/**
* forRoot method for setting user configuration
*
* @param config
*/
static forRoot(config: any): ModuleWithProviders<FuseConfigModule>
{
return {
ngModule : FuseConfigModule,
providers: [
{
provide : FUSE_APP_CONFIG,
useValue: config,
},
],
};
}
}

View File

@ -1,11 +1,9 @@
import { Inject, Injectable } from '@angular/core';
import { FUSE_APP_CONFIG } from '@fuse/services/config/config.constants';
import { FUSE_CONFIG } from '@fuse/services/config/config.constants';
import { merge } from 'lodash-es';
import { BehaviorSubject, Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class FuseConfigService
{
private _config: BehaviorSubject<any>;
@ -13,7 +11,7 @@ export class FuseConfigService
/**
* Constructor
*/
constructor(@Inject(FUSE_APP_CONFIG) config: any)
constructor(@Inject(FUSE_CONFIG) config: any)
{
// Private
this._config = new BehaviorSubject(config);

View File

@ -0,0 +1,18 @@
// Types
export type Scheme = 'auto' | 'dark' | 'light';
export type Screens = { [key: string]: string };
export type Theme = 'theme-default' | string;
export type Themes = { id: string; name: string }[];
/**
* AppConfig interface. Update this interface to strictly type your config
* object.
*/
export interface FuseConfig
{
layout: string;
scheme: Scheme;
screens: Screens;
theme: Theme;
themes: Themes;
}

View File

@ -1,2 +1,2 @@
export * from '@fuse/services/config/config.module';
export * from '@fuse/services/config/config.service';
export * from '@fuse/services/config/config.types';

View File

@ -1,29 +0,0 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule } from '@angular/material/dialog';
import { MatIconModule } from '@angular/material/icon';
import { FuseConfirmationService } from '@fuse/services/confirmation/confirmation.service';
import { FuseConfirmationDialogComponent } from '@fuse/services/confirmation/dialog/dialog.component';
@NgModule({
imports : [
MatButtonModule,
MatDialogModule,
MatIconModule,
CommonModule,
FuseConfirmationDialogComponent,
],
providers: [
FuseConfirmationService,
],
})
export class FuseConfirmationModule
{
/**
* Constructor
*/
constructor(private _fuseConfirmationService: FuseConfirmationService)
{
}
}

View File

@ -1,12 +1,13 @@
import { Injectable } from '@angular/core';
import { inject, Injectable } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { FuseConfirmationConfig } from '@fuse/services/confirmation/confirmation.types';
import { FuseConfirmationDialogComponent } from '@fuse/services/confirmation/dialog/dialog.component';
import { merge } from 'lodash-es';
@Injectable()
@Injectable({providedIn: 'root'})
export class FuseConfirmationService
{
private _matDialog: MatDialog = inject(MatDialog);
private _defaultConfig: FuseConfirmationConfig = {
title : 'Confirm action',
message : 'Are you sure you want to confirm this action?',
@ -32,9 +33,7 @@ export class FuseConfirmationService
/**
* Constructor
*/
constructor(
private _matDialog: MatDialog,
)
constructor()
{
}

View File

@ -1,3 +1,2 @@
export * from '@fuse/services/confirmation/confirmation.module';
export * from '@fuse/services/confirmation/confirmation.service';
export * from '@fuse/services/confirmation/confirmation.types';

View File

@ -1,50 +1,33 @@
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http';
import { inject } from '@angular/core';
import { FuseLoadingService } from '@fuse/services/loading/loading.service';
import { finalize, Observable } from 'rxjs';
import { finalize, Observable, take } from 'rxjs';
@Injectable()
export class FuseLoadingInterceptor implements HttpInterceptor
export const fuseLoadingInterceptor = (req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> =>
{
handleRequestsAutomatically: boolean;
const fuseLoadingService = inject(FuseLoadingService);
let handleRequestsAutomatically = false;
/**
* Constructor
*/
constructor(
private _fuseLoadingService: FuseLoadingService,
)
{
// Subscribe to the auto
this._fuseLoadingService.auto$
.subscribe((value) =>
{
this.handleRequestsAutomatically = value;
});
}
/**
* Intercept
*
* @param req
* @param next
*/
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
{
// If the Auto mode is turned off, do nothing
if ( !this.handleRequestsAutomatically )
fuseLoadingService.auto$
.pipe(take(1))
.subscribe((value) =>
{
return next.handle(req);
}
handleRequestsAutomatically = value;
});
// Set the loading status to true
this._fuseLoadingService._setLoadingStatus(true, req.url);
return next.handle(req).pipe(
finalize(() =>
{
// Set the status to false if there are any errors or the request is completed
this._fuseLoadingService._setLoadingStatus(false, req.url);
}));
// If the Auto mode is turned off, do nothing
if ( !handleRequestsAutomatically )
{
return next(req);
}
}
// Set the loading status to true
fuseLoadingService._setLoadingStatus(true, req.url);
return next(req).pipe(
finalize(() =>
{
// Set the status to false if there are any errors or the request is completed
fuseLoadingService._setLoadingStatus(false, req.url);
}));
};

View File

@ -1,16 +0,0 @@
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { FuseLoadingInterceptor } from '@fuse/services/loading/loading.interceptor';
@NgModule({
providers: [
{
provide : HTTP_INTERCEPTORS,
useClass: FuseLoadingInterceptor,
multi : true,
},
],
})
export class FuseLoadingModule
{
}

View File

@ -2,9 +2,7 @@ import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class FuseLoadingService
{
private _auto$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);

View File

@ -1,2 +1,2 @@
export * from '@fuse/services/loading/loading.service';
export * from '@fuse/services/loading/loading.module';
export * from '@fuse/services/loading/loading.interceptor';

View File

@ -1,17 +0,0 @@
import { NgModule } from '@angular/core';
import { FuseMediaWatcherService } from '@fuse/services/media-watcher/media-watcher.service';
@NgModule({
providers: [
FuseMediaWatcherService,
],
})
export class FuseMediaWatcherModule
{
/**
* Constructor
*/
constructor(private _fuseMediaWatcherService: FuseMediaWatcherService)
{
}
}

View File

@ -4,7 +4,7 @@ import { FuseConfigService } from '@fuse/services/config';
import { fromPairs } from 'lodash-es';
import { map, Observable, ReplaySubject, switchMap } from 'rxjs';
@Injectable()
@Injectable({providedIn: 'root'})
export class FuseMediaWatcherService
{
private _onMediaChange: ReplaySubject<{ matchingAliases: string[]; matchingQueries: any }> = new ReplaySubject<{ matchingAliases: string[]; matchingQueries: any }>(1);

View File

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

View File

@ -1,17 +0,0 @@
import { NgModule } from '@angular/core';
import { FusePlatformService } from '@fuse/services/platform/platform.service';
@NgModule({
providers: [
FusePlatformService,
],
})
export class FusePlatformModule
{
/**
* Constructor
*/
constructor(private _fusePlatformService: FusePlatformService)
{
}
}

View File

@ -1,9 +1,7 @@
import { Platform } from '@angular/cdk/platform';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class FusePlatformService
{
osName = 'os-unknown';

View File

@ -1,2 +1 @@
export * from '@fuse/services/splash-screen/splash-screen.module';
export * from '@fuse/services/splash-screen/splash-screen.service';

View File

@ -1,17 +0,0 @@
import { NgModule } from '@angular/core';
import { FuseSplashScreenService } from '@fuse/services/splash-screen/splash-screen.service';
@NgModule({
providers: [
FuseSplashScreenService,
],
})
export class FuseSplashScreenModule
{
/**
* Constructor
*/
constructor(private _fuseSplashScreenService: FuseSplashScreenService)
{
}
}

View File

@ -3,7 +3,7 @@ import { Inject, Injectable } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { filter, take } from 'rxjs';
@Injectable()
@Injectable({providedIn: 'root'})
export class FuseSplashScreenService
{
/**

View File

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

View File

@ -1,17 +0,0 @@
import { NgModule } from '@angular/core';
import { FuseUtilsService } from '@fuse/services/utils/utils.service';
@NgModule({
providers: [
FuseUtilsService,
],
})
export class FuseUtilsModule
{
/**
* Constructor
*/
constructor(private _fuseUtilsService: FuseUtilsService)
{
}
}

View File

@ -1,9 +1,7 @@
import { Injectable } from '@angular/core';
import { IsActiveMatchOptions } from '@angular/router';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class FuseUtilsService
{
/**

File diff suppressed because one or more lines are too long

View File

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

93
src/app/app.config.ts Normal file
View File

@ -0,0 +1,93 @@
import { provideHttpClient } from '@angular/common/http';
import { ApplicationConfig } from '@angular/core';
import { LuxonDateAdapter } from '@angular/material-luxon-adapter';
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
import { provideAnimations } from '@angular/platform-browser/animations';
import { PreloadAllModules, provideRouter, withInMemoryScrolling, withPreloading } from '@angular/router';
import { provideFuse } from '@fuse';
import { appRoutes } from 'app/app.routes';
import { provideAuth } from 'app/core/auth/auth.provider';
import { provideIcons } from 'app/core/icons/icons.provider';
import { provideTransloco } from 'app/core/transloco/transloco.provider';
import { mockApiServices } from 'app/mock-api';
export const appConfig: ApplicationConfig = {
providers: [
provideAnimations(),
provideHttpClient(),
provideRouter(appRoutes,
withPreloading(PreloadAllModules),
withInMemoryScrolling({scrollPositionRestoration: 'enabled'}),
),
// Material Date Adapter
{
provide : DateAdapter,
useClass: LuxonDateAdapter,
},
{
provide : MAT_DATE_FORMATS,
useValue: {
parse : {
dateInput: 'D',
},
display: {
dateInput : 'DDD',
monthYearLabel : 'LLL yyyy',
dateA11yLabel : 'DD',
monthYearA11yLabel: 'LLLL yyyy',
},
},
},
// Transloco Config
provideTransloco(),
// Fuse
provideAuth(),
provideIcons(),
provideFuse({
mockApi: {
delay : 0,
services: mockApiServices,
},
fuse : {
layout : 'classy',
scheme : 'light',
screens: {
sm: '600px',
md: '960px',
lg: '1280px',
xl: '1440px',
},
theme : 'theme-default',
themes : [
{
id : 'theme-default',
name: 'Default',
},
{
id : 'theme-brand',
name: 'Brand',
},
{
id : 'theme-teal',
name: 'Teal',
},
{
id : 'theme-rose',
name: 'Rose',
},
{
id : 'theme-purple',
name: 'Purple',
},
{
id : 'theme-amber',
name: 'Amber',
},
],
},
}),
],
};

View File

@ -101,108 +101,104 @@ export const appRoutes: Route[] = [
{path: 'pages', children: [
// Activities
{path: 'activities', loadChildren: () => import('app/modules/admin/pages/activities/activities.module').then(m => m.ActivitiesModule)},
{path: 'activities', loadChildren: () => import('app/modules/admin/pages/activities/activities.routes')},
// Authentication
{path: 'authentication', loadChildren: () => import('app/modules/admin/pages/authentication/authentication.module').then(m => m.AuthenticationModule)},
{path: 'authentication', loadChildren: () => import('app/modules/admin/pages/authentication/authentication.routes')},
// Coming Soon
{path: 'coming-soon', loadChildren: () => import('app/modules/admin/pages/coming-soon/coming-soon.module').then(m => m.ComingSoonModule)},
{path: 'coming-soon', loadChildren: () => import('app/modules/admin/pages/coming-soon/coming-soon.routes')},
// Error
{path: 'error', children: [
{path: '404', loadChildren: () => import('app/modules/admin/pages/error/error-404/error-404.module').then(m => m.Error404Module)},
{path: '500', loadChildren: () => import('app/modules/admin/pages/error/error-500/error-500.module').then(m => m.Error500Module)}
{path: '404', loadChildren: () => import('app/modules/admin/pages/error/error-404/error-404.routes')},
{path: '500', loadChildren: () => import('app/modules/admin/pages/error/error-500/error-500.routes')}
]},
// Invoice
{path: 'invoice', children: [
{path: 'printable', children: [
{path: 'compact', loadChildren: () => import('app/modules/admin/pages/invoice/printable/compact/compact.module').then(m => m.CompactModule)},
{path: 'modern', loadChildren: () => import('app/modules/admin/pages/invoice/printable/modern/modern.module').then(m => m.ModernModule)}
{path: 'compact', loadChildren: () => import('app/modules/admin/pages/invoice/printable/compact/compact.routes')},
{path: 'modern', loadChildren: () => import('app/modules/admin/pages/invoice/printable/modern/modern.routes')}
]}
]},
// Maintenance
{path: 'maintenance', loadChildren: () => import('app/modules/admin/pages/maintenance/maintenance.module').then(m => m.MaintenanceModule)},
{path: 'maintenance', loadChildren: () => import('app/modules/admin/pages/maintenance/maintenance.routes')},
// Pricing
{path: 'pricing', children: [
{path: 'modern', loadChildren: () => import('app/modules/admin/pages/pricing/modern/modern.module').then(m => m.PricingModernModule)},
{path: 'simple', loadChildren: () => import('app/modules/admin/pages/pricing/simple/simple.module').then(m => m.PricingSimpleModule)},
{path: 'single', loadChildren: () => import('app/modules/admin/pages/pricing/single/single.module').then(m => m.PricingSingleModule)},
{path: 'table', loadChildren: () => import('app/modules/admin/pages/pricing/table/table.module').then(m => m.PricingTableModule)}
{path: 'modern', loadChildren: () => import('app/modules/admin/pages/pricing/modern/modern.routes')},
{path: 'simple', loadChildren: () => import('app/modules/admin/pages/pricing/simple/simple.routes')},
{path: 'single', loadChildren: () => import('app/modules/admin/pages/pricing/single/single.routes')},
{path: 'table', loadChildren: () => import('app/modules/admin/pages/pricing/table/table.routes')}
]},
// Profile
{path: 'profile', loadChildren: () => import('app/modules/admin/pages/profile/profile.module').then(m => m.ProfileModule)},
{path: 'profile', loadChildren: () => import('app/modules/admin/pages/profile/profile.routes')},
// Settings
{path: 'settings', loadChildren: () => import('app/modules/admin/pages/settings/settings.module').then(m => m.SettingsModule)},
{path: 'settings', loadChildren: () => import('app/modules/admin/pages/settings/settings.routes')},
]},
// User Interface
{path: 'ui', children: [
// Material Components
{path: 'material-components', loadChildren: () => import('app/modules/admin/ui/material-components/material-components.module').then(m => m.MaterialComponentsModule)},
{path: 'material-components', loadChildren: () => import('app/modules/admin/ui/material-components/material-components.routes')},
// Fuse Components
{path: 'fuse-components', loadChildren: () => import('app/modules/admin/ui/fuse-components/fuse-components.module').then(m => m.FuseComponentsModule)},
{path: 'fuse-components', loadChildren: () => import('app/modules/admin/ui/fuse-components/fuse-components.routes')},
// Other Components
{path: 'other-components', loadChildren: () => import('app/modules/admin/ui/other-components/other-components.module').then(m => m.OtherComponentsModule)},
{path: 'other-components', loadChildren: () => import('app/modules/admin/ui/other-components/other-components.routes')},
// TailwindCSS
{path: 'tailwindcss', loadChildren: () => import('app/modules/admin/ui/tailwindcss/tailwindcss.module').then(m => m.TailwindCSSModule)},
{path: 'tailwindcss', loadChildren: () => import('app/modules/admin/ui/tailwindcss/tailwindcss.routes')},
// Advanced Search
{path: 'advanced-search', loadChildren: () => import('app/modules/admin/ui/advanced-search/advanced-search.module').then(m => m.AdvancedSearchModule)},
{path: 'advanced-search', loadChildren: () => import('app/modules/admin/ui/advanced-search/advanced-search.routes')},
// Animations
{path: 'animations', loadChildren: () => import('app/modules/admin/ui/animations/animations.module').then(m => m.AnimationsModule)},
{path: 'animations', loadChildren: () => import('app/modules/admin/ui/animations/animations.routes')},
// Cards
{path: 'cards', loadChildren: () => import('app/modules/admin/ui/cards/cards.module').then(m => m.CardsModule)},
{path: 'cards', loadChildren: () => import('app/modules/admin/ui/cards/cards.routes')},
// Colors
{path: 'colors', loadChildren: () => import('app/modules/admin/ui/colors/colors.module').then(m => m.ColorsModule)},
{path: 'colors', loadChildren: () => import('app/modules/admin/ui/colors/colors.routes')},
// Confirmation Dialog
{path: 'confirmation-dialog', loadChildren: () => import('app/modules/admin/ui/confirmation-dialog/confirmation-dialog.module').then(m => m.ConfirmationDialogModule)},
{path: 'confirmation-dialog', loadChildren: () => import('app/modules/admin/ui/confirmation-dialog/confirmation-dialog.routes')},
// Datatable
{path: 'datatable', loadChildren: () => import('app/modules/admin/ui/datatable/datatable.module').then(m => m.DatatableModule)},
{path: 'datatable', loadChildren: () => import('app/modules/admin/ui/datatable/datatable.routes')},
// Forms
{path: 'forms', children: [
{path: 'fields', loadChildren: () => import('app/modules/admin/ui/forms/fields/fields.module').then(m => m.FormsFieldsModule)},
{path: 'layouts', loadChildren: () => import('app/modules/admin/ui/forms/layouts/layouts.module').then(m => m.FormsLayoutsModule)},
{path: 'wizards', loadChildren: () => import('app/modules/admin/ui/forms/wizards/wizards.module').then(m => m.FormsWizardsModule)}
]},
{path: 'forms', loadChildren: () => import('app/modules/admin/ui/forms/forms.routes')},
// Icons
{path: 'icons', loadChildren: () => import('app/modules/admin/ui/icons/icons.module').then(m => m.IconsModule)},
{path: 'icons', loadChildren: () => import('app/modules/admin/ui/icons/icons.routes')},
// Page Layouts
{path: 'page-layouts', loadChildren: () => import('app/modules/admin/ui/page-layouts/page-layouts.module').then(m => m.PageLayoutsModule)},
{path: 'page-layouts', loadChildren: () => import('app/modules/admin/ui/page-layouts/page-layouts.routes')},
// Typography
{path: 'typography', loadChildren: () => import('app/modules/admin/ui/typography/typography.module').then(m => m.TypographyModule)}
{path: 'typography', loadChildren: () => import('app/modules/admin/ui/typography/typography.routes')}
]},
// Documentation
{path: 'docs', children: [
// Changelog
{path: 'changelog', loadChildren: () => import('app/modules/admin/docs/changelog/changelog.module').then(m => m.ChangelogModule)},
{path: 'changelog', loadChildren: () => import('app/modules/admin/docs/changelog/changelog.routes')},
// Guides
{path: 'guides', loadChildren: () => import('app/modules/admin/docs/guides/guides.module').then(m => m.GuidesModule)}
{path: 'guides', loadChildren: () => import('app/modules/admin/docs/guides/guides.routes')}
]},
// 404 & Catch all
{path: '404-not-found', pathMatch: 'full', loadChildren: () => import('app/modules/admin/pages/error/error-404/error-404.module').then(m => m.Error404Module)},
{path: '404-not-found', pathMatch: 'full', loadChildren: () => import('app/modules/admin/pages/error/error-404/error-404.routes')},
{path: '**', redirectTo: '404-not-found'}
]
}

View File

@ -1,61 +1,52 @@
import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { HttpErrorResponse, HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http';
import { inject } from '@angular/core';
import { AuthService } from 'app/core/auth/auth.service';
import { AuthUtils } from 'app/core/auth/auth.utils';
import { catchError, Observable, throwError } from 'rxjs';
@Injectable()
export class AuthInterceptor implements HttpInterceptor
/**
* Intercept
*
* @param req
* @param next
*/
export const authInterceptor = (req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> =>
{
/**
* Constructor
*/
constructor(private _authService: AuthService)
const authService = inject(AuthService);
// Clone the request object
let newReq = req.clone();
// Request
//
// If the access token didn't expire, add the Authorization header.
// We won't add the Authorization header if the access token expired.
// This will force the server to return a "401 Unauthorized" response
// for the protected API routes which our response interceptor will
// catch and delete the access token from the local storage while logging
// the user out from the app.
if ( authService.accessToken && !AuthUtils.isTokenExpired(authService.accessToken) )
{
newReq = req.clone({
headers: req.headers.set('Authorization', 'Bearer ' + authService.accessToken),
});
}
/**
* Intercept
*
* @param req
* @param next
*/
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
{
// Clone the request object
let newReq = req.clone();
// Request
//
// If the access token didn't expire, add the Authorization header.
// We won't add the Authorization header if the access token expired.
// This will force the server to return a "401 Unauthorized" response
// for the protected API routes which our response interceptor will
// catch and delete the access token from the local storage while logging
// the user out from the app.
if ( this._authService.accessToken && !AuthUtils.isTokenExpired(this._authService.accessToken) )
// Response
return next(newReq).pipe(
catchError((error) =>
{
newReq = req.clone({
headers: req.headers.set('Authorization', 'Bearer ' + this._authService.accessToken),
});
}
// Response
return next.handle(newReq).pipe(
catchError((error) =>
// Catch "401 Unauthorized" responses
if ( error instanceof HttpErrorResponse && error.status === 401 )
{
// Catch "401 Unauthorized" responses
if ( error instanceof HttpErrorResponse && error.status === 401 )
{
// Sign out
this._authService.signOut();
// Sign out
authService.signOut();
// Reload the app
location.reload();
}
// Reload the app
location.reload();
}
return throwError(error);
}),
);
}
}
return throwError(error);
}),
);
};

View File

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

View File

@ -0,0 +1,16 @@
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { ENVIRONMENT_INITIALIZER, EnvironmentProviders, inject, Provider } from '@angular/core';
import { authInterceptor } from 'app/core/auth/auth.interceptor';
import { AuthService } from 'app/core/auth/auth.service';
export const provideAuth = (): Array<Provider | EnvironmentProviders> =>
{
return [
provideHttpClient(withInterceptors([authInterceptor])),
{
provide : ENVIRONMENT_INITIALIZER,
useValue: () => inject(AuthService),
multi : true,
},
];
};

View File

@ -4,7 +4,7 @@ import { AuthUtils } from 'app/core/auth/auth.utils';
import { UserService } from 'app/core/user/user.service';
import { catchError, Observable, of, switchMap, throwError } from 'rxjs';
@Injectable()
@Injectable({providedIn: 'root'})
export class AuthService
{
private _authenticated: boolean = false;

View File

@ -1,71 +0,0 @@
import { Layout } from 'app/layout/layout.types';
// Types
export type Scheme = 'auto' | 'dark' | 'light';
export type Screens = { [key: string]: string };
export type Theme = 'theme-default' | string;
export type Themes = { id: string; name: string }[];
/**
* AppConfig interface. Update this interface to strictly type your config
* object.
*/
export interface AppConfig
{
layout: Layout;
scheme: Scheme;
screens: Screens;
theme: Theme;
themes: Themes;
}
/**
* Default configuration for the entire application. This object is used by
* FuseConfigService to set the default configuration.
*
* If you need to store global configuration for your app, you can use this
* object to set the defaults. To access, update and reset the config, use
* FuseConfigService and its methods.
*
* "Screens" are carried over to the BreakpointObserver for accessing them within
* components, and they are required.
*
* "Themes" are required for Tailwind to generate themes.
*/
export const appConfig: AppConfig = {
layout : 'classy',
scheme : 'light',
screens: {
sm: '600px',
md: '960px',
lg: '1280px',
xl: '1440px',
},
theme : 'theme-default',
themes : [
{
id : 'theme-default',
name: 'Default',
},
{
id : 'theme-brand',
name: 'Brand',
},
{
id : 'theme-teal',
name: 'Teal',
},
{
id : 'theme-rose',
name: 'Rose',
},
{
id : 'theme-purple',
name: 'Purple',
},
{
id : 'theme-amber',
name: 'Amber',
},
],
};

View File

@ -1,28 +0,0 @@
import { NgModule, Optional, SkipSelf } from '@angular/core';
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: [
AuthModule,
IconsModule,
TranslocoCoreModule,
],
})
export class CoreModule
{
/**
* Constructor
*/
constructor(
@Optional() @SkipSelf() parentModule?: CoreModule,
)
{
// Do not allow multiple injections
if ( parentModule )
{
throw new Error('CoreModule has already been loaded. Import this module in the AppModule only.');
}
}
}

View File

@ -1,24 +0,0 @@
import { NgModule } from '@angular/core';
import { MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from '@angular/platform-browser';
@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('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,13 @@
import { ENVIRONMENT_INITIALIZER, EnvironmentProviders, inject, Provider } from '@angular/core';
import { IconsService } from 'app/core/icons/icons.service';
export const provideIcons = (): Array<Provider | EnvironmentProviders> =>
{
return [
{
provide : ENVIRONMENT_INITIALIZER,
useValue: () => inject(IconsService),
multi : true,
},
];
};

View File

@ -0,0 +1,24 @@
import { inject, Injectable } from '@angular/core';
import { MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from '@angular/platform-browser';
@Injectable({providedIn: 'root'})
export class IconsService
{
/**
* Constructor
*/
constructor()
{
const domSanitizer = inject(DomSanitizer);
const matIconRegistry = inject(MatIconRegistry);
// Register icon sets
matIconRegistry.addSvgIconSet(domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/material-twotone.svg'));
matIconRegistry.addSvgIconSetInNamespace('mat_outline', domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/material-outline.svg'));
matIconRegistry.addSvgIconSetInNamespace('mat_solid', domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/material-solid.svg'));
matIconRegistry.addSvgIconSetInNamespace('feather', domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/feather.svg'));
matIconRegistry.addSvgIconSetInNamespace('heroicons_outline', domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/heroicons-outline.svg'));
matIconRegistry.addSvgIconSetInNamespace('heroicons_solid', domSanitizer.bypassSecurityTrustResourceUrl('assets/icons/heroicons-solid.svg'));
}
}

View File

@ -3,9 +3,7 @@ import { Injectable } from '@angular/core';
import { Navigation } from 'app/core/navigation/navigation.types';
import { Observable, ReplaySubject, tap } from 'rxjs';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class NavigationService
{
private _navigation: ReplaySubject<Navigation> = new ReplaySubject<Navigation>(1);

View File

@ -3,9 +3,7 @@ import { Injectable } from '@angular/core';
import { Translation, TranslocoLoader } from '@ngneat/transloco';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class TranslocoHttpLoader implements TranslocoLoader
{
/**

View File

@ -1,12 +1,11 @@
import { APP_INITIALIZER, NgModule } from '@angular/core';
import { Translation, TRANSLOCO_CONFIG, TRANSLOCO_LOADER, translocoConfig, TranslocoModule, TranslocoService } from '@ngneat/transloco';
import { APP_INITIALIZER, EnvironmentProviders, importProvidersFrom, inject, Provider } from '@angular/core';
import { TRANSLOCO_CONFIG, TRANSLOCO_LOADER, translocoConfig, TranslocoModule, TranslocoService } from '@ngneat/transloco';
import { TranslocoHttpLoader } from 'app/core/transloco/transloco.http-loader';
@NgModule({
exports : [
TranslocoModule,
],
providers: [
export const provideTransloco = (): Array<Provider | EnvironmentProviders> =>
{
return [
importProvidersFrom(TranslocoModule),
{
// Provide the default Transloco configuration
provide : TRANSLOCO_CONFIG,
@ -35,17 +34,15 @@ import { TranslocoHttpLoader } from 'app/core/transloco/transloco.http-loader';
{
// Preload the default language before the app starts to prevent empty/jumping content
provide : APP_INITIALIZER,
deps : [TranslocoService],
useFactory: (translocoService: TranslocoService): any => (): Promise<Translation> =>
useFactory: () =>
{
const translocoService = inject(TranslocoService);
const defaultLang = translocoService.getDefaultLang();
translocoService.setActiveLang(defaultLang);
return translocoService.load(defaultLang).toPromise();
return () => translocoService.load(defaultLang).toPromise();
},
multi : true,
},
],
})
export class TranslocoCoreModule
{
}
];
};

View File

@ -3,9 +3,7 @@ import { Injectable } from '@angular/core';
import { User } from 'app/core/user/user.types';
import { map, Observable, ReplaySubject, tap } from 'rxjs';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class UserService
{
private _user: ReplaySubject<User> = new ReplaySubject<User>(1);

View File

@ -3,9 +3,7 @@ import { Injectable } from '@angular/core';
import { Message } from 'app/layout/common/messages/messages.types';
import { map, Observable, ReplaySubject, switchMap, take, tap } from 'rxjs';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class MessagesService
{
private _messages: ReplaySubject<Message[]> = new ReplaySubject<Message[]>(1);

View File

@ -3,9 +3,7 @@ import { Injectable } from '@angular/core';
import { Notification } from 'app/layout/common/notifications/notifications.types';
import { map, Observable, ReplaySubject, switchMap, take, tap } from 'rxjs';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class NotificationsService
{
private _notifications: ReplaySubject<Notification[]> = new ReplaySubject<Notification[]>(1);

View File

@ -3,9 +3,7 @@ import { Injectable } from '@angular/core';
import { Chat } from 'app/layout/common/quick-chat/quick-chat.types';
import { BehaviorSubject, map, Observable, of, switchMap, tap, throwError } from 'rxjs';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class QuickChatService
{
private _chat: BehaviorSubject<Chat> = new BehaviorSubject(null);

View File

@ -1,8 +1,9 @@
import { Overlay } from '@angular/cdk/overlay';
import { NgClass, NgFor, NgIf, NgTemplateOutlet } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { Component, ElementRef, EventEmitter, HostBinding, Input, OnChanges, OnDestroy, OnInit, Output, Renderer2, SimpleChanges, ViewChild, ViewEncapsulation } from '@angular/core';
import { Component, ElementRef, EventEmitter, HostBinding, inject, Input, OnChanges, OnDestroy, OnInit, Output, Renderer2, SimpleChanges, ViewChild, ViewEncapsulation } from '@angular/core';
import { FormsModule, ReactiveFormsModule, UntypedFormControl } from '@angular/forms';
import { MatAutocomplete, MatAutocompleteModule } from '@angular/material/autocomplete';
import { MAT_AUTOCOMPLETE_SCROLL_STRATEGY, MatAutocomplete, MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatButtonModule } from '@angular/material/button';
import { MatOptionModule } from '@angular/material/core';
import { MatFormFieldModule } from '@angular/material/form-field';
@ -20,6 +21,16 @@ import { debounceTime, filter, map, Subject, takeUntil } from 'rxjs';
animations : fuseAnimations,
standalone : true,
imports : [NgIf, MatButtonModule, MatIconModule, FormsModule, MatAutocompleteModule, ReactiveFormsModule, MatOptionModule, NgFor, RouterLink, NgTemplateOutlet, MatFormFieldModule, MatInputModule, NgClass],
providers : [
{
provide : MAT_AUTOCOMPLETE_SCROLL_STRATEGY,
useFactory: () =>
{
const overlay = inject(Overlay);
return () => overlay.scrollStrategies.block();
},
},
],
})
export class SearchComponent implements OnChanges, OnInit, OnDestroy
{

View File

@ -1,35 +0,0 @@
import { BlockScrollStrategy, Overlay } from '@angular/cdk/overlay';
import { NgModule } from '@angular/core';
import { MAT_AUTOCOMPLETE_SCROLL_STRATEGY, MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatButtonModule } from '@angular/material/button';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { RouterModule } from '@angular/router';
import { SearchComponent } from 'app/layout/common/search/search.component';
@NgModule({
imports : [
RouterModule.forChild([]),
MatAutocompleteModule,
MatButtonModule,
MatFormFieldModule,
MatIconModule,
MatInputModule,
SearchComponent,
],
exports : [
SearchComponent,
],
providers: [
{
provide : MAT_AUTOCOMPLETE_SCROLL_STRATEGY,
useFactory: (overlay: Overlay) => (): BlockScrollStrategy => overlay.scrollStrategies.block(),
deps : [Overlay],
},
],
})
export class SearchModule
{
}

View File

@ -5,9 +5,8 @@ import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';
import { Router } from '@angular/router';
import { FuseDrawerComponent } from '@fuse/components/drawer';
import { FuseConfigService } from '@fuse/services/config';
import { AppConfig, Scheme, Theme, Themes } from 'app/core/config/app.config';
import { Layout } from 'app/layout/layout.types';
import { FuseConfig, FuseConfigService, Scheme, Theme, Themes } from '@fuse/services/config';
import { Subject, takeUntil } from 'rxjs';
@Component({
@ -36,8 +35,8 @@ import { Subject, takeUntil } from 'rxjs';
})
export class SettingsComponent implements OnInit, OnDestroy
{
config: AppConfig;
layout: Layout;
config: FuseConfig;
layout: string;
scheme: 'dark' | 'light';
theme: string;
themes: Themes;
@ -65,7 +64,7 @@ export class SettingsComponent implements OnInit, OnDestroy
// Subscribe to config changes
this._fuseConfigService.config$
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((config: AppConfig) =>
.subscribe((config: FuseConfig) =>
{
// Store the config
this.config = config;

View File

@ -3,9 +3,7 @@ import { Injectable } from '@angular/core';
import { Shortcut } from 'app/layout/common/shortcuts/shortcuts.types';
import { map, Observable, ReplaySubject, switchMap, take, tap } from 'rxjs';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class ShortcutsService
{
private _shortcuts: ReplaySubject<Shortcut[]> = new ReplaySubject<Shortcut[]>(1);

View File

@ -1,12 +1,10 @@
import { DOCUMENT, NgIf } from '@angular/common';
import { Component, Inject, OnDestroy, OnInit, Renderer2, ViewEncapsulation } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { FuseConfigService } from '@fuse/services/config';
import { FuseConfig, FuseConfigService } from '@fuse/services/config';
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
import { FusePlatformService } from '@fuse/services/platform';
import { FUSE_VERSION } from '@fuse/version';
import { AppConfig } from 'app/core/config/app.config';
import { Layout } from 'app/layout/layout.types';
import { combineLatest, filter, map, Subject, takeUntil } from 'rxjs';
import { SettingsComponent } from './common/settings/settings.component';
import { EmptyLayoutComponent } from './layouts/empty/empty.component';
@ -31,8 +29,8 @@ import { ThinLayoutComponent } from './layouts/vertical/thin/thin.component';
})
export class LayoutComponent implements OnInit, OnDestroy
{
config: AppConfig;
layout: Layout;
config: FuseConfig;
layout: string;
scheme: 'dark' | 'light';
theme: string;
private _unsubscribeAll: Subject<any> = new Subject<any>();
@ -97,7 +95,7 @@ export class LayoutComponent implements OnInit, OnDestroy
// Subscribe to config changes
this._fuseConfigService.config$
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((config: AppConfig) =>
.subscribe((config: FuseConfig) =>
{
// Store the config
this.config = config;
@ -154,7 +152,7 @@ export class LayoutComponent implements OnInit, OnDestroy
// 2. Get the query parameter from the current route and
// set the layout and save the layout to the config
const layoutFromQueryParam = (route.snapshot.queryParamMap.get('layout') as Layout);
const layoutFromQueryParam = route.snapshot.queryParamMap.get('layout');
if ( layoutFromQueryParam )
{
this.layout = layoutFromQueryParam;

View File

@ -1,42 +0,0 @@
import { NgModule } from '@angular/core';
import { LayoutComponent } from 'app/layout/layout.component';
import { CenteredLayoutModule } from 'app/layout/layouts/horizontal/centered/centered.module';
import { EnterpriseLayoutModule } from 'app/layout/layouts/horizontal/enterprise/enterprise.module';
import { MaterialLayoutModule } from 'app/layout/layouts/horizontal/material/material.module';
import { ModernLayoutModule } from 'app/layout/layouts/horizontal/modern/modern.module';
import { ClassicLayoutModule } from 'app/layout/layouts/vertical/classic/classic.module';
import { ClassyLayoutModule } from 'app/layout/layouts/vertical/classy/classy.module';
import { CompactLayoutModule } from 'app/layout/layouts/vertical/compact/compact.module';
import { DenseLayoutModule } from 'app/layout/layouts/vertical/dense/dense.module';
import { FuturisticLayoutModule } from 'app/layout/layouts/vertical/futuristic/futuristic.module';
import { ThinLayoutModule } from 'app/layout/layouts/vertical/thin/thin.module';
const layoutModules = [
// Horizontal navigation
CenteredLayoutModule,
EnterpriseLayoutModule,
MaterialLayoutModule,
ModernLayoutModule,
// Vertical navigation
ClassicLayoutModule,
ClassyLayoutModule,
CompactLayoutModule,
DenseLayoutModule,
FuturisticLayoutModule,
ThinLayoutModule,
];
@NgModule({
imports: [
...layoutModules,
LayoutComponent,
],
exports: [
LayoutComponent,
...layoutModules,
],
})
export class LayoutModule
{
}

View File

@ -1,14 +0,0 @@
export type Layout =
| 'empty'
// Horizontal
| 'centered'
| 'enterprise'
| 'material'
| 'modern'
// Vertical
| 'classic'
| 'classy'
| 'compact'
| 'dense'
| 'futuristic'
| 'thin';

View File

@ -1,30 +0,0 @@
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
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 { RouterModule } from '@angular/router';
import { SearchModule } from 'app/layout/common/search/search.module';
import { CenteredLayoutComponent } from 'app/layout/layouts/horizontal/centered/centered.component';
@NgModule({
imports: [
HttpClientModule,
RouterModule,
MatButtonModule,
MatDividerModule,
MatIconModule,
MatMenuModule,
SearchModule,
CenteredLayoutComponent,
],
exports: [
CenteredLayoutComponent,
],
})
export class CenteredLayoutModule
{
}

View File

@ -1,30 +0,0 @@
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
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 { RouterModule } from '@angular/router';
import { SearchModule } from 'app/layout/common/search/search.module';
import { EnterpriseLayoutComponent } from 'app/layout/layouts/horizontal/enterprise/enterprise.component';
@NgModule({
imports: [
HttpClientModule,
RouterModule,
MatButtonModule,
MatDividerModule,
MatIconModule,
MatMenuModule,
SearchModule,
EnterpriseLayoutComponent,
],
exports: [
EnterpriseLayoutComponent,
],
})
export class EnterpriseLayoutModule
{
}

View File

@ -1,30 +0,0 @@
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
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 { RouterModule } from '@angular/router';
import { SearchModule } from 'app/layout/common/search/search.module';
import { MaterialLayoutComponent } from 'app/layout/layouts/horizontal/material/material.component';
@NgModule({
imports: [
HttpClientModule,
RouterModule,
MatButtonModule,
MatDividerModule,
MatIconModule,
MatMenuModule,
SearchModule,
MaterialLayoutComponent,
],
exports: [
MaterialLayoutComponent,
],
})
export class MaterialLayoutModule
{
}

View File

@ -1,30 +0,0 @@
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
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 { RouterModule } from '@angular/router';
import { SearchModule } from 'app/layout/common/search/search.module';
import { ModernLayoutComponent } from 'app/layout/layouts/horizontal/modern/modern.component';
@NgModule({
imports: [
HttpClientModule,
RouterModule,
MatButtonModule,
MatDividerModule,
MatIconModule,
MatMenuModule,
SearchModule,
ModernLayoutComponent,
],
exports: [
ModernLayoutComponent,
],
})
export class ModernLayoutModule
{
}

View File

@ -1,30 +0,0 @@
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
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 { RouterModule } from '@angular/router';
import { SearchModule } from 'app/layout/common/search/search.module';
import { ClassicLayoutComponent } from 'app/layout/layouts/vertical/classic/classic.component';
@NgModule({
imports: [
HttpClientModule,
RouterModule,
MatButtonModule,
MatDividerModule,
MatIconModule,
MatMenuModule,
SearchModule,
ClassicLayoutComponent,
],
exports: [
ClassicLayoutComponent,
],
})
export class ClassicLayoutModule
{
}

View File

@ -1,30 +0,0 @@
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
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 { RouterModule } from '@angular/router';
import { SearchModule } from 'app/layout/common/search/search.module';
import { ClassyLayoutComponent } from 'app/layout/layouts/vertical/classy/classy.component';
@NgModule({
imports: [
HttpClientModule,
RouterModule,
MatButtonModule,
MatDividerModule,
MatIconModule,
MatMenuModule,
SearchModule,
ClassyLayoutComponent,
],
exports: [
ClassyLayoutComponent,
],
})
export class ClassyLayoutModule
{
}

View File

@ -1,30 +0,0 @@
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
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 { RouterModule } from '@angular/router';
import { SearchModule } from 'app/layout/common/search/search.module';
import { CompactLayoutComponent } from 'app/layout/layouts/vertical/compact/compact.component';
@NgModule({
imports: [
HttpClientModule,
RouterModule,
MatButtonModule,
MatDividerModule,
MatIconModule,
MatMenuModule,
SearchModule,
CompactLayoutComponent,
],
exports: [
CompactLayoutComponent,
],
})
export class CompactLayoutModule
{
}

View File

@ -1,30 +0,0 @@
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
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 { RouterModule } from '@angular/router';
import { SearchModule } from 'app/layout/common/search/search.module';
import { DenseLayoutComponent } from 'app/layout/layouts/vertical/dense/dense.component';
@NgModule({
imports: [
HttpClientModule,
RouterModule,
MatButtonModule,
MatDividerModule,
MatIconModule,
MatMenuModule,
SearchModule,
DenseLayoutComponent,
],
exports: [
DenseLayoutComponent,
],
})
export class DenseLayoutModule
{
}

View File

@ -1,30 +0,0 @@
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
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 { RouterModule } from '@angular/router';
import { SearchModule } from 'app/layout/common/search/search.module';
import { FuturisticLayoutComponent } from 'app/layout/layouts/vertical/futuristic/futuristic.component';
@NgModule({
imports: [
HttpClientModule,
RouterModule,
MatButtonModule,
MatDividerModule,
MatIconModule,
MatMenuModule,
SearchModule,
FuturisticLayoutComponent,
],
exports: [
FuturisticLayoutComponent,
],
})
export class FuturisticLayoutModule
{
}

View File

@ -1,30 +0,0 @@
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
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 { RouterModule } from '@angular/router';
import { SearchModule } from 'app/layout/common/search/search.module';
import { ThinLayoutComponent } from 'app/layout/layouts/vertical/thin/thin.component';
@NgModule({
imports: [
HttpClientModule,
RouterModule,
MatButtonModule,
MatDividerModule,
MatIconModule,
MatMenuModule,
SearchModule,
ThinLayoutComponent,
],
exports: [
ThinLayoutComponent,
],
})
export class ThinLayoutModule
{
}

View File

@ -3,9 +3,7 @@ import { FuseMockApiService } from '@fuse/lib/mock-api/mock-api.service';
import { categories as categoriesData, courses as coursesData, demoCourseSteps as demoCourseStepsData } from 'app/mock-api/apps/academy/data';
import { cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class AcademyMockApi
{
private _categories: any[] = categoriesData;

View File

@ -3,9 +3,7 @@ import { FuseMockApiService } from '@fuse/lib/mock-api';
import { chats as chatsData, contacts as contactsData, messages as messagesData, profile as profileData } from 'app/mock-api/apps/chat/data';
import { assign, cloneDeep, omit } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class ChatMockApi
{
private _chats: any[] = chatsData;

View File

@ -4,9 +4,7 @@ import { contacts as contactsData, countries as countriesData, tags as tagsData
import { assign, cloneDeep } from 'lodash-es';
import { from, map } from 'rxjs';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class ContactsMockApi
{
private _contacts: any[] = contactsData;

View File

@ -3,9 +3,7 @@ import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api';
import { brands as brandsData, categories as categoriesData, products as productsData, tags as tagsData, vendors as vendorsData } from 'app/mock-api/apps/ecommerce/inventory/data';
import { assign, cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class ECommerceInventoryMockApi
{
private _categories: any[] = categoriesData;

View File

@ -3,9 +3,7 @@ import { FuseMockApiService } from '@fuse/lib/mock-api/mock-api.service';
import { items as itemsData } from 'app/mock-api/apps/file-manager/data';
import { cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class FileManagerMockApi
{
private _items: any[] = itemsData;

View File

@ -3,9 +3,7 @@ import { FuseMockApiService } from '@fuse/lib/mock-api';
import { faqCategories as faqCategoriesData, faqs as faqsData, guideCategories as guideCategoriesData, guideContent as guideContentData, guides as guidesData } from 'app/mock-api/apps/help-center/data';
import { cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class HelpCenterMockApi
{
private _faqCategories: any[] = faqCategoriesData;

View File

@ -3,9 +3,7 @@ import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api';
import { filters as filtersData, folders as foldersData, labels as labelsData, mails as mailsData, settings as settingsData } from 'app/mock-api/apps/mailbox/data';
import { assign, cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class MailboxMockApi
{
private _filters: any[] = filtersData;

View File

@ -4,9 +4,7 @@ import { FuseMockApiService } from '@fuse/lib/mock-api/mock-api.service';
import { labels as labelsData, notes as notesData } from 'app/mock-api/apps/notes/data';
import { cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class NotesMockApi
{
private _labels: any[] = labelsData;

View File

@ -3,9 +3,7 @@ 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';
import { assign, cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class ScrumboardMockApi
{
// Private

View File

@ -4,9 +4,7 @@ import { FuseMockApiUtils } from '@fuse/lib/mock-api/mock-api.utils';
import { tags as tagsData, tasks as tasksData } from 'app/mock-api/apps/tasks/data';
import { assign, cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class TasksMockApi
{
private _tags: any[] = tagsData;

View File

@ -6,9 +6,7 @@ import Utf8 from 'crypto-js/enc-utf8';
import HmacSHA256 from 'crypto-js/hmac-sha256';
import { cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class AuthMockApi
{
private readonly _secret: any;

View File

@ -3,9 +3,7 @@ import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api';
import { messages as messagesData } from 'app/mock-api/common/messages/data';
import { assign, cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class MessagesMockApi
{
private _messages: any = messagesData;

View File

@ -4,9 +4,7 @@ import { FuseMockApiService } from '@fuse/lib/mock-api';
import { compactNavigation, defaultNavigation, futuristicNavigation, horizontalNavigation } from 'app/mock-api/common/navigation/data';
import { cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class NavigationMockApi
{
private readonly _compactNavigation: FuseNavigationItem[] = compactNavigation;

View File

@ -967,7 +967,7 @@ export const defaultNavigation: FuseNavigationItem[] = [
icon : 'heroicons_outline:speakerphone',
link : '/docs/changelog',
badge: {
title : '17.2.0',
title : '18.0.0',
classes: 'px-2 bg-yellow-300 text-black rounded-full',
},
},
@ -978,6 +978,27 @@ export const defaultNavigation: FuseNavigationItem[] = [
icon : 'heroicons_outline:book-open',
link : '/docs/guides',
},
{
id : 'user-interface.material-components',
title: 'Material Components',
type : 'basic',
icon : 'heroicons_outline:chip',
link : '/ui/material-components',
},
{
id : 'user-interface.fuse-components',
title: 'Fuse Components',
type : 'basic',
icon : 'heroicons_outline:chip',
link : '/ui/fuse-components',
},
{
id : 'user-interface.other-components',
title: 'Other Components',
type : 'basic',
icon : 'heroicons_outline:chip',
link : '/ui/other-components',
},
],
},
{

View File

@ -3,9 +3,7 @@ import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api';
import { notifications as notificationsData } from 'app/mock-api/common/notifications/data';
import { assign, cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class NotificationsMockApi
{
private _notifications: any = notificationsData;

View File

@ -6,9 +6,7 @@ import { tasks } from 'app/mock-api/apps/tasks/data';
import { defaultNavigation } from 'app/mock-api/common/navigation/data';
import { cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class SearchMockApi
{
private readonly _defaultNavigation: FuseNavigationItem[] = defaultNavigation;

View File

@ -3,9 +3,7 @@ import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api';
import { shortcuts as shortcutsData } from 'app/mock-api/common/shortcuts/data';
import { assign, cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class ShortcutsMockApi
{
private _shortcuts: any = shortcutsData;

View File

@ -3,9 +3,7 @@ import { FuseMockApiService } from '@fuse/lib/mock-api';
import { user as userData } from 'app/mock-api/common/user/data';
import { assign, cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class UserMockApi
{
private _user: any = userData;

View File

@ -3,9 +3,7 @@ import { FuseMockApiService } from '@fuse/lib/mock-api';
import { analytics as analyticsData } from 'app/mock-api/dashboards/analytics/data';
import { cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class AnalyticsMockApi
{
private _analytics: any = analyticsData;

View File

@ -3,9 +3,7 @@ import { FuseMockApiService } from '@fuse/lib/mock-api';
import { crypto as cryptoData } from 'app/mock-api/dashboards/crypto/data';
import { cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class CryptoMockApi
{
private _crypto: any = cryptoData;

View File

@ -3,9 +3,7 @@ import { FuseMockApiService } from '@fuse/lib/mock-api';
import { finance as financeData } from 'app/mock-api/dashboards/finance/data';
import { cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class FinanceMockApi
{
private _finance: any = financeData;

View File

@ -3,9 +3,7 @@ import { FuseMockApiService } from '@fuse/lib/mock-api';
import { project as projectData } from 'app/mock-api/dashboards/project/data';
import { cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class ProjectMockApi
{
private _project: any = projectData;

View File

@ -3,9 +3,7 @@ import { FuseMockApiService } from '@fuse/lib/mock-api';
import { activities as activitiesData } from 'app/mock-api/pages/activities/data';
import { cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class ActivitiesMockApi
{
private _activities: any = activitiesData;

View File

@ -3,9 +3,7 @@ import { FuseMockApiService } from '@fuse/lib/mock-api';
import { feather, heroicons, material } from 'app/mock-api/ui/icons/data';
import { cloneDeep } from 'lodash-es';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class IconsMockApi
{
private readonly _feather: any = feather;

View File

@ -3,9 +3,7 @@ import { Injectable } from '@angular/core';
import { Category, Course } from 'app/modules/admin/apps/academy/academy.types';
import { BehaviorSubject, map, Observable, of, switchMap, tap, throwError } from 'rxjs';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class AcademyService
{
// Private

View File

@ -3,9 +3,7 @@ import { Injectable } from '@angular/core';
import { Chat, Contact, Profile } from 'app/modules/admin/apps/chat/chat.types';
import { BehaviorSubject, filter, map, Observable, of, switchMap, take, tap, throwError } from 'rxjs';
@Injectable({
providedIn: 'root',
})
@Injectable({providedIn: 'root'})
export class ChatService
{
private _chat: BehaviorSubject<Chat> = new BehaviorSubject(null);

View File

@ -1,5 +1,4 @@
import { ChangeDetectionStrategy, Component, ViewEncapsulation } from '@angular/core';
import { MatLuxonDateModule } from '@angular/material-luxon-adapter';
import { RouterOutlet } from '@angular/router';
@Component({

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