mirror of
https://github.com/richard-loafle/fuse-angular.git
synced 2025-01-09 20:15:07 +00:00
Merge remote-tracking branch 'origin/demo' into starter
This commit is contained in:
commit
b84fb68a47
|
@ -14,4 +14,3 @@ last 2 Edge major versions
|
|||
last 2 Safari major versions
|
||||
last 2 iOS major versions
|
||||
Firefox ESR
|
||||
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -31,6 +31,7 @@ chrome-profiler-events*.json
|
|||
.history/*
|
||||
|
||||
# misc
|
||||
/.angular/cache
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage
|
||||
|
|
26516
package-lock.json
generated
26516
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
96
package.json
96
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@fuse/starter",
|
||||
"version": "13.6.2",
|
||||
"version": "14.0.0",
|
||||
"description": "Fuse - Angular Admin Template and Starter Project",
|
||||
"author": "https://themeforest.net/user/srcn",
|
||||
"license": "https://themeforest.net/licenses/standard",
|
||||
|
@ -14,78 +14,68 @@
|
|||
"lint": "ng lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/animations": "12.2.4",
|
||||
"@angular/cdk": "12.2.4",
|
||||
"@angular/common": "12.2.4",
|
||||
"@angular/compiler": "12.2.4",
|
||||
"@angular/core": "12.2.4",
|
||||
"@angular/forms": "12.2.4",
|
||||
"@angular/material": "12.2.4",
|
||||
"@angular/material-moment-adapter": "12.2.4",
|
||||
"@angular/platform-browser": "12.2.4",
|
||||
"@angular/platform-browser-dynamic": "12.2.4",
|
||||
"@angular/router": "12.2.4",
|
||||
"@fullcalendar/angular": "4.4.5-beta",
|
||||
"@fullcalendar/core": "4.4.2",
|
||||
"@fullcalendar/daygrid": "4.4.2",
|
||||
"@fullcalendar/interaction": "4.4.2",
|
||||
"@fullcalendar/list": "4.4.2",
|
||||
"@fullcalendar/moment": "4.4.2",
|
||||
"@fullcalendar/rrule": "4.4.2",
|
||||
"@fullcalendar/timegrid": "4.4.2",
|
||||
"@ngneat/transloco": "2.22.0",
|
||||
"apexcharts": "3.28.1",
|
||||
"@angular/animations": "13.0.1",
|
||||
"@angular/cdk": "13.0.0",
|
||||
"@angular/common": "13.0.1",
|
||||
"@angular/compiler": "13.0.1",
|
||||
"@angular/core": "13.0.1",
|
||||
"@angular/forms": "13.0.1",
|
||||
"@angular/material": "13.0.0",
|
||||
"@angular/material-moment-adapter": "13.0.0",
|
||||
"@angular/platform-browser": "13.0.1",
|
||||
"@angular/platform-browser-dynamic": "13.0.1",
|
||||
"@angular/router": "13.0.1",
|
||||
"@ngneat/transloco": "3.1.0",
|
||||
"apexcharts": "3.29.0",
|
||||
"crypto-js": "3.3.0",
|
||||
"highlight.js": "11.2.0",
|
||||
"highlight.js": "11.3.1",
|
||||
"lodash-es": "4.17.21",
|
||||
"moment": "2.29.1",
|
||||
"ng-apexcharts": "1.5.12",
|
||||
"ngx-markdown": "12.0.1",
|
||||
"ngx-quill": "14.3.0",
|
||||
"perfect-scrollbar": "1.5.2",
|
||||
"ngx-markdown": "13.0.0",
|
||||
"ngx-quill": "16.0.1",
|
||||
"perfect-scrollbar": "1.5.3",
|
||||
"quill": "1.3.7",
|
||||
"rrule": "2.6.8",
|
||||
"rxjs": "6.6.7",
|
||||
"rxjs": "7.4.0",
|
||||
"tslib": "2.3.1",
|
||||
"web-animations-js": "2.3.2",
|
||||
"zone.js": "0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "12.2.4",
|
||||
"@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.2.4",
|
||||
"@angular/compiler-cli": "12.2.4",
|
||||
"@tailwindcss/aspect-ratio": "0.2.1",
|
||||
"@tailwindcss/line-clamp": "0.2.1",
|
||||
"@angular-devkit/build-angular": "13.0.2",
|
||||
"@angular-eslint/builder": "12.6.1",
|
||||
"@angular-eslint/eslint-plugin": "12.6.1",
|
||||
"@angular-eslint/eslint-plugin-template": "12.6.1",
|
||||
"@angular-eslint/schematics": "12.6.1",
|
||||
"@angular-eslint/template-parser": "12.6.1",
|
||||
"@angular/cli": "13.0.2",
|
||||
"@angular/compiler-cli": "13.0.1",
|
||||
"@tailwindcss/aspect-ratio": "0.3.0",
|
||||
"@tailwindcss/line-clamp": "0.2.2",
|
||||
"@tailwindcss/typography": "0.4.1",
|
||||
"@types/chroma-js": "2.1.3",
|
||||
"@types/crypto-js": "3.1.47",
|
||||
"@types/highlight.js": "10.1.0",
|
||||
"@types/jasmine": "3.8.2",
|
||||
"@types/lodash": "4.14.172",
|
||||
"@types/lodash-es": "4.17.4",
|
||||
"@types/node": "12.20.21",
|
||||
"@typescript-eslint/eslint-plugin": "4.31.0",
|
||||
"@typescript-eslint/parser": "4.31.0",
|
||||
"autoprefixer": "10.3.4",
|
||||
"@types/jasmine": "3.10.2",
|
||||
"@types/lodash": "4.14.176",
|
||||
"@types/lodash-es": "4.17.5",
|
||||
"@types/node": "12.20.37",
|
||||
"@typescript-eslint/eslint-plugin": "5.3.1",
|
||||
"@typescript-eslint/parser": "5.3.1",
|
||||
"autoprefixer": "10.4.0",
|
||||
"chroma-js": "2.1.2",
|
||||
"eslint": "7.32.0",
|
||||
"eslint-plugin-import": "2.24.2",
|
||||
"eslint-plugin-jsdoc": "36.0.8",
|
||||
"eslint-plugin-import": "2.25.3",
|
||||
"eslint-plugin-jsdoc": "37.0.3",
|
||||
"eslint-plugin-prefer-arrow": "1.2.3",
|
||||
"jasmine-core": "3.8.0",
|
||||
"karma": "6.3.4",
|
||||
"jasmine-core": "3.10.1",
|
||||
"karma": "6.3.8",
|
||||
"karma-chrome-launcher": "3.1.0",
|
||||
"karma-coverage": "2.0.3",
|
||||
"karma-jasmine": "4.0.1",
|
||||
"karma-jasmine-html-reporter": "1.7.0",
|
||||
"lodash": "4.17.21",
|
||||
"postcss": "8.3.6",
|
||||
"tailwindcss": "2.2.9",
|
||||
"typescript": "4.3.5"
|
||||
"postcss": "8.3.11",
|
||||
"tailwindcss": "2.2.19",
|
||||
"typescript": "4.4.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, HostBinding, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { filter, takeUntil } from 'rxjs/operators';
|
||||
import { filter, Subject, takeUntil } from 'rxjs';
|
||||
import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseAlertAppearance, FuseAlertType } from '@fuse/components/alert/alert.types';
|
||||
|
@ -145,7 +144,7 @@ export class FuseAlertComponent implements OnChanges, OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
<div
|
||||
class="range"
|
||||
(click)="openPickerPanel()"
|
||||
#pickerPanelOrigin>
|
||||
|
||||
<div class="start">
|
||||
<div class="date">{{range.startDate}}</div>
|
||||
<div
|
||||
class="time"
|
||||
*ngIf="range.startTime">{{range.startTime}}</div>
|
||||
</div>
|
||||
|
||||
<div class="separator">-</div>
|
||||
|
||||
<div class="end">
|
||||
<div class="date">{{range.endDate}}</div>
|
||||
<div
|
||||
class="time"
|
||||
*ngIf="range.endTime">{{range.endTime}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<ng-template #pickerPanel>
|
||||
|
||||
<!-- Start -->
|
||||
<div class="start">
|
||||
|
||||
<div class="month">
|
||||
<div class="month-header">
|
||||
<button
|
||||
class="previous-button"
|
||||
mat-icon-button
|
||||
(click)="prev()"
|
||||
tabindex="1">
|
||||
<mat-icon [svgIcon]="'heroicons_outline:chevron-left'"></mat-icon>
|
||||
</button>
|
||||
<div class="month-label">{{getMonthLabel(1)}}</div>
|
||||
</div>
|
||||
<mat-month-view
|
||||
[(activeDate)]="activeDates.month1"
|
||||
[dateFilter]="dateFilter()"
|
||||
[dateClass]="dateClass()"
|
||||
(click)="$event.stopImmediatePropagation()"
|
||||
(selectedChange)="onSelectedDateChange($event)"
|
||||
#matMonthView1>
|
||||
</mat-month-view>
|
||||
</div>
|
||||
|
||||
<mat-form-field
|
||||
class="fuse-mat-no-subscript time start-time"
|
||||
*ngIf="timeRange">
|
||||
<input
|
||||
matInput
|
||||
[autocomplete]="'off'"
|
||||
[formControl]="startTimeFormControl"
|
||||
(blur)="updateStartTime($event)"
|
||||
tabindex="3">
|
||||
<mat-label>Start time</mat-label>
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- End -->
|
||||
<div class="end">
|
||||
|
||||
<div class="month">
|
||||
<div class="month-header">
|
||||
<div class="month-label">{{getMonthLabel(2)}}</div>
|
||||
<button
|
||||
class="next-button"
|
||||
mat-icon-button
|
||||
(click)="next()"
|
||||
tabindex="2">
|
||||
<mat-icon [svgIcon]="'heroicons_outline:chevron-right'"></mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<mat-month-view
|
||||
[(activeDate)]="activeDates.month2"
|
||||
[dateFilter]="dateFilter()"
|
||||
[dateClass]="dateClass()"
|
||||
(click)="$event.stopImmediatePropagation()"
|
||||
(selectedChange)="onSelectedDateChange($event)"
|
||||
#matMonthView2>
|
||||
</mat-month-view>
|
||||
</div>
|
||||
|
||||
<mat-form-field
|
||||
class="fuse-mat-no-subscript time end-time"
|
||||
*ngIf="timeRange">
|
||||
<input
|
||||
matInput
|
||||
[formControl]="endTimeFormControl"
|
||||
(blur)="updateEndTime($event)"
|
||||
tabindex="4">
|
||||
<mat-label>End time</mat-label>
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
|
||||
</ng-template>
|
|
@ -1,292 +0,0 @@
|
|||
/* Variables */
|
||||
$body-cell-padding: 2px;
|
||||
|
||||
fuse-date-range {
|
||||
display: flex;
|
||||
|
||||
.range {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 48px;
|
||||
min-height: 48px;
|
||||
max-height: 48px;
|
||||
cursor: pointer;
|
||||
|
||||
.start,
|
||||
.end {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
padding: 0 16px;
|
||||
border-radius: 6px;
|
||||
border-width: 1px;
|
||||
line-height: 1;
|
||||
@apply shadow-sm border-gray-300 dark:bg-black dark:bg-opacity-5 dark:border-gray-500;
|
||||
|
||||
.date {
|
||||
white-space: nowrap;
|
||||
|
||||
+ .time {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.time {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.separator {
|
||||
margin: 0 2px;
|
||||
|
||||
@screen sm {
|
||||
margin: 0 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fuse-date-range-panel {
|
||||
border-radius: 4px;
|
||||
padding: 24px;
|
||||
@apply shadow-2xl bg-card;
|
||||
|
||||
.start,
|
||||
.end {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.month {
|
||||
max-width: 196px;
|
||||
min-width: 196px;
|
||||
width: 196px;
|
||||
|
||||
.month-header {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 32px;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.previous-button,
|
||||
.next-button {
|
||||
position: absolute;
|
||||
width: 24px !important;
|
||||
height: 24px !important;
|
||||
min-height: 24px !important;
|
||||
max-height: 24px !important;
|
||||
line-height: 24px !important;
|
||||
|
||||
.mat-icon {
|
||||
@apply icon-size-5;
|
||||
}
|
||||
}
|
||||
|
||||
.previous-button {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.next-button {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.month-label {
|
||||
font-weight: 500;
|
||||
@apply text-secondary;
|
||||
}
|
||||
}
|
||||
|
||||
mat-month-view {
|
||||
display: flex;
|
||||
min-height: 188px;
|
||||
|
||||
.mat-calendar-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
|
||||
tbody {
|
||||
|
||||
tr {
|
||||
|
||||
&[aria-hidden=true] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
|
||||
td:first-child {
|
||||
|
||||
&[aria-hidden=true] {
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
td,
|
||||
td:hover {
|
||||
|
||||
&.fuse-date-range {
|
||||
|
||||
&:before {
|
||||
@apply bg-primary-200;
|
||||
}
|
||||
|
||||
.mat-calendar-body-cell-content {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
&.fuse-date-range-start,
|
||||
&.fuse-date-range-end {
|
||||
|
||||
.mat-calendar-body-cell-content {
|
||||
@apply bg-primary text-on-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-calendar-body-today {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
td.mat-calendar-body-cell {
|
||||
width: 28px !important;
|
||||
height: 28px !important;
|
||||
padding: $body-cell-padding !important;
|
||||
|
||||
&.fuse-date-range {
|
||||
position: relative;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: $body-cell-padding;
|
||||
right: 0;
|
||||
bottom: $body-cell-padding;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
&.fuse-date-range-start {
|
||||
|
||||
&:before {
|
||||
left: $body-cell-padding;
|
||||
border-radius: 999px 0 0 999px;
|
||||
}
|
||||
|
||||
&.fuse-date-range-end,
|
||||
&:last-child {
|
||||
|
||||
&:before {
|
||||
right: $body-cell-padding;
|
||||
border-radius: 999px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.fuse-date-range-end {
|
||||
|
||||
&:before {
|
||||
right: $body-cell-padding;
|
||||
border-radius: 0 999px 999px 0;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
|
||||
&:before {
|
||||
left: $body-cell-padding;
|
||||
border-radius: 999px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
|
||||
&:before {
|
||||
border-radius: 999px 0 0 999px;
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
|
||||
&:before {
|
||||
border-radius: 0 999px 999px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mat-calendar-body-cell-content {
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
td.mat-calendar-body-label {
|
||||
|
||||
+ td.mat-calendar-body-cell {
|
||||
|
||||
&.fuse-date-range {
|
||||
|
||||
&:before {
|
||||
border-radius: 999px 0 0 999px;
|
||||
}
|
||||
|
||||
&.fuse-date-range-start {
|
||||
|
||||
&.fuse-date-range-end {
|
||||
border-radius: 999px;
|
||||
}
|
||||
}
|
||||
|
||||
&.fuse-date-range-end {
|
||||
|
||||
&:before {
|
||||
left: $body-cell-padding;
|
||||
border-radius: 999px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.time {
|
||||
width: 100%;
|
||||
max-width: 196px;
|
||||
}
|
||||
}
|
||||
|
||||
.start {
|
||||
align-items: flex-start;
|
||||
margin-right: 20px;
|
||||
|
||||
.month {
|
||||
|
||||
.month-label {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.end {
|
||||
align-items: flex-end;
|
||||
margin-left: 20px;
|
||||
|
||||
.month {
|
||||
|
||||
.month-label {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,682 +0,0 @@
|
|||
import { ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, HostBinding, Input, OnDestroy, OnInit, Output, Renderer2, TemplateRef, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core';
|
||||
import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
|
||||
import { Overlay } from '@angular/cdk/overlay';
|
||||
import { TemplatePortal } from '@angular/cdk/portal';
|
||||
import { MatCalendarCellCssClasses, MatMonthView } from '@angular/material/datepicker';
|
||||
import { Subject } from 'rxjs';
|
||||
import * as moment from 'moment';
|
||||
import { Moment } from 'moment';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-date-range',
|
||||
templateUrl : './date-range.component.html',
|
||||
styleUrls : ['./date-range.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
exportAs : 'fuseDateRange',
|
||||
providers : [
|
||||
{
|
||||
provide : NG_VALUE_ACCESSOR,
|
||||
useExisting: forwardRef(() => FuseDateRangeComponent),
|
||||
multi : true
|
||||
}
|
||||
]
|
||||
})
|
||||
export class FuseDateRangeComponent implements ControlValueAccessor, OnInit, OnDestroy
|
||||
{
|
||||
@Output() readonly rangeChanged: EventEmitter<{ start: string; end: string }> = new EventEmitter<{ start: string; end: string }>();
|
||||
@ViewChild('matMonthView1') private _matMonthView1: MatMonthView<any>;
|
||||
@ViewChild('matMonthView2') private _matMonthView2: MatMonthView<any>;
|
||||
@ViewChild('pickerPanelOrigin', {read: ElementRef}) private _pickerPanelOrigin: ElementRef;
|
||||
@ViewChild('pickerPanel') private _pickerPanel: TemplateRef<any>;
|
||||
@HostBinding('class.fuse-date-range') private _defaultClassNames = true;
|
||||
|
||||
activeDates: { month1: Moment | null; month2: Moment | null } = {
|
||||
month1: null,
|
||||
month2: null
|
||||
};
|
||||
setWhichDate: 'start' | 'end' = 'start';
|
||||
startTimeFormControl: FormControl;
|
||||
endTimeFormControl: FormControl;
|
||||
private _dateFormat: string;
|
||||
private _onChange: (value: any) => void;
|
||||
private _onTouched: (value: any) => void;
|
||||
private _programmaticChange!: boolean;
|
||||
private _range: { start: Moment | null; end: Moment | null } = {
|
||||
start: null,
|
||||
end : null
|
||||
};
|
||||
private _timeFormat: string;
|
||||
private _timeRange: boolean;
|
||||
private readonly _timeRegExp: RegExp = new RegExp('^(0[0-9]|1[0-9]|2[0-4]|[0-9]):([0-5][0-9])(A|(?:AM)|P|(?:PM))?$', 'i');
|
||||
private _unsubscribeAll: Subject<any> = new Subject<any>();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(
|
||||
private _changeDetectorRef: ChangeDetectorRef,
|
||||
private _elementRef: ElementRef,
|
||||
private _overlay: Overlay,
|
||||
private _renderer2: Renderer2,
|
||||
private _viewContainerRef: ViewContainerRef
|
||||
)
|
||||
{
|
||||
this._onChange = (): void => {
|
||||
};
|
||||
this._onTouched = (): void => {
|
||||
};
|
||||
this.dateFormat = 'DD/MM/YYYY';
|
||||
this.timeFormat = '12';
|
||||
|
||||
// Initialize the component
|
||||
this._init();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Accessors
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Setter & getter for dateFormat input
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
@Input()
|
||||
set dateFormat(value: string)
|
||||
{
|
||||
// Return if the values are the same
|
||||
if ( this._dateFormat === value )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Store the value
|
||||
this._dateFormat = value;
|
||||
}
|
||||
|
||||
get dateFormat(): string
|
||||
{
|
||||
return this._dateFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter & getter for timeFormat input
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
@Input()
|
||||
set timeFormat(value: string)
|
||||
{
|
||||
// Return if the values are the same
|
||||
if ( this._timeFormat === value )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set format based on the time format input
|
||||
this._timeFormat = value === '12' ? 'hh:mmA' : 'HH:mm';
|
||||
}
|
||||
|
||||
get timeFormat(): string
|
||||
{
|
||||
return this._timeFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter & getter for timeRange input
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
@Input()
|
||||
set timeRange(value: boolean)
|
||||
{
|
||||
// Return if the values are the same
|
||||
if ( this._timeRange === value )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Store the value
|
||||
this._timeRange = value;
|
||||
|
||||
// If the time range turned off...
|
||||
if ( !value )
|
||||
{
|
||||
this.range = {
|
||||
start: this._range.start.clone().startOf('day'),
|
||||
end : this._range.end.clone().endOf('day')
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
get timeRange(): boolean
|
||||
{
|
||||
return this._timeRange;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter & getter for range input
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
@Input()
|
||||
set range(value)
|
||||
{
|
||||
if ( !value )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the value is an object and has 'start' and 'end' values
|
||||
if ( !value.start || !value.end )
|
||||
{
|
||||
console.error('Range input must have "start" and "end" properties!');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we are setting an individual date or both of them
|
||||
const whichDate = value.whichDate || null;
|
||||
|
||||
// Get the start and end dates as moment
|
||||
const start = moment(value.start);
|
||||
const end = moment(value.end);
|
||||
|
||||
// If we are only setting the start date...
|
||||
if ( whichDate === 'start' )
|
||||
{
|
||||
// Set the start date
|
||||
this._range.start = start.clone();
|
||||
|
||||
// If the selected start date is after the end date...
|
||||
if ( this._range.start.isAfter(this._range.end) )
|
||||
{
|
||||
// Set the end date to the start date but keep the end date's time
|
||||
const endDate = start.clone().hours(this._range.end.hours()).minutes(this._range.end.minutes()).seconds(this._range.end.seconds());
|
||||
|
||||
// Test this new end date to see if it's ahead of the start date
|
||||
if ( this._range.start.isBefore(endDate) )
|
||||
{
|
||||
// If it's, set the new end date
|
||||
this._range.end = endDate;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, set the end date same as the start date
|
||||
this._range.end = start.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we are only setting the end date...
|
||||
if ( whichDate === 'end' )
|
||||
{
|
||||
// Set the end date
|
||||
this._range.end = end.clone();
|
||||
|
||||
// If the selected end date is before the start date...
|
||||
if ( this._range.start.isAfter(this._range.end) )
|
||||
{
|
||||
// Set the start date to the end date but keep the start date's time
|
||||
const startDate = end.clone().hours(this._range.start.hours()).minutes(this._range.start.minutes()).seconds(this._range.start.seconds());
|
||||
|
||||
// Test this new end date to see if it's ahead of the start date
|
||||
if ( this._range.end.isAfter(startDate) )
|
||||
{
|
||||
// If it's, set the new start date
|
||||
this._range.start = startDate;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, set the start date same as the end date
|
||||
this._range.start = end.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we are setting both dates...
|
||||
if ( !whichDate )
|
||||
{
|
||||
// Set the start date
|
||||
this._range.start = start.clone();
|
||||
|
||||
// If the start date is before the end date, set the end date as normal.
|
||||
// If the start date is after the end date, set the end date same as the start date.
|
||||
this._range.end = start.isBefore(end) ? end.clone() : start.clone();
|
||||
}
|
||||
|
||||
// Prepare another range object that holds the ISO formatted range dates
|
||||
const range = {
|
||||
start: this._range.start.clone().toISOString(),
|
||||
end : this._range.end.clone().toISOString()
|
||||
};
|
||||
|
||||
// Emit the range changed event with the range
|
||||
this.rangeChanged.emit(range);
|
||||
|
||||
// Update the model with the range if the change was not a programmatic change
|
||||
// Because programmatic changes trigger writeValue which triggers onChange and onTouched
|
||||
// internally causing them to trigger twice which breaks the form's pristine and touched
|
||||
// statuses.
|
||||
if ( !this._programmaticChange )
|
||||
{
|
||||
this._onTouched(range);
|
||||
this._onChange(range);
|
||||
}
|
||||
|
||||
// Set the active dates
|
||||
this.activeDates = {
|
||||
month1: this._range.start.clone(),
|
||||
month2: this._range.start.clone().add(1, 'month')
|
||||
};
|
||||
|
||||
// Set the time form controls
|
||||
this.startTimeFormControl.setValue(this._range.start.clone().format(this._timeFormat).toString());
|
||||
this.endTimeFormControl.setValue(this._range.end.clone().format(this._timeFormat).toString());
|
||||
|
||||
// Run ngAfterContentInit on month views to trigger
|
||||
// re-render on month views if they are available
|
||||
if ( this._matMonthView1 && this._matMonthView2 )
|
||||
{
|
||||
this._matMonthView1.ngAfterContentInit();
|
||||
this._matMonthView2.ngAfterContentInit();
|
||||
}
|
||||
|
||||
// Reset the programmatic change status
|
||||
this._programmaticChange = false;
|
||||
}
|
||||
|
||||
get range(): any
|
||||
{
|
||||
// Clone the range start and end
|
||||
const start = this._range.start.clone();
|
||||
const end = this._range.end.clone();
|
||||
|
||||
// Build and return the range object
|
||||
return {
|
||||
startDate: start.clone().format(this.dateFormat),
|
||||
startTime: this.timeRange ? start.clone().format(this.timeFormat) : null,
|
||||
endDate : end.clone().format(this.dateFormat),
|
||||
endTime : this.timeRange ? end.clone().format(this.timeFormat) : null
|
||||
};
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Control Value Accessor
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Update the form model on change
|
||||
*
|
||||
* @param fn
|
||||
*/
|
||||
registerOnChange(fn: any): void
|
||||
{
|
||||
this._onChange = fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the form model on blur
|
||||
*
|
||||
* @param fn
|
||||
*/
|
||||
registerOnTouched(fn: any): void
|
||||
{
|
||||
this._onTouched = fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to view from model when the form model changes programmatically
|
||||
*
|
||||
* @param range
|
||||
*/
|
||||
writeValue(range: { start: string; end: string }): void
|
||||
{
|
||||
// Set this change as a programmatic one
|
||||
this._programmaticChange = true;
|
||||
|
||||
// Set the range
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
|
||||
// @ TODO: Workaround until "angular/issues/20007" resolved
|
||||
this.writeValue = (): void => {
|
||||
};
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Open the picker panel
|
||||
*/
|
||||
openPickerPanel(): void
|
||||
{
|
||||
// Create the overlay
|
||||
const overlayRef = this._overlay.create({
|
||||
panelClass : 'fuse-date-range-panel',
|
||||
backdropClass : '',
|
||||
hasBackdrop : true,
|
||||
scrollStrategy : this._overlay.scrollStrategies.reposition(),
|
||||
positionStrategy: this._overlay.position()
|
||||
.flexibleConnectedTo(this._pickerPanelOrigin)
|
||||
.withPositions([
|
||||
{
|
||||
originX : 'start',
|
||||
originY : 'bottom',
|
||||
overlayX: 'start',
|
||||
overlayY: 'top',
|
||||
offsetY : 8
|
||||
},
|
||||
{
|
||||
originX : 'start',
|
||||
originY : 'top',
|
||||
overlayX: 'start',
|
||||
overlayY: 'bottom',
|
||||
offsetY : -8
|
||||
}
|
||||
])
|
||||
});
|
||||
|
||||
// Create a portal from the template
|
||||
const templatePortal = new TemplatePortal(this._pickerPanel, this._viewContainerRef);
|
||||
|
||||
// On backdrop click
|
||||
overlayRef.backdropClick().subscribe(() => {
|
||||
|
||||
// If template portal exists and attached...
|
||||
if ( templatePortal && templatePortal.isAttached )
|
||||
{
|
||||
// Detach it
|
||||
templatePortal.detach();
|
||||
}
|
||||
|
||||
// If overlay exists and attached...
|
||||
if ( overlayRef && overlayRef.hasAttached() )
|
||||
{
|
||||
// Detach it
|
||||
overlayRef.detach();
|
||||
overlayRef.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
// Attach the portal to the overlay
|
||||
overlayRef.attach(templatePortal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get month label
|
||||
*
|
||||
* @param month
|
||||
*/
|
||||
getMonthLabel(month: number): string
|
||||
{
|
||||
if ( month === 1 )
|
||||
{
|
||||
return this.activeDates.month1.clone().format('MMMM Y');
|
||||
}
|
||||
|
||||
return this.activeDates.month2.clone().format('MMMM Y');
|
||||
}
|
||||
|
||||
/**
|
||||
* Date class function to add/remove class names to calendar days
|
||||
*/
|
||||
dateClass(): any
|
||||
{
|
||||
return (date: Moment): MatCalendarCellCssClasses => {
|
||||
|
||||
// If the date is both start and end date...
|
||||
if ( date.isSame(this._range.start, 'day') && date.isSame(this._range.end, 'day') )
|
||||
{
|
||||
return ['fuse-date-range', 'fuse-date-range-start', 'fuse-date-range-end'];
|
||||
}
|
||||
|
||||
// If the date is the start date...
|
||||
if ( date.isSame(this._range.start, 'day') )
|
||||
{
|
||||
return ['fuse-date-range', 'fuse-date-range-start'];
|
||||
}
|
||||
|
||||
// If the date is the end date...
|
||||
if ( date.isSame(this._range.end, 'day') )
|
||||
{
|
||||
return ['fuse-date-range', 'fuse-date-range-end'];
|
||||
}
|
||||
|
||||
// If the date is in between start and end dates...
|
||||
if ( date.isBetween(this._range.start, this._range.end, 'day') )
|
||||
{
|
||||
return ['fuse-date-range', 'fuse-date-range-mid'];
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Date filter to enable/disable calendar days
|
||||
*/
|
||||
dateFilter(): any
|
||||
{
|
||||
// If we are selecting the end date, disable all the dates that comes before the start date
|
||||
return (date: Moment): boolean => !(this.setWhichDate === 'end' && date.isBefore(this._range.start, 'day'));
|
||||
}
|
||||
|
||||
/**
|
||||
* On selected date change
|
||||
*
|
||||
* @param date
|
||||
*/
|
||||
onSelectedDateChange(date: Moment): void
|
||||
{
|
||||
// Create a new range object
|
||||
const newRange = {
|
||||
start : this._range.start.clone().toISOString(),
|
||||
end : this._range.end.clone().toISOString(),
|
||||
whichDate: null
|
||||
};
|
||||
|
||||
// Replace either the start or the end date with the new one
|
||||
// depending on which date we are setting
|
||||
if ( this.setWhichDate === 'start' )
|
||||
{
|
||||
newRange.start = moment(newRange.start).year(date.year()).month(date.month()).date(date.date()).toISOString();
|
||||
}
|
||||
else
|
||||
{
|
||||
newRange.end = moment(newRange.end).year(date.year()).month(date.month()).date(date.date()).toISOString();
|
||||
}
|
||||
|
||||
// Append the which date to the new range object
|
||||
newRange.whichDate = this.setWhichDate;
|
||||
|
||||
// Switch which date to set on the next run
|
||||
this.setWhichDate = this.setWhichDate === 'start' ? 'end' : 'start';
|
||||
|
||||
// Set the range
|
||||
this.range = newRange;
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to previous month on both views
|
||||
*/
|
||||
prev(): void
|
||||
{
|
||||
this.activeDates.month1 = moment(this.activeDates.month1).subtract(1, 'month');
|
||||
this.activeDates.month2 = moment(this.activeDates.month2).subtract(1, 'month');
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to next month on both views
|
||||
*/
|
||||
next(): void
|
||||
{
|
||||
this.activeDates.month1 = moment(this.activeDates.month1).add(1, 'month');
|
||||
this.activeDates.month2 = moment(this.activeDates.month2).add(1, 'month');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the start time
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
updateStartTime(event): void
|
||||
{
|
||||
// Parse the time
|
||||
const parsedTime = this._parseTime(event.target.value);
|
||||
|
||||
// Go back to the previous value if the form control is not valid
|
||||
if ( this.startTimeFormControl.invalid )
|
||||
{
|
||||
// Override the time
|
||||
const time = this._range.start.clone().format(this._timeFormat);
|
||||
|
||||
// Set the time
|
||||
this.startTimeFormControl.setValue(time);
|
||||
|
||||
// Do not update the range
|
||||
return;
|
||||
}
|
||||
|
||||
// Append the new time to the start date
|
||||
const startDate = this._range.start.clone().hours(parsedTime.hours()).minutes(parsedTime.minutes());
|
||||
|
||||
// If the new start date is after the current end date,
|
||||
// use the end date's time and set the start date again
|
||||
if ( startDate.isAfter(this._range.end) )
|
||||
{
|
||||
const endDateHours = this._range.end.hours();
|
||||
const endDateMinutes = this._range.end.minutes();
|
||||
|
||||
// Set the start date
|
||||
startDate.hours(endDateHours).minutes(endDateMinutes);
|
||||
}
|
||||
|
||||
// If everything is okay, set the new date
|
||||
this.range = {
|
||||
start : startDate.toISOString(),
|
||||
end : this._range.end.clone().toISOString(),
|
||||
whichDate: 'start'
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the end time
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
updateEndTime(event): void
|
||||
{
|
||||
// Parse the time
|
||||
const parsedTime = this._parseTime(event.target.value);
|
||||
|
||||
// Go back to the previous value if the form control is not valid
|
||||
if ( this.endTimeFormControl.invalid )
|
||||
{
|
||||
// Override the time
|
||||
const time = this._range.end.clone().format(this._timeFormat);
|
||||
|
||||
// Set the time
|
||||
this.endTimeFormControl.setValue(time);
|
||||
|
||||
// Do not update the range
|
||||
return;
|
||||
}
|
||||
|
||||
// Append the new time to the end date
|
||||
const endDate = this._range.end.clone().hours(parsedTime.hours()).minutes(parsedTime.minutes());
|
||||
|
||||
// If the new end date is before the current start date,
|
||||
// use the start date's time and set the end date again
|
||||
if ( endDate.isBefore(this._range.start) )
|
||||
{
|
||||
const startDateHours = this._range.start.hours();
|
||||
const startDateMinutes = this._range.start.minutes();
|
||||
|
||||
// Set the end date
|
||||
endDate.hours(startDateHours).minutes(startDateMinutes);
|
||||
}
|
||||
|
||||
// If everything is okay, set the new date
|
||||
this.range = {
|
||||
start : this._range.start.clone().toISOString(),
|
||||
end : endDate.toISOString(),
|
||||
whichDate: 'end'
|
||||
};
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Private methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private _init(): void
|
||||
{
|
||||
// Start and end time form controls
|
||||
this.startTimeFormControl = new FormControl('', [Validators.pattern(this._timeRegExp)]);
|
||||
this.endTimeFormControl = new FormControl('', [Validators.pattern(this._timeRegExp)]);
|
||||
|
||||
// Set the default range
|
||||
this._programmaticChange = true;
|
||||
this.range = {
|
||||
start: moment().startOf('day').toISOString(),
|
||||
end : moment().add(1, 'day').endOf('day').toISOString()
|
||||
};
|
||||
|
||||
// Set the default time range
|
||||
this._programmaticChange = true;
|
||||
this.timeRange = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the time from the inputs
|
||||
*
|
||||
* @param value
|
||||
* @private
|
||||
*/
|
||||
private _parseTime(value: string): Moment
|
||||
{
|
||||
// Parse the time using the time regexp
|
||||
const timeArr = value.split(this._timeRegExp).filter(part => part !== '');
|
||||
|
||||
// Get the meridiem
|
||||
const meridiem = timeArr[2] || null;
|
||||
|
||||
// If meridiem exists...
|
||||
if ( meridiem )
|
||||
{
|
||||
// Create a moment using 12-hours format and return it
|
||||
return moment(value, 'hh:mmA').seconds(0);
|
||||
}
|
||||
|
||||
// If meridiem doesn't exist, create a moment using 24-hours format and return in
|
||||
return moment(value, 'HH:mm').seconds(0);
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatMomentDateModule } from '@angular/material-moment-adapter';
|
||||
import { FuseDateRangeComponent } from '@fuse/components/date-range/date-range.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
FuseDateRangeComponent
|
||||
],
|
||||
imports : [
|
||||
CommonModule,
|
||||
ReactiveFormsModule,
|
||||
MatButtonModule,
|
||||
MatDatepickerModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
MatIconModule,
|
||||
MatMomentDateModule
|
||||
],
|
||||
exports : [
|
||||
FuseDateRangeComponent
|
||||
]
|
||||
})
|
||||
export class FuseDateRangeModule
|
||||
{
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
export * from '@fuse/components/date-range/public-api';
|
|
@ -1,2 +0,0 @@
|
|||
export * from '@fuse/components/date-range/date-range.component';
|
||||
export * from '@fuse/components/date-range/date-range.module';
|
|
@ -9,7 +9,7 @@ import { CommonModule } from '@angular/common';
|
|||
declarations: [
|
||||
FuseFullscreenComponent
|
||||
],
|
||||
imports: [
|
||||
imports : [
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
MatTooltipModule,
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewEncapsulation } from '@angular/core';
|
||||
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
||||
import { FuseLoadingBarService } from '@fuse/components/loading-bar/loading-bar.service';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject } from 'rxjs';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseLoadingService } from '@fuse/services/loading';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-loading-bar',
|
||||
|
@ -22,7 +21,7 @@ export class FuseLoadingBarComponent implements OnChanges, OnInit, OnDestroy
|
|||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(private _fuseLoadingBarService: FuseLoadingBarService)
|
||||
constructor(private _fuseLoadingService: FuseLoadingService)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -41,7 +40,7 @@ export class FuseLoadingBarComponent implements OnChanges, OnInit, OnDestroy
|
|||
if ( 'autoMode' in changes )
|
||||
{
|
||||
// Set the auto mode in the service
|
||||
this._fuseLoadingBarService.setAutoMode(coerceBooleanProperty(changes.autoMode.currentValue));
|
||||
this._fuseLoadingService.setAutoMode(coerceBooleanProperty(changes.autoMode.currentValue));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,19 +50,19 @@ export class FuseLoadingBarComponent implements OnChanges, OnInit, OnDestroy
|
|||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to the service
|
||||
this._fuseLoadingBarService.mode$
|
||||
this._fuseLoadingService.mode$
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((value) => {
|
||||
this.mode = value;
|
||||
});
|
||||
|
||||
this._fuseLoadingBarService.progress$
|
||||
this._fuseLoadingService.progress$
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((value) => {
|
||||
this.progress = value;
|
||||
});
|
||||
|
||||
this._fuseLoadingBarService.show$
|
||||
this._fuseLoadingService.show$
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((value) => {
|
||||
this.show = value;
|
||||
|
@ -77,7 +76,7 @@ export class FuseLoadingBarComponent implements OnChanges, OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { FuseLoadingBarComponent } from '@fuse/components/loading-bar/loading-bar.component';
|
||||
import { FuseLoadingBarInterceptor } from '@fuse/components/loading-bar/loading-bar.interceptor';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
@ -15,13 +13,6 @@ import { FuseLoadingBarInterceptor } from '@fuse/components/loading-bar/loading-
|
|||
],
|
||||
exports : [
|
||||
FuseLoadingBarComponent
|
||||
],
|
||||
providers : [
|
||||
{
|
||||
provide : HTTP_INTERCEPTORS,
|
||||
useClass: FuseLoadingBarInterceptor,
|
||||
multi : true
|
||||
}
|
||||
]
|
||||
})
|
||||
export class FuseLoadingBarModule
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
export * from '@fuse/components/loading-bar/loading-bar.component';
|
||||
export * from '@fuse/components/loading-bar/loading-bar.service';
|
||||
export * from '@fuse/components/loading-bar/loading-bar.module';
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { IsActiveMatchOptions } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseHorizontalNavigationComponent } from '@fuse/components/navigation/horizontal/horizontal.component';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types';
|
||||
|
@ -76,7 +75,7 @@ export class FuseHorizontalNavigationBasicItemComponent implements OnInit, OnDes
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||
import { BooleanInput } from '@angular/cdk/coercion';
|
||||
import { MatMenu } from '@angular/material/menu';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseHorizontalNavigationComponent } from '@fuse/components/navigation/horizontal/horizontal.component';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types';
|
||||
|
@ -64,7 +63,7 @@ export class FuseHorizontalNavigationBranchItemComponent implements OnInit, OnDe
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseHorizontalNavigationComponent } from '@fuse/components/navigation/horizontal/horizontal.component';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types';
|
||||
|
@ -56,7 +55,7 @@ export class FuseHorizontalNavigationDividerItemComponent implements OnInit, OnD
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject } from 'rxjs';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseHorizontalNavigationComponent } from '@fuse/components/navigation/horizontal/horizontal.component';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types';
|
||||
|
@ -56,7 +55,7 @@ export class FuseHorizontalNavigationSpacerItemComponent implements OnInit, OnDe
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ export class FuseHorizontalNavigationComponent implements OnChanges, OnInit, OnD
|
|||
this._fuseNavigationService.deregisterComponent(this.name);
|
||||
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core';
|
||||
import { NavigationEnd, Router } from '@angular/router';
|
||||
import { BooleanInput } from '@angular/cdk/coercion';
|
||||
import { Subject } from 'rxjs';
|
||||
import { filter, takeUntil } from 'rxjs/operators';
|
||||
import { filter, Subject, takeUntil } from 'rxjs';
|
||||
import { FuseVerticalNavigationComponent } from '@fuse/components/navigation/vertical/vertical.component';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types';
|
||||
|
@ -98,7 +97,7 @@ export class FuseVerticalNavigationAsideItemComponent implements OnChanges, OnIn
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { IsActiveMatchOptions } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseVerticalNavigationComponent } from '@fuse/components/navigation/vertical/vertical.component';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types';
|
||||
|
@ -76,7 +75,7 @@ export class FuseVerticalNavigationBasicItemComponent implements OnInit, OnDestr
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostBinding, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { NavigationEnd, Router } from '@angular/router';
|
||||
import { BooleanInput } from '@angular/cdk/coercion';
|
||||
import { Subject } from 'rxjs';
|
||||
import { filter, takeUntil } from 'rxjs/operators';
|
||||
import { filter, Subject, takeUntil } from 'rxjs';
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseVerticalNavigationComponent } from '@fuse/components/navigation/vertical/vertical.component';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
|
@ -176,7 +175,7 @@ export class FuseVerticalNavigationCollapsableItemComponent implements OnInit, O
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseVerticalNavigationComponent } from '@fuse/components/navigation/vertical/vertical.component';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types';
|
||||
|
@ -56,7 +55,7 @@ export class FuseVerticalNavigationDividerItemComponent implements OnInit, OnDes
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { BooleanInput } from '@angular/cdk/coercion';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseVerticalNavigationComponent } from '@fuse/components/navigation/vertical/vertical.component';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types';
|
||||
|
@ -62,7 +61,7 @@ export class FuseVerticalNavigationGroupItemComponent implements OnInit, OnDestr
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject } from 'rxjs';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseVerticalNavigationComponent } from '@fuse/components/navigation/vertical/vertical.component';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
import { FuseNavigationItem } from '@fuse/components/navigation/navigation.types';
|
||||
|
@ -56,7 +55,7 @@ export class FuseVerticalNavigationSpacerItemComponent implements OnInit, OnDest
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
/* Variables */
|
||||
$fuse-vertical-navigation-compact-width: 112;
|
||||
$fuse-vertical-navigation-compact-width: 112px;
|
||||
|
||||
fuse-vertical-navigation {
|
||||
|
||||
/* Compact appearance overrides */
|
||||
&.fuse-vertical-navigation-appearance-compact {
|
||||
width: #{$fuse-vertical-navigation-compact-width}px;
|
||||
min-width: #{$fuse-vertical-navigation-compact-width}px;
|
||||
max-width: #{$fuse-vertical-navigation-compact-width}px;
|
||||
width: $fuse-vertical-navigation-compact-width;
|
||||
min-width: $fuse-vertical-navigation-compact-width;
|
||||
max-width: $fuse-vertical-navigation-compact-width;
|
||||
|
||||
/* Left positioned */
|
||||
&.fuse-vertical-navigation-position-left {
|
||||
|
||||
/* Side mode */
|
||||
&.fuse-vertical-navigation-mode-side {
|
||||
margin-left: -#{$fuse-vertical-navigation-compact-width}px;
|
||||
margin-left: -$fuse-vertical-navigation-compact-width;
|
||||
}
|
||||
|
||||
/* Opened */
|
||||
|
@ -28,7 +28,7 @@ fuse-vertical-navigation {
|
|||
|
||||
/* Side mode */
|
||||
&.fuse-vertical-navigation-mode-side {
|
||||
margin-right: -#{$fuse-vertical-navigation-compact-width}px;
|
||||
margin-right: -$fuse-vertical-navigation-compact-width;
|
||||
}
|
||||
|
||||
/* Opened */
|
||||
|
@ -39,7 +39,7 @@ fuse-vertical-navigation {
|
|||
/* Aside wrapper */
|
||||
.fuse-vertical-navigation-aside-wrapper {
|
||||
left: auto;
|
||||
right: #{$fuse-vertical-navigation-compact-width}px;
|
||||
right: $fuse-vertical-navigation-compact-width;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ fuse-vertical-navigation {
|
|||
|
||||
/* Aside wrapper */
|
||||
.fuse-vertical-navigation-aside-wrapper {
|
||||
left: #{$fuse-vertical-navigation-compact-width}px;
|
||||
left: $fuse-vertical-navigation-compact-width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Variables */
|
||||
$fuse-vertical-navigation-width: 280;
|
||||
$fuse-vertical-navigation-width: 280px;
|
||||
|
||||
fuse-vertical-navigation {
|
||||
position: sticky;
|
||||
|
@ -7,9 +7,9 @@ fuse-vertical-navigation {
|
|||
flex-direction: column;
|
||||
flex: 1 0 auto;
|
||||
top: 0;
|
||||
width: #{$fuse-vertical-navigation-width}px;
|
||||
min-width: #{$fuse-vertical-navigation-width}px;
|
||||
max-width: #{$fuse-vertical-navigation-width}px;
|
||||
width: $fuse-vertical-navigation-width;
|
||||
min-width: $fuse-vertical-navigation-width;
|
||||
max-width: $fuse-vertical-navigation-width;
|
||||
height: 100vh;
|
||||
min-height: 100vh;
|
||||
max-height: 100vh;
|
||||
|
@ -45,7 +45,7 @@ fuse-vertical-navigation {
|
|||
|
||||
/* Side mode */
|
||||
&.fuse-vertical-navigation-mode-side {
|
||||
margin-left: -#{$fuse-vertical-navigation-width}px;
|
||||
margin-left: -$fuse-vertical-navigation-width;
|
||||
|
||||
&.fuse-vertical-navigation-opened {
|
||||
margin-left: 0;
|
||||
|
@ -73,7 +73,7 @@ fuse-vertical-navigation {
|
|||
|
||||
/* Side mode */
|
||||
&.fuse-vertical-navigation-mode-side {
|
||||
margin-right: -#{$fuse-vertical-navigation-width}px;
|
||||
margin-right: -$fuse-vertical-navigation-width;
|
||||
|
||||
&.fuse-vertical-navigation-opened {
|
||||
margin-right: 0;
|
||||
|
@ -170,8 +170,8 @@ fuse-vertical-navigation {
|
|||
flex-direction: column;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: #{$fuse-vertical-navigation-width}px;
|
||||
width: #{$fuse-vertical-navigation-width}px;
|
||||
left: $fuse-vertical-navigation-width;
|
||||
width: $fuse-vertical-navigation-width;
|
||||
height: 100%;
|
||||
z-index: 5;
|
||||
overflow-x: hidden;
|
||||
|
@ -196,7 +196,7 @@ fuse-vertical-navigation {
|
|||
|
||||
.fuse-vertical-navigation-aside-wrapper {
|
||||
left: auto;
|
||||
right: #{$fuse-vertical-navigation-width}px;
|
||||
right: $fuse-vertical-navigation-width;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Variables */
|
||||
$fuse-vertical-navigation-width: 280;
|
||||
$fuse-vertical-navigation-dense-width: 80;
|
||||
$fuse-vertical-navigation-width: 280px;
|
||||
$fuse-vertical-navigation-dense-width: 80px;
|
||||
|
||||
fuse-vertical-navigation {
|
||||
|
||||
|
@ -8,16 +8,16 @@ fuse-vertical-navigation {
|
|||
&.fuse-vertical-navigation-appearance-dense {
|
||||
|
||||
&:not(.fuse-vertical-navigation-mode-over) {
|
||||
width: #{$fuse-vertical-navigation-dense-width}px;
|
||||
min-width: #{$fuse-vertical-navigation-dense-width}px;
|
||||
max-width: #{$fuse-vertical-navigation-dense-width}px;
|
||||
width: $fuse-vertical-navigation-dense-width;
|
||||
min-width: $fuse-vertical-navigation-dense-width;
|
||||
max-width: $fuse-vertical-navigation-dense-width;
|
||||
|
||||
/* Left positioned */
|
||||
&.fuse-vertical-navigation-position-left {
|
||||
|
||||
/* Side mode */
|
||||
&.fuse-vertical-navigation-mode-side {
|
||||
margin-left: -#{$fuse-vertical-navigation-dense-width}px;
|
||||
margin-left: -$fuse-vertical-navigation-dense-width;
|
||||
}
|
||||
|
||||
/* Opened */
|
||||
|
@ -31,7 +31,7 @@ fuse-vertical-navigation {
|
|||
|
||||
/* Side mode */
|
||||
&.fuse-vertical-navigation-mode-side {
|
||||
margin-right: -#{$fuse-vertical-navigation-dense-width}px;
|
||||
margin-right: -$fuse-vertical-navigation-dense-width;
|
||||
}
|
||||
|
||||
/* Opened */
|
||||
|
@ -42,14 +42,14 @@ fuse-vertical-navigation {
|
|||
/* Aside wrapper */
|
||||
.fuse-vertical-navigation-aside-wrapper {
|
||||
left: auto;
|
||||
right: #{$fuse-vertical-navigation-dense-width}px;
|
||||
right: $fuse-vertical-navigation-dense-width;
|
||||
}
|
||||
|
||||
&.fuse-vertical-navigation-hover {
|
||||
|
||||
.fuse-vertical-navigation-aside-wrapper {
|
||||
left: auto;
|
||||
right: #{$fuse-vertical-navigation-width}px;
|
||||
right: $fuse-vertical-navigation-width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,9 +69,9 @@ fuse-vertical-navigation {
|
|||
.fuse-vertical-navigation-item-wrapper {
|
||||
|
||||
.fuse-vertical-navigation-item {
|
||||
width: #{$fuse-vertical-navigation-width}px - 24px;
|
||||
min-width: #{$fuse-vertical-navigation-width}px - 24px;
|
||||
max-width: #{$fuse-vertical-navigation-width}px - 24px;
|
||||
width: $fuse-vertical-navigation-dense-width - 24px;
|
||||
min-width: $fuse-vertical-navigation-dense-width - 24px;
|
||||
max-width: $fuse-vertical-navigation-dense-width - 24px;
|
||||
|
||||
.fuse-vertical-navigation-item-arrow,
|
||||
.fuse-vertical-navigation-item-badge,
|
||||
|
@ -142,20 +142,23 @@ fuse-vertical-navigation {
|
|||
|
||||
/* Aside wrapper */
|
||||
.fuse-vertical-navigation-aside-wrapper {
|
||||
left: #{$fuse-vertical-navigation-dense-width}px;
|
||||
left: $fuse-vertical-navigation-dense-width;
|
||||
}
|
||||
|
||||
/* Hover */
|
||||
&.fuse-vertical-navigation-hover {
|
||||
|
||||
.fuse-vertical-navigation-wrapper {
|
||||
width: #{$fuse-vertical-navigation-width}px;
|
||||
width: $fuse-vertical-navigation-width;
|
||||
|
||||
.fuse-vertical-navigation-content {
|
||||
|
||||
.fuse-vertical-navigation-item-wrapper {
|
||||
|
||||
.fuse-vertical-navigation-item {
|
||||
width: $fuse-vertical-navigation-width - 24px;
|
||||
min-width: $fuse-vertical-navigation-width - 24px;
|
||||
max-width: $fuse-vertical-navigation-width - 24px;
|
||||
|
||||
.fuse-vertical-navigation-item-arrow,
|
||||
.fuse-vertical-navigation-item-badge,
|
||||
|
@ -170,7 +173,7 @@ fuse-vertical-navigation {
|
|||
}
|
||||
|
||||
.fuse-vertical-navigation-aside-wrapper {
|
||||
left: #{$fuse-vertical-navigation-width}px;
|
||||
left: $fuse-vertical-navigation-width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/* Variables */
|
||||
$fuse-vertical-navigation-thin-width: 80;
|
||||
$fuse-vertical-navigation-thin-width: 80px;
|
||||
|
||||
fuse-vertical-navigation {
|
||||
|
||||
/* Thin appearance overrides */
|
||||
&.fuse-vertical-navigation-appearance-thin {
|
||||
width: #{$fuse-vertical-navigation-thin-width}px;
|
||||
min-width: #{$fuse-vertical-navigation-thin-width}px;
|
||||
max-width: #{$fuse-vertical-navigation-thin-width}px;
|
||||
width: $fuse-vertical-navigation-thin-width;
|
||||
min-width: $fuse-vertical-navigation-thin-width;
|
||||
max-width: $fuse-vertical-navigation-thin-width;
|
||||
|
||||
/* Left positioned */
|
||||
&.fuse-vertical-navigation-position-left {
|
||||
|
||||
&.fuse-vertical-navigation-mode-side {
|
||||
margin-left: -#{$fuse-vertical-navigation-thin-width}px;
|
||||
margin-left: -$fuse-vertical-navigation-thin-width;
|
||||
}
|
||||
|
||||
&.fuse-vertical-navigation-opened {
|
||||
|
@ -25,7 +25,7 @@ fuse-vertical-navigation {
|
|||
&.fuse-vertical-navigation-position-right {
|
||||
|
||||
&.fuse-vertical-navigation-mode-side {
|
||||
margin-right: -#{$fuse-vertical-navigation-thin-width}px;
|
||||
margin-right: -$fuse-vertical-navigation-thin-width;
|
||||
}
|
||||
|
||||
&.fuse-vertical-navigation-opened {
|
||||
|
@ -34,7 +34,7 @@ fuse-vertical-navigation {
|
|||
|
||||
.fuse-vertical-navigation-aside-wrapper {
|
||||
left: auto;
|
||||
right: #{$fuse-vertical-navigation-thin-width}px;
|
||||
right: $fuse-vertical-navigation-thin-width;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ fuse-vertical-navigation {
|
|||
|
||||
/* Aside wrapper */
|
||||
.fuse-vertical-navigation-aside-wrapper {
|
||||
left: #{$fuse-vertical-navigation-thin-width}px;
|
||||
left: $fuse-vertical-navigation-thin-width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,7 @@ import { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, E
|
|||
import { animate, AnimationBuilder, AnimationPlayer, style } from '@angular/animations';
|
||||
import { NavigationEnd, Router } from '@angular/router';
|
||||
import { ScrollStrategy, ScrollStrategyOptions } from '@angular/cdk/overlay';
|
||||
import { merge, ReplaySubject, Subject, Subscription } from 'rxjs';
|
||||
import { delay, filter, takeUntil } from 'rxjs/operators';
|
||||
import { delay, filter, merge, ReplaySubject, Subject, Subscription, takeUntil } from 'rxjs';
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseNavigationItem, FuseVerticalNavigationAppearance, FuseVerticalNavigationMode, FuseVerticalNavigationPosition } from '@fuse/components/navigation/navigation.types';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
|
@ -382,7 +381,7 @@ export class FuseVerticalNavigationComponent implements OnChanges, OnInit, After
|
|||
this._fuseNavigationService.deregisterComponent(this.name);
|
||||
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Directive, ElementRef, OnDestroy, OnInit } from '@angular/core';
|
||||
import { NavigationEnd, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { filter, takeUntil } from 'rxjs/operators';
|
||||
import { filter, Subject, takeUntil } from 'rxjs';
|
||||
|
||||
@Directive({
|
||||
selector: '[fuseScrollReset]',
|
||||
|
@ -47,7 +46,7 @@ export class FuseScrollResetDirective implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,7 @@ import { Directive, ElementRef, Input, OnChanges, OnDestroy, OnInit, SimpleChang
|
|||
import { Router } from '@angular/router';
|
||||
import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';
|
||||
import { Platform } from '@angular/cdk/platform';
|
||||
import { fromEvent, Subject } from 'rxjs';
|
||||
import { debounceTime, takeUntil } from 'rxjs/operators';
|
||||
import { debounceTime, fromEvent, Subject, takeUntil } from 'rxjs';
|
||||
import PerfectScrollbar from 'perfect-scrollbar';
|
||||
import { merge } from 'lodash-es';
|
||||
import { ScrollbarGeometry, ScrollbarPosition } from '@fuse/directives/scrollbar/scrollbar.types';
|
||||
|
@ -138,7 +137,7 @@ export class FuseScrollbarDirective implements OnChanges, OnInit, OnDestroy
|
|||
this._destroy();
|
||||
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import { NgModule, Optional, SkipSelf } from '@angular/core';
|
|||
import { MATERIAL_SANITY_CHECKS } from '@angular/material/core';
|
||||
import { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
|
||||
import { FuseConfirmationModule } from '@fuse/services/confirmation';
|
||||
import { FuseLoadingModule } from '@fuse/services/loading';
|
||||
import { FuseMediaWatcherModule } from '@fuse/services/media-watcher/media-watcher.module';
|
||||
import { FuseSplashScreenModule } from '@fuse/services/splash-screen/splash-screen.module';
|
||||
import { FuseTailwindConfigModule } from '@fuse/services/tailwind/tailwind.module';
|
||||
|
@ -10,6 +11,7 @@ import { FuseUtilsModule } from '@fuse/services/utils/utils.module';
|
|||
@NgModule({
|
||||
imports : [
|
||||
FuseConfirmationModule,
|
||||
FuseLoadingModule,
|
||||
FuseMediaWatcherModule,
|
||||
FuseSplashScreenModule,
|
||||
FuseTailwindConfigModule,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Inject, Injectable } from '@angular/core';
|
||||
import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
|
||||
import { Observable, of, throwError } from 'rxjs';
|
||||
import { delay, switchMap } from 'rxjs/operators';
|
||||
import { delay, Observable, of, switchMap, throwError } from 'rxjs';
|
||||
import { FUSE_MOCK_API_DEFAULT_DELAY } from '@fuse/lib/mock-api/mock-api.constants';
|
||||
import { FuseMockApiService } from '@fuse/lib/mock-api/mock-api.service';
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { HttpRequest } from '@angular/common/http';
|
||||
import { Observable, of, throwError } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { Observable, of, take, throwError } from 'rxjs';
|
||||
import { FuseMockApiReplyCallback } from '@fuse/lib/mock-api/mock-api.types';
|
||||
|
||||
export class FuseMockApiHandler
|
||||
|
|
|
@ -9,11 +9,14 @@ import { FuseMockApiMethods } from '@fuse/lib/mock-api/mock-api.types';
|
|||
export class FuseMockApiService
|
||||
{
|
||||
private _handlers: { [key: string]: Map<string, FuseMockApiHandler> } = {
|
||||
'delete': new Map<string, FuseMockApiHandler>(),
|
||||
'get' : new Map<string, FuseMockApiHandler>(),
|
||||
'patch' : new Map<string, FuseMockApiHandler>(),
|
||||
'post' : new Map<string, FuseMockApiHandler>(),
|
||||
'put' : new Map<string, FuseMockApiHandler>()
|
||||
'patch' : new Map<string, FuseMockApiHandler>(),
|
||||
'delete' : new Map<string, FuseMockApiHandler>(),
|
||||
'put' : new Map<string, FuseMockApiHandler>(),
|
||||
'head' : new Map<string, FuseMockApiHandler>(),
|
||||
'jsonp' : new Map<string, FuseMockApiHandler>(),
|
||||
'options': new Map<string, FuseMockApiHandler>()
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -86,18 +89,7 @@ export class FuseMockApiService
|
|||
}
|
||||
|
||||
/**
|
||||
* Register a DELETE request handler
|
||||
*
|
||||
* @param url - URL address of the mocked API endpoint
|
||||
* @param delay - Delay of the response in milliseconds
|
||||
*/
|
||||
onDelete(url: string, delay?: number): FuseMockApiHandler
|
||||
{
|
||||
return this._registerHandler('delete', url, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a GET request handler
|
||||
* Register GET request handler
|
||||
*
|
||||
* @param url - URL address of the mocked API endpoint
|
||||
* @param delay - Delay of the response in milliseconds
|
||||
|
@ -108,18 +100,7 @@ export class FuseMockApiService
|
|||
}
|
||||
|
||||
/**
|
||||
* Register a PATCH request handler
|
||||
*
|
||||
* @param url - URL address of the mocked API endpoint
|
||||
* @param delay - Delay of the response in milliseconds
|
||||
*/
|
||||
onPatch(url: string, delay?: number): FuseMockApiHandler
|
||||
{
|
||||
return this._registerHandler('patch', url, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a POST request handler
|
||||
* Register POST request handler
|
||||
*
|
||||
* @param url - URL address of the mocked API endpoint
|
||||
* @param delay - Delay of the response in milliseconds
|
||||
|
@ -130,7 +111,29 @@ export class FuseMockApiService
|
|||
}
|
||||
|
||||
/**
|
||||
* Register a PUT request handler
|
||||
* Register PATCH request handler
|
||||
*
|
||||
* @param url - URL address of the mocked API endpoint
|
||||
* @param delay - Delay of the response in milliseconds
|
||||
*/
|
||||
onPatch(url: string, delay?: number): FuseMockApiHandler
|
||||
{
|
||||
return this._registerHandler('patch', url, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register DELETE request handler
|
||||
*
|
||||
* @param url - URL address of the mocked API endpoint
|
||||
* @param delay - Delay of the response in milliseconds
|
||||
*/
|
||||
onDelete(url: string, delay?: number): FuseMockApiHandler
|
||||
{
|
||||
return this._registerHandler('delete', url, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register PUT request handler
|
||||
*
|
||||
* @param url - URL address of the mocked API endpoint
|
||||
* @param delay - Delay of the response in milliseconds
|
||||
|
@ -140,6 +143,39 @@ export class FuseMockApiService
|
|||
return this._registerHandler('put', url, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register HEAD request handler
|
||||
*
|
||||
* @param url - URL address of the mocked API endpoint
|
||||
* @param delay - Delay of the response in milliseconds
|
||||
*/
|
||||
onHead(url: string, delay?: number): FuseMockApiHandler
|
||||
{
|
||||
return this._registerHandler('head', url, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register JSONP request handler
|
||||
*
|
||||
* @param url - URL address of the mocked API endpoint
|
||||
* @param delay - Delay of the response in milliseconds
|
||||
*/
|
||||
onJsonp(url: string, delay?: number): FuseMockApiHandler
|
||||
{
|
||||
return this._registerHandler('jsonp', url, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register OPTIONS request handler
|
||||
*
|
||||
* @param url - URL address of the mocked API endpoint
|
||||
* @param delay - Delay of the response in milliseconds
|
||||
*/
|
||||
onOptions(url: string, delay?: number): FuseMockApiHandler
|
||||
{
|
||||
return this._registerHandler('options', url, delay);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Private methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -8,6 +8,9 @@ export type FuseMockApiReplyCallback =
|
|||
export type FuseMockApiMethods =
|
||||
| 'get'
|
||||
| 'post'
|
||||
| 'put'
|
||||
| 'patch'
|
||||
| 'delete';
|
||||
| 'delete'
|
||||
| 'put'
|
||||
| 'head'
|
||||
| 'jsonp'
|
||||
| 'options';
|
||||
|
|
|
@ -10,7 +10,7 @@ import { CommonModule } from '@angular/common';
|
|||
declarations: [
|
||||
FuseConfirmationDialogComponent
|
||||
],
|
||||
imports: [
|
||||
imports : [
|
||||
MatButtonModule,
|
||||
MatDialogModule,
|
||||
MatIconModule,
|
||||
|
|
1
src/@fuse/services/loading/index.ts
Normal file
1
src/@fuse/services/loading/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export * from '@fuse/services/loading/public-api';
|
|
@ -1,11 +1,10 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { finalize } from 'rxjs/operators';
|
||||
import { FuseLoadingBarService } from '@fuse/components/loading-bar/loading-bar.service';
|
||||
import { finalize, Observable } from 'rxjs';
|
||||
import { FuseLoadingService } from '@fuse/services/loading/loading.service';
|
||||
|
||||
@Injectable()
|
||||
export class FuseLoadingBarInterceptor implements HttpInterceptor
|
||||
export class FuseLoadingInterceptor implements HttpInterceptor
|
||||
{
|
||||
handleRequestsAutomatically: boolean;
|
||||
|
||||
|
@ -13,11 +12,11 @@ export class FuseLoadingBarInterceptor implements HttpInterceptor
|
|||
* Constructor
|
||||
*/
|
||||
constructor(
|
||||
private _fuseLoadingBarService: FuseLoadingBarService
|
||||
private _fuseLoadingService: FuseLoadingService
|
||||
)
|
||||
{
|
||||
// Subscribe to the auto
|
||||
this._fuseLoadingBarService.auto$
|
||||
this._fuseLoadingService.auto$
|
||||
.subscribe((value) => {
|
||||
this.handleRequestsAutomatically = value;
|
||||
});
|
||||
|
@ -38,12 +37,12 @@ export class FuseLoadingBarInterceptor implements HttpInterceptor
|
|||
}
|
||||
|
||||
// Set the loading status to true
|
||||
this._fuseLoadingBarService._setLoadingStatus(true, req.url);
|
||||
this._fuseLoadingService._setLoadingStatus(true, req.url);
|
||||
|
||||
return next.handle(req).pipe(
|
||||
finalize(() => {
|
||||
// Set the status to false if there are any errors or the request is completed
|
||||
this._fuseLoadingBarService._setLoadingStatus(false, req.url);
|
||||
this._fuseLoadingService._setLoadingStatus(false, req.url);
|
||||
}));
|
||||
}
|
||||
}
|
16
src/@fuse/services/loading/loading.module.ts
Normal file
16
src/@fuse/services/loading/loading.module.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import { FuseLoadingInterceptor } from '@fuse/services/loading/loading.interceptor';
|
||||
|
||||
@NgModule({
|
||||
providers: [
|
||||
{
|
||||
provide : HTTP_INTERCEPTORS,
|
||||
useClass: FuseLoadingInterceptor,
|
||||
multi : true
|
||||
}
|
||||
]
|
||||
})
|
||||
export class FuseLoadingModule
|
||||
{
|
||||
}
|
|
@ -5,7 +5,7 @@ import { BehaviorSubject, Observable } from 'rxjs';
|
|||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class FuseLoadingBarService
|
||||
export class FuseLoadingService
|
||||
{
|
||||
private _auto$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
|
||||
private _mode$: BehaviorSubject<'determinate' | 'indeterminate'> = new BehaviorSubject<'determinate' | 'indeterminate'>('indeterminate');
|
2
src/@fuse/services/loading/public-api.ts
Normal file
2
src/@fuse/services/loading/public-api.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export * from '@fuse/services/loading/loading.service';
|
||||
export * from '@fuse/services/loading/loading.module';
|
|
@ -1,7 +1,6 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';
|
||||
import { Observable, ReplaySubject } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { map, Observable, ReplaySubject, switchMap } from 'rxjs';
|
||||
import { FuseTailwindService } from '@fuse/services/tailwind/tailwind.service';
|
||||
|
||||
@Injectable()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Inject, Injectable } from '@angular/core';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { NavigationEnd, Router } from '@angular/router';
|
||||
import { filter, take } from 'rxjs/operators';
|
||||
import { filter, take } from 'rxjs';
|
||||
|
||||
@Injectable()
|
||||
export class FuseSplashScreenService
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
/* 3. Overrides */
|
||||
@import 'overrides/angular-material';
|
||||
@import 'overrides/fullcalendar';
|
||||
@import 'overrides/highlightjs';
|
||||
@import 'overrides/perfect-scrollbar';
|
||||
@import 'overrides/quill';
|
||||
|
|
|
@ -1,680 +0,0 @@
|
|||
/* ----------------------------------------------------------------------------------------------------- */
|
||||
/* @ FullCalendar overrides
|
||||
/* ----------------------------------------------------------------------------------------------------- */
|
||||
.fc {
|
||||
|
||||
.fc-view-container {
|
||||
|
||||
/* Day Grid - Month view */
|
||||
.fc-view.fc-dayGridMonth-view {
|
||||
|
||||
.fc-head {
|
||||
|
||||
> tr > .fc-head-container {
|
||||
border: none;
|
||||
|
||||
.fc-row {
|
||||
|
||||
.fc-day-header {
|
||||
border-color: var(--fuse-divider);
|
||||
|
||||
span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-top: 8px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
@apply text-secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fc-body {
|
||||
|
||||
> tr > .fc-widget-content {
|
||||
border: none;
|
||||
|
||||
.fc-day-grid {
|
||||
|
||||
.fc-week {
|
||||
|
||||
.fc-bg {
|
||||
|
||||
.fc-day {
|
||||
border-color: var(--fuse-divider);
|
||||
|
||||
&.fc-today {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fc-content-skeleton {
|
||||
|
||||
.fc-day-top {
|
||||
text-align: center;
|
||||
|
||||
&.fc-other-month {
|
||||
opacity: 1;
|
||||
|
||||
.fc-day-number {
|
||||
@apply text-hint;
|
||||
}
|
||||
}
|
||||
|
||||
&.fc-today {
|
||||
|
||||
.fc-day-number {
|
||||
@apply bg-primary text-on-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.fc-day-number {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 22px;
|
||||
height: 21px;
|
||||
margin: 4px 0;
|
||||
font-size: 12px;
|
||||
border-radius: 50%;
|
||||
float: none;
|
||||
}
|
||||
}
|
||||
|
||||
.fc-event-container {
|
||||
|
||||
.fc-day-grid-event {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 22px;
|
||||
min-height: 22px;
|
||||
max-height: 22px;
|
||||
margin: 0 6px 4px 6px;
|
||||
padding: 0 5px;
|
||||
font-size: 12px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
|
||||
@screen sm {
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fc-more {
|
||||
padding: 0 3px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
@apply text-secondary;
|
||||
|
||||
@screen sm {
|
||||
padding: 0 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fc-highlight-skeleton {
|
||||
|
||||
.fc-highlight {
|
||||
position: relative;
|
||||
opacity: 1;
|
||||
@apply bg-gray-100;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fc-popover {
|
||||
@apply bg-card;
|
||||
|
||||
&.fc-more-popover {
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
@apply shadow-2xl;
|
||||
|
||||
.fc-header {
|
||||
height: 32px;
|
||||
min-height: 32px;
|
||||
max-height: 32px;
|
||||
padding: 0 8px;
|
||||
@apply bg-hover;
|
||||
|
||||
.fc-title {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.fc-body {
|
||||
max-height: 160px;
|
||||
overflow: hidden auto;
|
||||
|
||||
.fc-event-container {
|
||||
padding: 8px;
|
||||
|
||||
.fc-day-grid-event {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 22px;
|
||||
min-height: 22px;
|
||||
max-height: 22px;
|
||||
margin: 0 0 6px 0;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Time Grid - Week view */
|
||||
.fc-view.fc-timeGridWeek-view {
|
||||
|
||||
.fc-head {
|
||||
|
||||
> tr > .fc-head-container {
|
||||
border: none;
|
||||
|
||||
.fc-row {
|
||||
|
||||
.fc-axis {
|
||||
width: 48px !important;
|
||||
border-color: var(--fuse-divider);
|
||||
}
|
||||
|
||||
.fc-day-header {
|
||||
border-color: var(--fuse-divider);
|
||||
|
||||
span {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
@apply text-secondary;
|
||||
|
||||
&.fc-weekday {
|
||||
padding-top: 16px;
|
||||
font-size: 12px;
|
||||
letter-spacing: 0.055em;
|
||||
text-transform: uppercase;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
&.fc-date {
|
||||
padding-bottom: 12px;
|
||||
font-size: 26px;
|
||||
font-weight: 300;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fc-body {
|
||||
|
||||
> tr > .fc-widget-content {
|
||||
border: none;
|
||||
|
||||
.fc-day-grid {
|
||||
|
||||
.fc-row {
|
||||
min-height: 0;
|
||||
|
||||
.fc-bg {
|
||||
|
||||
.fc-axis {
|
||||
width: 48px !important;
|
||||
border-color: var(--fuse-divider);
|
||||
}
|
||||
|
||||
.fc-day {
|
||||
border-color: var(--fuse-divider);
|
||||
|
||||
&.fc-today {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fc-content-skeleton {
|
||||
padding-bottom: 0;
|
||||
|
||||
.fc-axis {
|
||||
width: 48px !important;
|
||||
}
|
||||
|
||||
.fc-event-container {
|
||||
|
||||
.fc-day-grid-event {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 22px;
|
||||
min-height: 22px;
|
||||
max-height: 22px;
|
||||
margin: 0 6px 6px 6px;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fc-divider {
|
||||
border: none;
|
||||
background: var(--fuse-divider);
|
||||
}
|
||||
|
||||
.fc-time-grid {
|
||||
|
||||
.fc-bg {
|
||||
|
||||
.fc-axis {
|
||||
border: none;
|
||||
width: 48px !important;
|
||||
|
||||
+ .fc-day {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.fc-day {
|
||||
border-color: var(--fuse-divider);
|
||||
|
||||
&.fc-today {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fc-slats {
|
||||
|
||||
.fc-axis {
|
||||
width: 48px !important;
|
||||
height: 48px;
|
||||
text-align: center;
|
||||
|
||||
span {
|
||||
font-size: 12px;
|
||||
width: 48px;
|
||||
min-width: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
.fc-time {
|
||||
border-color: var(--fuse-divider);
|
||||
}
|
||||
|
||||
.fc-widget-content {
|
||||
border-color: var(--fuse-divider);
|
||||
}
|
||||
}
|
||||
|
||||
.fc-content-skeleton {
|
||||
|
||||
.fc-axis {
|
||||
width: 48px !important;
|
||||
}
|
||||
|
||||
.fc-event-container {
|
||||
margin: 0 12px 0 0;
|
||||
|
||||
.fc-time-grid-event {
|
||||
display: flex;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
|
||||
.fc-time,
|
||||
.fc-title {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Time Grid - Day view */
|
||||
.fc-view.fc-timeGridDay-view {
|
||||
|
||||
.fc-head {
|
||||
|
||||
> tr > .fc-head-container {
|
||||
border: none;
|
||||
|
||||
.fc-row {
|
||||
|
||||
.fc-axis {
|
||||
width: 48px !important;
|
||||
border-color: var(--fuse-divider);
|
||||
}
|
||||
|
||||
.fc-day-header {
|
||||
border-color: var(--fuse-divider);
|
||||
|
||||
span {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
@apply text-secondary;
|
||||
|
||||
&.fc-weekday {
|
||||
padding-top: 16px;
|
||||
font-size: 12px;
|
||||
letter-spacing: 0.055em;
|
||||
text-transform: uppercase;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
&.fc-date {
|
||||
padding-bottom: 12px;
|
||||
font-size: 26px;
|
||||
font-weight: 300;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fc-body {
|
||||
|
||||
> tr > .fc-widget-content {
|
||||
border: none;
|
||||
|
||||
.fc-day-grid {
|
||||
|
||||
.fc-bg {
|
||||
|
||||
.fc-axis {
|
||||
border-color: var(--fuse-divider);
|
||||
}
|
||||
|
||||
.fc-day {
|
||||
border-color: var(--fuse-divider);
|
||||
|
||||
&.fc-today {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fc-row {
|
||||
min-height: 0;
|
||||
|
||||
.fc-bg {
|
||||
|
||||
.fc-axis {
|
||||
width: 48px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.fc-content-skeleton {
|
||||
padding-bottom: 0;
|
||||
|
||||
.fc-axis {
|
||||
width: 48px !important;
|
||||
}
|
||||
|
||||
.fc-event-container {
|
||||
|
||||
.fc-day-grid-event {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 22px;
|
||||
min-height: 22px;
|
||||
max-height: 22px;
|
||||
margin: 0 6px 6px 6px;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fc-divider {
|
||||
border: none;
|
||||
border-color: var(--fuse-divider);
|
||||
}
|
||||
|
||||
.fc-time-grid {
|
||||
|
||||
.fc-bg {
|
||||
|
||||
.fc-day {
|
||||
border-color: var(--fuse-divider);
|
||||
|
||||
&.fc-today {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
|
||||
.fc-axis {
|
||||
border: none;
|
||||
width: 48px !important;
|
||||
|
||||
+ .fc-day {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fc-slats {
|
||||
|
||||
.fc-axis {
|
||||
width: 48px !important;
|
||||
height: 48px;
|
||||
text-align: center;
|
||||
|
||||
span {
|
||||
font-size: 12px;
|
||||
width: 48px;
|
||||
min-width: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
.fc-time {
|
||||
border-color: var(--fuse-divider);
|
||||
}
|
||||
|
||||
.fc-widget-content {
|
||||
border-color: var(--fuse-divider);
|
||||
}
|
||||
}
|
||||
|
||||
.fc-content-skeleton {
|
||||
|
||||
.fc-axis {
|
||||
width: 48px !important;
|
||||
}
|
||||
|
||||
.fc-event-container {
|
||||
margin: 0 12px 0 0;
|
||||
|
||||
.fc-time-grid-event {
|
||||
display: flex;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
|
||||
.fc-time,
|
||||
.fc-title {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* List - Year view */
|
||||
.fc-view.fc-listYear-view {
|
||||
border: none;
|
||||
|
||||
.fc-list-table {
|
||||
|
||||
.fc-list-heading {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.fc-list-item {
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
|
||||
td {
|
||||
@apply bg-hover;
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: auto;
|
||||
height: 48px;
|
||||
min-height: 48px;
|
||||
padding: 0 8px;
|
||||
border-width: 0 0 1px 0;
|
||||
border-color: var(--fuse-divider);
|
||||
|
||||
&.fc-list-item-date {
|
||||
order: 1;
|
||||
padding-left: 16px;
|
||||
width: 100px;
|
||||
min-width: 100px;
|
||||
max-width: 100px;
|
||||
|
||||
@screen sm {
|
||||
width: 120px;
|
||||
min-width: 120px;
|
||||
max-width: 120px;
|
||||
}
|
||||
|
||||
> span {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
|
||||
span {
|
||||
|
||||
&:first-child {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding-right: 2px;
|
||||
width: 32px;
|
||||
min-width: 32px;
|
||||
max-width: 32px;
|
||||
font-size: 18px;
|
||||
|
||||
@screen sm {
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
+ span {
|
||||
display: flex;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.055em;
|
||||
text-transform: uppercase;
|
||||
@apply text-secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.fc-list-item-time {
|
||||
flex: 0 0 auto;
|
||||
order: 3;
|
||||
width: 120px;
|
||||
min-width: 120px;
|
||||
max-width: 120px;
|
||||
|
||||
@screen sm {
|
||||
width: 160px;
|
||||
min-width: 160px;
|
||||
max-width: 160px;
|
||||
}
|
||||
}
|
||||
|
||||
&.fc-list-item-marker {
|
||||
flex: 0 0 auto;
|
||||
order: 2;
|
||||
|
||||
.fc-event-dot {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
&.fc-list-item-title {
|
||||
flex: 1 1 auto;
|
||||
order: 4;
|
||||
padding-right: 24px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Day grid event - Dragging */
|
||||
.fc-day-grid-event {
|
||||
|
||||
&.fc-dragging,
|
||||
&.fc-resizing {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 22px;
|
||||
min-height: 22px;
|
||||
max-height: 22px;
|
||||
margin: 0 6px 4px 6px;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
@use '~@angular/material' as mat;
|
||||
@use '@angular/material' as mat;
|
||||
@use "sass:map";
|
||||
|
||||
/* Include the core Angular Material styles */
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import { Version } from '@fuse/version/version';
|
||||
|
||||
export const FUSE_VERSION = new Version('13.6.2').full;
|
||||
export const FUSE_VERSION = new Version('14.0.0').full;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
|
||||
import { Observable, throwError } from 'rxjs';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
import { catchError, Observable, throwError } from 'rxjs';
|
||||
import { AuthService } from 'app/core/auth/auth.service';
|
||||
import { AuthUtils } from 'app/core/auth/auth.utils';
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable, of, throwError } from 'rxjs';
|
||||
import { catchError, switchMap } from 'rxjs/operators';
|
||||
import { catchError, Observable, of, switchMap, throwError } from 'rxjs';
|
||||
import { AuthUtils } from 'app/core/auth/auth.utils';
|
||||
import { UserService } from 'app/core/user/user.service';
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, CanLoad, Route, Router, RouterStateSnapshot, UrlSegment, UrlTree } from '@angular/router';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { Observable, of, switchMap } from 'rxjs';
|
||||
import { AuthService } from 'app/core/auth/auth.service';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, CanLoad, Route, Router, RouterStateSnapshot, UrlSegment, UrlTree } from '@angular/router';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { Observable, of, switchMap } from 'rxjs';
|
||||
import { AuthService } from 'app/core/auth/auth.service';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable, ReplaySubject } from 'rxjs';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { Observable, ReplaySubject, tap } from 'rxjs';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
|
||||
@Injectable({
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable, ReplaySubject } from 'rxjs';
|
||||
import { map, tap } from 'rxjs/operators';
|
||||
import { map, Observable, ReplaySubject, tap } from 'rxjs';
|
||||
import { User } from 'app/core/user/user.types';
|
||||
|
||||
@Injectable({
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { take } from 'rxjs';
|
||||
import { AvailableLangs, TranslocoService } from '@ngneat/transloco';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
|
||||
|
|
|
@ -2,8 +2,7 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnIni
|
|||
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
|
||||
import { TemplatePortal } from '@angular/cdk/portal';
|
||||
import { MatButton } from '@angular/material/button';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { Message } from 'app/layout/common/messages/messages.types';
|
||||
import { MessagesService } from 'app/layout/common/messages/messages.service';
|
||||
|
||||
|
@ -67,7 +66,7 @@ export class MessagesComponent implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
|
||||
// Dispose the overlay
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable, ReplaySubject } from 'rxjs';
|
||||
import { map, Observable, ReplaySubject, switchMap, take, tap } from 'rxjs';
|
||||
import { Message } from 'app/layout/common/messages/messages.types';
|
||||
import { map, switchMap, take, tap } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
|
|
|
@ -2,8 +2,7 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnIni
|
|||
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
|
||||
import { TemplatePortal } from '@angular/cdk/portal';
|
||||
import { MatButton } from '@angular/material/button';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { Notification } from 'app/layout/common/notifications/notifications.types';
|
||||
import { NotificationsService } from 'app/layout/common/notifications/notifications.service';
|
||||
|
||||
|
@ -67,7 +66,7 @@ export class NotificationsComponent implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
|
||||
// Dispose the overlay
|
||||
|
@ -103,7 +102,7 @@ export class NotificationsComponent implements OnInit, OnDestroy
|
|||
}
|
||||
|
||||
/**
|
||||
* Close the messages panel
|
||||
* Close the notifications panel
|
||||
*/
|
||||
closePanel(): void
|
||||
{
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable, ReplaySubject } from 'rxjs';
|
||||
import { map, Observable, ReplaySubject, switchMap, take, tap } from 'rxjs';
|
||||
import { Notification } from 'app/layout/common/notifications/notifications.types';
|
||||
import { map, switchMap, take, tap } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
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 { Subject, takeUntil } from 'rxjs';
|
||||
import { QuickChatService } from 'app/layout/common/quick-chat/quick-chat.service';
|
||||
import { Chat } from 'app/layout/common/quick-chat/quick-chat.types';
|
||||
|
||||
|
@ -110,7 +109,7 @@ export class QuickChatComponent implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import { QuickChatComponent } from 'app/layout/common/quick-chat/quick-chat.comp
|
|||
declarations: [
|
||||
QuickChatComponent
|
||||
],
|
||||
imports: [
|
||||
imports : [
|
||||
RouterModule,
|
||||
MatButtonModule,
|
||||
MatFormFieldModule,
|
||||
|
@ -21,7 +21,7 @@ import { QuickChatComponent } from 'app/layout/common/quick-chat/quick-chat.comp
|
|||
MatInputModule,
|
||||
FuseDrawerModule,
|
||||
FuseScrollbarModule,
|
||||
SharedModule,
|
||||
SharedModule
|
||||
],
|
||||
exports : [
|
||||
QuickChatComponent
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
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 { BehaviorSubject, map, Observable, of, switchMap, tap, throwError } from 'rxjs';
|
||||
import { Chat } from 'app/layout/common/quick-chat/quick-chat.types';
|
||||
|
||||
@Injectable({
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Component, ElementRef, EventEmitter, HostBinding, Input, OnChanges, OnDestroy, OnInit, Output, Renderer2, SimpleChanges, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Subject } from 'rxjs';
|
||||
import { debounceTime, filter, map, takeUntil } from 'rxjs/operators';
|
||||
import { debounceTime, filter, map, Subject, takeUntil } from 'rxjs';
|
||||
import { fuseAnimations } from '@fuse/animations/public-api';
|
||||
|
||||
@Component({
|
||||
|
@ -138,7 +137,7 @@ export class SearchComponent implements OnChanges, OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseConfigService } from '@fuse/services/config';
|
||||
import { FuseTailwindService } from '@fuse/services/tailwind';
|
||||
import { AppConfig, Scheme, Theme } from 'app/core/config/app.config';
|
||||
|
@ -74,7 +73,7 @@ export class SettingsComponent implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import { MatButtonModule } from '@angular/material/button';
|
|||
declarations: [
|
||||
SettingsComponent
|
||||
],
|
||||
imports: [
|
||||
imports : [
|
||||
CommonModule,
|
||||
RouterModule,
|
||||
MatIconModule,
|
||||
|
|
|
@ -3,8 +3,7 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
|||
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
|
||||
import { TemplatePortal } from '@angular/cdk/portal';
|
||||
import { MatButton } from '@angular/material/button';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject } from 'rxjs';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { Shortcut } from 'app/layout/common/shortcuts/shortcuts.types';
|
||||
import { ShortcutsService } from 'app/layout/common/shortcuts/shortcuts.service';
|
||||
|
||||
|
@ -77,7 +76,7 @@ export class ShortcutsComponent implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
|
||||
// Dispose the overlay
|
||||
|
@ -116,7 +115,7 @@ export class ShortcutsComponent implements OnInit, OnDestroy
|
|||
}
|
||||
|
||||
/**
|
||||
* Close the messages panel
|
||||
* Close the shortcuts panel
|
||||
*/
|
||||
closePanel(): void
|
||||
{
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable, ReplaySubject } from 'rxjs';
|
||||
import { map, switchMap, take, tap } from 'rxjs/operators';
|
||||
import { map, Observable, ReplaySubject, switchMap, take, tap } from 'rxjs';
|
||||
import { Shortcut } from 'app/layout/common/shortcuts/shortcuts.types';
|
||||
|
||||
@Injectable({
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { BooleanInput } from '@angular/cdk/coercion';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { User } from 'app/core/user/user.types';
|
||||
import { UserService } from 'app/core/user/user.service';
|
||||
|
||||
|
@ -61,7 +60,7 @@ export class UserComponent implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Component, Inject, OnDestroy, OnInit, Renderer2, ViewEncapsulation } from '@angular/core';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
|
||||
import { combineLatest, Subject } from 'rxjs';
|
||||
import { filter, map, takeUntil } from 'rxjs/operators';
|
||||
import { combineLatest, filter, map, Subject, takeUntil } from 'rxjs';
|
||||
import { FuseConfigService } from '@fuse/services/config';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FUSE_VERSION } from '@fuse/version';
|
||||
|
@ -111,7 +110,7 @@ export class LayoutComponent implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ export class EmptyLayoutComponent implements OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Data, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
|
@ -75,7 +74,7 @@ export class CenteredLayoutComponent implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
|
@ -75,7 +74,7 @@ export class EnterpriseLayoutComponent implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
|
@ -75,7 +74,7 @@ export class MaterialLayoutComponent implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
|
@ -75,7 +74,7 @@ export class ModernLayoutComponent implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
|
@ -75,7 +74,7 @@ export class ClassicLayoutComponent implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
|
@ -86,7 +85,7 @@ export class ClassyLayoutComponent implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
|
@ -75,7 +74,7 @@ export class CompactLayoutComponent implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
|
@ -76,7 +75,7 @@ export class DenseLayoutComponent implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
|
@ -86,7 +85,7 @@ export class FuturisticLayoutComponent implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { FuseMediaWatcherService } from '@fuse/services/media-watcher';
|
||||
import { FuseNavigationService, FuseVerticalNavigationComponent } from '@fuse/components/navigation';
|
||||
import { Navigation } from 'app/core/navigation/navigation.types';
|
||||
|
@ -75,7 +74,7 @@ export class ThinLayoutComponent implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,624 +0,0 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { assign, cloneDeep, omit } from 'lodash-es';
|
||||
import * as moment from 'moment';
|
||||
import RRule, { RRuleSet, rrulestr } from 'rrule';
|
||||
import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api';
|
||||
import { calendars as calendarsData, events as eventsData, exceptions as exceptionsData, settings as settingsData, weekdays as weekdaysData } from 'app/mock-api/apps/calendar/data';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class CalendarMockApi
|
||||
{
|
||||
private _calendars: any[] = calendarsData;
|
||||
private _events: any[] = eventsData;
|
||||
private _exceptions: any[] = exceptionsData;
|
||||
private _settings: any = settingsData;
|
||||
private _weekdays: any = weekdaysData;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(private _fuseMockApiService: FuseMockApiService)
|
||||
{
|
||||
// Register Mock API handlers
|
||||
this.registerHandlers();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Register Mock API handlers
|
||||
*/
|
||||
registerHandlers(): void
|
||||
{
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Calendars - GET
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
this._fuseMockApiService
|
||||
.onGet('api/apps/calendar/calendars')
|
||||
.reply(() => {
|
||||
|
||||
// Clone the calendars
|
||||
const calendars = cloneDeep(this._calendars);
|
||||
|
||||
// Return the response
|
||||
return [200, calendars];
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Calendars - POST
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
this._fuseMockApiService
|
||||
.onPost('api/apps/calendar/calendars')
|
||||
.reply(({request}) => {
|
||||
|
||||
// Get the calendar as the new calendar
|
||||
const newCalendar = cloneDeep(request.body.calendar);
|
||||
|
||||
// Add an id to the new calendar
|
||||
newCalendar.id = FuseMockApiUtils.guid();
|
||||
|
||||
// Push the new calendar
|
||||
this._calendars.push(newCalendar);
|
||||
|
||||
// Return the response
|
||||
return [200, newCalendar];
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Calendars - PATCH
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
this._fuseMockApiService
|
||||
.onPatch('api/apps/calendar/calendars')
|
||||
.reply(({request}) => {
|
||||
|
||||
// Get the id and calendar
|
||||
const id = request.body.id;
|
||||
const calendar = cloneDeep(request.body.calendar);
|
||||
|
||||
// Prepare the updated calendar
|
||||
let updatedCalendar = null;
|
||||
|
||||
// Find the calendar and update it
|
||||
this._calendars.forEach((item, index, calendars) => {
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
// Update the calendar
|
||||
calendars[index] = assign({}, calendars[index], calendar);
|
||||
|
||||
// Store the updated calendar
|
||||
updatedCalendar = calendars[index];
|
||||
}
|
||||
});
|
||||
|
||||
// Return the response
|
||||
return [200, updatedCalendar];
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Calendars - DELETE
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
this._fuseMockApiService
|
||||
.onDelete('api/apps/calendar/calendars')
|
||||
.reply(({request}) => {
|
||||
|
||||
// Get the id
|
||||
const id = request.params.get('id');
|
||||
|
||||
// Find the calendar and delete it
|
||||
const index = this._calendars.findIndex(calendar => calendar.id === id);
|
||||
this._calendars.splice(index, 1);
|
||||
|
||||
// Find the events that belong to the calendar and remove them as well
|
||||
this._events = this._events.filter(event => event.calendarId !== id);
|
||||
|
||||
// Return the response
|
||||
return [200, true];
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Events - GET
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
this._fuseMockApiService
|
||||
.onGet('api/apps/calendar/events')
|
||||
.reply(({request}) => {
|
||||
|
||||
// Get the start and end dates as moment
|
||||
const viewStart = moment(request.params.get('start')).startOf('day');
|
||||
const viewEnd = moment(request.params.get('end')).endOf('day');
|
||||
|
||||
// Clone the events
|
||||
const events = cloneDeep(this._events);
|
||||
|
||||
// Prepare the results
|
||||
const results: any[] = [];
|
||||
|
||||
// Go through the events...
|
||||
events.forEach((event) => {
|
||||
|
||||
// Get the event's start and end dates as moment
|
||||
const eventStart = moment(event.start);
|
||||
const eventEnd = moment(event.end);
|
||||
|
||||
// If it's a normal event...
|
||||
if ( !event.recurrence )
|
||||
{
|
||||
// Only grab the event if it's within the range
|
||||
if ( eventStart.isSameOrAfter(viewStart, 'day') && eventEnd.isSameOrBefore(viewEnd, 'day') )
|
||||
{
|
||||
// Push the event into the results array
|
||||
results.push(event);
|
||||
}
|
||||
}
|
||||
// If it's a recurring event...
|
||||
else
|
||||
{
|
||||
// Skip if the event does not recur within the view range
|
||||
if ( eventStart.isAfter(viewEnd, 'day') || eventEnd.isBefore(viewStart, 'day') )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the DTSTART and UNTIL for RRule
|
||||
const dtStart = eventStart.clone();
|
||||
const until = viewEnd.isBefore(eventEnd) ? viewEnd.clone().utc() : eventEnd.clone().utc();
|
||||
|
||||
// Create an RRuleSet
|
||||
const rruleset = this._generateRuleset(event, dtStart, until);
|
||||
|
||||
// Generate the recurring dates and loop through them
|
||||
rruleset.all().forEach((date) => {
|
||||
|
||||
// Get the rule date as a moment
|
||||
const ruleDate = moment(date);
|
||||
|
||||
// Subtract the UTC Offset from the rule date as we use local time for DTSTART.
|
||||
// The reason for this is simple; if we use UTC dates for DTSTART, RRule generated
|
||||
// dates can shift. Since we have to store the dates as UTC, we can figure out the
|
||||
// UTC value by simply subtracting the UTC Offset (minutes) from the rule date rather
|
||||
// than using UTC dates in the first place. This will ensure there will be no time/day
|
||||
// shift on generated rules since they will be generated based on the local time.
|
||||
ruleDate.subtract(ruleDate.utcOffset(), 'minutes');
|
||||
|
||||
// Skip the date if it's not in between the view start and view end
|
||||
// to prevent generating unnecessary amount of instances and to
|
||||
// prevent instance duplication
|
||||
if ( !ruleDate.isBetween(viewStart, viewEnd, 'day', '[]') )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare the event instance
|
||||
const eventInstance = {
|
||||
|
||||
// Generate an instance id using the event id and rule date
|
||||
id: event.id + '_' + ruleDate.clone().utc().format('YYYYMMDD[T]HHmmss[Z]'),
|
||||
|
||||
// Set the recurringEventId on the event so we don't lose the event's origin
|
||||
recurringEventId: event.id,
|
||||
|
||||
// Whether this is the first instance of the recurring event or not
|
||||
isFirstInstance: event.start === ruleDate.clone().toISOString(),
|
||||
|
||||
// Get the rest of the mock-api
|
||||
calendarId : event.calendarId,
|
||||
title : event.title,
|
||||
description: event.description,
|
||||
start : ruleDate.toISOString(),
|
||||
end : ruleDate.add(event.duration, 'minutes').toISOString(),
|
||||
duration : event.duration,
|
||||
allDay : event.allDay,
|
||||
recurrence : event.recurrence
|
||||
};
|
||||
|
||||
// Push the event instance to the results array
|
||||
results.push(eventInstance);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Return the response
|
||||
return [200, results];
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Event - POST
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
this._fuseMockApiService
|
||||
.onPost('api/apps/calendar/event')
|
||||
.reply(({request}) => {
|
||||
|
||||
// Get the event as the new event
|
||||
const newEvent = cloneDeep(request.body.event);
|
||||
|
||||
// Add an id to the new event
|
||||
newEvent.id = FuseMockApiUtils.guid();
|
||||
|
||||
// Unshift the new event
|
||||
this._events.unshift(newEvent);
|
||||
|
||||
// Return the response
|
||||
return [200, newEvent];
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Event - PATCH
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
this._fuseMockApiService
|
||||
.onPatch('api/apps/calendar/event')
|
||||
.reply(({request}) => {
|
||||
|
||||
// Get the id and event
|
||||
const id = request.body.id;
|
||||
const event = cloneDeep(request.body.event);
|
||||
|
||||
// Prepare the updated event
|
||||
let updatedEvent = null;
|
||||
|
||||
// Find the event and update it
|
||||
this._events.forEach((item, index, events) => {
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
// Update the event
|
||||
events[index] = assign({}, events[index], event);
|
||||
|
||||
// Store the updated event
|
||||
updatedEvent = events[index];
|
||||
}
|
||||
});
|
||||
|
||||
// Return the response
|
||||
return [200, updatedEvent];
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Event - DELETE
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
this._fuseMockApiService
|
||||
.onDelete('api/apps/calendar/event')
|
||||
.reply(({request}) => {
|
||||
|
||||
// Get the id and event
|
||||
const id = request.params.get('id');
|
||||
|
||||
// Find the event and delete it
|
||||
const index = this._events.findIndex(item => item.id === id);
|
||||
this._events.splice(index, 1);
|
||||
|
||||
// Return the response
|
||||
return [200, true];
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Recurring Event - PATCH
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
this._fuseMockApiService
|
||||
.onPatch('api/apps/calendar/recurring-event')
|
||||
.reply(({request}) => {
|
||||
|
||||
// Get the event, original event and mode
|
||||
const event = cloneDeep(request.body.event);
|
||||
const originalEvent = cloneDeep(request.body.originalEvent);
|
||||
const mode = request.body.mode;
|
||||
|
||||
// Find the original recurring event from db
|
||||
const recurringEvent = this._events.find(item => item.id === event.recurringEventId);
|
||||
|
||||
// Single
|
||||
if ( mode === 'single' )
|
||||
{
|
||||
// Create a new event from the event while ignoring the range and recurringEventId
|
||||
const {
|
||||
range,
|
||||
recurringEventId,
|
||||
...newEvent
|
||||
} = event;
|
||||
|
||||
// Generate a unique id for the event
|
||||
newEvent.id = FuseMockApiUtils.guid();
|
||||
|
||||
// Calculate the end date using the start date and the duration
|
||||
newEvent.end = moment(newEvent.start).add(newEvent.duration, 'minutes');
|
||||
|
||||
// Null-ify the recurrence and duration
|
||||
newEvent.duration = null;
|
||||
newEvent.recurrence = null;
|
||||
|
||||
// Push the new event to the events array
|
||||
this._events.push(newEvent);
|
||||
|
||||
// If this is the first instance of the recurring event...
|
||||
if ( originalEvent.start === recurringEvent.start )
|
||||
{
|
||||
// Generate the rruleset
|
||||
const rruleset = this._generateRuleset(recurringEvent, moment(recurringEvent.start), moment(recurringEvent.end).utc());
|
||||
|
||||
// Generate the dates using rruleset and get the 2nd date from start
|
||||
const ruleDate = moment(rruleset.all((date, i) => i < 2)[1]);
|
||||
|
||||
// Subtract the UTC Offset from the rule date as we use local time for DTSTART.
|
||||
// The reason for this is simple; if we use UTC dates for DTSTART, RRule generated
|
||||
// dates can shift. Since we have to store the dates as UTC, we can figure out the
|
||||
// UTC value by simply subtracting the UTC Offset (minutes) from the rule date rather
|
||||
// than using UTC dates in the first place. This will ensure there will be no time/day
|
||||
// shift on generated rules since they will be generated based on the local time.
|
||||
ruleDate.subtract(ruleDate.utcOffset(), 'minutes');
|
||||
|
||||
// Update the recurring event's start date
|
||||
recurringEvent.start = ruleDate.toISOString();
|
||||
}
|
||||
// Otherwise...
|
||||
else
|
||||
{
|
||||
// Add a new exception for the recurring event that ignores this single event's start date
|
||||
this._exceptions.push({
|
||||
id : FuseMockApiUtils.guid(),
|
||||
eventId: originalEvent.recurringEventId,
|
||||
exdate : moment(originalEvent.start).toISOString()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Future
|
||||
if ( mode === 'future' )
|
||||
{
|
||||
// Update the end date
|
||||
recurringEvent.end = moment(originalEvent.start).subtract(1, 'day').endOf('day').toISOString();
|
||||
|
||||
// Parse the recurrence rules from the original event
|
||||
const parsedRules: any = {};
|
||||
originalEvent.recurrence.split(';').forEach((rule: string) => {
|
||||
const parsedRule = rule.split('=');
|
||||
parsedRules[parsedRule[0]] = parsedRule[1];
|
||||
});
|
||||
|
||||
// Add/Update the UNTIL rule
|
||||
parsedRules['UNTIL'] = moment(recurringEvent.end).utc().format('YYYYMMDD[T]HHmmss[Z]');
|
||||
|
||||
// Generate the rule string from the parsed rules
|
||||
const rules: string[] = [];
|
||||
Object.keys(parsedRules).forEach((key) => {
|
||||
rules.push(key + '=' + parsedRules[key]);
|
||||
});
|
||||
|
||||
// Update the recurrence on the original recurring event
|
||||
recurringEvent.recurrence = rules.join(';');
|
||||
|
||||
// Create a new event from the event while ignoring the recurringEventId
|
||||
const {
|
||||
recurringEventId,
|
||||
...newEvent
|
||||
} = event;
|
||||
|
||||
// Generate a unique id for the event
|
||||
newEvent.id = FuseMockApiUtils.guid();
|
||||
|
||||
// Push the new event to the events array
|
||||
this._events.push(newEvent);
|
||||
}
|
||||
|
||||
// All
|
||||
if ( mode === 'all' )
|
||||
{
|
||||
// Find the event index
|
||||
const eventIndex = this._events.findIndex(item => item.id === event.recurringEventId);
|
||||
|
||||
// Update the recurring event
|
||||
this._events[eventIndex] = assign({}, this._events[eventIndex], omit(event, ['id', 'recurringEventId', 'range']));
|
||||
}
|
||||
|
||||
// Return the response
|
||||
return [200, true];
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Recurring Event - DELETE
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
this._fuseMockApiService
|
||||
.onDelete('api/apps/calendar/recurring-event')
|
||||
.reply(({request}) => {
|
||||
|
||||
// Get the event and mode
|
||||
const event = JSON.parse(request.params.get('event') ?? '');
|
||||
const mode = request.params.get('mode');
|
||||
|
||||
// Find the recurring event
|
||||
const recurringEvent = this._events.find(item => item.id === event.recurringEventId);
|
||||
|
||||
// Single
|
||||
if ( mode === 'single' )
|
||||
{
|
||||
// If this is the first instance of the recurring event...
|
||||
if ( event.start === recurringEvent.start )
|
||||
{
|
||||
// Generate the rruleset
|
||||
const rruleset = this._generateRuleset(recurringEvent, moment(recurringEvent.start), moment(recurringEvent.end).utc());
|
||||
|
||||
// Generate the dates using rruleset and get the 2nd date from start
|
||||
const ruleDate = moment(rruleset.all((date, i) => i < 2)[1]);
|
||||
|
||||
// Subtract the UTC Offset from the rule date as we use local time for DTSTART.
|
||||
// The reason for this is simple; if we use UTC dates for DTSTART, RRule generated
|
||||
// dates can shift. Since we have to store the dates as UTC, we can figure out the
|
||||
// UTC value by simply subtracting the UTC Offset (minutes) from the rule date rather
|
||||
// than using UTC dates in the first place. This will ensure there will be no time/day
|
||||
// shift on generated rules since they will be generated based on the local time.
|
||||
ruleDate.subtract(ruleDate.utcOffset(), 'minutes');
|
||||
|
||||
// Update the recurring event's start date
|
||||
recurringEvent.start = ruleDate.toISOString();
|
||||
}
|
||||
// Otherwise...
|
||||
else
|
||||
{
|
||||
// Add a new exception for the recurring event that ignores this single event's start date
|
||||
this._exceptions.push({
|
||||
id : FuseMockApiUtils.guid(),
|
||||
eventId: event.recurringEventId,
|
||||
exdate : moment(event.start).toISOString()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Future
|
||||
if ( mode === 'future' )
|
||||
{
|
||||
// Update the end date of the event
|
||||
recurringEvent.end = moment(event.start).subtract(1, 'day').endOf('day').toISOString();
|
||||
|
||||
// Parse the recurrence rules of the event
|
||||
const parsedRules: any = {};
|
||||
recurringEvent.recurrence.split(';').forEach((rule: string) => {
|
||||
const parsedRule = rule.split('=');
|
||||
parsedRules[parsedRule[0]] = parsedRule[1];
|
||||
});
|
||||
|
||||
// Add/Update the UNTIL rule
|
||||
parsedRules['UNTIL'] = moment(event.end).utc().format('YYYYMMDD[T]HHmmss[Z]');
|
||||
|
||||
// Generate the rule string from the parsed rules
|
||||
const rules: string[] = [];
|
||||
Object.keys(parsedRules).forEach((key) => {
|
||||
rules.push(key + '=' + parsedRules[key]);
|
||||
});
|
||||
|
||||
// Update the recurrence of the event
|
||||
recurringEvent.recurrence = rules.join(';');
|
||||
}
|
||||
|
||||
// All
|
||||
if ( mode === 'all' )
|
||||
{
|
||||
// Find the event and delete it
|
||||
const index = this._events.findIndex(item => item.id === event.recurringEventId);
|
||||
this._events.splice(index, 1);
|
||||
}
|
||||
|
||||
// Return the response
|
||||
return [200, true];
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Settings - GET
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
this._fuseMockApiService
|
||||
.onGet('api/apps/calendar/settings')
|
||||
.reply(() => [200, cloneDeep(this._settings)]);
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Settings - PATCH
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
this._fuseMockApiService
|
||||
.onPatch('api/apps/calendar/settings')
|
||||
.reply(({request}) => {
|
||||
|
||||
// Get the settings
|
||||
const settings = cloneDeep(request.body.settings);
|
||||
|
||||
// Store the updated settings
|
||||
this._settings = settings;
|
||||
|
||||
// Return the response
|
||||
return [200, settings];
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Weekdays - GET
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
this._fuseMockApiService
|
||||
.onGet('api/apps/calendar/weekdays')
|
||||
.reply(() => {
|
||||
|
||||
// Clone the weekdays
|
||||
const weekdays = cloneDeep(this._weekdays);
|
||||
|
||||
// If the startWeekOn setting is set to Sunday...
|
||||
if ( this._settings.startWeekOn === 0 )
|
||||
{
|
||||
// Move the Sunday to the beginning
|
||||
weekdays.unshift(weekdays.pop());
|
||||
}
|
||||
|
||||
// If the startWeekOn is set to Saturday...
|
||||
if ( this._settings.startWeekOn === 6 )
|
||||
{
|
||||
// Move the Sunday to the beginning
|
||||
weekdays.unshift(weekdays.pop());
|
||||
|
||||
// Then move the Saturday to the beginning
|
||||
weekdays.unshift(weekdays.pop());
|
||||
}
|
||||
|
||||
// Return the response
|
||||
return [200, weekdays];
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Private methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Generates an RRuleSet from given event
|
||||
*
|
||||
* @param event
|
||||
* @param dtStart
|
||||
* @param until
|
||||
* @private
|
||||
*/
|
||||
private _generateRuleset(event: any, dtStart: any, until: any): RRuleSet | RRule
|
||||
{
|
||||
// Parse the recurrence rules
|
||||
const parsedRules: any = {};
|
||||
event.recurrence.split(';').forEach((rule: string) => {
|
||||
|
||||
// Split the rule
|
||||
const parsedRule = rule.split('=');
|
||||
|
||||
// Omit UNTIL or COUNT from the parsed rules since we only
|
||||
// need them for calculating the event's end date. We will
|
||||
// add an UNTIL later based on the above calculations.
|
||||
if ( parsedRule[0] === 'UNTIL' || parsedRule[0] === 'COUNT' )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the rule to the parsed rules
|
||||
parsedRules[parsedRule[0]] = parsedRule[1];
|
||||
});
|
||||
|
||||
// Generate the rule array from the parsed rules
|
||||
const rules: string[] = [];
|
||||
Object.keys(parsedRules).forEach((key) => {
|
||||
rules.push(key + '=' + parsedRules[key]);
|
||||
});
|
||||
|
||||
// Prepare the ruleSet
|
||||
const ruleSet = [];
|
||||
|
||||
// Add DTSTART
|
||||
ruleSet.push('DTSTART:' + dtStart.format('YYYYMMDD[T]HHmmss[Z]'));
|
||||
|
||||
// Add RRULE
|
||||
ruleSet.push('RRULE:' + rules.join(';') + ';UNTIL=' + until.format('YYYYMMDD[T]HHmmss[Z]'));
|
||||
|
||||
// Find and add any available exceptions to the rule
|
||||
this._exceptions.forEach((item) => {
|
||||
|
||||
// If the item is an exception to this event...
|
||||
if ( item.eventId === event.id )
|
||||
{
|
||||
// Add it as an EXDATE to the rrule
|
||||
ruleSet.push('EXDATE:' + moment(item.exdate).format('YYYYMMDD[T]HHmmss[Z]'));
|
||||
}
|
||||
});
|
||||
|
||||
// Create an RRuleSet from the ruleSet array
|
||||
return rrulestr(ruleSet.join('\n'), {forceset: true});
|
||||
}
|
||||
}
|
|
@ -1,170 +0,0 @@
|
|||
/* eslint-disable */
|
||||
import * as moment from 'moment';
|
||||
|
||||
export const calendars = [
|
||||
{
|
||||
id : '1a470c8e-40ed-4c2d-b590-a4f1f6ead6cc',
|
||||
title : 'Personal',
|
||||
color : 'bg-teal-500',
|
||||
visible: true
|
||||
},
|
||||
{
|
||||
id : '5dab5f7b-757a-4467-ace1-305fe07b11fe',
|
||||
title : 'Work',
|
||||
color : 'bg-indigo-500',
|
||||
visible: true
|
||||
},
|
||||
{
|
||||
id : '09887870-f85a-40eb-8171-1b13d7a7f529',
|
||||
title : 'Appointments',
|
||||
color : 'bg-pink-500',
|
||||
visible: true
|
||||
}
|
||||
];
|
||||
export const events = [
|
||||
// Personal
|
||||
{
|
||||
id : '3be50686-e3a1-4f4b-aa4d-5cb8517ba4e4',
|
||||
calendarId : '1a470c8e-40ed-4c2d-b590-a4f1f6ead6cc',
|
||||
title : 'Portfolio Design',
|
||||
description: '',
|
||||
start : moment().hour(9).minute(0).second(0).millisecond(0).toISOString(), // Today 09:00
|
||||
end : moment().add(1, 'day').hour(14).minute(0).second(0).millisecond(0).toISOString(), // Tomorrow 14:00
|
||||
duration : null,
|
||||
allDay : false,
|
||||
recurrence : null
|
||||
},
|
||||
{
|
||||
id : '660f0dcd-48f8-4266-a89a-8ee0789c074a',
|
||||
calendarId : '1a470c8e-40ed-4c2d-b590-a4f1f6ead6cc',
|
||||
title : 'Dinner with Mom',
|
||||
description: 'Do not forget to buy her lilacs!',
|
||||
start : moment().date(10).hour(18).minute(0).second(0).millisecond(0).toISOString(), // 10th of the current month at 18:00
|
||||
end : moment().date(10).hour(20).minute(0).second(0).millisecond(0).toISOString(), // 10th of the current month at 20:00
|
||||
duration : null,
|
||||
allDay : false,
|
||||
recurrence : null
|
||||
},
|
||||
{
|
||||
id : '7471b840-5efb-45da-9092-a0f04ee5617b',
|
||||
calendarId : '1a470c8e-40ed-4c2d-b590-a4f1f6ead6cc',
|
||||
title : 'Lunch with Becky',
|
||||
description: '',
|
||||
start : moment().date(21).hour(12).minute(0).second(0).millisecond(0).toISOString(), // 21st of the current month at noon
|
||||
end : moment().date(21).hour(14).minute(0).second(0).millisecond(0).toISOString(), // 21st of the current month at 14:00
|
||||
duration : null,
|
||||
allDay : false,
|
||||
recurrence : null
|
||||
},
|
||||
{
|
||||
id : 'c3e6c110-9b67-4e6b-a2ab-3046abf1b074',
|
||||
calendarId : '1a470c8e-40ed-4c2d-b590-a4f1f6ead6cc',
|
||||
title : 'Mom\'s Birthday',
|
||||
description: '',
|
||||
start : moment().date(8).startOf('day').toISOString(), // 8th of the current month at start of the day
|
||||
end : moment().year(9999).endOf('year').toISOString(), // End of the times
|
||||
duration : 0,
|
||||
allDay : true,
|
||||
recurrence : 'FREQ=YEARLY;INTERVAL=1'
|
||||
},
|
||||
// Appointments
|
||||
{
|
||||
id : 'd2220429-9214-4c4b-9da6-f8da2fbfd507',
|
||||
calendarId : '09887870-f85a-40eb-8171-1b13d7a7f529',
|
||||
title : 'Doctor\'s Visit',
|
||||
description: 'Measure blood pressure before leaving home',
|
||||
start : moment().date(1).hour(10).minute(0).second(0).millisecond(0).add((9 - moment().date(1).day()) % 7, 'day').toISOString(), // First Tuesday of the current month at 10:00
|
||||
end : moment().year(9999).endOf('year').toISOString(), // End of the times
|
||||
duration : 90, // Minutes
|
||||
allDay : false,
|
||||
recurrence : 'FREQ=MONTHLY;INTERVAL=1;BYDAY=1TU'
|
||||
},
|
||||
{
|
||||
id : '4d88418c-cbdf-4f03-89e1-e3dca14a9e92',
|
||||
calendarId : '09887870-f85a-40eb-8171-1b13d7a7f529',
|
||||
title : 'Therapy Session',
|
||||
description: '',
|
||||
start : moment().date(1).hour(13).minute(0).second(0).millisecond(0).add((6 - moment().date(1).day()) % 7, 'day').add(1, 'week').toISOString(), // Second Saturday of the current month at 13:00
|
||||
end : moment().year(9999).endOf('year').toISOString(), // End of the times
|
||||
duration : 120, // Minutes
|
||||
allDay : false,
|
||||
recurrence : 'FREQ=WEEKLY;INTERVAL=2;BYDAY=SA'
|
||||
},
|
||||
// Work
|
||||
{
|
||||
id : '0e848e4a-0333-42e3-b223-0209c4b58a3b',
|
||||
calendarId : '5dab5f7b-757a-4467-ace1-305fe07b11fe',
|
||||
title : 'Design Review',
|
||||
description: '',
|
||||
start : moment().date(19).hour(15).minute(0).second(0).millisecond(0).toISOString(), // 19th of the current month at 15:00
|
||||
end : moment().date(19).hour(17).minute(30).second(0).millisecond(0).toISOString(), // 19th of the current month at 17:30
|
||||
duration : null,
|
||||
allDay : true,
|
||||
recurrence : null
|
||||
},
|
||||
{
|
||||
id : 'f619eb76-c21b-4bb0-aeff-41e765cae290',
|
||||
calendarId : '5dab5f7b-757a-4467-ace1-305fe07b11fe',
|
||||
title : 'Consulting',
|
||||
description: 'Sarah and Jessica will be joining the call',
|
||||
start : moment().date(8).hour(11).minute(30).second(0).millisecond(0).toISOString(), // 8th of the current month at 11:30
|
||||
end : moment().date(8).hour(12).minute(45).second(0).millisecond(0).toISOString(), // 8th of the current month at 12:45
|
||||
duration : null,
|
||||
allDay : false,
|
||||
recurrence : null
|
||||
},
|
||||
{
|
||||
id : 'd97ea3ca-0e5a-4b86-a4fa-5b80a261081e',
|
||||
calendarId : '5dab5f7b-757a-4467-ace1-305fe07b11fe',
|
||||
title : 'Meeting',
|
||||
description: '',
|
||||
start : moment().date(1).hour(9).minute(0).second(0).millisecond(0).add((5 - moment().date(1).day()) % 7, 'day').add(1, 'week').toISOString(), // Second Friday of the current month at 09:00
|
||||
end : moment().year(9999).endOf('year').toISOString(), // End of the times
|
||||
duration : 150, // Minutes
|
||||
allDay : false,
|
||||
recurrence : 'FREQ=WEEKLY;INTERVAL=2;BYDAY=FR'
|
||||
}
|
||||
];
|
||||
export const exceptions = [];
|
||||
export const settings = {
|
||||
dateFormat : 'll', // Aug 20, 2019
|
||||
timeFormat : '24', // 24-hour format
|
||||
startWeekOn: 1 // Monday
|
||||
};
|
||||
export const weekdays = [
|
||||
{
|
||||
abbr : 'M',
|
||||
label: 'Monday',
|
||||
value: 'MO'
|
||||
},
|
||||
{
|
||||
abbr : 'T',
|
||||
label: 'Tuesday',
|
||||
value: 'TU'
|
||||
},
|
||||
{
|
||||
abbr : 'W',
|
||||
label: 'Wednesday',
|
||||
value: 'WE'
|
||||
},
|
||||
{
|
||||
abbr : 'T',
|
||||
label: 'Thursday',
|
||||
value: 'TH'
|
||||
},
|
||||
{
|
||||
abbr : 'F',
|
||||
label: 'Friday',
|
||||
value: 'FR'
|
||||
},
|
||||
{
|
||||
abbr : 'S',
|
||||
label: 'Saturday',
|
||||
value: 'SA'
|
||||
},
|
||||
{
|
||||
abbr : 'S',
|
||||
label: 'Sunday',
|
||||
value: 'SU'
|
||||
}
|
||||
];
|
|
@ -1,6 +1,5 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { from } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { from, map } from 'rxjs';
|
||||
import { assign, cloneDeep } from 'lodash-es';
|
||||
import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api';
|
||||
import { contacts as contactsData, countries as countriesData, tags as tagsData } from 'app/mock-api/apps/contacts/data';
|
||||
|
|
|
@ -32,14 +32,6 @@ export const shortcuts = [
|
|||
link : '/dashboards/analytics',
|
||||
useRouter : true
|
||||
},
|
||||
{
|
||||
id : '34fb28db-4ec8-4570-8584-2414d6de796b',
|
||||
label : 'Calendar',
|
||||
description: 'Latest appointments',
|
||||
icon : 'heroicons_outline:calendar',
|
||||
link : '/apps/calendar',
|
||||
useRouter : true
|
||||
},
|
||||
{
|
||||
id : '2daac375-a2f7-4393-b4d7-ce6061628b66',
|
||||
label : 'Mailbox',
|
||||
|
|
|
@ -2,7 +2,6 @@ import { AcademyMockApi } from 'app/mock-api/apps/academy/api';
|
|||
import { ActivitiesMockApi } from 'app/mock-api/pages/activities/api';
|
||||
import { AnalyticsMockApi } from 'app/mock-api/dashboards/analytics/api';
|
||||
import { AuthMockApi } from 'app/mock-api/common/auth/api';
|
||||
import { CalendarMockApi } from 'app/mock-api/apps/calendar/api';
|
||||
import { ChatMockApi } from 'app/mock-api/apps/chat/api';
|
||||
import { ContactsMockApi } from 'app/mock-api/apps/contacts/api';
|
||||
import { CryptoMockApi } from 'app/mock-api/dashboards/crypto/api';
|
||||
|
@ -28,7 +27,6 @@ export const mockApiServices = [
|
|||
ActivitiesMockApi,
|
||||
AnalyticsMockApi,
|
||||
AuthMockApi,
|
||||
CalendarMockApi,
|
||||
ChatMockApi,
|
||||
ContactsMockApi,
|
||||
CryptoMockApi,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, NgForm, Validators } from '@angular/forms';
|
||||
import { finalize } from 'rxjs/operators';
|
||||
import { finalize } from 'rxjs';
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseAlertType } from '@fuse/components/alert';
|
||||
import { AuthService } from 'app/core/auth/auth.service';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, NgForm, Validators } from '@angular/forms';
|
||||
import { finalize } from 'rxjs/operators';
|
||||
import { finalize } from 'rxjs';
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseValidators } from '@fuse/validators';
|
||||
import { FuseAlertType } from '@fuse/components/alert';
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { Subject, timer } from 'rxjs';
|
||||
import { finalize, takeUntil, takeWhile, tap } from 'rxjs/operators';
|
||||
import { finalize, Subject, takeUntil, takeWhile, tap, timer } from 'rxjs';
|
||||
import { AuthService } from 'app/core/auth/auth.service';
|
||||
|
||||
@Component({
|
||||
|
@ -59,7 +58,7 @@ export class AuthSignOutComponent implements OnInit, OnDestroy
|
|||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
* file.
|
||||
*
|
||||
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
|
||||
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
|
||||
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
|
||||
* automatically update themselves. This includes recent versions of Safari, Chrome (including
|
||||
* Opera), Edge on the desktop, and iOS and Chrome on mobile.
|
||||
*
|
||||
* Learn more in https://angular.io/guide/browser-support
|
||||
*/
|
||||
|
@ -18,18 +18,6 @@
|
|||
* BROWSER POLYFILLS
|
||||
*/
|
||||
|
||||
/**
|
||||
* IE11 requires the following for NgClass support on SVG elements
|
||||
*/
|
||||
// import 'classlist.js'; // Run `npm install --save classlist.js`.
|
||||
|
||||
/**
|
||||
* Web Animations `@angular/platform-browser/animations`
|
||||
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
|
||||
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
|
||||
*/
|
||||
import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
||||
|
||||
/**
|
||||
* By default, zone.js will patch all possible macroTask and DomEvents
|
||||
* user can disable parts of macroTask/DomEvents patch by setting following flags
|
||||
|
|
|
@ -2,12 +2,6 @@
|
|||
/* @ Import third party library styles here.
|
||||
/* ----------------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* FullCalendar */
|
||||
@import '~@fullcalendar/core/main.css';
|
||||
@import '~@fullcalendar/daygrid/main.css';
|
||||
@import '~@fullcalendar/timegrid/main.css';
|
||||
@import '~@fullcalendar/list/main.css';
|
||||
|
||||
/* Perfect scrollbar */
|
||||
@import '~perfect-scrollbar/css/perfect-scrollbar.css';
|
||||
|
||||
|
|
|
@ -14,8 +14,7 @@ declare const require: {
|
|||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting(),
|
||||
{teardown: {destroyAfterEach: true}}
|
||||
platformBrowserDynamicTesting()
|
||||
);
|
||||
|
||||
// Then we find all the tests.
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
"target": "es2017",
|
||||
"module": "es2020",
|
||||
"lib": [
|
||||
"es2018",
|
||||
"es2020",
|
||||
"dom"
|
||||
]
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue
Block a user