diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 521a9f7c..00000000 --- a/.npmrc +++ /dev/null @@ -1 +0,0 @@ -legacy-peer-deps=true diff --git a/.nvmrc b/.nvmrc index b6a7d89c..209e3ef4 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16 +20 diff --git a/angular.json b/angular.json index e4df938c..98cd72a4 100644 --- a/angular.json +++ b/angular.json @@ -32,7 +32,7 @@ "crypto-js/hmac-sha256", "crypto-js/enc-base64", "flat", - "quill" + "quill-delta" ], "assets": [ "src/favicon-16x16.png", @@ -90,10 +90,10 @@ "builder": "@angular-devkit/build-angular:dev-server", "configurations": { "production": { - "browserTarget": "fuse:build:production" + "buildTarget": "fuse:build:production" }, "development": { - "browserTarget": "fuse:build:development" + "buildTarget": "fuse:build:development" } }, "defaultConfiguration": "development" @@ -101,7 +101,7 @@ "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": { - "browserTarget": "fuse:build" + "buildTarget": "fuse:build" } }, "test": { diff --git a/package.json b/package.json index be50fb42..24198e3e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fuse-angular", - "version": "18.0.0", + "version": "19.1.0", "description": "Fuse - Angular Admin Template and Starter Project", "author": "https://themeforest.net/user/srcn", "license": "https://themeforest.net/licenses/standard", @@ -13,54 +13,53 @@ "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", + "@angular/animations": "17.2.4", + "@angular/cdk": "17.2.2", + "@angular/common": "17.2.4", + "@angular/compiler": "17.2.4", + "@angular/core": "17.2.4", + "@angular/forms": "17.2.4", + "@angular/material": "17.2.2", + "@angular/material-luxon-adapter": "17.2.2", + "@angular/platform-browser": "17.2.4", + "@angular/platform-browser-dynamic": "17.2.4", + "@angular/router": "17.2.4", + "@ngneat/transloco": "6.0.4", + "apexcharts": "3.47.0", + "crypto-js": "4.2.0", + "highlight.js": "11.9.0", "lodash-es": "4.17.21", - "luxon": "3.3.0", - "ng-apexcharts": "1.7.6", - "ngx-quill": "22.0.0", + "luxon": "3.4.4", + "ng-apexcharts": "1.9.0", + "ngx-quill": "25.1.1", "perfect-scrollbar": "1.5.5", - "quill": "1.3.7", "rxjs": "7.8.1", - "tslib": "2.5.2", - "zone.js": "0.13.0" + "tslib": "2.6.2", + "zone.js": "0.14.4" }, "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", + "@angular-devkit/build-angular": "17.2.3", + "@angular/cli": "17.2.3", + "@angular/compiler-cli": "17.2.4", + "@tailwindcss/typography": "0.5.10", + "@types/chroma-js": "2.4.4", + "@types/crypto-js": "4.2.2", "@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", + "@types/jasmine": "5.1.4", + "@types/lodash": "4.14.202", + "@types/lodash-es": "4.17.12", + "@types/luxon": "3.4.2", + "autoprefixer": "10.4.18", "chroma-js": "2.4.2", - "jasmine-core": "5.0.0", - "karma": "6.4.2", + "jasmine-core": "5.1.2", + "karma": "6.4.3", "karma-chrome-launcher": "3.2.0", - "karma-coverage": "2.2.0", + "karma-coverage": "2.2.1", "karma-jasmine": "5.1.0", - "karma-jasmine-html-reporter": "2.0.0", + "karma-jasmine-html-reporter": "2.1.0", "lodash": "4.17.21", - "postcss": "8.4.24", - "tailwindcss": "3.3.2", - "typescript": "5.0.4" + "postcss": "8.4.35", + "tailwindcss": "3.4.1", + "typescript": "5.3.3" } } diff --git a/src/@fuse/components/fullscreen/fullscreen.component.ts b/src/@fuse/components/fullscreen/fullscreen.component.ts index 258267b7..b78e0424 100644 --- a/src/@fuse/components/fullscreen/fullscreen.component.ts +++ b/src/@fuse/components/fullscreen/fullscreen.component.ts @@ -1,46 +1,27 @@ import { DOCUMENT, NgTemplateOutlet } from '@angular/common'; -import { ChangeDetectionStrategy, Component, Inject, Input, OnInit, TemplateRef, ViewEncapsulation } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Inject, Input, TemplateRef, ViewEncapsulation } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { MatIconModule } from '@angular/material/icon'; import { MatTooltipModule } from '@angular/material/tooltip'; -import { FSDocument, FSDocumentElement } from '@fuse/components/fullscreen/fullscreen.types'; @Component({ - selector : 'fuse-fullscreen', - templateUrl : './fullscreen.component.html', - encapsulation : ViewEncapsulation.None, + selector: 'fuse-fullscreen', + templateUrl: './fullscreen.component.html', + encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, - exportAs : 'fuseFullscreen', - standalone : true, - imports : [MatButtonModule, MatTooltipModule, NgTemplateOutlet, MatIconModule], + exportAs: 'fuseFullscreen', + standalone: true, + imports: [MatButtonModule, MatTooltipModule, NgTemplateOutlet, MatIconModule], }) -export class FuseFullscreenComponent implements OnInit +export class FuseFullscreenComponent { @Input() iconTpl: TemplateRef; @Input() tooltip: string; - private _fsDoc: FSDocument; - private _fsDocEl: FSDocumentElement; - private _isFullscreen: boolean = false; /** * Constructor */ - constructor(@Inject(DOCUMENT) private _document: Document) - { - this._fsDoc = _document as FSDocument; - } - - // ----------------------------------------------------------------------------------------------------- - // @ Lifecycle hooks - // ----------------------------------------------------------------------------------------------------- - - /** - * On init - */ - ngOnInit(): void - { - this._fsDocEl = document.documentElement as FSDocumentElement; - } + constructor(@Inject(DOCUMENT) private _document: Document) { } // ----------------------------------------------------------------------------------------------------- // @ Public methods @@ -51,121 +32,27 @@ export class FuseFullscreenComponent implements OnInit */ toggleFullscreen(): void { - // Check if the fullscreen is open - this._isFullscreen = this._getBrowserFullscreenElement() !== null; + if (!this._document.fullscreenEnabled) + { + console.log('Fullscreen is not available in this browser.'); + return; + } + + // Check if the fullscreen is already open + const fullScreen = this._document.fullscreenElement; // Toggle the fullscreen - if ( this._isFullscreen ) + if (fullScreen) { - this._closeFullscreen(); + this._document.exitFullscreen(); } else { - this._openFullscreen(); - } - } - - // ----------------------------------------------------------------------------------------------------- - // @ Private methods - // ----------------------------------------------------------------------------------------------------- - - /** - * Get browser's fullscreen element - * - * @private - */ - private _getBrowserFullscreenElement(): Element - { - if ( typeof this._fsDoc.fullscreenElement !== 'undefined' ) - { - return this._fsDoc.fullscreenElement; - } - - if ( typeof this._fsDoc.mozFullScreenElement !== 'undefined' ) - { - return this._fsDoc.mozFullScreenElement; - } - - if ( typeof this._fsDoc.msFullscreenElement !== 'undefined' ) - { - return this._fsDoc.msFullscreenElement; - } - - if ( typeof this._fsDoc.webkitFullscreenElement !== 'undefined' ) - { - return this._fsDoc.webkitFullscreenElement; - } - - throw new Error('Fullscreen mode is not supported by this browser'); - } - - /** - * Open the fullscreen - * - * @private - */ - private _openFullscreen(): void - { - if ( this._fsDocEl.requestFullscreen ) - { - this._fsDocEl.requestFullscreen(); - return; - } - - // Firefox - if ( this._fsDocEl.mozRequestFullScreen ) - { - this._fsDocEl.mozRequestFullScreen(); - return; - } - - // Chrome, Safari and Opera - if ( this._fsDocEl.webkitRequestFullscreen ) - { - this._fsDocEl.webkitRequestFullscreen(); - return; - } - - // IE/Edge - if ( this._fsDocEl.msRequestFullscreen ) - { - this._fsDocEl.msRequestFullscreen(); - return; - } - } - - /** - * Close the fullscreen - * - * @private - */ - private _closeFullscreen(): void - { - if ( this._fsDoc.exitFullscreen ) - { - this._fsDoc.exitFullscreen(); - return; - } - - // Firefox - if ( this._fsDoc.mozCancelFullScreen ) - { - this._fsDoc.mozCancelFullScreen(); - return; - } - - // Chrome, Safari and Opera - if ( this._fsDoc.webkitExitFullscreen ) - { - this._fsDoc.webkitExitFullscreen(); - return; - } - - // IE/Edge - else if ( this._fsDoc.msExitFullscreen ) - { - this._fsDoc.msExitFullscreen(); - return; + this._document.documentElement.requestFullscreen() + .catch(() => + { + console.error('Entering fullscreen mode failed.'); + }); } } } diff --git a/src/@fuse/components/fullscreen/fullscreen.types.ts b/src/@fuse/components/fullscreen/fullscreen.types.ts deleted file mode 100644 index 0477a1d4..00000000 --- a/src/@fuse/components/fullscreen/fullscreen.types.ts +++ /dev/null @@ -1,16 +0,0 @@ -export interface FSDocument extends HTMLDocument -{ - mozFullScreenElement?: Element; - mozCancelFullScreen?: () => void; - msFullscreenElement?: Element; - msExitFullscreen?: () => void; - webkitFullscreenElement?: Element; - webkitExitFullscreen?: () => void; -} - -export interface FSDocumentElement extends HTMLElement -{ - mozRequestFullScreen?: () => void; - msRequestFullscreen?: () => void; - webkitRequestFullscreen?: () => void; -} diff --git a/src/@fuse/components/fullscreen/public-api.ts b/src/@fuse/components/fullscreen/public-api.ts index 03aee0fc..3db68687 100644 --- a/src/@fuse/components/fullscreen/public-api.ts +++ b/src/@fuse/components/fullscreen/public-api.ts @@ -1,2 +1 @@ export * from '@fuse/components/fullscreen/fullscreen.component'; -export * from '@fuse/components/fullscreen/fullscreen.types'; diff --git a/src/@fuse/styles/components/input.scss b/src/@fuse/styles/components/input.scss index 4ac91a49..391b400d 100644 --- a/src/@fuse/styles/components/input.scss +++ b/src/@fuse/styles/components/input.scss @@ -19,20 +19,22 @@ textarea { @apply text-hint; } - &:-webkit-autofill { - transition: background-color 600000s 0s, color 600000s 0s !important; - } - - &:-webkit-autofill:hover { - transition: background-color 600000s 0s, color 600000s 0s !important; - } - - &:-webkit-autofill:focus { - transition: background-color 600000s 0s, color 600000s 0s !important; - } - + /* Autofill color fix */ + &:-webkit-autofill, + &:-webkit-autofill:hover, + &:-webkit-autofill:focus, &:-webkit-autofill:active { - transition: background-color 600000s 0s, color 600000s 0s !important; + -webkit-background-clip: text; + transition: background-color 5000s !important; + } + + .dark & { + &:-webkit-autofill, + &:-webkit-autofill:hover, + &:-webkit-autofill:focus, + &:-webkit-autofill:active { + -webkit-text-fill-color: rgba(255, 255, 255, 0.87); + } } [data-autocompleted] { diff --git a/src/@fuse/styles/overrides/angular-material.scss b/src/@fuse/styles/overrides/angular-material.scss index 99d2b488..fb6f3c2a 100644 --- a/src/@fuse/styles/overrides/angular-material.scss +++ b/src/@fuse/styles/overrides/angular-material.scss @@ -1192,6 +1192,21 @@ /* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +/* @ Snack bar +/* -------------------------------------------------------------------------- */ +.mat-mdc-snack-bar-container { + + .mat-mdc-button.mat-mdc-snack-bar-action:not(:disabled) { + color: #FFFFFF !important; + + .dark & { + color: #000000 !important; + } + } +} + + /* -------------------------------------------------------------------------- */ /* @ Stepper /* -------------------------------------------------------------------------- */ diff --git a/src/@fuse/styles/tailwind.scss b/src/@fuse/styles/tailwind.scss index b3f83023..ec8610ab 100644 --- a/src/@fuse/styles/tailwind.scss +++ b/src/@fuse/styles/tailwind.scss @@ -121,7 +121,7 @@ } /* Set the foreground color for disabled elements */ - [disabled] * { + [disabled] { @apply text-disabled #{'!important'}; } diff --git a/src/@fuse/version/fuse-version.ts b/src/@fuse/version/fuse-version.ts index 80774733..d358a42a 100644 --- a/src/@fuse/version/fuse-version.ts +++ b/src/@fuse/version/fuse-version.ts @@ -1,3 +1,3 @@ import { Version } from '@fuse/version/version'; -export const FUSE_VERSION = new Version('18.0.0').full; +export const FUSE_VERSION = new Version('19.1.0').full; diff --git a/src/app/app.config.ts b/src/app/app.config.ts index 46531567..04e8eeb4 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -1,15 +1,17 @@ import { provideHttpClient } from '@angular/common/http'; -import { ApplicationConfig } from '@angular/core'; +import { APP_INITIALIZER, ApplicationConfig, inject } 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 { provideTransloco, TranslocoService } from '@ngneat/transloco'; +import { firstValueFrom } from 'rxjs'; 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'; +import { TranslocoHttpLoader } from './core/transloco/transloco.http-loader'; export const appConfig: ApplicationConfig = { providers: [ @@ -41,7 +43,38 @@ export const appConfig: ApplicationConfig = { }, // Transloco Config - provideTransloco(), + provideTransloco({ + config: { + availableLangs : [ + { + id : 'en', + label: 'English', + }, + { + id : 'tr', + label: 'Turkish', + }, + ], + defaultLang : 'en', + fallbackLang : 'en', + reRenderOnLangChange: true, + prodMode : true, + }, + loader: TranslocoHttpLoader, + }), + { + // Preload the default language before the app starts to prevent empty/jumping content + provide : APP_INITIALIZER, + useFactory: () => + { + const translocoService = inject(TranslocoService); + const defaultLang = translocoService.getDefaultLang(); + translocoService.setActiveLang(defaultLang); + + return () => firstValueFrom(translocoService.load(defaultLang)); + }, + multi : true, + }, // Fuse provideAuth(), diff --git a/src/app/core/auth/auth.service.ts b/src/app/core/auth/auth.service.ts index dcd7bf72..794acab5 100644 --- a/src/app/core/auth/auth.service.ts +++ b/src/app/core/auth/auth.service.ts @@ -1,5 +1,5 @@ import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { AuthUtils } from 'app/core/auth/auth.utils'; import { UserService } from 'app/core/user/user.service'; import { catchError, Observable, of, switchMap, throwError } from 'rxjs'; @@ -8,16 +8,8 @@ import { catchError, Observable, of, switchMap, throwError } from 'rxjs'; export class AuthService { private _authenticated: boolean = false; - - /** - * Constructor - */ - constructor( - private _httpClient: HttpClient, - private _userService: UserService, - ) - { - } + private _httpClient = inject(HttpClient); + private _userService = inject(UserService); // ----------------------------------------------------------------------------------------------------- // @ Accessors diff --git a/src/app/core/auth/auth.utils.ts b/src/app/core/auth/auth.utils.ts index 233fe799..38d02396 100644 --- a/src/app/core/auth/auth.utils.ts +++ b/src/app/core/auth/auth.utils.ts @@ -7,13 +7,6 @@ export class AuthUtils { - /** - * Constructor - */ - constructor() - { - } - // ----------------------------------------------------------------------------------------------------- // @ Public methods // ----------------------------------------------------------------------------------------------------- diff --git a/src/app/core/navigation/navigation.service.ts b/src/app/core/navigation/navigation.service.ts index 7309b151..e5dbeb50 100644 --- a/src/app/core/navigation/navigation.service.ts +++ b/src/app/core/navigation/navigation.service.ts @@ -1,20 +1,14 @@ import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { Navigation } from 'app/core/navigation/navigation.types'; import { Observable, ReplaySubject, tap } from 'rxjs'; @Injectable({providedIn: 'root'}) export class NavigationService { + private _httpClient = inject(HttpClient); private _navigation: ReplaySubject = new ReplaySubject(1); - /** - * Constructor - */ - constructor(private _httpClient: HttpClient) - { - } - // ----------------------------------------------------------------------------------------------------- // @ Accessors // ----------------------------------------------------------------------------------------------------- diff --git a/src/app/core/transloco/transloco.http-loader.ts b/src/app/core/transloco/transloco.http-loader.ts index 958e2107..07870e28 100644 --- a/src/app/core/transloco/transloco.http-loader.ts +++ b/src/app/core/transloco/transloco.http-loader.ts @@ -1,18 +1,12 @@ import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { Translation, TranslocoLoader } from '@ngneat/transloco'; import { Observable } from 'rxjs'; @Injectable({providedIn: 'root'}) export class TranslocoHttpLoader implements TranslocoLoader { - /** - * Constructor - */ - constructor( - private _httpClient: HttpClient) - { - } + private _httpClient = inject(HttpClient); // ----------------------------------------------------------------------------------------------------- // @ Public methods diff --git a/src/app/core/transloco/transloco.provider.ts b/src/app/core/transloco/transloco.provider.ts deleted file mode 100644 index 1b86009a..00000000 --- a/src/app/core/transloco/transloco.provider.ts +++ /dev/null @@ -1,48 +0,0 @@ -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'; - -export const provideTransloco = (): Array => -{ - return [ - importProvidersFrom(TranslocoModule), - { - // Provide the default Transloco configuration - provide : TRANSLOCO_CONFIG, - useValue: translocoConfig({ - availableLangs : [ - { - id : 'en', - label: 'English', - }, - { - id : 'tr', - label: 'Turkish', - }, - ], - defaultLang : 'en', - fallbackLang : 'en', - reRenderOnLangChange: true, - prodMode : true, - }), - }, - { - // 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, - useFactory: () => - { - const translocoService = inject(TranslocoService); - const defaultLang = translocoService.getDefaultLang(); - translocoService.setActiveLang(defaultLang); - - return () => translocoService.load(defaultLang).toPromise(); - }, - multi : true, - }, - ]; -}; diff --git a/src/app/core/user/user.service.ts b/src/app/core/user/user.service.ts index a7d71d02..ee4ba2b4 100644 --- a/src/app/core/user/user.service.ts +++ b/src/app/core/user/user.service.ts @@ -1,20 +1,14 @@ import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { User } from 'app/core/user/user.types'; import { map, Observable, ReplaySubject, tap } from 'rxjs'; @Injectable({providedIn: 'root'}) export class UserService { + private _httpClient = inject(HttpClient); private _user: ReplaySubject = new ReplaySubject(1); - /** - * Constructor - */ - constructor(private _httpClient: HttpClient) - { - } - // ----------------------------------------------------------------------------------------------------- // @ Accessors // ----------------------------------------------------------------------------------------------------- @@ -40,7 +34,7 @@ export class UserService // ----------------------------------------------------------------------------------------------------- /** - * Get the current logged in user data + * Get the current signed-in user data */ get(): Observable { diff --git a/src/app/layout/common/messages/messages.component.html b/src/app/layout/common/messages/messages.component.html index 8608f0fc..74613839 100644 --- a/src/app/layout/common/messages/messages.component.html +++ b/src/app/layout/common/messages/messages.component.html @@ -32,6 +32,7 @@
Messages
diff --git a/src/app/layout/layouts/vertical/futuristic/futuristic.component.html b/src/app/layout/layouts/vertical/futuristic/futuristic.component.html index 7411e164..43a688f2 100644 --- a/src/app/layout/layouts/vertical/futuristic/futuristic.component.html +++ b/src/app/layout/layouts/vertical/futuristic/futuristic.component.html @@ -27,7 +27,7 @@ {{user.name}}
- brian.hughes@company.com + brian.hughes@company.com