Compare commits

..

19 Commits

Author SHA1 Message Date
sercan
206ef711a4 (QuickChat) Don't use types from outside 2021-08-31 10:17:57 +03:00
sercan
7e0cc1249e (QuickChat) Don't use types from outside 2021-08-31 10:17:06 +03:00
sercan
138a43da59 (QuickChat) Don't use types from outside 2021-08-31 10:16:13 +03:00
sercan
fe7e2514a6 Updated dependencies, increased the version number & updated the changelog 2021-08-31 09:43:10 +03:00
sercan
b8f0d9f0b2 (QuickChat) Added the Quick Chat bar 2021-08-31 09:21:28 +03:00
sercan
2a4a392153 (layout) Separated the Settings drawer from the layout component 2021-08-31 09:20:55 +03:00
sercan
c2fa88f4d4 (fuse/drawer) Fixed: Final opacity of the overlay is not permanent due to player being destroyed right after the animation 2021-08-17 22:05:13 +03:00
sercan
67d25012ec Increased the version number & updated the changelog 2021-08-12 17:04:57 +03:00
sercan
6de6a07778 Decreased budget sizes since new Fuse is a lot smaller compared to the one with the old design 2021-08-12 13:57:29 +03:00
sercan
e7ab0ea13f (apps/mailbox) Fixed: Compose dialog doesn't work correctly on small height resolutions
(apps/mailbox) Style improvements
2021-08-12 13:45:34 +03:00
sercan
4b686d86cc (@fuse/overrides) Fixed: Quill editor is not styled correctly by default 2021-08-12 13:42:59 +03:00
sercan
190395f14b (@fuse/theming) Better structuring on the themes.scss file
(@fuse) Disabled Angular Material 'theme' sanity check since we use 'all-component-themes' without a color map
2021-08-12 13:17:53 +03:00
sercan
4a9b8ee91e (dependencies) Updated Angular, Angular Material and various other dependencies 2021-08-12 11:32:04 +03:00
sercan
488fe8a1eb (ui/page-layouts) Fixed: Demo layout navigation appearance is not correct 2021-08-11 22:25:49 +03:00
sercan
db9a2a2433 (dependencies) Updated Angular, Angular Material and various other dependencies 2021-08-11 22:25:15 +03:00
sercan
3dda8479cf (tailwindcss) Removed old jsdoc from the config file 2021-08-08 22:27:24 +03:00
sercan
7c402670a1 (docs/confirmation) Updated the docs of the confirmation dialog 2021-08-04 10:10:07 +03:00
sercan
f6bf0fb5d3 (fuse/confirmation) Fixed: Dialog size cannot be updated using dialogRef's "updateSize" method 2021-08-04 09:54:35 +03:00
sercan
d44c004d01 Removed empty "styles" from component decorators 2021-08-04 09:46:36 +03:00
96 changed files with 2593 additions and 1720 deletions

View File

@@ -12,7 +12,7 @@ Run `ng generate component component-name` to generate a new component. You can
## Build
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
## Running unit tests
@@ -20,7 +20,7 @@ Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.
## Running end-to-end tests
Run `ng e2e` to execute the end-to-end tests via a platform of your choice.
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
## Further help

View File

@@ -60,13 +60,13 @@
"budgets": [
{
"type": "initial",
"maximumWarning": "5mb",
"maximumError": "8mb"
"maximumWarning": "3mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "100kb",
"maximumError": "150kb"
"maximumWarning": "75kb",
"maximumError": "90kb"
}
],
"fileReplacements": [

1882
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "@fuse/demo",
"version": "13.4.0",
"version": "13.6.0",
"description": "Fuse - Angular Admin Template and Starter Project",
"author": "https://themeforest.net/user/srcn",
"license": "https://themeforest.net/licenses/standard",
@@ -9,21 +9,22 @@
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test",
"lint": "ng lint"
},
"dependencies": {
"@angular/animations": "12.1.4",
"@angular/cdk": "12.1.4",
"@angular/common": "12.1.4",
"@angular/compiler": "12.1.4",
"@angular/core": "12.1.4",
"@angular/forms": "12.1.4",
"@angular/material": "12.1.4",
"@angular/material-moment-adapter": "12.1.4",
"@angular/platform-browser": "12.1.4",
"@angular/platform-browser-dynamic": "12.1.4",
"@angular/router": "12.1.4",
"@angular/animations": "12.2.3",
"@angular/cdk": "12.2.3",
"@angular/common": "12.2.3",
"@angular/compiler": "12.2.3",
"@angular/core": "12.2.3",
"@angular/forms": "12.2.3",
"@angular/material": "12.2.3",
"@angular/material-moment-adapter": "12.2.3",
"@angular/platform-browser": "12.2.3",
"@angular/platform-browser-dynamic": "12.2.3",
"@angular/router": "12.2.3",
"@fullcalendar/angular": "4.4.5-beta",
"@fullcalendar/core": "4.4.2",
"@fullcalendar/daygrid": "4.4.2",
@@ -33,31 +34,31 @@
"@fullcalendar/rrule": "4.4.2",
"@fullcalendar/timegrid": "4.4.2",
"@ngneat/transloco": "2.22.0",
"apexcharts": "3.27.3",
"apexcharts": "3.28.1",
"crypto-js": "3.3.0",
"highlight.js": "11.1.0",
"highlight.js": "11.2.0",
"lodash-es": "4.17.21",
"moment": "2.29.1",
"ng-apexcharts": "1.5.12",
"ngx-markdown": "12.0.1",
"ngx-quill": "14.1.2",
"ngx-quill": "14.3.0",
"perfect-scrollbar": "1.5.2",
"quill": "1.3.7",
"rrule": "2.6.8",
"rxjs": "6.6.7",
"tslib": "2.3.0",
"tslib": "2.3.1",
"web-animations-js": "2.3.2",
"zone.js": "0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "12.1.4",
"@angular-devkit/build-angular": "12.2.3",
"@angular-eslint/builder": "12.3.1",
"@angular-eslint/eslint-plugin": "12.3.1",
"@angular-eslint/eslint-plugin-template": "12.3.1",
"@angular-eslint/schematics": "12.3.1",
"@angular-eslint/template-parser": "12.3.1",
"@angular/cli": "12.1.4",
"@angular/compiler-cli": "12.1.4",
"@angular/cli": "12.2.3",
"@angular/compiler-cli": "12.2.3",
"@tailwindcss/aspect-ratio": "0.2.1",
"@tailwindcss/line-clamp": "0.2.1",
"@tailwindcss/typography": "0.4.1",
@@ -65,16 +66,16 @@
"@types/crypto-js": "3.1.47",
"@types/highlight.js": "10.1.0",
"@types/jasmine": "3.8.2",
"@types/lodash": "4.14.171",
"@types/lodash": "4.14.172",
"@types/lodash-es": "4.17.4",
"@types/node": "12.20.17",
"@typescript-eslint/eslint-plugin": "4.28.5",
"@typescript-eslint/parser": "4.28.5",
"autoprefixer": "10.3.1",
"@types/node": "12.20.21",
"@typescript-eslint/eslint-plugin": "4.30.0",
"@typescript-eslint/parser": "4.30.0",
"autoprefixer": "10.3.3",
"chroma-js": "2.1.2",
"eslint": "7.31.0",
"eslint-plugin-import": "2.23.4",
"eslint-plugin-jsdoc": "36.0.6",
"eslint": "7.32.0",
"eslint-plugin-import": "2.24.2",
"eslint-plugin-jsdoc": "36.0.8",
"eslint-plugin-prefer-arrow": "1.2.3",
"jasmine-core": "3.8.0",
"karma": "6.3.4",
@@ -84,7 +85,7 @@
"karma-jasmine-html-reporter": "1.7.0",
"lodash": "4.17.21",
"postcss": "8.3.6",
"tailwindcss": "2.2.7",
"tailwindcss": "2.2.9",
"typescript": "4.3.5"
}
}

View File

@@ -116,7 +116,7 @@ fuse-drawer {
left: 0;
right: 0;
z-index: 299;
opacity: 0;
opacity: 1;
background-color: rgba(0, 0, 0, 0.6);
/* Fixed mode */

View File

@@ -211,6 +211,12 @@ export class FuseDrawerComponent implements OnChanges, OnInit, OnDestroy
*/
ngOnDestroy(): void
{
// Finish the animation
if ( this._player )
{
this._player.finish();
}
// Deregister the drawer from the registry
this._fuseDrawerService.deregisterComponent(this.name);
}
@@ -338,6 +344,7 @@ export class FuseDrawerComponent implements OnChanges, OnInit, OnDestroy
// Create the enter animation and attach it to the player
this._player = this._animationBuilder.build([
style({opacity: 0}),
animate('300ms cubic-bezier(0.25, 0.8, 0.25, 1)', style({opacity: 1}))
]).create(this._overlay);
@@ -346,6 +353,7 @@ export class FuseDrawerComponent implements OnChanges, OnInit, OnDestroy
// Destroy the player
this._player.destroy();
this._player = null;
});
// Play the animation
@@ -382,6 +390,7 @@ export class FuseDrawerComponent implements OnChanges, OnInit, OnDestroy
// Destroy the player
this._player.destroy();
this._player = null;
// If the backdrop still exists...
if ( this._overlay )

View File

@@ -10,7 +10,6 @@ import { FuseUtilsService } from '@fuse/services/utils/utils.service';
@Component({
selector : 'fuse-horizontal-navigation-basic-item',
templateUrl : './basic.component.html',
styles : [],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FuseHorizontalNavigationBasicItemComponent implements OnInit, OnDestroy

View File

@@ -10,7 +10,6 @@ import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types
@Component({
selector : 'fuse-horizontal-navigation-branch-item',
templateUrl : './branch.component.html',
styles : [],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FuseHorizontalNavigationBranchItemComponent implements OnInit, OnDestroy

View File

@@ -8,7 +8,6 @@ import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types
@Component({
selector : 'fuse-horizontal-navigation-divider-item',
templateUrl : './divider.component.html',
styles : [],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FuseHorizontalNavigationDividerItemComponent implements OnInit, OnDestroy

View File

@@ -8,7 +8,6 @@ import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types
@Component({
selector : 'fuse-horizontal-navigation-spacer-item',
templateUrl : './spacer.component.html',
styles : [],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FuseHorizontalNavigationSpacerItemComponent implements OnInit, OnDestroy

View File

@@ -10,7 +10,6 @@ import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types
@Component({
selector : 'fuse-vertical-navigation-aside-item',
templateUrl : './aside.component.html',
styles : [],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FuseVerticalNavigationAsideItemComponent implements OnChanges, OnInit, OnDestroy

View File

@@ -10,7 +10,6 @@ import { FuseUtilsService } from '@fuse/services/utils/utils.service';
@Component({
selector : 'fuse-vertical-navigation-basic-item',
templateUrl : './basic.component.html',
styles : [],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FuseVerticalNavigationBasicItemComponent implements OnInit, OnDestroy

View File

@@ -11,7 +11,6 @@ import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types
@Component({
selector : 'fuse-vertical-navigation-collapsable-item',
templateUrl : './collapsable.component.html',
styles : [],
animations : fuseAnimations,
changeDetection: ChangeDetectionStrategy.OnPush
})

View File

@@ -8,7 +8,6 @@ import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types
@Component({
selector : 'fuse-vertical-navigation-divider-item',
templateUrl : './divider.component.html',
styles : [],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FuseVerticalNavigationDividerItemComponent implements OnInit, OnDestroy

View File

@@ -9,7 +9,6 @@ import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types
@Component({
selector : 'fuse-vertical-navigation-group-item',
templateUrl : './group.component.html',
styles : [],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FuseVerticalNavigationGroupItemComponent implements OnInit, OnDestroy

View File

@@ -8,7 +8,6 @@ import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types
@Component({
selector : 'fuse-vertical-navigation-spacer-item',
templateUrl : './spacer.component.html',
styles : [],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FuseVerticalNavigationSpacerItemComponent implements OnInit, OnDestroy

View File

@@ -1,4 +1,5 @@
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 { FuseMediaWatcherModule } from '@fuse/services/media-watcher/media-watcher.module';
@@ -15,6 +16,15 @@ import { FuseUtilsModule } from '@fuse/services/utils/utils.module';
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,

View File

@@ -51,7 +51,8 @@ export class FuseConfirmationService
return this._matDialog.open(FuseConfirmationDialogComponent, {
autoFocus : false,
disableClose: !userConfig.dismissible,
data : userConfig
data : userConfig,
panelClass : 'fuse-confirmation-dialog-panel'
});
}
}

View File

@@ -1,4 +1,4 @@
<div class="relative flex flex-col md:w-128 -m-6">
<div class="relative flex flex-col w-full h-full">
<!-- Dismiss button -->
<ng-container *ngIf="data.dismissible">
@@ -14,7 +14,7 @@
</ng-container>
<!-- Content -->
<div class="flex flex-col sm:flex-row items-center sm:items-start p-8 pb-6 sm:pb-8">
<div class="flex flex-col sm:flex-row flex-auto items-center sm:items-start p-8 pb-6 sm:pb-8">
<!-- Icon -->
<ng-container *ngIf="data.icon.show">

View File

@@ -5,6 +5,20 @@ import { FuseConfirmationConfig } from '@fuse/services/confirmation/confirmation
@Component({
selector : 'fuse-confirmation-dialog',
templateUrl : './dialog.component.html',
styles : [
/* language=SCSS */
`
.fuse-confirmation-dialog-panel {
@screen md {
@apply w-128;
}
.mat-dialog-container {
padding: 0 !important;
}
}
`
],
encapsulation: ViewEncapsulation.None
})
export class FuseConfirmationDialogComponent implements OnInit

View File

@@ -4,11 +4,12 @@
.ql-toolbar {
border-radius: 6px 6px 0 0;
padding: 0 !important;
@apply bg-gray-100 border-gray-300;
@apply bg-gray-100;
@apply border-gray-300 border-opacity-100 #{'!important'};
.dark & {
background-color: rgba(0, 0, 0, 0.05);
@apply border-gray-500;
@apply border-gray-500 #{'!important'};
}
.ql-formats {
@@ -81,26 +82,22 @@
.ql-container {
overflow: hidden;
border-radius: 0 0 6px 6px;
@apply border-gray-300 shadow-sm;
@apply border-gray-300 border-opacity-100 shadow-sm #{'!important'};
.dark & {
@apply border-gray-500;
@apply border-gray-500 #{'!important'};
}
.ql-editor {
min-height: 160px;
max-height: 160px;
height: 160px;
@apply bg-gray-50;
@apply bg-card;
.dark & {
background-color: rgba(0, 0, 0, 0.05);
}
&:focus {
@apply bg-card;
}
&.ql-blank::before {
@apply text-hint;
}

View File

@@ -18,81 +18,6 @@
)
));
/* Prepare the Background and Foreground maps */
$background-light: (
status-bar: #CBD5E1, /* blueGray.300 */
app-bar: #FFFFFF,
background: #F1F5F9, /* blueGray.100 */
hover: rgba(148, 163, 184, 0.12), /* blueGray.400 + opacity */
card: #FFFFFF,
dialog: #FFFFFF,
disabled-button: rgba(148, 163, 184, 0.38), /* blueGray.400 + opacity */
raised-button: #FFFFFF,
focused-button: #64748B, /* blueGray.500 */
selected-button: #E2E8F0, /* blueGray.200 */
selected-disabled-button: #E2E8F0, /* blueGray.200 */
disabled-button-toggle: #CBD5E1, /* blueGray.300 */
unselected-chip: #E2E8F0, /* blueGray.200 */
disabled-list-option: #CBD5E1, /* blueGray.300 */
tooltip: #1E293B /* blueGray.800 */
);
$background-dark: (
status-bar: #0F172A, /* blueGray.900 */
app-bar: #0F172A, /* blueGray.900 */
background: #0F172A, /* blueGray.900 */
hover: rgba(255, 255, 255, 0.05),
card: #1E293B, /* blueGray.800 */
dialog: #1E293B, /* blueGray.800 */
disabled-button: rgba(15, 23, 42, 0.38), /* blueGray.900 + opacity */
raised-button: #0F172A, /* blueGray.900 */
focused-button: #E2E8F0, /* blueGray.200 */
selected-button: rgba(255, 255, 255, 0.05),
selected-disabled-button: #1E293B, /* blueGray.800 */
disabled-button-toggle: #0F172A, /* blueGray.900 */
unselected-chip: #475569, /* blueGray.600 */
disabled-list-option: #E2E8F0, /* blueGray.200 */
tooltip: #64748B /* blueGray.500 */
);
$foreground-light: (
base: #000000,
divider: #E2E8F0, /* blueGray.200 */
dividers: #E2E8F0, /* blueGray.200 */
disabled: #94A3B8, /* blueGray.400 */
disabled-button: #94A3B8, /* blueGray.400 */
disabled-text: #94A3B8, /* blueGray.400 */
elevation: #000000,
hint-text: #94A3B8, /* blueGray.400 */
secondary-text: #64748B, /* blueGray.500 */
icon: #64748B, /* blueGray.500 */
icons: #64748B, /* blueGray.500 */
mat-icon: #64748B, /* blueGray.500 */
text: #1E293B, /* blueGray.800 */
slider-min: #1E293B, /* blueGray.800 */
slider-off: #CBD5E1, /* blueGray.300 */
slider-off-active: #94A3B8 /* blueGray.400 */
);
$foreground-dark: (
base: #FFFFFF,
divider: rgba(241, 245, 249, 0.12), /* blueGray.100 + opacity */
dividers: rgba(241, 245, 249, 0.12), /* blueGray.100 + opacity */
disabled: #475569, /* blueGray.600 */
disabled-button: #1E293B, /* blueGray.800 */
disabled-text: #475569, /* blueGray.600 */
elevation: #000000,
hint-text: #64748B, /* blueGray.500 */
secondary-text: #94A3B8, /* blueGray.400 */
icon: #F1F5F9, /* blueGray.100 */
icons: #F1F5F9, /* blueGray.100 */
mat-icon: #94A3B8, /* blueGray.400 */
text: #FFFFFF,
slider-min: #FFFFFF,
slider-off: #64748B, /* blueGray.500 */
slider-off-active: #94A3B8 /* blueGray.400 */
);
/* Generate Primary, Accent and Warn palettes */
$palettes: ();
@each $name in (primary, accent, warn) {
@@ -145,8 +70,41 @@ body .light {
accent: map.get(map.get($base-light-theme, color), accent),
warn: map.get(map.get($base-light-theme, color), warn),
is-dark: map.get(map.get($base-light-theme, color), is-dark),
foreground: $foreground-light,
background: $background-light
foreground: (
base: #000000,
divider: #E2E8F0, /* blueGray.200 */
dividers: #E2E8F0, /* blueGray.200 */
disabled: #94A3B8, /* blueGray.400 */
disabled-button: #94A3B8, /* blueGray.400 */
disabled-text: #94A3B8, /* blueGray.400 */
elevation: #000000,
hint-text: #94A3B8, /* blueGray.400 */
secondary-text: #64748B, /* blueGray.500 */
icon: #64748B, /* blueGray.500 */
icons: #64748B, /* blueGray.500 */
mat-icon: #64748B, /* blueGray.500 */
text: #1E293B, /* blueGray.800 */
slider-min: #1E293B, /* blueGray.800 */
slider-off: #CBD5E1, /* blueGray.300 */
slider-off-active: #94A3B8 /* blueGray.400 */
),
background: (
status-bar: #CBD5E1, /* blueGray.300 */
app-bar: #FFFFFF,
background: #F1F5F9, /* blueGray.100 */
hover: rgba(148, 163, 184, 0.12), /* blueGray.400 + opacity */
card: #FFFFFF,
dialog: #FFFFFF,
disabled-button: rgba(148, 163, 184, 0.38), /* blueGray.400 + opacity */
raised-button: #FFFFFF,
focused-button: #64748B, /* blueGray.500 */
selected-button: #E2E8F0, /* blueGray.200 */
selected-disabled-button: #E2E8F0, /* blueGray.200 */
disabled-button-toggle: #CBD5E1, /* blueGray.300 */
unselected-chip: #E2E8F0, /* blueGray.200 */
disabled-list-option: #CBD5E1, /* blueGray.300 */
tooltip: #1E293B /* blueGray.800 */
)
)
);
@@ -166,8 +124,41 @@ body .dark {
accent: map.get(map.get($base-dark-theme, color), accent),
warn: map.get(map.get($base-dark-theme, color), warn),
is-dark: map.get(map.get($base-dark-theme, color), is-dark),
foreground: $foreground-dark,
background: $background-dark
foreground: (
base: #FFFFFF,
divider: rgba(241, 245, 249, 0.12), /* blueGray.100 + opacity */
dividers: rgba(241, 245, 249, 0.12), /* blueGray.100 + opacity */
disabled: #475569, /* blueGray.600 */
disabled-button: #1E293B, /* blueGray.800 */
disabled-text: #475569, /* blueGray.600 */
elevation: #000000,
hint-text: #64748B, /* blueGray.500 */
secondary-text: #94A3B8, /* blueGray.400 */
icon: #F1F5F9, /* blueGray.100 */
icons: #F1F5F9, /* blueGray.100 */
mat-icon: #94A3B8, /* blueGray.400 */
text: #FFFFFF,
slider-min: #FFFFFF,
slider-off: #64748B, /* blueGray.500 */
slider-off-active: #94A3B8 /* blueGray.400 */
),
background: (
status-bar: #0F172A, /* blueGray.900 */
app-bar: #0F172A, /* blueGray.900 */
background: #0F172A, /* blueGray.900 */
hover: rgba(255, 255, 255, 0.05),
card: #1E293B, /* blueGray.800 */
dialog: #1E293B, /* blueGray.800 */
disabled-button: rgba(15, 23, 42, 0.38), /* blueGray.900 + opacity */
raised-button: #0F172A, /* blueGray.900 */
focused-button: #E2E8F0, /* blueGray.200 */
selected-button: rgba(255, 255, 255, 0.05),
selected-disabled-button: #1E293B, /* blueGray.800 */
disabled-button-toggle: #0F172A, /* blueGray.900 */
unselected-chip: #475569, /* blueGray.600 */
disabled-list-option: #E2E8F0, /* blueGray.200 */
tooltip: #64748B /* blueGray.500 */
)
)
);

View File

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

View File

@@ -4,6 +4,7 @@ import { forkJoin, Observable } from 'rxjs';
import { MessagesService } from 'app/layout/common/messages/messages.service';
import { NavigationService } from 'app/core/navigation/navigation.service';
import { NotificationsService } from 'app/layout/common/notifications/notifications.service';
import { QuickChatService } from 'app/layout/common/quick-chat/quick-chat.service';
import { ShortcutsService } from 'app/layout/common/shortcuts/shortcuts.service';
import { UserService } from 'app/core/user/user.service';
@@ -19,6 +20,7 @@ export class InitialDataResolver implements Resolve<any>
private _messagesService: MessagesService,
private _navigationService: NavigationService,
private _notificationsService: NotificationsService,
private _quickChatService: QuickChatService,
private _shortcutsService: ShortcutsService,
private _userService: UserService
)
@@ -42,6 +44,7 @@ export class InitialDataResolver implements Resolve<any>
this._navigationService.get(),
this._messagesService.getAll(),
this._notificationsService.getAll(),
this._quickChatService.getChats(),
this._shortcutsService.getAll(),
this._userService.get()
]);

View File

@@ -0,0 +1,196 @@
<div class="fixed lg:sticky top-0 bottom-0 lg:left-full w-full sm:w-96 lg:w-16 lg:h-screen">
<div
class="flex flex-col w-full sm:w-96 h-full lg:shadow transform transition-transform duration-400 ease-drawer bg-card"
[ngClass]="{'-translate-x-full sm:-translate-x-96 lg:-translate-x-80 shadow': opened, 'translate-x-0': !opened}">
<!-- Header -->
<div
class="quick-chat-header flex flex-0 items-center justify-start cursor-pointer"
(click)="toggle()">
<!-- Toggle -->
<ng-container *ngIf="!opened || (opened && !selectedChat)">
<div class="flex flex-auto items-center justify-center">
<div class="flex flex-0 items-center justify-center w-16">
<mat-icon
class="icon-size-6"
[svgIcon]="'heroicons_outline:chat-alt-2'"></mat-icon>
</div>
<div class="text-lg font-medium text-secondary">Team Chat</div>
<button
class="ml-auto mr-4"
mat-icon-button>
<mat-icon [svgIcon]="'heroicons_outline:x'"></mat-icon>
</button>
</div>
</ng-container>
<!-- Contact info -->
<ng-container *ngIf="opened && selectedChat">
<div class="flex flex-auto items-center ml-3">
<div class="relative flex flex-0 items-center justify-center w-10 h-10">
<ng-container *ngIf="chat.contact.avatar">
<img
class="w-full h-full rounded-full object-cover"
[src]="chat.contact.avatar"
alt="Contact avatar"/>
</ng-container>
<ng-container *ngIf="!chat.contact.avatar">
<div class="flex items-center justify-center w-full h-full rounded-full text-lg uppercase bg-gray-200 text-gray-600 dark:bg-gray-700 dark:text-gray-200">
{{chat.contact.name.charAt(0)}}
</div>
</ng-container>
</div>
<div class="ml-4 text-lg font-medium leading-5 truncate">{{chat.contact.name}}</div>
<button
class="ml-auto mr-4"
mat-icon-button>
<mat-icon [svgIcon]="'heroicons_outline:x'"></mat-icon>
</button>
</div>
</ng-container>
</div>
<!-- Content -->
<div class="flex flex-auto border-t overflow-hidden">
<!-- Chat list -->
<div
class="flex-0 w-16 h-full overflow-y-auto overscroll-y-contain sm:overflow-hidden sm:overscroll-auto"
fuseScrollbar
[fuseScrollbarOptions]="{wheelPropagation: false}">
<div class="flex-auto">
<ng-container *ngFor="let chat of chats; trackBy: trackByFn">
<div
class="flex items-center py-3 px-4 cursor-pointer"
[ngClass]="{'hover:bg-gray-100 dark:hover:bg-hover': !selectedChat || selectedChat.id !== chat.id,
'bg-primary-50 dark:bg-hover': selectedChat && selectedChat.id === chat.id}"
(click)="selectChat(chat.id)">
<div class="relative flex flex-0 items-center justify-center w-8 h-8">
<ng-container *ngIf="chat.unreadCount > 0">
<div
class="absolute bottom-0 right-0 flex-0 w-2 h-2 -ml-0.5 rounded-full ring-2 ring-bg-card dark:ring-gray-900 bg-primary dark:bg-primary-500 text-on-primary"
[class.ring-primary-50]="selectedChat && selectedChat.id === chat.id"></div>
</ng-container>
<ng-container *ngIf="chat.contact.avatar">
<img
class="w-full h-full rounded-full object-cover"
[src]="chat.contact.avatar"
alt="Contact avatar"/>
</ng-container>
<ng-container *ngIf="!chat.contact.avatar">
<div class="flex items-center justify-center w-full h-full rounded-full text-lg uppercase bg-gray-200 text-gray-600 dark:bg-gray-700 dark:text-gray-200">
{{chat.contact.name.charAt(0)}}
</div>
</ng-container>
</div>
</div>
</ng-container>
</div>
</div>
<!-- Conversation -->
<div class="flex flex-col flex-auto border-l overflow-hidden bg-gray-50 dark:bg-transparent">
<ng-container *ngIf="chat; else selectChatOrStartNew">
<div class="flex flex-col-reverse overflow-y-auto overscroll-y-contain">
<div class="flex flex-col flex-auto flex-shrink p-6">
<ng-container *ngFor="let message of chat.messages; let i = index; let first = first; let last = last; trackBy: trackByFn">
<!-- Start of the day -->
<ng-container *ngIf="first || (chat.messages[i - 1].createdAt | date:'d') !== (message.createdAt | date:'d')">
<div class="flex items-center justify-center my-3 -mx-6">
<div class="flex-auto border-b"></div>
<div class="flex-0 mx-4 text-sm font-medium leading-5 text-secondary">
{{message.createdAt | date: 'longDate'}}
</div>
<div class="flex-auto border-b"></div>
</div>
</ng-container>
<div
class="flex flex-col"
[ngClass]="{'items-end': message.isMine,
'items-start': !message.isMine,
'mt-0.5': i > 0 && chat.messages[i - 1].isMine === message.isMine,
'mt-3': i > 0 && chat.messages[i - 1].isMine !== message.isMine}">
<!-- Bubble -->
<div
class="relative max-w-3/4 px-3 py-2 rounded-lg"
[ngClass]="{'bg-blue-500 text-blue-50': message.isMine,
'bg-gray-500 text-gray-50': !message.isMine}">
<!-- Speech bubble tail -->
<ng-container *ngIf="last || chat.messages[i + 1].isMine !== message.isMine">
<div
class="absolute bottom-0 w-3 transform"
[ngClass]="{'text-blue-500 -right-1 -mr-px mb-px': message.isMine,
'text-gray-500 -left-1 -ml-px mb-px -scale-x-1': !message.isMine}">
<ng-container *ngTemplateOutlet="speechBubbleExtension"></ng-container>
</div>
</ng-container>
<!-- Message -->
<div
class="min-w-4 leading-5"
[innerHTML]="message.value">
</div>
</div>
<!-- Time -->
<ng-container
*ngIf="first
|| last
|| chat.messages[i + 1].isMine !== message.isMine
|| chat.messages[i + 1].createdAt !== message.createdAt">
<div
class="my-0.5 text-sm font-medium text-secondary"
[ngClass]="{'mr-3': message.isMine,
'ml-3': !message.isMine}">
{{message.createdAt | date:'HH:mm'}}
</div>
</ng-container>
</div>
</ng-container>
</div>
</div>
<!-- Message field -->
<div class="flex items-end p-4 border-t bg-gray-50 dark:bg-transparent">
<mat-form-field class="fuse-mat-dense fuse-mat-no-subscript fuse-mat-rounded fuse-mat-bold w-full">
<textarea
class="min-h-5 my-0 resize-none"
style="margin: 11px 0 !important; padding: 0 !important;"
[rows]="1"
matInput
#messageInput></textarea>
</mat-form-field>
<div class="flex items-center h-11 my-px ml-4">
<button
mat-icon-button>
<mat-icon
class="transform rotate-90"
[svgIcon]="'heroicons_outline:paper-airplane'"></mat-icon>
</button>
</div>
</div>
</ng-container>
</div>
</div>
</div>
</div>
<!-- Select chat or start new template -->
<ng-template #selectChatOrStartNew>
<div class="flex flex-col flex-auto items-center justify-center w-full h-full p-4">
<mat-icon
class="icon-size-20"
[svgIcon]="'iconsmind:speach_bubble'"></mat-icon>
<div class="mt-4 text-xl text-center font-medium tracking-tight text-secondary">Select a conversation</div>
</div>
</ng-template>
<!-- Speech bubble tail SVG -->
<!-- @formatter:off -->
<ng-template #speechBubbleExtension>
<svg width="100%" height="100%" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M1.01522827,0.516204834 C-8.83532715,54.3062744 61.7609863,70.5215302 64.8009949,64.3061218 C68.8074951,54.8859711 30.1663208,52.9997559 37.5036011,0.516204834 L1.01522827,0.516204834 Z" fill="currentColor" fill-rule="nonzero"></path>
</g>
</svg>
</ng-template>
<!-- @formatter:on -->

View File

@@ -0,0 +1,26 @@
quick-chat {
z-index: 399;
}
/* Adjustments depending on the selected layout */
.quick-chat-header {
height: 64px;
enterprise-layout &,
modern-layout & {
height: 80px !important;
}
}
/* Overlay */
.quick-chat-overlay {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 299;
opacity: 1;
background-color: transparent;
}

View File

@@ -0,0 +1,275 @@
import { Component, ElementRef, HostBinding, HostListener, NgZone, OnDestroy, OnInit, Renderer2, ViewChild, ViewEncapsulation } from '@angular/core';
import { ScrollStrategy, ScrollStrategyOptions } from '@angular/cdk/overlay';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { QuickChatService } from 'app/layout/common/quick-chat/quick-chat.service';
import { Chat } from 'app/layout/common/quick-chat/quick-chat.types';
@Component({
selector : 'quick-chat',
templateUrl : './quick-chat.component.html',
styleUrls : ['./quick-chat.component.scss'],
encapsulation: ViewEncapsulation.None,
exportAs : 'quickChat'
})
export class QuickChatComponent implements OnInit, OnDestroy
{
@ViewChild('messageInput') messageInput: ElementRef;
chat: Chat;
chats: Chat[];
opened: boolean = false;
selectedChat: Chat;
private _scrollStrategy: ScrollStrategy = this._scrollStrategyOptions.block();
private _overlay: HTMLElement;
private _unsubscribeAll: Subject<any> = new Subject<any>();
/**
* Constructor
*/
constructor(
private _elementRef: ElementRef,
private _renderer2: Renderer2,
private _ngZone: NgZone,
private _quickChatService: QuickChatService,
private _scrollStrategyOptions: ScrollStrategyOptions
)
{
}
// -----------------------------------------------------------------------------------------------------
// @ Decorated methods
// -----------------------------------------------------------------------------------------------------
/**
* Host binding for component classes
*/
@HostBinding('class') get classList(): any
{
return {
'quick-chat-opened': this.opened
};
}
/**
* Resize on 'input' and 'ngModelChange' events
*
* @private
*/
@HostListener('input')
@HostListener('ngModelChange')
private _resizeMessageInput(): void
{
// This doesn't need to trigger Angular's change detection by itself
this._ngZone.runOutsideAngular(() => {
setTimeout(() => {
// Set the height to 'auto' so we can correctly read the scrollHeight
this.messageInput.nativeElement.style.height = 'auto';
// Get the scrollHeight and subtract the vertical padding
this.messageInput.nativeElement.style.height = `${this.messageInput.nativeElement.scrollHeight}px`;
});
});
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On init
*/
ngOnInit(): void
{
// Chat
this._quickChatService.chat$
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((chat: Chat) => {
this.chat = chat;
});
// Chats
this._quickChatService.chats$
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((chats: Chat[]) => {
this.chats = chats;
});
// Selected chat
this._quickChatService.chat$
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((chat: Chat) => {
this.selectedChat = chat;
});
}
/**
* On destroy
*/
ngOnDestroy(): void
{
// Unsubscribe from all subscriptions
this._unsubscribeAll.next();
this._unsubscribeAll.complete();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Open the panel
*/
open(): void
{
// Return if the panel has already opened
if ( this.opened )
{
return;
}
// Open the panel
this._toggleOpened(true);
}
/**
* Close the panel
*/
close(): void
{
// Return if the panel has already closed
if ( !this.opened )
{
return;
}
// Close the panel
this._toggleOpened(false);
}
/**
* Toggle the panel
*/
toggle(): void
{
if ( this.opened )
{
this.close();
}
else
{
this.open();
}
}
/**
* Select the chat
*
* @param id
*/
selectChat(id: string): void
{
// Open the panel
this._toggleOpened(true);
// Get the chat data
this._quickChatService.getChatById(id).subscribe();
}
/**
* Track by function for ngFor loops
*
* @param index
* @param item
*/
trackByFn(index: number, item: any): any
{
return item.id || index;
}
// -----------------------------------------------------------------------------------------------------
// @ Private methods
// -----------------------------------------------------------------------------------------------------
/**
* Show the backdrop
*
* @private
*/
private _showOverlay(): void
{
// Try hiding the overlay in case there is one already opened
this._hideOverlay();
// Create the backdrop element
this._overlay = this._renderer2.createElement('div');
// Return if overlay couldn't be create for some reason
if ( !this._overlay )
{
return;
}
// Add a class to the backdrop element
this._overlay.classList.add('quick-chat-overlay');
// Append the backdrop to the parent of the panel
this._renderer2.appendChild(this._elementRef.nativeElement.parentElement, this._overlay);
// Enable block scroll strategy
this._scrollStrategy.enable();
// Add an event listener to the overlay
this._overlay.addEventListener('click', () => {
this.close();
});
}
/**
* Hide the backdrop
*
* @private
*/
private _hideOverlay(): void
{
if ( !this._overlay )
{
return;
}
// If the backdrop still exists...
if ( this._overlay )
{
// Remove the backdrop
this._overlay.parentNode.removeChild(this._overlay);
this._overlay = null;
}
// Disable block scroll strategy
this._scrollStrategy.disable();
}
/**
* Open/close the panel
*
* @param open
* @private
*/
private _toggleOpened(open: boolean): void
{
// Set the opened
this.opened = open;
// If the panel opens, show the overlay
if ( open )
{
this._showOverlay();
}
// Otherwise, hide the overlay
else
{
this._hideOverlay();
}
}
}

View File

@@ -0,0 +1,32 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
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 { FuseDrawerModule } from '@fuse/components/drawer';
import { FuseScrollbarModule } from '@fuse/directives/scrollbar';
import { SharedModule } from 'app/shared/shared.module';
import { QuickChatComponent } from 'app/layout/common/quick-chat/quick-chat.component';
@NgModule({
declarations: [
QuickChatComponent
],
imports: [
RouterModule,
MatButtonModule,
MatFormFieldModule,
MatIconModule,
MatInputModule,
FuseDrawerModule,
FuseScrollbarModule,
SharedModule,
],
exports : [
QuickChatComponent
]
})
export class QuickChatModule
{
}

View File

@@ -0,0 +1,85 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable, of, throwError } from 'rxjs';
import { map, switchMap, tap } from 'rxjs/operators';
import { Chat } from 'app/layout/common/quick-chat/quick-chat.types';
@Injectable({
providedIn: 'root'
})
export class QuickChatService
{
private _chat: BehaviorSubject<Chat> = new BehaviorSubject(null);
private _chats: BehaviorSubject<Chat[]> = new BehaviorSubject<Chat[]>(null);
/**
* Constructor
*/
constructor(private _httpClient: HttpClient)
{
}
// -----------------------------------------------------------------------------------------------------
// @ Accessors
// -----------------------------------------------------------------------------------------------------
/**
* Getter for chat
*/
get chat$(): Observable<Chat>
{
return this._chat.asObservable();
}
/**
* Getter for chat
*/
get chats$(): Observable<Chat[]>
{
return this._chats.asObservable();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Get chats
*/
getChats(): Observable<any>
{
return this._httpClient.get<Chat[]>('api/apps/chat/chats').pipe(
tap((response: Chat[]) => {
this._chats.next(response);
})
);
}
/**
* Get chat
*
* @param id
*/
getChatById(id: string): Observable<any>
{
return this._httpClient.get<Chat>('api/apps/chat/chat', {params: {id}}).pipe(
map((chat) => {
// Update the chat
this._chat.next(chat);
// Return the chat
return chat;
}),
switchMap((chat) => {
if ( !chat )
{
return throwError('Could not found chat with id of ' + id + '!');
}
return of(chat);
})
);
}
}

View File

@@ -0,0 +1,46 @@
export interface Chat
{
id?: string;
contactId?: string;
contact?: Contact;
unreadCount?: number;
muted?: boolean;
lastMessage?: string;
lastMessageAt?: string;
messages?: {
id?: string;
chatId?: string;
contactId?: string;
isMine?: boolean;
value?: string;
createdAt?: string;
}[];
}
export interface Contact
{
id?: string;
avatar?: string;
name?: string;
about?: string;
details?: {
emails?: {
email?: string;
label?: string;
}[];
phoneNumbers?: {
country?: string;
phoneNumber?: string;
label?: string;
}[];
title?: string;
company?: string;
birthday?: string;
address?: string;
};
attachments?: {
media?: any[];
docs?: any[];
links?: any[];
};
}

View File

@@ -0,0 +1,474 @@
<div
class="fixed flex items-center justify-center right-0 w-10 h-10 shadow-lg rounded-l-lg z-90 cursor-pointer bg-red-600 bg-opacity-90 print:hidden"
[class.lg:right-0]="config.layout === 'centered' || config.layout === 'material'"
[class.lg:right-16]="config.layout !== 'centered' && config.layout !== 'material'"
style="top: 275px"
(click)="settingsDrawer.toggle()">
<mat-icon
class="icon-size-5 text-white animate-spin-slow"
[svgIcon]="'heroicons_solid:cog'"></mat-icon>
</div>
<fuse-drawer
class="w-screen min-w-screen sm:w-100 sm:min-w-100 z-999"
fixed
[mode]="'over'"
[name]="'settingsDrawer'"
[position]="'right'"
#settingsDrawer>
<div class="flex flex-col w-full overflow-auto bg-card">
<div class="flex flex-row items-center px-6 h-20 min-h-20 text-white bg-primary">
<mat-icon
class="icon-size-7 text-current"
[svgIcon]="'heroicons_solid:cog'"></mat-icon>
<div class="ml-3 text-2xl font-semibold tracking-tight">Settings</div>
<button
class="ml-auto"
mat-icon-button
(click)="settingsDrawer.close()">
<mat-icon
class="text-current"
[svgIcon]="'heroicons_outline:x'"></mat-icon>
</button>
</div>
<div class="flex flex-col p-6">
<!-- Theme -->
<div class="text-md font-semibold text-secondary">THEME</div>
<div class="grid grid-cols-2 sm:grid-cols-3 gap-3 mt-6">
<ng-container *ngFor="let theme of themes">
<div
class="flex items-center justify-center px-4 py-3 rounded-full cursor-pointer ring-inset ring-primary bg-hover"
[class.ring-2]="config.theme === theme[0]"
(click)="setTheme(theme[0])">
<div
class="flex-0 w-3 h-3 rounded-full"
[style.background-color]="theme[1].primary"></div>
<div
class="ml-2.5 font-medium leading-5 truncate"
[class.text-secondary]="config.theme !== theme[0]">
{{theme[0] | titlecase}}
</div>
</div>
</ng-container>
</div>
<hr class="my-8">
<!-- Scheme -->
<div class="text-md font-semibold text-secondary">SCHEME</div>
<div class="grid grid-cols-3 gap-3 justify-items-start mt-6">
<!-- Auto -->
<div
class="flex items-center py-3 pl-5 pr-6 rounded-full cursor-pointer ring-inset ring-primary bg-hover"
[class.ring-2]="config.scheme === 'auto'"
matTooltip="Automatically sets the scheme based on user's operating system's color scheme preference using 'prefer-color-scheme' media query."
(click)="setScheme('auto')">
<div class="flex items-center rounded-full overflow-hidden">
<mat-icon
class="icon-size-5"
[svgIcon]="'heroicons_solid:lightning-bolt'"></mat-icon>
</div>
<div
class="flex items-center ml-2 font-medium leading-5"
[class.text-secondary]="config.scheme !== 'auto'">
Auto
</div>
</div>
<!-- Dark -->
<div
class="flex items-center py-3 pl-5 pr-6 rounded-full cursor-pointer ring-inset ring-primary bg-hover"
[class.ring-2]="config.scheme === 'dark'"
(click)="setScheme('dark')">
<div class="flex items-center rounded-full overflow-hidden">
<mat-icon
class="icon-size-5"
[svgIcon]="'heroicons_solid:moon'"></mat-icon>
</div>
<div
class="flex items-center ml-2 font-medium leading-5"
[class.text-secondary]="config.scheme !== 'dark'">
Dark
</div>
</div>
<!-- Light -->
<div
class="flex items-center py-3 pl-5 pr-6 rounded-full cursor-pointer ring-inset ring-primary bg-hover"
[class.ring-2]="config.scheme === 'light'"
(click)="setScheme('light')">
<div class="flex items-center rounded-full overflow-hidden">
<mat-icon
class="icon-size-5"
[svgIcon]="'heroicons_solid:sun'"></mat-icon>
</div>
<div
class="flex items-center ml-2 font-medium leading-5"
[class.text-secondary]="config.scheme !== 'light'">
Light
</div>
</div>
</div>
<hr class="my-8">
<!-- Layout -->
<div class="text-md font-semibold text-secondary">LAYOUT</div>
<div class="grid grid-cols-3 gap-3 mt-6">
<!-- Empty -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('empty')">
<div
class="flex flex-col h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'empty'">
<div class="flex flex-col flex-auto bg-gray-50 dark:bg-gray-900"></div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'empty'">
Empty
</div>
</div>
<!-- Classic -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('classic')">
<div
class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'classic'">
<div class="w-8 bg-gray-100 dark:bg-gray-800">
<div class="mt-3 mx-1.5 space-y-1">
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-col flex-auto border-l">
<div class="h-3 bg-gray-100 dark:bg-gray-800">
<div class="flex items-center justify-end h-full mr-1.5">
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'classic'">
Classic
</div>
</div>
<!-- Classy -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('classy')">
<div
class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'classy'">
<div class="w-8 bg-gray-100 dark:bg-gray-800">
<div class="flex items-center mt-1 mx-1">
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-auto rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-0.5 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
<div class="w-4 h-4 mt-2.5 mx-auto rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="mt-2 mx-1 space-y-1">
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-col flex-auto border-l">
<div class="h-3 bg-gray-100 dark:bg-gray-800">
<div class="flex items-center justify-end h-full mr-2">
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'classy'">
Classy
</div>
</div>
<!-- Compact -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('compact')">
<div
class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'compact'">
<div class="w-5 bg-gray-100 dark:bg-gray-800">
<div class="w-3 h-3 mt-2 mx-auto rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="flex flex-col items-center w-full mt-2 space-y-1">
<div class="w-3 h-2.5 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-2.5 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-2.5 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-col flex-auto border-l">
<div class="h-3 bg-gray-100 dark:bg-gray-800">
<div class="flex items-center justify-end h-full mr-1.5">
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'compact'">
Compact
</div>
</div>
<!-- Dense -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('dense')">
<div
class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'dense'">
<div class="w-4 bg-gray-100 dark:bg-gray-800">
<div class="w-2 h-2 mt-2 mx-auto rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="flex flex-col items-center w-full mt-2 space-y-1">
<div class="w-2 h-2 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="w-2 h-2 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="w-2 h-2 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-col flex-auto border-l">
<div class="h-3 bg-gray-100 dark:bg-gray-800">
<div class="flex items-center justify-end h-full mr-1.5">
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'dense'">
Dense
</div>
</div>
<!-- Futuristic -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('futuristic')">
<div
class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'futuristic'">
<div class="w-8 bg-gray-100 dark:bg-gray-800">
<div class="flex flex-col flex-auto h-full py-3 px-1.5 space-y-1">
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="flex-auto"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-col flex-auto border-l">
<div class="h-3 bg-gray-100 dark:bg-gray-800">
<div class="flex items-center justify-end h-full mr-1.5">
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'futuristic'">
Futuristic
</div>
</div>
<!-- Thin -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('thin')">
<div
class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'thin'">
<div class="w-3 bg-gray-100 dark:bg-gray-800">
<div class="w-1.5 h-1.5 mt-2 mx-auto rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="flex flex-col items-center w-full mt-2 space-y-1">
<div class="w-1.5 h-1.5 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1.5 h-1.5 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1.5 h-1.5 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1.5 h-1.5 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1.5 h-1.5 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-col flex-auto border-l">
<div class="h-3 bg-gray-100 dark:bg-gray-800">
<div class="flex items-center justify-end h-full mr-1.5">
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'thin'">
Thin
</div>
</div>
<div class="col-span-2"></div>
<!-- Centered -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('centered')">
<div
class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'centered'">
<div class="flex flex-col flex-auto my-1 mx-2 border rounded-md overflow-hidden">
<div class="flex items-center h-3 bg-gray-100 dark:bg-gray-800">
<div class="flex ml-1.5">
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
<div class="flex items-center justify-end ml-auto mr-1.5">
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'centered'">
Centered
</div>
</div>
<!-- Enterprise -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('enterprise')">
<div
class="flex flex-col h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'enterprise'">
<div class="flex items-center h-3 px-2 bg-gray-100 dark:bg-gray-800">
<div class="w-2 h-2 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="flex items-center justify-end ml-auto space-x-1">
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex items-center h-3 px-2 border-t border-b space-x-1 bg-gray-100 dark:bg-gray-800">
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
<div class="flex flex-col flex-auto my-1 mx-2 border rounded overflow-hidden">
<div class="flex flex-auto bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'enterprise'">
Enterprise
</div>
</div>
<!-- Material -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('material')">
<div
class="flex flex-col h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'material'">
<div class="flex flex-col flex-auto my-1 mx-2 border rounded overflow-hidden">
<div class="flex items-center h-4 px-2 bg-gray-100 dark:bg-gray-800">
<div class="w-2 h-2 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="flex items-center justify-end ml-auto space-x-1">
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex items-center h-2 px-2 space-x-1 bg-gray-100 dark:bg-gray-800">
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'material'">
Material
</div>
</div>
<!-- Modern -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('modern')">
<div
class="flex flex-col h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'modern'">
<div class="flex items-center h-4 px-2 border-b bg-gray-100 dark:bg-gray-800">
<div class="w-2 h-2 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="flex items-center h-3 ml-2 space-x-1">
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
<div class="flex items-center justify-end ml-auto space-x-1">
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-col flex-auto">
<div class="flex flex-auto bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'modern'">
Modern
</div>
</div>
</div>
</div>
</div>
</fuse-drawer>

View File

@@ -0,0 +1,124 @@
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { Router } from '@angular/router';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseConfigService } from '@fuse/services/config';
import { FuseTailwindService } from '@fuse/services/tailwind';
import { AppConfig, Scheme, Theme } from 'app/core/config/app.config';
import { Layout } from 'app/layout/layout.types';
@Component({
selector : 'settings',
templateUrl : './settings.component.html',
styles : [
`
settings {
position: static;
display: block;
flex: none;
width: auto;
}
`
],
encapsulation: ViewEncapsulation.None
})
export class SettingsComponent implements OnInit, OnDestroy
{
config: AppConfig;
layout: Layout;
scheme: 'dark' | 'light';
theme: string;
themes: [string, any][] = [];
private _unsubscribeAll: Subject<any> = new Subject<any>();
/**
* Constructor
*/
constructor(
private _router: Router,
private _fuseConfigService: FuseConfigService,
private _fuseTailwindService: FuseTailwindService
)
{
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On init
*/
ngOnInit(): void
{
// Get the themes
this._fuseTailwindService.tailwindConfig$
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((config) => {
this.themes = Object.entries(config.themes);
});
// Subscribe to config changes
this._fuseConfigService.config$
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((config: AppConfig) => {
// Store the config
this.config = config;
});
}
/**
* On destroy
*/
ngOnDestroy(): void
{
// Unsubscribe from all subscriptions
this._unsubscribeAll.next();
this._unsubscribeAll.complete();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Set the layout on the config
*
* @param layout
*/
setLayout(layout: string): void
{
// Clear the 'layout' query param to allow layout changes
this._router.navigate([], {
queryParams : {
layout: null
},
queryParamsHandling: 'merge'
}).then(() => {
// Set the config
this._fuseConfigService.config = {layout};
});
}
/**
* Set the scheme on the config
*
* @param scheme
*/
setScheme(scheme: Scheme): void
{
this._fuseConfigService.config = {scheme};
}
/**
* Set the theme on the config
*
* @param theme
*/
setTheme(theme: Theme): void
{
this._fuseConfigService.config = {theme};
}
}

View File

@@ -0,0 +1,28 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';
import { FuseDrawerModule } from '@fuse/components/drawer';
import { SettingsComponent } from 'app/layout/common/settings/settings.component';
import { MatButtonModule } from '@angular/material/button';
@NgModule({
declarations: [
SettingsComponent
],
imports: [
CommonModule,
RouterModule,
MatIconModule,
MatTooltipModule,
FuseDrawerModule,
MatButtonModule
],
exports : [
SettingsComponent
]
})
export class SettingsModule
{
}

View File

@@ -44,468 +44,4 @@
<!-- ----------------------------------------------------------------------------------------------------- -->
<!-- Settings drawer - Remove this to remove the drawer and its button -->
<!-- ----------------------------------------------------------------------------------------------------- -->
<div
class="fixed flex items-center justify-center right-0 w-10 h-10 shadow-lg rounded-l-lg z-999 cursor-pointer bg-red-600 bg-opacity-90 print:hidden"
style="top: 275px"
(click)="settingsDrawer.toggle()">
<mat-icon
class="icon-size-5 text-white animate-spin-slow"
[svgIcon]="'heroicons_solid:cog'"></mat-icon>
</div>
<fuse-drawer
class="w-screen min-w-screen sm:w-100 sm:min-w-100"
fixed
transparentOverlay
[mode]="'over'"
[name]="'settingsDrawer'"
[position]="'right'"
#settingsDrawer>
<div class="flex flex-col w-full overflow-auto bg-card">
<div class="flex flex-row items-center px-6 h-20 min-h-20 text-white bg-primary">
<mat-icon
class="icon-size-7 text-current"
[svgIcon]="'heroicons_solid:cog'"></mat-icon>
<div class="ml-3 text-2xl font-semibold tracking-tight">Settings</div>
</div>
<div class="flex flex-col p-6">
<!-- Theme -->
<div class="text-md font-semibold text-secondary">THEME</div>
<div class="grid grid-cols-2 sm:grid-cols-3 gap-3 mt-6">
<ng-container *ngFor="let theme of themes">
<div
class="flex items-center justify-center px-4 py-3 rounded-full cursor-pointer ring-inset ring-primary bg-hover"
[class.ring-2]="config.theme === theme[0]"
(click)="setTheme(theme[0])">
<div
class="flex-0 w-3 h-3 rounded-full"
[style.background-color]="theme[1].primary"></div>
<div
class="ml-2.5 font-medium leading-5 truncate"
[class.text-secondary]="config.theme !== theme[0]">
{{theme[0] | titlecase}}
</div>
</div>
</ng-container>
</div>
<hr class="my-8">
<!-- Scheme -->
<div class="text-md font-semibold text-secondary">SCHEME</div>
<div class="grid grid-cols-3 gap-3 justify-items-start mt-6">
<!-- Auto -->
<div
class="flex items-center py-3 pl-5 pr-6 rounded-full cursor-pointer ring-inset ring-primary bg-hover"
[class.ring-2]="config.scheme === 'auto'"
[matTooltip]="'Automatically sets the scheme based on user\'s operating system\'s color scheme preference using \'prefer-color-scheme\' media query.'"
(click)="setScheme('auto')">
<div class="flex items-center rounded-full overflow-hidden">
<mat-icon
class="icon-size-5"
[svgIcon]="'heroicons_solid:lightning-bolt'"></mat-icon>
</div>
<div
class="flex items-center ml-2 font-medium leading-5"
[class.text-secondary]="config.scheme !== 'auto'">
Auto
</div>
</div>
<!-- Dark -->
<div
class="flex items-center py-3 pl-5 pr-6 rounded-full cursor-pointer ring-inset ring-primary bg-hover"
[class.ring-2]="config.scheme === 'dark'"
(click)="setScheme('dark')">
<div class="flex items-center rounded-full overflow-hidden">
<mat-icon
class="icon-size-5"
[svgIcon]="'heroicons_solid:moon'"></mat-icon>
</div>
<div
class="flex items-center ml-2 font-medium leading-5"
[class.text-secondary]="config.scheme !== 'dark'">
Dark
</div>
</div>
<!-- Light -->
<div
class="flex items-center py-3 pl-5 pr-6 rounded-full cursor-pointer ring-inset ring-primary bg-hover"
[class.ring-2]="config.scheme === 'light'"
(click)="setScheme('light')">
<div class="flex items-center rounded-full overflow-hidden">
<mat-icon
class="icon-size-5"
[svgIcon]="'heroicons_solid:sun'"></mat-icon>
</div>
<div
class="flex items-center ml-2 font-medium leading-5"
[class.text-secondary]="config.scheme !== 'light'">
Light
</div>
</div>
</div>
<hr class="my-8">
<!-- Layout -->
<div class="text-md font-semibold text-secondary">LAYOUT</div>
<div class="grid grid-cols-3 gap-3 mt-6">
<!-- Empty -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('empty')">
<div
class="flex flex-col h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'empty'">
<div class="flex flex-col flex-auto bg-gray-50 dark:bg-gray-900"></div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'empty'">
Empty
</div>
</div>
<!-- Classic -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('classic')">
<div
class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'classic'">
<div class="w-8 bg-gray-100 dark:bg-gray-800">
<div class="mt-3 mx-1.5 space-y-1">
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-col flex-auto border-l">
<div class="h-3 bg-gray-100 dark:bg-gray-800">
<div class="flex items-center justify-end h-full mr-1.5">
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'classic'">
Classic
</div>
</div>
<!-- Classy -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('classy')">
<div
class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'classy'">
<div class="w-8 bg-gray-100 dark:bg-gray-800">
<div class="flex items-center mt-1 mx-1">
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-auto rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-0.5 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
<div class="w-4 h-4 mt-2.5 mx-auto rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="mt-2 mx-1 space-y-1">
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-col flex-auto border-l">
<div class="h-3 bg-gray-100 dark:bg-gray-800">
<div class="flex items-center justify-end h-full mr-2">
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'classy'">
Classy
</div>
</div>
<!-- Compact -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('compact')">
<div
class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'compact'">
<div class="w-5 bg-gray-100 dark:bg-gray-800">
<div class="w-3 h-3 mt-2 mx-auto rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="flex flex-col items-center w-full mt-2 space-y-1">
<div class="w-3 h-2.5 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-2.5 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-2.5 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-col flex-auto border-l">
<div class="h-3 bg-gray-100 dark:bg-gray-800">
<div class="flex items-center justify-end h-full mr-1.5">
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'compact'">
Compact
</div>
</div>
<!-- Dense -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('dense')">
<div
class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'dense'">
<div class="w-4 bg-gray-100 dark:bg-gray-800">
<div class="w-2 h-2 mt-2 mx-auto rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="flex flex-col items-center w-full mt-2 space-y-1">
<div class="w-2 h-2 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="w-2 h-2 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="w-2 h-2 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-col flex-auto border-l">
<div class="h-3 bg-gray-100 dark:bg-gray-800">
<div class="flex items-center justify-end h-full mr-1.5">
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'dense'">
Dense
</div>
</div>
<!-- Futuristic -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('futuristic')">
<div
class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'futuristic'">
<div class="w-8 bg-gray-100 dark:bg-gray-800">
<div class="flex flex-col flex-auto h-full py-3 px-1.5 space-y-1">
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="flex-auto"></div>
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-col flex-auto border-l">
<div class="h-3 bg-gray-100 dark:bg-gray-800">
<div class="flex items-center justify-end h-full mr-1.5">
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'futuristic'">
Futuristic
</div>
</div>
<!-- Thin -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('thin')">
<div
class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'thin'">
<div class="w-3 bg-gray-100 dark:bg-gray-800">
<div class="w-1.5 h-1.5 mt-2 mx-auto rounded-sm bg-gray-300 dark:bg-gray-700"></div>
<div class="flex flex-col items-center w-full mt-2 space-y-1">
<div class="w-1.5 h-1.5 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1.5 h-1.5 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1.5 h-1.5 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1.5 h-1.5 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1.5 h-1.5 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-col flex-auto border-l">
<div class="h-3 bg-gray-100 dark:bg-gray-800">
<div class="flex items-center justify-end h-full mr-1.5">
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'thin'">
Thin
</div>
</div>
<div class="col-span-2"></div>
<!-- Centered -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('centered')">
<div
class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'centered'">
<div class="flex flex-col flex-auto my-1 mx-2 border rounded-md overflow-hidden">
<div class="flex items-center h-3 bg-gray-100 dark:bg-gray-800">
<div class="flex ml-1.5">
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
<div class="flex items-center justify-end ml-auto mr-1.5">
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'centered'">
Centered
</div>
</div>
<!-- Enterprise -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('enterprise')">
<div
class="flex flex-col h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'enterprise'">
<div class="flex items-center h-3 px-2 bg-gray-100 dark:bg-gray-800">
<div class="w-2 h-2 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="flex items-center justify-end ml-auto space-x-1">
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex items-center h-3 px-2 border-t border-b space-x-1 bg-gray-100 dark:bg-gray-800">
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
<div class="flex flex-col flex-auto my-1 mx-2 border rounded overflow-hidden">
<div class="flex flex-auto bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'enterprise'">
Enterprise
</div>
</div>
<!-- Material -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('material')">
<div
class="flex flex-col h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'material'">
<div class="flex flex-col flex-auto my-1 mx-2 border rounded overflow-hidden">
<div class="flex items-center h-4 px-2 bg-gray-100 dark:bg-gray-800">
<div class="w-2 h-2 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="flex items-center justify-end ml-auto space-x-1">
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex items-center h-2 px-2 space-x-1 bg-gray-100 dark:bg-gray-800">
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'material'">
Material
</div>
</div>
<!-- Modern -->
<div
class="flex flex-col cursor-pointer"
(click)="setLayout('modern')">
<div
class="flex flex-col h-20 rounded-md overflow-hidden border-2 hover:opacity-80"
[class.border-primary]="config.layout === 'modern'">
<div class="flex items-center h-4 px-2 border-b bg-gray-100 dark:bg-gray-800">
<div class="w-2 h-2 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="flex items-center h-3 ml-2 space-x-1">
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
<div class="flex items-center justify-end ml-auto space-x-1">
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
<div class="flex flex-col flex-auto">
<div class="flex flex-auto bg-gray-50 dark:bg-gray-900"></div>
</div>
</div>
<div
class="mt-2 text-md font-medium text-center text-secondary"
[class.text-primary]="config.layout === 'modern'">
Modern
</div>
</div>
</div>
</div>
</div>
</fuse-drawer>
<settings></settings>

View File

@@ -5,10 +5,9 @@ import { combineLatest, Subject } from 'rxjs';
import { filter, map, takeUntil } from 'rxjs/operators';
import { FuseConfigService } from '@fuse/services/config';
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
import { FuseTailwindService } from '@fuse/services/tailwind/tailwind.service';
import { FUSE_VERSION } from '@fuse/version';
import { Layout } from 'app/layout/layout.types';
import { AppConfig, Scheme, Theme } from 'app/core/config/app.config';
import { AppConfig } from 'app/core/config/app.config';
@Component({
selector : 'layout',
@@ -22,7 +21,6 @@ export class LayoutComponent implements OnInit, OnDestroy
layout: Layout;
scheme: 'dark' | 'light';
theme: string;
themes: [string, any][] = [];
private _unsubscribeAll: Subject<any> = new Subject<any>();
/**
@@ -34,8 +32,7 @@ export class LayoutComponent implements OnInit, OnDestroy
private _renderer2: Renderer2,
private _router: Router,
private _fuseConfigService: FuseConfigService,
private _fuseMediaWatcherService: FuseMediaWatcherService,
private _fuseTailwindConfigService: FuseTailwindService
private _fuseMediaWatcherService: FuseMediaWatcherService
)
{
}
@@ -49,11 +46,6 @@ export class LayoutComponent implements OnInit, OnDestroy
*/
ngOnInit(): void
{
// Get the themes
this._fuseTailwindConfigService.tailwindConfig$.subscribe((config) => {
this.themes = Object.entries(config.themes);
});
// Set the theme and scheme based on the configuration
combineLatest([
this._fuseConfigService.config$,
@@ -123,50 +115,6 @@ export class LayoutComponent implements OnInit, OnDestroy
this._unsubscribeAll.complete();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Set the layout on the config
*
* @param layout
*/
setLayout(layout: string): void
{
// Clear the 'layout' query param to allow layout changes
this._router.navigate([], {
queryParams : {
layout: null
},
queryParamsHandling: 'merge'
}).then(() => {
// Set the config
this._fuseConfigService.config = {layout};
});
}
/**
* Set the scheme on the config
*
* @param scheme
*/
setScheme(scheme: Scheme): void
{
this._fuseConfigService.config = {scheme};
}
/**
* Set the theme on the config
*
* @param theme
*/
setTheme(theme: Theme): void
{
this._fuseConfigService.config = {theme};
}
// -----------------------------------------------------------------------------------------------------
// @ Private methods
// -----------------------------------------------------------------------------------------------------

View File

@@ -14,6 +14,7 @@ import { CompactLayoutModule } from 'app/layout/layouts/vertical/compact/compact
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';
import { SettingsModule } from 'app/layout/common/settings/settings.module';
import { SharedModule } from 'app/shared/shared.module';
const layoutModules = [
@@ -39,12 +40,13 @@ const layoutModules = [
declarations: [
LayoutComponent
],
imports : [
imports: [
MatIconModule,
MatTooltipModule,
FuseDrawerModule,
SharedModule,
...layoutModules
SettingsModule,
...layoutModules,
],
exports : [
LayoutComponent,

View File

@@ -45,13 +45,19 @@
</button>
</ng-container>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-1 sm:space-x-2">
<div class="flex items-center pl-2 ml-auto space-x-0.5 sm:space-x-2">
<languages></languages>
<fuse-fullscreen class="hidden md:block"></fuse-fullscreen>
<search [appearance]="'bar'"></search>
<shortcuts></shortcuts>
<messages></messages>
<notifications></notifications>
<button
class="lg:hidden"
mat-icon-button
(click)="quickChat.toggle()">
<mat-icon [svgIcon]="'heroicons_outline:chat-alt-2'"></mat-icon>
</button>
<user></user>
</div>
</div>
@@ -86,3 +92,6 @@
</div>
</div>
<!-- Quick chat -->
<quick-chat #quickChat="quickChat"></quick-chat>

View File

@@ -10,6 +10,7 @@ import { FuseNavigationModule } from '@fuse/components/navigation';
import { LanguagesModule } from 'app/layout/common/languages/languages.module';
import { MessagesModule } from 'app/layout/common/messages/messages.module';
import { NotificationsModule } from 'app/layout/common/notifications/notifications.module';
import { QuickChatModule } from 'app/layout/common/quick-chat/quick-chat.module';
import { SearchModule } from 'app/layout/common/search/search.module';
import { ShortcutsModule } from 'app/layout/common/shortcuts/shortcuts.module';
import { UserModule } from 'app/layout/common/user/user.module';
@@ -32,6 +33,7 @@ import { EnterpriseLayoutComponent } from 'app/layout/layouts/horizontal/enterpr
LanguagesModule,
MessagesModule,
NotificationsModule,
QuickChatModule,
SearchModule,
ShortcutsModule,
UserModule,

View File

@@ -54,13 +54,19 @@
</button>
</ng-container>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-1 sm:space-x-2">
<div class="flex items-center pl-2 ml-auto space-x-0.5 sm:space-x-2">
<languages></languages>
<fuse-fullscreen class="hidden md:block"></fuse-fullscreen>
<search [appearance]="'bar'"></search>
<shortcuts></shortcuts>
<messages></messages>
<notifications></notifications>
<button
class="lg:hidden"
mat-icon-button
(click)="quickChat.toggle()">
<mat-icon [svgIcon]="'heroicons_outline:chat-alt-2'"></mat-icon>
</button>
<user></user>
</div>
</div>
@@ -78,3 +84,6 @@
</div>
</div>
<!-- Quick chat -->
<quick-chat #quickChat="quickChat"></quick-chat>

View File

@@ -10,6 +10,7 @@ import { FuseNavigationModule } from '@fuse/components/navigation';
import { LanguagesModule } from 'app/layout/common/languages/languages.module';
import { MessagesModule } from 'app/layout/common/messages/messages.module';
import { NotificationsModule } from 'app/layout/common/notifications/notifications.module';
import { QuickChatModule } from 'app/layout/common/quick-chat/quick-chat.module';
import { SearchModule } from 'app/layout/common/search/search.module';
import { ShortcutsModule } from 'app/layout/common/shortcuts/shortcuts.module';
import { UserModule } from 'app/layout/common/user/user.module';
@@ -32,6 +33,7 @@ import { ModernLayoutComponent } from 'app/layout/layouts/horizontal/modern/mode
LanguagesModule,
MessagesModule,
NotificationsModule,
QuickChatModule,
SearchModule,
ShortcutsModule,
UserModule,

View File

@@ -35,13 +35,19 @@
<mat-icon [svgIcon]="'heroicons_outline:menu'"></mat-icon>
</button>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-1 sm:space-x-2">
<div class="flex items-center pl-2 ml-auto space-x-0.5 sm:space-x-2">
<languages></languages>
<fuse-fullscreen class="hidden md:block"></fuse-fullscreen>
<search [appearance]="'bar'"></search>
<shortcuts></shortcuts>
<messages></messages>
<notifications></notifications>
<button
class="lg:hidden"
mat-icon-button
(click)="quickChat.toggle()">
<mat-icon [svgIcon]="'heroicons_outline:chat-alt-2'"></mat-icon>
</button>
<user></user>
</div>
</div>
@@ -59,3 +65,6 @@
</div>
</div>
<!-- Quick chat -->
<quick-chat #quickChat="quickChat"></quick-chat>

View File

@@ -10,6 +10,7 @@ import { FuseNavigationModule } from '@fuse/components/navigation';
import { LanguagesModule } from 'app/layout/common/languages/languages.module';
import { MessagesModule } from 'app/layout/common/messages/messages.module';
import { NotificationsModule } from 'app/layout/common/notifications/notifications.module';
import { QuickChatModule } from 'app/layout/common/quick-chat/quick-chat.module';
import { SearchModule } from 'app/layout/common/search/search.module';
import { ShortcutsModule } from 'app/layout/common/shortcuts/shortcuts.module';
import { UserModule } from 'app/layout/common/user/user.module';
@@ -32,6 +33,7 @@ import { ClassicLayoutComponent } from 'app/layout/layouts/vertical/classic/clas
LanguagesModule,
MessagesModule,
NotificationsModule,
QuickChatModule,
SearchModule,
ShortcutsModule,
UserModule,

View File

@@ -65,12 +65,18 @@
<mat-icon [svgIcon]="'heroicons_outline:menu'"></mat-icon>
</button>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-1 sm:space-x-2">
<div class="flex items-center pl-2 ml-auto space-x-0.5 sm:space-x-2">
<languages></languages>
<fuse-fullscreen class="hidden md:block"></fuse-fullscreen>
<search [appearance]="'bar'"></search>
<shortcuts></shortcuts>
<messages></messages>
<button
class="lg:hidden"
mat-icon-button
(click)="quickChat.toggle()">
<mat-icon [svgIcon]="'heroicons_outline:chat-alt-2'"></mat-icon>
</button>
</div>
</div>
@@ -87,3 +93,6 @@
</div>-->
</div>
<!-- Quick chat -->
<quick-chat #quickChat="quickChat"></quick-chat>

View File

@@ -10,6 +10,7 @@ import { FuseFullscreenModule } from '@fuse/components/fullscreen/fullscreen.mod
import { LanguagesModule } from 'app/layout/common/languages/languages.module';
import { MessagesModule } from 'app/layout/common/messages/messages.module';
import { NotificationsModule } from 'app/layout/common/notifications/notifications.module';
import { QuickChatModule } from 'app/layout/common/quick-chat/quick-chat.module';
import { SearchModule } from 'app/layout/common/search/search.module';
import { ShortcutsModule } from 'app/layout/common/shortcuts/shortcuts.module';
import { UserModule } from 'app/layout/common/user/user.module';
@@ -32,6 +33,7 @@ import { ClassyLayoutComponent } from 'app/layout/layouts/vertical/classy/classy
LanguagesModule,
MessagesModule,
NotificationsModule,
QuickChatModule,
SearchModule,
ShortcutsModule,
UserModule,

View File

@@ -30,13 +30,19 @@
<mat-icon [svgIcon]="'heroicons_outline:menu'"></mat-icon>
</button>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-1 sm:space-x-2">
<div class="flex items-center pl-2 ml-auto space-x-0.5 sm:space-x-2">
<languages></languages>
<fuse-fullscreen class="hidden md:block"></fuse-fullscreen>
<search [appearance]="'bar'"></search>
<shortcuts></shortcuts>
<messages></messages>
<notifications></notifications>
<button
class="lg:hidden"
mat-icon-button
(click)="quickChat.toggle()">
<mat-icon [svgIcon]="'heroicons_outline:chat-alt-2'"></mat-icon>
</button>
<user></user>
</div>
</div>
@@ -54,3 +60,6 @@
</div>
</div>
<!-- Quick chat -->
<quick-chat #quickChat="quickChat"></quick-chat>

View File

@@ -10,6 +10,7 @@ import { FuseNavigationModule } from '@fuse/components/navigation';
import { LanguagesModule } from 'app/layout/common/languages/languages.module';
import { MessagesModule } from 'app/layout/common/messages/messages.module';
import { NotificationsModule } from 'app/layout/common/notifications/notifications.module';
import { QuickChatModule } from 'app/layout/common/quick-chat/quick-chat.module';
import { SearchModule } from 'app/layout/common/search/search.module';
import { ShortcutsModule } from 'app/layout/common/shortcuts/shortcuts.module';
import { UserModule } from 'app/layout/common/user/user.module';
@@ -32,6 +33,7 @@ import { CompactLayoutComponent } from 'app/layout/layouts/vertical/compact/comp
LanguagesModule,
MessagesModule,
NotificationsModule,
QuickChatModule,
SearchModule,
ShortcutsModule,
UserModule,

View File

@@ -39,13 +39,19 @@
</button>
</div>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-1 sm:space-x-2">
<div class="flex items-center pl-2 ml-auto space-x-0.5 sm:space-x-2">
<languages></languages>
<fuse-fullscreen class="hidden md:block"></fuse-fullscreen>
<search [appearance]="'bar'"></search>
<shortcuts></shortcuts>
<messages></messages>
<notifications></notifications>
<button
class="lg:hidden"
mat-icon-button
(click)="quickChat.toggle()">
<mat-icon [svgIcon]="'heroicons_outline:chat-alt-2'"></mat-icon>
</button>
<user></user>
</div>
</div>
@@ -63,3 +69,6 @@
</div>
</div>
<!-- Quick chat -->
<quick-chat #quickChat="quickChat"></quick-chat>

View File

@@ -10,6 +10,7 @@ import { FuseNavigationModule } from '@fuse/components/navigation';
import { LanguagesModule } from 'app/layout/common/languages/languages.module';
import { MessagesModule } from 'app/layout/common/messages/messages.module';
import { NotificationsModule } from 'app/layout/common/notifications/notifications.module';
import { QuickChatModule } from 'app/layout/common/quick-chat/quick-chat.module';
import { SearchModule } from 'app/layout/common/search/search.module';
import { ShortcutsModule } from 'app/layout/common/shortcuts/shortcuts.module';
import { UserModule } from 'app/layout/common/user/user.module';
@@ -32,6 +33,7 @@ import { DenseLayoutComponent } from 'app/layout/layouts/vertical/dense/dense.co
LanguagesModule,
MessagesModule,
NotificationsModule,
QuickChatModule,
SearchModule,
ShortcutsModule,
UserModule,

View File

@@ -44,13 +44,19 @@
<mat-icon [svgIcon]="'heroicons_outline:menu'"></mat-icon>
</button>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-1 sm:space-x-2">
<div class="flex items-center pl-2 ml-auto space-x-0.5 sm:space-x-2">
<languages></languages>
<fuse-fullscreen class="hidden md:block"></fuse-fullscreen>
<search [appearance]="'bar'"></search>
<shortcuts></shortcuts>
<messages></messages>
<notifications></notifications>
<button
class="lg:hidden"
mat-icon-button
(click)="quickChat.toggle()">
<mat-icon [svgIcon]="'heroicons_outline:chat-alt-2'"></mat-icon>
</button>
</div>
</div>
@@ -67,3 +73,6 @@
</div>
</div>
<!-- Quick chat -->
<quick-chat #quickChat="quickChat"></quick-chat>

View File

@@ -10,6 +10,7 @@ import { FuseNavigationModule } from '@fuse/components/navigation';
import { LanguagesModule } from 'app/layout/common/languages/languages.module';
import { MessagesModule } from 'app/layout/common/messages/messages.module';
import { NotificationsModule } from 'app/layout/common/notifications/notifications.module';
import { QuickChatModule } from 'app/layout/common/quick-chat/quick-chat.module';
import { SearchModule } from 'app/layout/common/search/search.module';
import { ShortcutsModule } from 'app/layout/common/shortcuts/shortcuts.module';
import { UserModule } from 'app/layout/common/user/user.module';
@@ -32,6 +33,7 @@ import { FuturisticLayoutComponent } from 'app/layout/layouts/vertical/futuristi
LanguagesModule,
MessagesModule,
NotificationsModule,
QuickChatModule,
SearchModule,
ShortcutsModule,
UserModule,

View File

@@ -31,13 +31,19 @@
<mat-icon [svgIcon]="'heroicons_outline:menu'"></mat-icon>
</button>
<!-- Components -->
<div class="flex items-center pl-2 ml-auto space-x-1 sm:space-x-2">
<div class="flex items-center pl-2 ml-auto space-x-0.5 sm:space-x-2">
<languages></languages>
<fuse-fullscreen class="hidden md:block"></fuse-fullscreen>
<search [appearance]="'bar'"></search>
<shortcuts></shortcuts>
<messages></messages>
<notifications></notifications>
<button
class="lg:hidden"
mat-icon-button
(click)="quickChat.toggle()">
<mat-icon [svgIcon]="'heroicons_outline:chat-alt-2'"></mat-icon>
</button>
<user></user>
</div>
</div>
@@ -55,3 +61,6 @@
</div>
</div>
<!-- Quick chat -->
<quick-chat #quickChat="quickChat"></quick-chat>

View File

@@ -10,6 +10,7 @@ import { FuseNavigationModule } from '@fuse/components/navigation';
import { LanguagesModule } from 'app/layout/common/languages/languages.module';
import { MessagesModule } from 'app/layout/common/messages/messages.module';
import { NotificationsModule } from 'app/layout/common/notifications/notifications.module';
import { QuickChatModule } from 'app/layout/common/quick-chat/quick-chat.module';
import { SearchModule } from 'app/layout/common/search/search.module';
import { ShortcutsModule } from 'app/layout/common/shortcuts/shortcuts.module';
import { UserModule } from 'app/layout/common/user/user.module';
@@ -32,6 +33,7 @@ import { ThinLayoutComponent } from 'app/layout/layouts/vertical/thin/thin.compo
LanguagesModule,
MessagesModule,
NotificationsModule,
QuickChatModule,
SearchModule,
ShortcutsModule,
UserModule,

View File

@@ -981,7 +981,7 @@ export const defaultNavigation: FuseNavigationItem[] = [
icon : 'heroicons_outline:speakerphone',
link : '/docs/changelog',
badge: {
title : '13.4.0',
title : '13.6.0',
classes: 'px-2 bg-yellow-300 text-black rounded-full'
}
},

View File

@@ -1,4 +1,4 @@
<div class="flex flex-col max-w-240 md:min-w-160 -m-6">
<div class="flex flex-col max-w-240 md:min-w-160 max-h-screen -m-6">
<!-- Header -->
<div class="flex flex-0 items-center justify-between h-16 pr-3 sm:pr-5 pl-6 sm:pl-8 bg-primary text-on-primary">
@@ -107,14 +107,14 @@
<!-- Discard -->
<button
class="ml-auto sm:ml-0"
mat-button
mat-stroked-button
(click)="discard()">
Discard
</button>
<!-- Save as draft -->
<button
class="sm:mx-3"
mat-button
mat-stroked-button
(click)="saveAsDraft()">
<span>Save as draft</span>
</button>

View File

@@ -4,13 +4,69 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
@Component({
selector : 'changelog',
templateUrl : './changelog.html',
styles : [''],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChangelogComponent
{
changelog: any[] = [
// v13.6.0
{
version : 'v13.6.0',
releaseDate: 'Aug 31, 2021',
changes : [
{
type: 'Added',
list: [
'(QuickChat) Added the QuickChat bar'
]
},
{
type: 'Changed',
list: [
'(dependencies) Updated Angular & Angular Material to v12.2.3',
'(dependencies) Updated various other packages',
'(layout) Separated the Settings drawer from the layout component'
]
},
{
type: 'Fixed',
list: [
'(@fuse/drawer) Final opacity of the overlay is not permanent due to player being destroyed right after the animation'
]
}
]
},
// v13.5.0
{
version : 'v13.5.0',
releaseDate: 'Aug 13, 2021',
changes : [
{
type: 'Changed',
list: [
'Huge performance improvement due to Angular v12.2.0',
'(dependencies) Updated Angular & Angular Material to v12.2.1',
'(dependencies) Updated various other packages',
'(tailwindcss) Removed old jsdoc from the config file',
'(@fuse/theming) Better structuring on the themes.scss file',
'(@fuse) Disabled Angular Material "theme" sanity check since we use "all-component-themes" without a color map',
'(apps/mailbox) Style improvements',
'Removed empty "styles" from component decorators',
'Decreased budget sizes since new Fuse is a lot smaller compared to the one with the old design'
]
},
{
type: 'Fixed',
list: [
'(@fuse/overrides) Quill editor is not styled correctly by default',
'(@fuse/confirmation) Dialog size cannot be updated using dialogRef\'s "updateSize" method',
'(apps/mailbox) Compose dialog doesn\'t work correctly on small height resolutions',
'(ui/page-layouts) Demo layout navigation appearance is not correct'
]
}
]
},
// v13.4.0
{
version : 'v13.4.0',

View File

@@ -3,8 +3,7 @@ import { GuidesComponent } from 'app/modules/admin/docs/guides/guides.component'
@Component({
selector : 'jwt',
templateUrl: './jwt.html',
styles : ['']
templateUrl: './jwt.html'
})
export class JwtComponent
{

View File

@@ -3,8 +3,7 @@ import { GuidesComponent } from 'app/modules/admin/docs/guides/guides.component'
@Component({
selector : 'component-theming',
templateUrl: './component-theming.html',
styles : ['']
templateUrl: './component-theming.html'
})
export class ComponentThemingComponent
{

View File

@@ -3,8 +3,7 @@ import { GuidesComponent } from 'app/modules/admin/docs/guides/guides.component'
@Component({
selector : 'multi-language',
templateUrl: './multi-language.html',
styles : ['']
templateUrl: './multi-language.html'
})
export class MultiLanguageCustomizationComponent
{

View File

@@ -3,8 +3,7 @@ import { GuidesComponent } from 'app/modules/admin/docs/guides/guides.component'
@Component({
selector : 'page-layouts',
templateUrl: './page-layouts.html',
styles : ['']
templateUrl: './page-layouts.html'
})
export class PageLayoutsComponent
{

View File

@@ -3,8 +3,7 @@ import { GuidesComponent } from 'app/modules/admin/docs/guides/guides.component'
@Component({
selector : 'splash-screen',
templateUrl: './splash-screen.html',
styles : ['']
templateUrl: './splash-screen.html'
})
export class SplashScreenCustomizationComponent
{

View File

@@ -3,8 +3,7 @@ import { GuidesComponent } from 'app/modules/admin/docs/guides/guides.component'
@Component({
selector : 'tailwindcss',
templateUrl: './tailwindcss.html',
styles : ['']
templateUrl: './tailwindcss.html'
})
export class TailwindCSSComponent
{

View File

@@ -3,8 +3,7 @@ import { GuidesComponent } from 'app/modules/admin/docs/guides/guides.component'
@Component({
selector : 'theme-layouts',
templateUrl: './theme-layouts.html',
styles : ['']
templateUrl: './theme-layouts.html'
})
export class ThemeLayoutsComponent
{

View File

@@ -3,8 +3,7 @@ import { GuidesComponent } from 'app/modules/admin/docs/guides/guides.component'
@Component({
selector : 'theming',
templateUrl: './theming.html',
styles : ['']
templateUrl: './theming.html'
})
export class ThemingComponent
{

View File

@@ -3,8 +3,7 @@ import { GuidesComponent } from 'app/modules/admin/docs/guides/guides.component'
@Component({
selector : 'component-structure',
templateUrl: './component-structure.html',
styles : ['']
templateUrl: './component-structure.html'
})
export class ComponentStructureComponent
{

View File

@@ -3,8 +3,7 @@ import { GuidesComponent } from 'app/modules/admin/docs/guides/guides.component'
@Component({
selector : 'deployment',
templateUrl: './deployment.html',
styles : ['']
templateUrl: './deployment.html'
})
export class DeploymentComponent
{

View File

@@ -3,8 +3,7 @@ import { GuidesComponent } from 'app/modules/admin/docs/guides/guides.component'
@Component({
selector : 'starter-kit',
templateUrl: './starter-kit.html',
styles : ['']
templateUrl: './starter-kit.html'
})
export class StarterKitComponent
{

View File

@@ -3,8 +3,7 @@ import { GuidesComponent } from 'app/modules/admin/docs/guides/guides.component'
@Component({
selector : 'updating',
templateUrl: './updating.html',
styles : ['']
templateUrl: './updating.html'
})
export class UpdatingComponent
{

View File

@@ -3,8 +3,7 @@ import { GuidesComponent } from 'app/modules/admin/docs/guides/guides.component'
@Component({
selector : 'installation',
templateUrl: './installation.html',
styles : ['']
templateUrl: './installation.html'
})
export class InstallationComponent
{

View File

@@ -3,8 +3,7 @@ import { GuidesComponent } from 'app/modules/admin/docs/guides/guides.component'
@Component({
selector : 'introduction',
templateUrl: './introduction.html',
styles : ['']
templateUrl: './introduction.html'
})
export class IntroductionComponent
{

View File

@@ -3,8 +3,7 @@ import { GuidesComponent } from 'app/modules/admin/docs/guides/guides.component'
@Component({
selector : 'prerequisites',
templateUrl: './prerequisites.html',
styles : ['']
templateUrl: './prerequisites.html'
})
export class PrerequisitesComponent
{

View File

@@ -3,8 +3,7 @@ import { GuidesComponent } from 'app/modules/admin/docs/guides/guides.component'
@Component({
selector : 'serving',
templateUrl: './serving.html',
styles : ['']
templateUrl: './serving.html'
})
export class ServingComponent
{

View File

@@ -24,7 +24,7 @@
<div class="max-w-3xl">
<div class="max-w-3xl prose prose-sm">
<p>
One of the repetitive and tedious jobs in Angular is to create confirmation dialogs. Since dialogs require their own component
One of the repetitive and tedious jobs in Angular is to create confirmation dialogs. Since dialogs require their own components
you have to either create a separate component every time you need a confirmation dialog or you have to create your own
confirmation dialog system that can be configured.
</p>

View File

@@ -3,8 +3,7 @@ import { FuseComponentsComponent } from 'app/modules/admin/ui/fuse-components/fu
@Component({
selector : 'card',
templateUrl: './card.component.html',
styles : ['']
templateUrl: './card.component.html'
})
export class CardComponent
{

View File

@@ -3,8 +3,7 @@ import { FuseComponentsComponent } from 'app/modules/admin/ui/fuse-components/fu
@Component({
selector : 'date-range',
templateUrl: './date-range.component.html',
styles : ['']
templateUrl: './date-range.component.html'
})
export class DateRangeComponent
{

View File

@@ -4,8 +4,7 @@ import { FuseComponentsComponent } from 'app/modules/admin/ui/fuse-components/fu
@Component({
selector : 'drawer',
templateUrl: './drawer.component.html',
styles : ['']
templateUrl: './drawer.component.html'
})
export class DrawerComponent
{

View File

@@ -3,8 +3,7 @@ import { FuseComponentsComponent } from 'app/modules/admin/ui/fuse-components/fu
@Component({
selector : 'fullscreen',
templateUrl: './fullscreen.component.html',
styles : ['']
templateUrl: './fullscreen.component.html'
})
export class FullscreenComponent
{

View File

@@ -3,8 +3,7 @@ import { FuseComponentsComponent } from 'app/modules/admin/ui/fuse-components/fu
@Component({
selector : 'highlight',
templateUrl: './highlight.component.html',
styles : ['']
templateUrl: './highlight.component.html'
})
export class HighlightComponent
{

View File

@@ -6,8 +6,7 @@ import { takeUntil } from 'rxjs/operators';
@Component({
selector : 'masonry',
templateUrl: './masonry.component.html',
styles : ['']
templateUrl: './masonry.component.html'
})
export class MasonryComponent implements OnInit
{

View File

@@ -4,8 +4,7 @@ import { FuseComponentsComponent } from 'app/modules/admin/ui/fuse-components/fu
@Component({
selector : 'navigation',
templateUrl: './navigation.component.html',
styles : ['']
templateUrl: './navigation.component.html'
})
export class NavigationComponent
{

View File

@@ -3,8 +3,7 @@ import { FuseComponentsComponent } from 'app/modules/admin/ui/fuse-components/fu
@Component({
selector : 'scroll-reset',
templateUrl: './scroll-reset.component.html',
styles : ['']
templateUrl: './scroll-reset.component.html'
})
export class ScrollResetComponent
{

View File

@@ -3,8 +3,7 @@ import { FuseComponentsComponent } from 'app/modules/admin/ui/fuse-components/fu
@Component({
selector : 'scrollbar',
templateUrl: './scrollbar.component.html',
styles : ['']
templateUrl: './scrollbar.component.html'
})
export class ScrollbarComponent
{

View File

@@ -3,8 +3,7 @@ import { FuseComponentsComponent } from 'app/modules/admin/ui/fuse-components/fu
@Component({
selector : 'mock-api',
templateUrl: './mock-api.component.html',
styles : ['']
templateUrl: './mock-api.component.html'
})
export class MockApiComponent
{

View File

@@ -3,8 +3,7 @@ import { FuseComponentsComponent } from 'app/modules/admin/ui/fuse-components/fu
@Component({
selector : 'find-by-key',
templateUrl: './find-by-key.component.html',
styles : ['']
templateUrl: './find-by-key.component.html'
})
export class FindByKeyComponent
{

View File

@@ -3,8 +3,7 @@ import { FuseComponentsComponent } from 'app/modules/admin/ui/fuse-components/fu
@Component({
selector : 'config',
templateUrl: './config.component.html',
styles : ['']
templateUrl: './config.component.html'
})
export class ConfigComponent
{

View File

@@ -208,7 +208,21 @@
<h2>MatDialogRef</h2>
<p>
Since <code>FuseConfirmationService</code> uses <em>MatDialog</em> behind the scenes, it returns
a reference to the created dialog. Using that reference, you can access to the user input:
a reference to the created dialog. You can use all available methods from that reference such as
<code>updateSize</code> and <code>updatePosition</code> to further customize the dialog.
</p>
<p>
See
<a
href="https://material.angular.io/components/dialog/api#MatDialogRef"
target="_blank"
rel="noreferrer">
https://material.angular.io/components/dialog/api#MatDialogRef
</a>
for the complete list of available methods.
</p>
<p>
Using the reference, you can also access to the user input:
</p>
<!-- @formatter:off -->
<textarea

View File

@@ -3,8 +3,7 @@ import { FuseComponentsComponent } from 'app/modules/admin/ui/fuse-components/fu
@Component({
selector : 'media-watcher',
templateUrl: './media-watcher.component.html',
styles : ['']
templateUrl: './media-watcher.component.html'
})
export class MediaWatcherComponent
{

View File

@@ -3,8 +3,7 @@ import { FuseComponentsComponent } from 'app/modules/admin/ui/fuse-components/fu
@Component({
selector : 'splash-screen',
templateUrl: './splash-screen.component.html',
styles : ['']
templateUrl: './splash-screen.component.html'
})
export class SplashScreenComponent
{

View File

@@ -3,8 +3,7 @@ import { FuseComponentsComponent } from 'app/modules/admin/ui/fuse-components/fu
@Component({
selector : 'must-match',
templateUrl: './must-match.component.html',
styles : ['']
templateUrl: './must-match.component.html'
})
export class MustMatchComponent
{

View File

@@ -3,8 +3,7 @@ import { OtherComponentsComponent } from 'app/modules/admin/ui/other-components/
@Component({
selector : 'overview',
templateUrl: './overview.component.html',
styles : ['']
templateUrl: './overview.component.html'
})
export class OverviewComponent
{

View File

@@ -3,8 +3,7 @@ import { OtherComponentsComponent } from 'app/modules/admin/ui/other-components/
@Component({
selector : 'apex-charts',
templateUrl: './apex-charts.component.html',
styles : ['']
templateUrl: './apex-charts.component.html'
})
export class ApexChartsComponent
{

View File

@@ -3,8 +3,7 @@ import { OtherComponentsComponent } from 'app/modules/admin/ui/other-components/
@Component({
selector : 'full-calendar',
templateUrl: './full-calendar.component.html',
styles : ['']
templateUrl: './full-calendar.component.html'
})
export class FullCalendarComponent
{

View File

@@ -3,8 +3,7 @@ import { OtherComponentsComponent } from 'app/modules/admin/ui/other-components/
@Component({
selector : 'ngx-markdown',
templateUrl: './ngx-markdown.component.html',
styles : ['']
templateUrl: './ngx-markdown.component.html'
})
export class NgxMarkdownComponent
{

View File

@@ -3,8 +3,7 @@ import { OtherComponentsComponent } from 'app/modules/admin/ui/other-components/
@Component({
selector : 'quill-editor',
templateUrl: './quill-editor.component.html',
styles : ['']
templateUrl: './quill-editor.component.html'
})
export class QuillEditorComponent
{

View File

@@ -13,7 +13,7 @@ import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types
<!-- Fixed demo sidebar -->
<div class="mx-6 text-3xl font-bold tracking-tighter">Demo Sidebar</div>
<fuse-vertical-navigation
[appearance]="'classic'"
[appearance]="'default'"
[navigation]="menuData"
[inner]="true"
[mode]="'side'"

View File

@@ -14,7 +14,8 @@ declare const require: {
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
platformBrowserDynamicTesting(),
{teardown: {destroyAfterEach: true}}
);
// Then we find all the tests.

View File

@@ -63,10 +63,6 @@ const themes = {
/**
* Tailwind configuration
*
* @param isProd
* This will be automatically supplied by the custom Angular builder
* based on the current environment of the application (prod, dev etc.)
*/
const config = {
experimental: {},
@@ -180,7 +176,7 @@ const config = {
* smaller by not generating useless utilities such as
* p-1/4 or m-480.
*/
extendedSpacing: {
extendedSpacing : {
// Fractional values
'1/2': '50%',
'1/3': '33.333333%',
@@ -206,30 +202,36 @@ const config = {
'400': '100rem',
'480': '120rem'
},
height : theme => ({
height : theme => ({
...theme('extendedSpacing')
}),
minHeight : theme => ({
minHeight : theme => ({
...theme('spacing'),
...theme('extendedSpacing')
}),
maxHeight : theme => ({
maxHeight : theme => ({
...theme('extendedSpacing'),
none: 'none'
}),
width : theme => ({
width : theme => ({
...theme('extendedSpacing')
}),
minWidth : theme => ({
minWidth : theme => ({
...theme('spacing'),
...theme('extendedSpacing'),
screen: '100vw'
}),
maxWidth : theme => ({
maxWidth : theme => ({
...theme('spacing'),
...theme('extendedSpacing'),
screen: '100vw'
}),
transitionDuration : {
'400': '400ms'
},
transitionTimingFunction: {
'drawer': 'cubic-bezier(0.25, 0.8, 0.25, 1)'
},
// @tailwindcss/typography
typography: (theme) => ({
@@ -417,7 +419,7 @@ const config = {
transitionDuration : [],
transitionProperty : [],
transitionTimingFunction: [],
translate : ['hover'],
translate : ['responsive', 'hover'],
userSelect : ['responsive'],
visibility : ['responsive'],
whitespace : ['responsive'],