mirror of
https://github.com/richard-loafle/fuse-angular.git
synced 2025-01-06 18:45:08 +00:00
Second pass through for standalone components.
This commit is contained in:
parent
b2cb20634e
commit
5d42763f1b
46712
package-lock.json
generated
46712
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
130
package.json
130
package.json
|
@ -1,66 +1,66 @@
|
|||
{
|
||||
"name": "fuse-angular",
|
||||
"version": "18.0.0",
|
||||
"description": "Fuse - Angular Admin Template and Starter Project",
|
||||
"author": "https://themeforest.net/user/srcn",
|
||||
"license": "https://themeforest.net/licenses/standard",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"test": "ng test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/animations": "15.2.9",
|
||||
"@angular/cdk": "15.2.9",
|
||||
"@angular/common": "15.2.9",
|
||||
"@angular/compiler": "15.2.9",
|
||||
"@angular/core": "15.2.9",
|
||||
"@angular/forms": "15.2.9",
|
||||
"@angular/material": "15.2.9",
|
||||
"@angular/material-luxon-adapter": "15.2.9",
|
||||
"@angular/platform-browser": "15.2.9",
|
||||
"@angular/platform-browser-dynamic": "15.2.9",
|
||||
"@angular/router": "15.2.9",
|
||||
"@ngneat/transloco": "4.2.6",
|
||||
"apexcharts": "3.40.0",
|
||||
"crypto-js": "3.3.0",
|
||||
"highlight.js": "11.8.0",
|
||||
"lodash-es": "4.17.21",
|
||||
"luxon": "3.3.0",
|
||||
"ng-apexcharts": "1.7.6",
|
||||
"ngx-quill": "21.0.0",
|
||||
"perfect-scrollbar": "1.5.5",
|
||||
"quill": "1.3.7",
|
||||
"rxjs": "7.8.1",
|
||||
"tslib": "2.5.0",
|
||||
"zone.js": "0.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "15.2.8",
|
||||
"@angular/cli": "15.2.8",
|
||||
"@angular/compiler-cli": "15.2.9",
|
||||
"@tailwindcss/typography": "0.5.9",
|
||||
"@types/chroma-js": "2.4.0",
|
||||
"@types/crypto-js": "3.1.47",
|
||||
"@types/highlight.js": "10.1.0",
|
||||
"@types/jasmine": "4.3.1",
|
||||
"@types/lodash": "4.14.194",
|
||||
"@types/lodash-es": "4.17.7",
|
||||
"@types/luxon": "3.3.0",
|
||||
"autoprefixer": "10.4.14",
|
||||
"chroma-js": "2.4.2",
|
||||
"jasmine-core": "4.6.0",
|
||||
"karma": "6.4.2",
|
||||
"karma-chrome-launcher": "3.2.0",
|
||||
"karma-coverage": "2.2.0",
|
||||
"karma-jasmine": "5.1.0",
|
||||
"karma-jasmine-html-reporter": "2.0.0",
|
||||
"lodash": "4.17.21",
|
||||
"postcss": "8.4.23",
|
||||
"tailwindcss": "3.3.2",
|
||||
"typescript": "4.9.5"
|
||||
}
|
||||
}
|
||||
"name": "fuse-angular",
|
||||
"version": "18.0.0",
|
||||
"description": "Fuse - Angular Admin Template and Starter Project",
|
||||
"author": "https://themeforest.net/user/srcn",
|
||||
"license": "https://themeforest.net/licenses/standard",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"test": "ng test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/animations": "16.0.0",
|
||||
"@angular/cdk": "16.0.0",
|
||||
"@angular/common": "16.0.0",
|
||||
"@angular/compiler": "16.0.0",
|
||||
"@angular/core": "16.0.0",
|
||||
"@angular/forms": "16.0.0",
|
||||
"@angular/material": "16.0.0",
|
||||
"@angular/material-luxon-adapter": "16.0.0",
|
||||
"@angular/platform-browser": "16.0.0",
|
||||
"@angular/platform-browser-dynamic": "16.0.0",
|
||||
"@angular/router": "16.0.0",
|
||||
"@ngneat/transloco": "4.2.6",
|
||||
"apexcharts": "3.40.0",
|
||||
"crypto-js": "3.3.0",
|
||||
"highlight.js": "11.8.0",
|
||||
"lodash-es": "4.17.21",
|
||||
"luxon": "3.3.0",
|
||||
"ng-apexcharts": "1.7.6",
|
||||
"ngx-quill": "21.0.0",
|
||||
"perfect-scrollbar": "1.5.5",
|
||||
"quill": "1.3.7",
|
||||
"rxjs": "7.8.1",
|
||||
"tslib": "2.5.0",
|
||||
"zone.js": "0.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "16.0.0",
|
||||
"@angular/cli": "16.0.0",
|
||||
"@angular/compiler-cli": "16.0.0",
|
||||
"@tailwindcss/typography": "0.5.9",
|
||||
"@types/chroma-js": "2.4.0",
|
||||
"@types/crypto-js": "3.1.47",
|
||||
"@types/highlight.js": "10.1.0",
|
||||
"@types/jasmine": "4.3.1",
|
||||
"@types/lodash": "4.14.194",
|
||||
"@types/lodash-es": "4.17.7",
|
||||
"@types/luxon": "3.3.0",
|
||||
"autoprefixer": "10.4.14",
|
||||
"chroma-js": "2.4.2",
|
||||
"jasmine-core": "4.6.0",
|
||||
"karma": "6.4.2",
|
||||
"karma-chrome-launcher": "3.2.0",
|
||||
"karma-coverage": "2.2.0",
|
||||
"karma-jasmine": "5.1.0",
|
||||
"karma-jasmine-html-reporter": "2.0.0",
|
||||
"lodash": "4.17.21",
|
||||
"postcss": "8.4.23",
|
||||
"tailwindcss": "3.3.2",
|
||||
"typescript": "4.9.5"
|
||||
}
|
||||
}
|
|
@ -128,7 +128,6 @@ export class FuseAlertComponent implements OnChanges, OnInit, OnDestroy
|
|||
)
|
||||
.subscribe(() =>
|
||||
{
|
||||
|
||||
// Dismiss the alert
|
||||
this.dismiss();
|
||||
});
|
||||
|
@ -141,7 +140,6 @@ export class FuseAlertComponent implements OnChanges, OnInit, OnDestroy
|
|||
)
|
||||
.subscribe(() =>
|
||||
{
|
||||
|
||||
// Show the alert
|
||||
this.show();
|
||||
});
|
||||
|
|
|
@ -381,7 +381,6 @@ export class FuseDrawerComponent implements OnChanges, OnInit, OnDestroy
|
|||
// Once the animation is done...
|
||||
this._player.onDone(() =>
|
||||
{
|
||||
|
||||
// If the overlay still exists...
|
||||
if ( this._overlay )
|
||||
{
|
||||
|
|
|
@ -63,7 +63,6 @@ export class FuseHighlightService
|
|||
lines.filter(line => line.length)
|
||||
.forEach((line, index) =>
|
||||
{
|
||||
|
||||
// Always get the indentation of the first line so we can
|
||||
// have something to compare with
|
||||
if ( index === 0 )
|
||||
|
|
|
@ -70,7 +70,6 @@ export class FuseHorizontalNavigationBasicItemComponent implements OnInit, OnDes
|
|||
takeUntil(this._unsubscribeAll),
|
||||
).subscribe(() =>
|
||||
{
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
});
|
||||
|
|
|
@ -59,7 +59,6 @@ export class FuseHorizontalNavigationBranchItemComponent implements OnInit, OnDe
|
|||
takeUntil(this._unsubscribeAll),
|
||||
).subscribe(() =>
|
||||
{
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
});
|
||||
|
|
|
@ -47,7 +47,6 @@ export class FuseHorizontalNavigationDividerItemComponent implements OnInit, OnD
|
|||
takeUntil(this._unsubscribeAll),
|
||||
).subscribe(() =>
|
||||
{
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
});
|
||||
|
|
|
@ -47,7 +47,6 @@ export class FuseHorizontalNavigationSpacerItemComponent implements OnInit, OnDe
|
|||
takeUntil(this._unsubscribeAll),
|
||||
).subscribe(() =>
|
||||
{
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
});
|
||||
|
|
|
@ -84,7 +84,6 @@ export class FuseVerticalNavigationAsideItemComponent implements OnChanges, OnIn
|
|||
)
|
||||
.subscribe((event: NavigationEnd) =>
|
||||
{
|
||||
|
||||
// Mark if active
|
||||
this._markIfActive(event.urlAfterRedirects);
|
||||
});
|
||||
|
@ -97,7 +96,6 @@ export class FuseVerticalNavigationAsideItemComponent implements OnChanges, OnIn
|
|||
takeUntil(this._unsubscribeAll),
|
||||
).subscribe(() =>
|
||||
{
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
});
|
||||
|
|
|
@ -69,7 +69,6 @@ export class FuseVerticalNavigationBasicItemComponent implements OnInit, OnDestr
|
|||
takeUntil(this._unsubscribeAll),
|
||||
).subscribe(() =>
|
||||
{
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
});
|
||||
|
|
|
@ -97,7 +97,6 @@ export class FuseVerticalNavigationCollapsableItemComponent implements OnInit, O
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((collapsedItem) =>
|
||||
{
|
||||
|
||||
// Check if the collapsed item is null
|
||||
if ( collapsedItem === null )
|
||||
{
|
||||
|
@ -118,7 +117,6 @@ export class FuseVerticalNavigationCollapsableItemComponent implements OnInit, O
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((expandedItem) =>
|
||||
{
|
||||
|
||||
// Check if the expanded item is null
|
||||
if ( expandedItem === null )
|
||||
{
|
||||
|
@ -156,7 +154,6 @@ export class FuseVerticalNavigationCollapsableItemComponent implements OnInit, O
|
|||
)
|
||||
.subscribe((event: NavigationEnd) =>
|
||||
{
|
||||
|
||||
// If the item has a children that has a matching url with the current url, expand...
|
||||
if ( this._hasActiveChild(this.item, event.urlAfterRedirects) )
|
||||
{
|
||||
|
@ -178,7 +175,6 @@ export class FuseVerticalNavigationCollapsableItemComponent implements OnInit, O
|
|||
takeUntil(this._unsubscribeAll),
|
||||
).subscribe(() =>
|
||||
{
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
});
|
||||
|
|
|
@ -47,7 +47,6 @@ export class FuseVerticalNavigationDividerItemComponent implements OnInit, OnDes
|
|||
takeUntil(this._unsubscribeAll),
|
||||
).subscribe(() =>
|
||||
{
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
});
|
||||
|
|
|
@ -58,7 +58,6 @@ export class FuseVerticalNavigationGroupItemComponent implements OnInit, OnDestr
|
|||
takeUntil(this._unsubscribeAll),
|
||||
).subscribe(() =>
|
||||
{
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
});
|
||||
|
|
|
@ -47,7 +47,6 @@ export class FuseVerticalNavigationSpacerItemComponent implements OnInit, OnDest
|
|||
takeUntil(this._unsubscribeAll),
|
||||
).subscribe(() =>
|
||||
{
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
});
|
||||
|
|
|
@ -160,7 +160,6 @@ export class FuseVerticalNavigationComponent implements OnChanges, OnInit, After
|
|||
)
|
||||
.subscribe(() =>
|
||||
{
|
||||
|
||||
// Loop through the scrollbars and update them
|
||||
fuseScrollbarDirectives.forEach((fuseScrollbarDirective) =>
|
||||
{
|
||||
|
@ -325,7 +324,6 @@ export class FuseVerticalNavigationComponent implements OnChanges, OnInit, After
|
|||
)
|
||||
.subscribe(() =>
|
||||
{
|
||||
|
||||
// If the mode is 'over' and the navigation is opened...
|
||||
if ( this.mode === 'over' && this.opened )
|
||||
{
|
||||
|
@ -379,7 +377,6 @@ export class FuseVerticalNavigationComponent implements OnChanges, OnInit, After
|
|||
|
||||
setTimeout(() =>
|
||||
{
|
||||
|
||||
// Return if 'navigation content' element does not exist
|
||||
if ( !this._navigationContentEl )
|
||||
{
|
||||
|
@ -405,7 +402,6 @@ export class FuseVerticalNavigationComponent implements OnChanges, OnInit, After
|
|||
// Go through all the scrollbar directives
|
||||
this._fuseScrollbarDirectives.forEach((fuseScrollbarDirective) =>
|
||||
{
|
||||
|
||||
// Skip if not enabled
|
||||
if ( !fuseScrollbarDirective.isEnabled() )
|
||||
{
|
||||
|
@ -675,7 +671,6 @@ export class FuseVerticalNavigationComponent implements OnChanges, OnInit, After
|
|||
// Once the animation is done...
|
||||
this._player.onDone(() =>
|
||||
{
|
||||
|
||||
// If the overlay still exists...
|
||||
if ( this._overlay )
|
||||
{
|
||||
|
@ -753,7 +748,6 @@ export class FuseVerticalNavigationComponent implements OnChanges, OnInit, After
|
|||
// Once the animation is done...
|
||||
this._player.onDone(() =>
|
||||
{
|
||||
|
||||
// If the aside overlay still exists...
|
||||
if ( this._asideOverlay )
|
||||
{
|
||||
|
|
|
@ -36,7 +36,6 @@ export class FuseScrollResetDirective implements OnInit, OnDestroy
|
|||
takeUntil(this._unsubscribeAll),
|
||||
).subscribe(() =>
|
||||
{
|
||||
|
||||
// Reset the element's scroll position to the top
|
||||
this._elementRef.nativeElement.scrollTop = 0;
|
||||
});
|
||||
|
|
|
@ -127,7 +127,6 @@ export class FuseScrollbarDirective implements OnChanges, OnInit, OnDestroy
|
|||
)
|
||||
.subscribe(() =>
|
||||
{
|
||||
|
||||
// Update the PerfectScrollbar
|
||||
this.update();
|
||||
});
|
||||
|
|
|
@ -50,7 +50,6 @@ export class FuseMockApiInterceptor implements HttpInterceptor
|
|||
delay(handler.delay ?? this._defaultDelay ?? 0),
|
||||
switchMap((response) =>
|
||||
{
|
||||
|
||||
// If there is no response data,
|
||||
// throw an error response
|
||||
if ( !response )
|
||||
|
|
|
@ -54,7 +54,6 @@ export class FuseMockApiService
|
|||
// Iterate through the handlers
|
||||
handlers.forEach((handler, handlerUrl) =>
|
||||
{
|
||||
|
||||
// Skip if there is already a matching handler
|
||||
if ( matchingHandler.handler )
|
||||
{
|
||||
|
|
|
@ -22,7 +22,6 @@ export class FuseMediaWatcherService
|
|||
switchMap(screens => this._breakpointObserver.observe(Object.values(screens)).pipe(
|
||||
map((state) =>
|
||||
{
|
||||
|
||||
// Prepare the observable values and set their defaults
|
||||
const matchingAliases: string[] = [];
|
||||
const matchingQueries: any = {};
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -22,7 +22,6 @@ export class FuseValidators
|
|||
{
|
||||
return (formGroup: AbstractControl): ValidationErrors | null =>
|
||||
{
|
||||
|
||||
// Get the control and matching control
|
||||
const control = formGroup.get(controlPath);
|
||||
const matchingControl = formGroup.get(matchingControlPath);
|
||||
|
|
|
@ -1,49 +1,25 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||
import { inject } from '@angular/core';
|
||||
import { NavigationService } from 'app/core/navigation/navigation.service';
|
||||
import { MessagesService } from 'app/layout/common/messages/messages.service';
|
||||
import { NotificationsService } from 'app/layout/common/notifications/notifications.service';
|
||||
import { QuickChatService } from 'app/layout/common/quick-chat/quick-chat.service';
|
||||
import { ShortcutsService } from 'app/layout/common/shortcuts/shortcuts.service';
|
||||
import { forkJoin, Observable } from 'rxjs';
|
||||
import { forkJoin } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class InitialDataResolver implements Resolve<any>
|
||||
export const initialDataResolver = () =>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(
|
||||
private _messagesService: MessagesService,
|
||||
private _navigationService: NavigationService,
|
||||
private _notificationsService: NotificationsService,
|
||||
private _quickChatService: QuickChatService,
|
||||
private _shortcutsService: ShortcutsService,
|
||||
)
|
||||
{
|
||||
}
|
||||
const messagesService = inject(MessagesService);
|
||||
const navigationService = inject(NavigationService);
|
||||
const notificationsService = inject(NotificationsService);
|
||||
const quickChatService = inject(QuickChatService);
|
||||
const shortcutsService = inject(ShortcutsService);
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Use this resolver to resolve initial mock-api for the application
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any>
|
||||
{
|
||||
// Fork join multiple API endpoint calls to wait all of them to finish
|
||||
return forkJoin([
|
||||
this._navigationService.get(),
|
||||
this._messagesService.getAll(),
|
||||
this._notificationsService.getAll(),
|
||||
this._quickChatService.getChats(),
|
||||
this._shortcutsService.getAll(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
// Fork join multiple API endpoint calls to wait all of them to finish
|
||||
return forkJoin([
|
||||
navigationService.get(),
|
||||
messagesService.getAll(),
|
||||
notificationsService.getAll(),
|
||||
quickChatService.getChats(),
|
||||
shortcutsService.getAll(),
|
||||
]);
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Route } from '@angular/router';
|
||||
import { InitialDataResolver } from 'app/app.resolvers';
|
||||
import { initialDataResolver } from 'app/app.resolvers';
|
||||
import { AuthGuard } from 'app/core/auth/guards/auth.guard';
|
||||
import { NoAuthGuard } from 'app/core/auth/guards/noAuth.guard';
|
||||
import { LayoutComponent } from 'app/layout/layout.component';
|
||||
|
@ -29,11 +29,11 @@ export const appRoutes: Route[] = [
|
|||
layout: 'empty'
|
||||
},
|
||||
children: [
|
||||
{path: 'confirmation-required', loadChildren: () => import('app/modules/auth/confirmation-required/confirmation-required.module').then(m => m.AuthConfirmationRequiredModule)},
|
||||
{path: 'forgot-password', loadChildren: () => import('app/modules/auth/forgot-password/forgot-password.module').then(m => m.AuthForgotPasswordModule)},
|
||||
{path: 'reset-password', loadChildren: () => import('app/modules/auth/reset-password/reset-password.module').then(m => m.AuthResetPasswordModule)},
|
||||
{path: 'sign-in', loadChildren: () => import('app/modules/auth/sign-in/sign-in.module').then(m => m.AuthSignInModule)},
|
||||
{path: 'sign-up', loadChildren: () => import('app/modules/auth/sign-up/sign-up.module').then(m => m.AuthSignUpModule)}
|
||||
{path: 'confirmation-required', loadChildren: () => import('app/modules/auth/confirmation-required/confirmation-required.routes')},
|
||||
{path: 'forgot-password', loadChildren: () => import('app/modules/auth/forgot-password/forgot-password.routes')},
|
||||
{path: 'reset-password', loadChildren: () => import('app/modules/auth/reset-password/reset-password.routes')},
|
||||
{path: 'sign-in', loadChildren: () => import('app/modules/auth/sign-in/sign-in.routes')},
|
||||
{path: 'sign-up', loadChildren: () => import('app/modules/auth/sign-up/sign-up.routes')}
|
||||
]
|
||||
},
|
||||
|
||||
|
@ -47,8 +47,8 @@ export const appRoutes: Route[] = [
|
|||
layout: 'empty'
|
||||
},
|
||||
children: [
|
||||
{path: 'sign-out', loadChildren: () => import('app/modules/auth/sign-out/sign-out.module').then(m => m.AuthSignOutModule)},
|
||||
{path: 'unlock-session', loadChildren: () => import('app/modules/auth/unlock-session/unlock-session.module').then(m => m.AuthUnlockSessionModule)}
|
||||
{path: 'sign-out', loadChildren: () => import('app/modules/auth/sign-out/sign-out.routes')},
|
||||
{path: 'unlock-session', loadChildren: () => import('app/modules/auth/unlock-session/unlock-session.routes')}
|
||||
]
|
||||
},
|
||||
|
||||
|
@ -60,7 +60,7 @@ export const appRoutes: Route[] = [
|
|||
layout: 'empty'
|
||||
},
|
||||
children: [
|
||||
{path: 'home', loadChildren: () => import('app/modules/landing/home/home.module').then(m => m.LandingHomeModule)},
|
||||
{path: 'home', loadChildren: () => import('app/modules/landing/home/home.routes')},
|
||||
]
|
||||
},
|
||||
|
||||
|
@ -71,30 +71,30 @@ export const appRoutes: Route[] = [
|
|||
canActivateChild: [AuthGuard],
|
||||
component: LayoutComponent,
|
||||
resolve: {
|
||||
initialData: InitialDataResolver,
|
||||
initialData: initialDataResolver
|
||||
},
|
||||
children: [
|
||||
|
||||
// Dashboards
|
||||
{path: 'dashboards', children: [
|
||||
{path: 'project', loadChildren: () => import('app/modules/admin/dashboards/project/project.module').then(m => m.ProjectModule)},
|
||||
{path: 'analytics', loadChildren: () => import('app/modules/admin/dashboards/analytics/analytics.module').then(m => m.AnalyticsModule)},
|
||||
{path: 'finance', loadChildren: () => import('app/modules/admin/dashboards/finance/finance.module').then(m => m.FinanceModule)},
|
||||
{path: 'crypto', loadChildren: () => import('app/modules/admin/dashboards/crypto/crypto.module').then(m => m.CryptoModule)},
|
||||
{path: 'project', loadChildren: () => import('app/modules/admin/dashboards/project/project.routes')},
|
||||
{path: 'analytics', loadChildren: () => import('app/modules/admin/dashboards/analytics/analytics.routes')},
|
||||
{path: 'finance', loadChildren: () => import('app/modules/admin/dashboards/finance/finance.routes')},
|
||||
{path: 'crypto', loadChildren: () => import('app/modules/admin/dashboards/crypto/crypto.routes')},
|
||||
]},
|
||||
|
||||
// Apps
|
||||
{path: 'apps', children: [
|
||||
{path: 'academy', loadChildren: () => import('app/modules/admin/apps/academy/academy.module').then(m => m.AcademyModule)},
|
||||
{path: 'chat', loadChildren: () => import('app/modules/admin/apps/chat/chat.module').then(m => m.ChatModule)},
|
||||
{path: 'contacts', loadChildren: () => import('app/modules/admin/apps/contacts/contacts.module').then(m => m.ContactsModule)},
|
||||
{path: 'ecommerce', loadChildren: () => import('app/modules/admin/apps/ecommerce/ecommerce.module').then(m => m.ECommerceModule)},
|
||||
{path: 'file-manager', loadChildren: () => import('app/modules/admin/apps/file-manager/file-manager.module').then(m => m.FileManagerModule)},
|
||||
{path: 'help-center', loadChildren: () => import('app/modules/admin/apps/help-center/help-center.module').then(m => m.HelpCenterModule)},
|
||||
{path: 'mailbox', loadChildren: () => import('app/modules/admin/apps/mailbox/mailbox.module').then(m => m.MailboxModule)},
|
||||
{path: 'notes', loadChildren: () => import('app/modules/admin/apps/notes/notes.module').then(m => m.NotesModule)},
|
||||
{path: 'scrumboard', loadChildren: () => import('app/modules/admin/apps/scrumboard/scrumboard.module').then(m => m.ScrumboardModule)},
|
||||
{path: 'tasks', loadChildren: () => import('app/modules/admin/apps/tasks/tasks.module').then(m => m.TasksModule)},
|
||||
{path: 'academy', loadChildren: () => import('app/modules/admin/apps/academy/academy.routes')},
|
||||
{path: 'chat', loadChildren: () => import('app/modules/admin/apps/chat/chat.routes')},
|
||||
{path: 'contacts', loadChildren: () => import('app/modules/admin/apps/contacts/contacts.routes')},
|
||||
{path: 'ecommerce', loadChildren: () => import('app/modules/admin/apps/ecommerce/ecommerce.routes')},
|
||||
{path: 'file-manager', loadChildren: () => import('app/modules/admin/apps/file-manager/file-manager.routes')},
|
||||
{path: 'help-center', loadChildren: () => import('app/modules/admin/apps/help-center/help-center.routes')},
|
||||
{path: 'mailbox', loadChildren: () => import('app/modules/admin/apps/mailbox/mailbox.routes')},
|
||||
{path: 'notes', loadChildren: () => import('app/modules/admin/apps/notes/notes.routes')},
|
||||
{path: 'scrumboard', loadChildren: () => import('app/modules/admin/apps/scrumboard/scrumboard.routes')},
|
||||
{path: 'tasks', loadChildren: () => import('app/modules/admin/apps/tasks/tasks.routes')},
|
||||
]},
|
||||
|
||||
// Pages
|
||||
|
|
|
@ -44,7 +44,6 @@ export class AuthInterceptor implements HttpInterceptor
|
|||
return next.handle(newReq).pipe(
|
||||
catchError((error) =>
|
||||
{
|
||||
|
||||
// Catch "401 Unauthorized" responses
|
||||
if ( error instanceof HttpErrorResponse && error.status === 401 )
|
||||
{
|
||||
|
|
|
@ -76,7 +76,6 @@ export class AuthService
|
|||
return this._httpClient.post('api/auth/sign-in', credentials).pipe(
|
||||
switchMap((response: any) =>
|
||||
{
|
||||
|
||||
// Store the access token in the local storage
|
||||
this.accessToken = response.accessToken;
|
||||
|
||||
|
@ -108,7 +107,6 @@ export class AuthService
|
|||
),
|
||||
switchMap((response: any) =>
|
||||
{
|
||||
|
||||
// Replace the access token with the new one if it's available on
|
||||
// the response object.
|
||||
//
|
||||
|
|
|
@ -11,7 +11,6 @@ export const AuthGuard: CanActivateFn | CanActivateChildFn = (route, state) =>
|
|||
return inject(AuthService).check().pipe(
|
||||
switchMap((authenticated) =>
|
||||
{
|
||||
|
||||
// If the user is not authenticated...
|
||||
if ( !authenticated )
|
||||
{
|
||||
|
|
|
@ -11,7 +11,6 @@ export const NoAuthGuard: CanActivateFn | CanActivateChildFn = (route, state) =>
|
|||
return inject(AuthService).check().pipe(
|
||||
switchMap((authenticated) =>
|
||||
{
|
||||
|
||||
// If the user is authenticated...
|
||||
if ( authenticated )
|
||||
{
|
||||
|
|
|
@ -47,7 +47,6 @@ export class LanguagesComponent implements OnInit, OnDestroy
|
|||
// Subscribe to language changes
|
||||
this._translocoService.langChanges$.subscribe((activeLang) =>
|
||||
{
|
||||
|
||||
// Get the active lang
|
||||
this.activeLang = activeLang;
|
||||
|
||||
|
@ -133,7 +132,6 @@ export class LanguagesComponent implements OnInit, OnDestroy
|
|||
this._translocoService.selectTranslate('Project').pipe(take(1))
|
||||
.subscribe((translation) =>
|
||||
{
|
||||
|
||||
// Set the title
|
||||
projectDashboardItem.title = translation;
|
||||
|
||||
|
@ -149,7 +147,6 @@ export class LanguagesComponent implements OnInit, OnDestroy
|
|||
this._translocoService.selectTranslate('Analytics').pipe(take(1))
|
||||
.subscribe((translation) =>
|
||||
{
|
||||
|
||||
// Set the title
|
||||
analyticsDashboardItem.title = translation;
|
||||
|
||||
|
|
|
@ -55,7 +55,6 @@ export class MessagesComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((messages: Message[]) =>
|
||||
{
|
||||
|
||||
// Load the messages
|
||||
this.messages = messages;
|
||||
|
||||
|
|
|
@ -58,7 +58,6 @@ export class MessagesService
|
|||
switchMap(messages => this._httpClient.post<Message>('api/common/messages', {message}).pipe(
|
||||
map((newMessage) =>
|
||||
{
|
||||
|
||||
// Update the messages with the new message
|
||||
this._messages.next([...messages, newMessage]);
|
||||
|
||||
|
@ -85,7 +84,6 @@ export class MessagesService
|
|||
}).pipe(
|
||||
map((updatedMessage: Message) =>
|
||||
{
|
||||
|
||||
// Find the index of the updated message
|
||||
const index = messages.findIndex(item => item.id === id);
|
||||
|
||||
|
@ -114,7 +112,6 @@ export class MessagesService
|
|||
switchMap(messages => this._httpClient.delete<boolean>('api/common/messages', {params: {id}}).pipe(
|
||||
map((isDeleted: boolean) =>
|
||||
{
|
||||
|
||||
// Find the index of the deleted message
|
||||
const index = messages.findIndex(item => item.id === id);
|
||||
|
||||
|
@ -141,7 +138,6 @@ export class MessagesService
|
|||
switchMap(messages => this._httpClient.get<boolean>('api/common/messages/mark-all-as-read').pipe(
|
||||
map((isUpdated: boolean) =>
|
||||
{
|
||||
|
||||
// Go through all messages and set them as read
|
||||
messages.forEach((message, index) =>
|
||||
{
|
||||
|
|
|
@ -55,7 +55,6 @@ export class NotificationsComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((notifications: Notification[]) =>
|
||||
{
|
||||
|
||||
// Load the notifications
|
||||
this.notifications = notifications;
|
||||
|
||||
|
|
|
@ -58,7 +58,6 @@ export class NotificationsService
|
|||
switchMap(notifications => this._httpClient.post<Notification>('api/common/notifications', {notification}).pipe(
|
||||
map((newNotification) =>
|
||||
{
|
||||
|
||||
// Update the notifications with the new notification
|
||||
this._notifications.next([...notifications, newNotification]);
|
||||
|
||||
|
@ -85,7 +84,6 @@ export class NotificationsService
|
|||
}).pipe(
|
||||
map((updatedNotification: Notification) =>
|
||||
{
|
||||
|
||||
// Find the index of the updated notification
|
||||
const index = notifications.findIndex(item => item.id === id);
|
||||
|
||||
|
@ -114,7 +112,6 @@ export class NotificationsService
|
|||
switchMap(notifications => this._httpClient.delete<boolean>('api/common/notifications', {params: {id}}).pipe(
|
||||
map((isDeleted: boolean) =>
|
||||
{
|
||||
|
||||
// Find the index of the deleted notification
|
||||
const index = notifications.findIndex(item => item.id === id);
|
||||
|
||||
|
@ -141,7 +138,6 @@ export class NotificationsService
|
|||
switchMap(notifications => this._httpClient.get<boolean>('api/common/notifications/mark-all-as-read').pipe(
|
||||
map((isUpdated: boolean) =>
|
||||
{
|
||||
|
||||
// Go through all notifications and set them as read
|
||||
notifications.forEach((notification, index) =>
|
||||
{
|
||||
|
|
|
@ -72,10 +72,8 @@ export class QuickChatComponent implements OnInit, AfterViewInit, OnDestroy
|
|||
// This doesn't need to trigger Angular's change detection by itself
|
||||
this._ngZone.runOutsideAngular(() =>
|
||||
{
|
||||
|
||||
setTimeout(() =>
|
||||
{
|
||||
|
||||
// Set the height to 'auto' so we can correctly read the scrollHeight
|
||||
this.messageInput.nativeElement.style.height = 'auto';
|
||||
|
||||
|
|
|
@ -65,7 +65,6 @@ export class QuickChatService
|
|||
return this._httpClient.get<Chat>('api/apps/chat/chat', {params: {id}}).pipe(
|
||||
map((chat) =>
|
||||
{
|
||||
|
||||
// Update the chat
|
||||
this._chat.next(chat);
|
||||
|
||||
|
@ -74,7 +73,6 @@ export class QuickChatService
|
|||
}),
|
||||
switchMap((chat) =>
|
||||
{
|
||||
|
||||
if ( !chat )
|
||||
{
|
||||
return throwError('Could not found chat with id of ' + id + '!');
|
||||
|
|
|
@ -76,7 +76,6 @@ export class SearchComponent implements OnChanges, OnInit, OnDestroy
|
|||
// Give Angular time to complete the change detection cycle
|
||||
setTimeout(() =>
|
||||
{
|
||||
|
||||
// Focus to the input element
|
||||
value.nativeElement.focus();
|
||||
});
|
||||
|
@ -126,7 +125,6 @@ export class SearchComponent implements OnChanges, OnInit, OnDestroy
|
|||
takeUntil(this._unsubscribeAll),
|
||||
map((value) =>
|
||||
{
|
||||
|
||||
// Set the resultSets to null if there is no value or
|
||||
// the length of the value is smaller than the minLength
|
||||
// so the autocomplete panel can be closed
|
||||
|
@ -147,7 +145,6 @@ export class SearchComponent implements OnChanges, OnInit, OnDestroy
|
|||
this._httpClient.post('api/common/search', {query: value})
|
||||
.subscribe((resultSets: any) =>
|
||||
{
|
||||
|
||||
// Store the result sets
|
||||
this.resultSets = resultSets;
|
||||
|
||||
|
|
|
@ -67,7 +67,6 @@ export class SettingsComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((config: AppConfig) =>
|
||||
{
|
||||
|
||||
// Store the config
|
||||
this.config = config;
|
||||
});
|
||||
|
@ -102,7 +101,6 @@ export class SettingsComponent implements OnInit, OnDestroy
|
|||
queryParamsHandling: 'merge',
|
||||
}).then(() =>
|
||||
{
|
||||
|
||||
// Set the config
|
||||
this._fuseConfigService.config = {layout};
|
||||
});
|
||||
|
|
|
@ -71,7 +71,6 @@ export class ShortcutsComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((shortcuts: Shortcut[]) =>
|
||||
{
|
||||
|
||||
// Load the shortcuts
|
||||
this.shortcuts = shortcuts;
|
||||
|
||||
|
|
|
@ -58,7 +58,6 @@ export class ShortcutsService
|
|||
switchMap(shortcuts => this._httpClient.post<Shortcut>('api/common/shortcuts', {shortcut}).pipe(
|
||||
map((newShortcut) =>
|
||||
{
|
||||
|
||||
// Update the shortcuts with the new shortcut
|
||||
this._shortcuts.next([...shortcuts, newShortcut]);
|
||||
|
||||
|
@ -85,7 +84,6 @@ export class ShortcutsService
|
|||
}).pipe(
|
||||
map((updatedShortcut: Shortcut) =>
|
||||
{
|
||||
|
||||
// Find the index of the updated shortcut
|
||||
const index = shortcuts.findIndex(item => item.id === id);
|
||||
|
||||
|
@ -114,7 +112,6 @@ export class ShortcutsService
|
|||
switchMap(shortcuts => this._httpClient.delete<boolean>('api/common/shortcuts', {params: {id}}).pipe(
|
||||
map((isDeleted: boolean) =>
|
||||
{
|
||||
|
||||
// Find the index of the deleted shortcut
|
||||
const index = shortcuts.findIndex(item => item.id === id);
|
||||
|
||||
|
|
|
@ -69,7 +69,6 @@ export class LayoutComponent implements OnInit, OnDestroy
|
|||
takeUntil(this._unsubscribeAll),
|
||||
map(([config, mql]) =>
|
||||
{
|
||||
|
||||
const options = {
|
||||
scheme: config.scheme,
|
||||
theme : config.theme,
|
||||
|
@ -86,7 +85,6 @@ export class LayoutComponent implements OnInit, OnDestroy
|
|||
}),
|
||||
).subscribe((options) =>
|
||||
{
|
||||
|
||||
// Store the options
|
||||
this.scheme = options.scheme;
|
||||
this.theme = options.theme;
|
||||
|
@ -101,7 +99,6 @@ export class LayoutComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((config: AppConfig) =>
|
||||
{
|
||||
|
||||
// Store the config
|
||||
this.config = config;
|
||||
|
||||
|
@ -115,7 +112,6 @@ export class LayoutComponent implements OnInit, OnDestroy
|
|||
takeUntil(this._unsubscribeAll),
|
||||
).subscribe(() =>
|
||||
{
|
||||
|
||||
// Update the layout
|
||||
this._updateLayout();
|
||||
});
|
||||
|
@ -187,7 +183,6 @@ export class LayoutComponent implements OnInit, OnDestroy
|
|||
const paths = route.pathFromRoot;
|
||||
paths.forEach((path) =>
|
||||
{
|
||||
|
||||
// Check if there is a 'layout' data
|
||||
if ( path.routeConfig && path.routeConfig.data && path.routeConfig.data.layout )
|
||||
{
|
||||
|
|
|
@ -77,7 +77,6 @@ export class CenteredLayoutComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(({matchingAliases}) =>
|
||||
{
|
||||
|
||||
// Check if the screen is small
|
||||
this.isScreenSmall = !matchingAliases.includes('md');
|
||||
});
|
||||
|
|
|
@ -78,7 +78,6 @@ export class EnterpriseLayoutComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(({matchingAliases}) =>
|
||||
{
|
||||
|
||||
// Check if the screen is small
|
||||
this.isScreenSmall = !matchingAliases.includes('md');
|
||||
});
|
||||
|
|
|
@ -77,7 +77,6 @@ export class MaterialLayoutComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(({matchingAliases}) =>
|
||||
{
|
||||
|
||||
// Check if the screen is small
|
||||
this.isScreenSmall = !matchingAliases.includes('md');
|
||||
});
|
||||
|
|
|
@ -78,7 +78,6 @@ export class ModernLayoutComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(({matchingAliases}) =>
|
||||
{
|
||||
|
||||
// Check if the screen is small
|
||||
this.isScreenSmall = !matchingAliases.includes('md');
|
||||
});
|
||||
|
|
|
@ -78,7 +78,6 @@ export class ClassicLayoutComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(({matchingAliases}) =>
|
||||
{
|
||||
|
||||
// Check if the screen is small
|
||||
this.isScreenSmall = !matchingAliases.includes('md');
|
||||
});
|
||||
|
|
|
@ -90,7 +90,6 @@ export class ClassyLayoutComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(({matchingAliases}) =>
|
||||
{
|
||||
|
||||
// Check if the screen is small
|
||||
this.isScreenSmall = !matchingAliases.includes('md');
|
||||
});
|
||||
|
|
|
@ -78,7 +78,6 @@ export class CompactLayoutComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(({matchingAliases}) =>
|
||||
{
|
||||
|
||||
// Check if the screen is small
|
||||
this.isScreenSmall = !matchingAliases.includes('md');
|
||||
});
|
||||
|
|
|
@ -79,7 +79,6 @@ export class DenseLayoutComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(({matchingAliases}) =>
|
||||
{
|
||||
|
||||
// Check if the screen is small
|
||||
this.isScreenSmall = !matchingAliases.includes('md');
|
||||
|
||||
|
|
|
@ -90,7 +90,6 @@ export class FuturisticLayoutComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(({matchingAliases}) =>
|
||||
{
|
||||
|
||||
// Check if the screen is small
|
||||
this.isScreenSmall = !matchingAliases.includes('md');
|
||||
});
|
||||
|
|
|
@ -78,7 +78,6 @@ export class ThinLayoutComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(({matchingAliases}) =>
|
||||
{
|
||||
|
||||
// Check if the screen is small
|
||||
this.isScreenSmall = !matchingAliases.includes('md');
|
||||
});
|
||||
|
|
|
@ -37,7 +37,6 @@ export class AcademyMockApi
|
|||
.onGet('api/apps/academy/categories')
|
||||
.reply(() =>
|
||||
{
|
||||
|
||||
// Clone the categories
|
||||
const categories = cloneDeep(this._categories);
|
||||
|
||||
|
@ -54,7 +53,6 @@ export class AcademyMockApi
|
|||
.onGet('api/apps/academy/courses')
|
||||
.reply(() =>
|
||||
{
|
||||
|
||||
// Clone the courses
|
||||
const courses = cloneDeep(this._courses);
|
||||
|
||||
|
@ -68,7 +66,6 @@ export class AcademyMockApi
|
|||
.onGet('api/apps/academy/courses/course')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id from the params
|
||||
const id = request.params.get('id');
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ export class ChatMockApi
|
|||
.onGet('api/apps/chat/chats')
|
||||
.reply(() =>
|
||||
{
|
||||
|
||||
// Clone the chats
|
||||
const chats = cloneDeep(this._chats);
|
||||
|
||||
|
@ -67,7 +66,6 @@ export class ChatMockApi
|
|||
.onGet('api/apps/chat/chat')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the chat id
|
||||
const id = request.params.get('id');
|
||||
|
||||
|
@ -88,7 +86,6 @@ export class ChatMockApi
|
|||
.onPatch('api/apps/chat/chat')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id and chat
|
||||
const id = request.body.id;
|
||||
const chat = cloneDeep(request.body.chat);
|
||||
|
@ -99,7 +96,6 @@ export class ChatMockApi
|
|||
// Find the chat and update it
|
||||
this._chats.forEach((item, index, chats) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
// Update the chat
|
||||
|
@ -121,7 +117,6 @@ export class ChatMockApi
|
|||
.onGet('api/apps/chat/contacts')
|
||||
.reply(() =>
|
||||
{
|
||||
|
||||
// Clone the contacts
|
||||
let contacts = cloneDeep(this._contacts);
|
||||
|
||||
|
@ -142,7 +137,6 @@ export class ChatMockApi
|
|||
.onGet('api/apps/chat/contact')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the contact id
|
||||
const id = request.params.get('id');
|
||||
|
||||
|
@ -163,7 +157,6 @@ export class ChatMockApi
|
|||
.onGet('api/apps/chat/profile')
|
||||
.reply(() =>
|
||||
{
|
||||
|
||||
// Clone the profile
|
||||
const profile = cloneDeep(this._profile);
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@ export class ContactsMockApi
|
|||
.onGet('api/apps/contacts/all')
|
||||
.reply(() =>
|
||||
{
|
||||
|
||||
// Clone the contacts
|
||||
const contacts = cloneDeep(this._contacts);
|
||||
|
||||
|
@ -56,7 +55,6 @@ export class ContactsMockApi
|
|||
.onGet('api/apps/contacts/search')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the search query
|
||||
const query = request.params.get('query');
|
||||
|
||||
|
@ -84,7 +82,6 @@ export class ContactsMockApi
|
|||
.onGet('api/apps/contacts/contact')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id from the params
|
||||
const id = request.params.get('id');
|
||||
|
||||
|
@ -105,7 +102,6 @@ export class ContactsMockApi
|
|||
.onPost('api/apps/contacts/contact')
|
||||
.reply(() =>
|
||||
{
|
||||
|
||||
// Generate a new contact
|
||||
const newContact = {
|
||||
id : FuseMockApiUtils.guid(),
|
||||
|
@ -137,7 +133,6 @@ export class ContactsMockApi
|
|||
.onPatch('api/apps/contacts/contact')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id and contact
|
||||
const id = request.body.id;
|
||||
const contact = cloneDeep(request.body.contact);
|
||||
|
@ -148,7 +143,6 @@ export class ContactsMockApi
|
|||
// Find the contact and update it
|
||||
this._contacts.forEach((item, index, contacts) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
// Update the contact
|
||||
|
@ -170,14 +164,12 @@ export class ContactsMockApi
|
|||
.onDelete('api/apps/contacts/contact')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id
|
||||
const id = request.params.get('id');
|
||||
|
||||
// Find the contact and delete it
|
||||
this._contacts.forEach((item, index) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
this._contacts.splice(index, 1);
|
||||
|
@ -209,7 +201,6 @@ export class ContactsMockApi
|
|||
.onPost('api/apps/contacts/tag')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the tag
|
||||
const newTag = cloneDeep(request.body.tag);
|
||||
|
||||
|
@ -230,7 +221,6 @@ export class ContactsMockApi
|
|||
.onPatch('api/apps/contacts/tag')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id and tag
|
||||
const id = request.body.id;
|
||||
const tag = cloneDeep(request.body.tag);
|
||||
|
@ -241,7 +231,6 @@ export class ContactsMockApi
|
|||
// Find the tag and update it
|
||||
this._tags.forEach((item, index, tags) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
// Update the tag
|
||||
|
@ -263,14 +252,12 @@ export class ContactsMockApi
|
|||
.onDelete('api/apps/contacts/tag')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id
|
||||
const id = request.params.get('id');
|
||||
|
||||
// Find the tag and delete it
|
||||
this._tags.forEach((item, index) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
this._tags.splice(index, 1);
|
||||
|
@ -304,7 +291,6 @@ export class ContactsMockApi
|
|||
// Return a new promise
|
||||
new Promise((resolve, reject) =>
|
||||
{
|
||||
|
||||
// Create a new reader
|
||||
const reader = new FileReader();
|
||||
|
||||
|
@ -329,7 +315,6 @@ export class ContactsMockApi
|
|||
.onPost('api/apps/contacts/avatar')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id and avatar
|
||||
const id = request.body.id;
|
||||
const avatar = request.body.avatar;
|
||||
|
@ -346,11 +331,9 @@ export class ContactsMockApi
|
|||
return from(readAsDataURL(avatar)).pipe(
|
||||
map((path) =>
|
||||
{
|
||||
|
||||
// Find the contact and update it
|
||||
this._contacts.forEach((item, index, contacts) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
// Update the avatar
|
||||
|
|
|
@ -53,7 +53,6 @@ export class ECommerceInventoryMockApi
|
|||
.onGet('api/apps/ecommerce/inventory/products', 300)
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get available queries
|
||||
const search = request.params.get('search');
|
||||
const sort = request.params.get('sort') || 'name';
|
||||
|
@ -141,7 +140,6 @@ export class ECommerceInventoryMockApi
|
|||
.onGet('api/apps/ecommerce/inventory/product')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id from the params
|
||||
const id = request.params.get('id');
|
||||
|
||||
|
@ -162,7 +160,6 @@ export class ECommerceInventoryMockApi
|
|||
.onPost('api/apps/ecommerce/inventory/product')
|
||||
.reply(() =>
|
||||
{
|
||||
|
||||
// Generate a new product
|
||||
const newProduct = {
|
||||
id : FuseMockApiUtils.guid(),
|
||||
|
@ -200,7 +197,6 @@ export class ECommerceInventoryMockApi
|
|||
.onPatch('api/apps/ecommerce/inventory/product')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id and product
|
||||
const id = request.body.id;
|
||||
const product = cloneDeep(request.body.product);
|
||||
|
@ -211,7 +207,6 @@ export class ECommerceInventoryMockApi
|
|||
// Find the product and update it
|
||||
this._products.forEach((item, index, products) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
// Update the product
|
||||
|
@ -233,14 +228,12 @@ export class ECommerceInventoryMockApi
|
|||
.onDelete('api/apps/ecommerce/inventory/product')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id
|
||||
const id = request.params.get('id');
|
||||
|
||||
// Find the product and delete it
|
||||
this._products.forEach((item, index) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
this._products.splice(index, 1);
|
||||
|
@ -265,7 +258,6 @@ export class ECommerceInventoryMockApi
|
|||
.onPost('api/apps/ecommerce/inventory/tag')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the tag
|
||||
const newTag = cloneDeep(request.body.tag);
|
||||
|
||||
|
@ -286,7 +278,6 @@ export class ECommerceInventoryMockApi
|
|||
.onPatch('api/apps/ecommerce/inventory/tag')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id and tag
|
||||
const id = request.body.id;
|
||||
const tag = cloneDeep(request.body.tag);
|
||||
|
@ -297,7 +288,6 @@ export class ECommerceInventoryMockApi
|
|||
// Find the tag and update it
|
||||
this._tags.forEach((item, index, tags) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
// Update the tag
|
||||
|
@ -319,14 +309,12 @@ export class ECommerceInventoryMockApi
|
|||
.onDelete('api/apps/ecommerce/inventory/tag')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id
|
||||
const id = request.params.get('id');
|
||||
|
||||
// Find the tag and delete it
|
||||
this._tags.forEach((item, index) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
this._tags.splice(index, 1);
|
||||
|
|
|
@ -35,7 +35,6 @@ export class FileManagerMockApi
|
|||
.onGet('api/apps/file-manager')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Clone the items
|
||||
let items = cloneDeep(this._items);
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@ export class HelpCenterMockApi
|
|||
.onGet('api/apps/help-center/faqs')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the category slug
|
||||
const slug = request.params.get('slug');
|
||||
|
||||
|
@ -58,7 +57,6 @@ export class HelpCenterMockApi
|
|||
// Go through each category and set the results
|
||||
categories.forEach((category) =>
|
||||
{
|
||||
|
||||
results.push(
|
||||
{
|
||||
...category,
|
||||
|
@ -93,7 +91,6 @@ export class HelpCenterMockApi
|
|||
.onGet('api/apps/help-center/guides')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the slug & limit
|
||||
const slug = request.params.get('slug');
|
||||
const limit = request.params.get('limit');
|
||||
|
@ -116,7 +113,6 @@ export class HelpCenterMockApi
|
|||
// Go through each category and set the results
|
||||
categories.forEach((category) =>
|
||||
{
|
||||
|
||||
results.push(
|
||||
{
|
||||
...category,
|
||||
|
@ -153,7 +149,6 @@ export class HelpCenterMockApi
|
|||
.onGet('api/apps/help-center/guide')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the slugs
|
||||
const categorySlug = request.params.get('categorySlug');
|
||||
const guideSlug = request.params.get('guideSlug');
|
||||
|
|
|
@ -46,7 +46,6 @@ export class MailboxMockApi
|
|||
.onPatch('api/apps/mailbox/settings')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the settings
|
||||
const settings = cloneDeep(request.body.settings);
|
||||
|
||||
|
@ -64,13 +63,11 @@ export class MailboxMockApi
|
|||
.onGet('api/apps/mailbox/folders')
|
||||
.reply(() =>
|
||||
{
|
||||
|
||||
let count = 0;
|
||||
|
||||
// Iterate through the folders
|
||||
this._folders.forEach((folder) =>
|
||||
{
|
||||
|
||||
// Get the mails of this folder
|
||||
const mails = this._mails.filter(mail => mail.folder === folder.id);
|
||||
|
||||
|
@ -92,7 +89,6 @@ export class MailboxMockApi
|
|||
// Go through the mails and count the unread ones
|
||||
mails.forEach((mail) =>
|
||||
{
|
||||
|
||||
if ( mail.unread )
|
||||
{
|
||||
count++;
|
||||
|
@ -132,7 +128,6 @@ export class MailboxMockApi
|
|||
.onPost('api/apps/mailbox/label')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the label
|
||||
const label = cloneDeep(request.body.label);
|
||||
|
||||
|
@ -177,7 +172,6 @@ export class MailboxMockApi
|
|||
.onPatch('api/apps/mailbox/label')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id and label
|
||||
const id = request.body.id;
|
||||
const label = cloneDeep(request.body.label);
|
||||
|
@ -188,7 +182,6 @@ export class MailboxMockApi
|
|||
// Find the label and update it
|
||||
this._labels.forEach((item, index, labels) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
// Update the slug
|
||||
|
@ -216,7 +209,6 @@ export class MailboxMockApi
|
|||
.onDelete('api/apps/mailbox/label')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id
|
||||
const id = request.params.get('id');
|
||||
|
||||
|
@ -244,7 +236,6 @@ export class MailboxMockApi
|
|||
.onGet('api/apps/mailbox/mails', 625)
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// First, decide if mails are requested by folder, filter or label
|
||||
const byFolder = request.params.get('folder');
|
||||
const byFilter = request.params.get('filter');
|
||||
|
@ -256,7 +247,6 @@ export class MailboxMockApi
|
|||
// Filter the mails depending on the requested by type
|
||||
mails = mails.filter((mail) =>
|
||||
{
|
||||
|
||||
if ( byFolder )
|
||||
{
|
||||
return mail.folder === this._folders.find(folder => folder.slug === byFolder).id;
|
||||
|
@ -342,7 +332,6 @@ export class MailboxMockApi
|
|||
.onGet('api/apps/mailbox/mail')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id from the params
|
||||
const id = request.params.get('id');
|
||||
|
||||
|
@ -365,7 +354,6 @@ export class MailboxMockApi
|
|||
.onPatch('api/apps/mailbox/mail')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id and mail
|
||||
const id = request.body.id;
|
||||
const mail = cloneDeep(request.body.mail);
|
||||
|
@ -376,7 +364,6 @@ export class MailboxMockApi
|
|||
// Find the mail and update it
|
||||
this._mails.forEach((item, index, mails) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
// Update the mail
|
||||
|
|
|
@ -47,7 +47,6 @@ export class NotesMockApi
|
|||
.onPost('api/apps/notes/labels')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Create a new label
|
||||
const label = {
|
||||
id : FuseMockApiUtils.guid(),
|
||||
|
@ -70,7 +69,6 @@ export class NotesMockApi
|
|||
.onPatch('api/apps/notes/labels')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get label
|
||||
const updatedLabel = request.body.label;
|
||||
|
||||
|
@ -101,7 +99,6 @@ export class NotesMockApi
|
|||
.onDelete('api/apps/notes/labels')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get label id
|
||||
const id = request.params.get('id');
|
||||
|
||||
|
@ -127,7 +124,6 @@ export class NotesMockApi
|
|||
.onPost('api/apps/notes/tasks')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get note and task
|
||||
let updatedNote = request.body.note;
|
||||
const task = request.body.task;
|
||||
|
@ -173,7 +169,6 @@ export class NotesMockApi
|
|||
.onGet('api/apps/notes/all')
|
||||
.reply(() =>
|
||||
{
|
||||
|
||||
// Clone the labels and notes
|
||||
const labels = cloneDeep(this._labels);
|
||||
let notes = cloneDeep(this._notes);
|
||||
|
@ -199,7 +194,6 @@ export class NotesMockApi
|
|||
.onPost('api/apps/notes')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get note
|
||||
const note = request.body.note;
|
||||
|
||||
|
@ -222,7 +216,6 @@ export class NotesMockApi
|
|||
.onPatch('api/apps/notes')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get note
|
||||
const updatedNote = request.body.updatedNote;
|
||||
|
||||
|
@ -252,14 +245,12 @@ export class NotesMockApi
|
|||
.onDelete('api/apps/notes')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id
|
||||
const id = request.params.get('id');
|
||||
|
||||
// Find the note and delete it
|
||||
this._notes.forEach((item, index) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
this._notes.splice(index, 1);
|
||||
|
|
|
@ -40,7 +40,6 @@ export class ScrumboardMockApi
|
|||
.onGet('api/apps/scrumboard/boards')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Clone the boards
|
||||
let boards = cloneDeep(this._boards);
|
||||
|
||||
|
@ -63,7 +62,6 @@ export class ScrumboardMockApi
|
|||
.onGet('api/apps/scrumboard/board')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id
|
||||
const id = request.params.get('id');
|
||||
|
||||
|
@ -104,7 +102,6 @@ export class ScrumboardMockApi
|
|||
.onPost('api/apps/scrumboard/board/list')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the list
|
||||
const newList = cloneDeep(request.body.list);
|
||||
|
||||
|
@ -127,7 +124,6 @@ export class ScrumboardMockApi
|
|||
.onPatch('api/apps/scrumboard/board/list')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the list
|
||||
const list = cloneDeep(request.body.list);
|
||||
|
||||
|
@ -137,7 +133,6 @@ export class ScrumboardMockApi
|
|||
// Find the list and update it
|
||||
this._lists.forEach((item, index, lists) =>
|
||||
{
|
||||
|
||||
if ( item.id === list.id )
|
||||
{
|
||||
// Update the list
|
||||
|
@ -161,7 +156,6 @@ export class ScrumboardMockApi
|
|||
.onPatch('api/apps/scrumboard/board/lists')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the lists
|
||||
const lists = cloneDeep(request.body.lists);
|
||||
|
||||
|
@ -171,7 +165,6 @@ export class ScrumboardMockApi
|
|||
// Go through the lists
|
||||
lists.forEach((item) =>
|
||||
{
|
||||
|
||||
// Find the list
|
||||
const index = this._lists.findIndex(list => item.id === list.id);
|
||||
|
||||
|
@ -195,7 +188,6 @@ export class ScrumboardMockApi
|
|||
.onDelete('api/apps/scrumboard/board/list')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id
|
||||
const id = request.params.get('id');
|
||||
|
||||
|
@ -219,7 +211,6 @@ export class ScrumboardMockApi
|
|||
.onPut('api/apps/scrumboard/board/card')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the card
|
||||
const newCard = cloneDeep(request.body.card);
|
||||
|
||||
|
@ -242,7 +233,6 @@ export class ScrumboardMockApi
|
|||
.onPatch('api/apps/scrumboard/board/card')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id and card
|
||||
const id = request.body.id;
|
||||
const card = cloneDeep(request.body.card);
|
||||
|
@ -256,7 +246,6 @@ export class ScrumboardMockApi
|
|||
// Find the card and update it
|
||||
this._cards.forEach((item, index, cards) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
// Update the card
|
||||
|
@ -283,7 +272,6 @@ export class ScrumboardMockApi
|
|||
.onPatch('api/apps/scrumboard/board/cards')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the cards
|
||||
const cards = cloneDeep(request.body.cards);
|
||||
|
||||
|
@ -293,7 +281,6 @@ export class ScrumboardMockApi
|
|||
// Go through the cards
|
||||
cards.forEach((item) =>
|
||||
{
|
||||
|
||||
// Find the card
|
||||
const index = this._cards.findIndex(card => item.id === card.id);
|
||||
|
||||
|
@ -323,7 +310,6 @@ export class ScrumboardMockApi
|
|||
.onDelete('api/apps/scrumboard/board/card')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id
|
||||
const id = request.params.get('id');
|
||||
|
||||
|
@ -344,14 +330,12 @@ export class ScrumboardMockApi
|
|||
.onPatch('api/apps/scrumboard/board/card/positions')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the cards
|
||||
const cards = request.body.cards;
|
||||
|
||||
// Go through the cards
|
||||
this._cards.forEach((card) =>
|
||||
{
|
||||
|
||||
// Find this card's index within the cards array that comes with the request
|
||||
// and assign that index as the new position number for the card
|
||||
card.position = cards.findIndex(item => item.id === card.id && item.listId === card.listId && item.boardId === card.boardId);
|
||||
|
@ -373,7 +357,6 @@ export class ScrumboardMockApi
|
|||
.onGet('api/apps/scrumboard/board/labels')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the board id
|
||||
const boardId = request.params.get('boardId');
|
||||
|
||||
|
@ -393,7 +376,6 @@ export class ScrumboardMockApi
|
|||
.onPut('api/apps/scrumboard/board/label')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the label
|
||||
const newLabel = cloneDeep(request.body.label);
|
||||
|
||||
|
@ -416,7 +398,6 @@ export class ScrumboardMockApi
|
|||
.onPatch('api/apps/scrumboard/board/label')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id and label
|
||||
const id = request.body.id;
|
||||
const label = cloneDeep(request.body.label);
|
||||
|
@ -427,7 +408,6 @@ export class ScrumboardMockApi
|
|||
// Find the label and update it
|
||||
this._labels.forEach((item, index, labels) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
// Update the label
|
||||
|
@ -451,7 +431,6 @@ export class ScrumboardMockApi
|
|||
.onDelete('api/apps/scrumboard/board/label')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id
|
||||
const id = request.params.get('id');
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ export class TasksMockApi
|
|||
.onPost('api/apps/tasks/tag')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the tag
|
||||
const newTag = cloneDeep(request.body.tag);
|
||||
|
||||
|
@ -70,7 +69,6 @@ export class TasksMockApi
|
|||
.onPatch('api/apps/tasks/tag')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id and tag
|
||||
const id = request.body.id;
|
||||
const tag = cloneDeep(request.body.tag);
|
||||
|
@ -81,7 +79,6 @@ export class TasksMockApi
|
|||
// Find the tag and update it
|
||||
this._tags.forEach((item, index, tags) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
// Update the tag
|
||||
|
@ -105,7 +102,6 @@ export class TasksMockApi
|
|||
.onDelete('api/apps/tasks/tag')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id
|
||||
const id = request.params.get('id');
|
||||
|
||||
|
@ -135,7 +131,6 @@ export class TasksMockApi
|
|||
.onGet('api/apps/tasks/all')
|
||||
.reply(() =>
|
||||
{
|
||||
|
||||
// Clone the tasks
|
||||
const tasks = cloneDeep(this._tasks);
|
||||
|
||||
|
@ -155,7 +150,6 @@ export class TasksMockApi
|
|||
.onGet('api/apps/tasks/search')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the search query
|
||||
const query = request.params.get('query');
|
||||
|
||||
|
@ -201,14 +195,12 @@ export class TasksMockApi
|
|||
.onPatch('api/apps/tasks/order')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the tasks
|
||||
const tasks = request.body.tasks;
|
||||
|
||||
// Go through the tasks
|
||||
this._tasks.forEach((task) =>
|
||||
{
|
||||
|
||||
// Find this task's index within the tasks array that comes with the request
|
||||
// and assign that index as the new order number for the task
|
||||
task.order = tasks.findIndex((item: any) => item.id === task.id);
|
||||
|
@ -230,7 +222,6 @@ export class TasksMockApi
|
|||
.onGet('api/apps/tasks/task')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id from the params
|
||||
const id = request.params.get('id');
|
||||
|
||||
|
@ -253,7 +244,6 @@ export class TasksMockApi
|
|||
.onPost('api/apps/tasks/task')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Generate a new task
|
||||
const newTask = {
|
||||
id : FuseMockApiUtils.guid(),
|
||||
|
@ -289,7 +279,6 @@ export class TasksMockApi
|
|||
.onPatch('api/apps/tasks/task')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id and task
|
||||
const id = request.body.id;
|
||||
const task = cloneDeep(request.body.task);
|
||||
|
@ -300,7 +289,6 @@ export class TasksMockApi
|
|||
// Find the task and update it
|
||||
this._tasks.forEach((item, index, tasks) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
// Update the task
|
||||
|
@ -324,7 +312,6 @@ export class TasksMockApi
|
|||
.onDelete('api/apps/tasks/task')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id
|
||||
const id = request.params.get('id');
|
||||
|
||||
|
|
|
@ -66,7 +66,6 @@ export class AuthMockApi
|
|||
.onPost('api/auth/sign-in', 1500)
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Sign in successful
|
||||
if ( request.body.email === 'hughes.brian@company.com' && request.body.password === 'admin' )
|
||||
{
|
||||
|
@ -94,7 +93,6 @@ export class AuthMockApi
|
|||
.onPost('api/auth/sign-in-with-token')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the access token
|
||||
const accessToken = request.body.accessToken;
|
||||
|
||||
|
@ -141,7 +139,6 @@ export class AuthMockApi
|
|||
.onPost('api/auth/unlock-session', 1500)
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Sign in successful
|
||||
if ( request.body.email === 'hughes.brian@company.com' && request.body.password === 'admin' )
|
||||
{
|
||||
|
|
|
@ -42,7 +42,6 @@ export class MessagesMockApi
|
|||
.onPost('api/common/messages')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the message
|
||||
const newMessage = cloneDeep(request.body.message);
|
||||
|
||||
|
@ -63,7 +62,6 @@ export class MessagesMockApi
|
|||
.onPatch('api/common/messages')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id and message
|
||||
const id = request.body.id;
|
||||
const message = cloneDeep(request.body.message);
|
||||
|
@ -74,7 +72,6 @@ export class MessagesMockApi
|
|||
// Find the message and update it
|
||||
this._messages.forEach((item: any, index: number, messages: any[]) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
// Update the message
|
||||
|
@ -96,7 +93,6 @@ export class MessagesMockApi
|
|||
.onDelete('api/common/messages')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id
|
||||
const id = request.params.get('id');
|
||||
|
||||
|
@ -123,11 +119,9 @@ export class MessagesMockApi
|
|||
.onGet('api/common/messages/mark-all-as-read')
|
||||
.reply(() =>
|
||||
{
|
||||
|
||||
// Go through all messages
|
||||
this._messages.forEach((item: any, index: number, messages: any[]) =>
|
||||
{
|
||||
|
||||
// Mark it as read
|
||||
messages[index].read = true;
|
||||
messages[index].seen = true;
|
||||
|
@ -144,7 +138,6 @@ export class MessagesMockApi
|
|||
.onPost('api/common/messages/toggle-read-status')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the message
|
||||
const message = cloneDeep(request.body.message);
|
||||
|
||||
|
@ -154,7 +147,6 @@ export class MessagesMockApi
|
|||
// Find the message and update it
|
||||
this._messages.forEach((item: any, index: number, messages: any[]) =>
|
||||
{
|
||||
|
||||
if ( item.id === message.id )
|
||||
{
|
||||
// Update the message
|
||||
|
|
|
@ -39,7 +39,6 @@ export class NavigationMockApi
|
|||
.onGet('api/common/navigation')
|
||||
.reply(() =>
|
||||
{
|
||||
|
||||
// Fill compact navigation children using the default navigation
|
||||
this._compactNavigation.forEach((compactNavItem) =>
|
||||
{
|
||||
|
|
|
@ -42,7 +42,6 @@ export class NotificationsMockApi
|
|||
.onPost('api/common/notifications')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the notification
|
||||
const newNotification = cloneDeep(request.body.notification);
|
||||
|
||||
|
@ -63,7 +62,6 @@ export class NotificationsMockApi
|
|||
.onPatch('api/common/notifications')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id and notification
|
||||
const id = request.body.id;
|
||||
const notification = cloneDeep(request.body.notification);
|
||||
|
@ -74,7 +72,6 @@ export class NotificationsMockApi
|
|||
// Find the notification and update it
|
||||
this._notifications.forEach((item: any, index: number, notifications: any[]) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
// Update the notification
|
||||
|
@ -96,7 +93,6 @@ export class NotificationsMockApi
|
|||
.onDelete('api/common/notifications')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id
|
||||
const id = request.params.get('id');
|
||||
|
||||
|
@ -123,11 +119,9 @@ export class NotificationsMockApi
|
|||
.onGet('api/common/notifications/mark-all-as-read')
|
||||
.reply(() =>
|
||||
{
|
||||
|
||||
// Go through all notifications
|
||||
this._notifications.forEach((item: any, index: number, notifications: any[]) =>
|
||||
{
|
||||
|
||||
// Mark it as read
|
||||
notifications[index].read = true;
|
||||
notifications[index].seen = true;
|
||||
|
@ -144,7 +138,6 @@ export class NotificationsMockApi
|
|||
.onPost('api/common/notifications/toggle-read-status')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the notification
|
||||
const notification = cloneDeep(request.body.notification);
|
||||
|
||||
|
@ -154,7 +147,6 @@ export class NotificationsMockApi
|
|||
// Find the notification and update it
|
||||
this._notifications.forEach((item: any, index: number, notifications: any[]) =>
|
||||
{
|
||||
|
||||
if ( item.id === notification.id )
|
||||
{
|
||||
// Update the notification
|
||||
|
|
|
@ -46,7 +46,6 @@ export class SearchMockApi
|
|||
.onPost('api/common/search')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the search query
|
||||
const query = cloneDeep(request.body.query.toLowerCase());
|
||||
|
||||
|
@ -78,7 +77,6 @@ export class SearchMockApi
|
|||
// Normalize the results
|
||||
contactsResults.forEach((result) =>
|
||||
{
|
||||
|
||||
// Add a link
|
||||
result.link = '/apps/contacts/' + result.id;
|
||||
|
||||
|
@ -100,7 +98,6 @@ export class SearchMockApi
|
|||
// Normalize the results
|
||||
pagesResults.forEach((result: any) =>
|
||||
{
|
||||
|
||||
// Add the page title as the value
|
||||
result.value = result.title;
|
||||
});
|
||||
|
@ -119,7 +116,6 @@ export class SearchMockApi
|
|||
// Normalize the results
|
||||
tasksResults.forEach((result) =>
|
||||
{
|
||||
|
||||
// Add a link
|
||||
result.link = '/apps/tasks/' + result.id;
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ export class ShortcutsMockApi
|
|||
.onPost('api/common/shortcuts')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the shortcut
|
||||
const newShortcut = cloneDeep(request.body.shortcut);
|
||||
|
||||
|
@ -63,7 +62,6 @@ export class ShortcutsMockApi
|
|||
.onPatch('api/common/shortcuts')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id and shortcut
|
||||
const id = request.body.id;
|
||||
const shortcut = cloneDeep(request.body.shortcut);
|
||||
|
@ -74,7 +72,6 @@ export class ShortcutsMockApi
|
|||
// Find the shortcut and update it
|
||||
this._shortcuts.forEach((item: any, index: number, shortcuts: any[]) =>
|
||||
{
|
||||
|
||||
if ( item.id === id )
|
||||
{
|
||||
// Update the shortcut
|
||||
|
@ -96,7 +93,6 @@ export class ShortcutsMockApi
|
|||
.onDelete('api/common/shortcuts')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the id
|
||||
const id = request.params.get('id');
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ export class UserMockApi
|
|||
.onPatch('api/common/user')
|
||||
.reply(({request}) =>
|
||||
{
|
||||
|
||||
// Get the user mock-api
|
||||
const user = cloneDeep(request.body.user);
|
||||
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatSidenavModule } from '@angular/material/sidenav';
|
||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||
import { MatTabsModule } from '@angular/material/tabs';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { AcademyComponent } from 'app/modules/admin/apps/academy/academy.component';
|
||||
|
||||
import { academyRoutes } from 'app/modules/admin/apps/academy/academy.routing';
|
||||
import { AcademyDetailsComponent } from 'app/modules/admin/apps/academy/details/details.component';
|
||||
import { AcademyListComponent } from 'app/modules/admin/apps/academy/list/list.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild(academyRoutes),
|
||||
MatButtonModule,
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
MatProgressBarModule,
|
||||
MatSelectModule,
|
||||
MatSidenavModule,
|
||||
MatSlideToggleModule,
|
||||
MatTooltipModule,
|
||||
MatTabsModule,
|
||||
AcademyComponent,
|
||||
AcademyDetailsComponent,
|
||||
AcademyListComponent,
|
||||
],
|
||||
})
|
||||
export class AcademyModule
|
||||
{
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
|
||||
import { AcademyService } from 'app/modules/admin/apps/academy/academy.service';
|
||||
import { Category, Course } from 'app/modules/admin/apps/academy/academy.types';
|
||||
import { catchError, Observable, throwError } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class AcademyCategoriesResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(private _academyService: AcademyService)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Category[]>
|
||||
{
|
||||
return this._academyService.getCategories();
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class AcademyCoursesResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(private _academyService: AcademyService)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Course[]>
|
||||
{
|
||||
return this._academyService.getCourses();
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class AcademyCourseResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(
|
||||
private _router: Router,
|
||||
private _academyService: AcademyService,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Course>
|
||||
{
|
||||
return this._academyService.getCourseById(route.paramMap.get('id'))
|
||||
.pipe(
|
||||
// Error here means the requested task is not available
|
||||
catchError((error) =>
|
||||
{
|
||||
|
||||
// Log the error
|
||||
console.error(error);
|
||||
|
||||
// Get the parent url
|
||||
const parentUrl = state.url.split('/').slice(0, -1).join('/');
|
||||
|
||||
// Navigate to there
|
||||
this._router.navigateByUrl(parentUrl);
|
||||
|
||||
// Throw an error
|
||||
return throwError(error);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
64
src/app/modules/admin/apps/academy/academy.routes.ts
Normal file
64
src/app/modules/admin/apps/academy/academy.routes.ts
Normal file
|
@ -0,0 +1,64 @@
|
|||
import { inject } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot, Routes } from '@angular/router';
|
||||
import { AcademyComponent } from 'app/modules/admin/apps/academy/academy.component';
|
||||
import { AcademyService } from 'app/modules/admin/apps/academy/academy.service';
|
||||
import { AcademyDetailsComponent } from 'app/modules/admin/apps/academy/details/details.component';
|
||||
import { AcademyListComponent } from 'app/modules/admin/apps/academy/list/list.component';
|
||||
import { catchError, throwError } from 'rxjs';
|
||||
|
||||
/**
|
||||
* Course resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
const courseResolver = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) =>
|
||||
{
|
||||
const academyService = inject(AcademyService);
|
||||
const router = inject(Router);
|
||||
|
||||
return academyService.getCourseById(route.paramMap.get('id')).pipe(
|
||||
// Error here means the requested course is not available
|
||||
catchError((error) =>
|
||||
{
|
||||
// Log the error
|
||||
console.error(error);
|
||||
|
||||
// Get the parent url
|
||||
const parentUrl = state.url.split('/').slice(0, -1).join('/');
|
||||
|
||||
// Navigate to there
|
||||
router.navigateByUrl(parentUrl);
|
||||
|
||||
// Throw an error
|
||||
return throwError(error);
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
export default [
|
||||
{
|
||||
path : '',
|
||||
component: AcademyComponent,
|
||||
resolve : {
|
||||
categories: () => inject(AcademyService).getCategories(),
|
||||
},
|
||||
children : [
|
||||
{
|
||||
path : '',
|
||||
pathMatch: 'full',
|
||||
component: AcademyListComponent,
|
||||
resolve : {
|
||||
courses: () => inject(AcademyService).getCourses(),
|
||||
},
|
||||
},
|
||||
{
|
||||
path : ':id',
|
||||
component: AcademyDetailsComponent,
|
||||
resolve : {
|
||||
course: courseResolver,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
] as Routes;
|
|
@ -1,32 +0,0 @@
|
|||
import { Route } from '@angular/router';
|
||||
import { AcademyComponent } from 'app/modules/admin/apps/academy/academy.component';
|
||||
import { AcademyCategoriesResolver, AcademyCourseResolver, AcademyCoursesResolver } from 'app/modules/admin/apps/academy/academy.resolvers';
|
||||
import { AcademyDetailsComponent } from 'app/modules/admin/apps/academy/details/details.component';
|
||||
import { AcademyListComponent } from 'app/modules/admin/apps/academy/list/list.component';
|
||||
|
||||
export const academyRoutes: Route[] = [
|
||||
{
|
||||
path : '',
|
||||
component: AcademyComponent,
|
||||
resolve : {
|
||||
categories: AcademyCategoriesResolver,
|
||||
},
|
||||
children : [
|
||||
{
|
||||
path : '',
|
||||
pathMatch: 'full',
|
||||
component: AcademyListComponent,
|
||||
resolve : {
|
||||
courses: AcademyCoursesResolver,
|
||||
},
|
||||
},
|
||||
{
|
||||
path : ':id',
|
||||
component: AcademyDetailsComponent,
|
||||
resolve : {
|
||||
course: AcademyCourseResolver,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
|
@ -86,7 +86,6 @@ export class AcademyService
|
|||
return this._httpClient.get<Course>('api/apps/academy/courses/course', {params: {id}}).pipe(
|
||||
map((course) =>
|
||||
{
|
||||
|
||||
// Update the course
|
||||
this._course.next(course);
|
||||
|
||||
|
@ -95,7 +94,6 @@ export class AcademyService
|
|||
}),
|
||||
switchMap((course) =>
|
||||
{
|
||||
|
||||
if ( !course )
|
||||
{
|
||||
return throwError('Could not found course with id of ' + id + '!');
|
||||
|
|
|
@ -58,7 +58,6 @@ export class AcademyDetailsComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((categories: Category[]) =>
|
||||
{
|
||||
|
||||
// Get the categories
|
||||
this.categories = categories;
|
||||
|
||||
|
@ -71,7 +70,6 @@ export class AcademyDetailsComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((course: Course) =>
|
||||
{
|
||||
|
||||
// Get the course
|
||||
this.course = course;
|
||||
|
||||
|
@ -87,7 +85,6 @@ export class AcademyDetailsComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(({matchingAliases}) =>
|
||||
{
|
||||
|
||||
// Set the drawerMode and drawerOpened
|
||||
if ( matchingAliases.includes('lg') )
|
||||
{
|
||||
|
@ -201,7 +198,6 @@ export class AcademyDetailsComponent implements OnInit, OnDestroy
|
|||
// Wrap everything into setTimeout so we can make sure that the 'current-step' class points to correct element
|
||||
setTimeout(() =>
|
||||
{
|
||||
|
||||
// Get the current step element and scroll it into view
|
||||
const currentStepElement = this._document.getElementsByClassName('current-step')[0];
|
||||
if ( currentStepElement )
|
||||
|
|
|
@ -88,7 +88,6 @@ export class AcademyListComponent implements OnInit, OnDestroy
|
|||
combineLatest([this.filters.categorySlug$, this.filters.query$, this.filters.hideCompleted$])
|
||||
.subscribe(([categorySlug, query, hideCompleted]) =>
|
||||
{
|
||||
|
||||
// Reset the filtered courses
|
||||
this.filteredCourses = this.courses;
|
||||
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatSidenavModule } from '@angular/material/sidenav';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { ChatComponent } from 'app/modules/admin/apps/chat/chat.component';
|
||||
|
||||
import { chatRoutes } from 'app/modules/admin/apps/chat/chat.routing';
|
||||
import { ChatsComponent } from 'app/modules/admin/apps/chat/chats/chats.component';
|
||||
import { ContactInfoComponent } from 'app/modules/admin/apps/chat/contact-info/contact-info.component';
|
||||
import { ConversationComponent } from 'app/modules/admin/apps/chat/conversation/conversation.component';
|
||||
import { EmptyConversationComponent } from 'app/modules/admin/apps/chat/empty-conversation/empty-conversation.component';
|
||||
import { NewChatComponent } from 'app/modules/admin/apps/chat/new-chat/new-chat.component';
|
||||
import { ProfileComponent } from 'app/modules/admin/apps/chat/profile/profile.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild(chatRoutes),
|
||||
MatButtonModule,
|
||||
MatCheckboxModule,
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
MatMenuModule,
|
||||
MatSidenavModule,
|
||||
ChatComponent,
|
||||
ChatsComponent,
|
||||
ContactInfoComponent,
|
||||
ConversationComponent,
|
||||
EmptyConversationComponent,
|
||||
NewChatComponent,
|
||||
ProfileComponent,
|
||||
],
|
||||
})
|
||||
export class ChatModule
|
||||
{
|
||||
}
|
|
@ -1,147 +0,0 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
|
||||
import { ChatService } from 'app/modules/admin/apps/chat/chat.service';
|
||||
import { Chat, Contact, Profile } from 'app/modules/admin/apps/chat/chat.types';
|
||||
import { catchError, Observable, throwError } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ChatChatsResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(
|
||||
private _chatService: ChatService,
|
||||
private _router: Router,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Chat[]> | any
|
||||
{
|
||||
return this._chatService.getChats();
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ChatChatResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(
|
||||
private _chatService: ChatService,
|
||||
private _router: Router,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Chat>
|
||||
{
|
||||
return this._chatService.getChatById(route.paramMap.get('id'))
|
||||
.pipe(
|
||||
// Error here means the requested chat is not available
|
||||
catchError((error) =>
|
||||
{
|
||||
|
||||
// Log the error
|
||||
console.error(error);
|
||||
|
||||
// Get the parent url
|
||||
const parentUrl = state.url.split('/').slice(0, -1).join('/');
|
||||
|
||||
// Navigate to there
|
||||
this._router.navigateByUrl(parentUrl);
|
||||
|
||||
// Throw an error
|
||||
return throwError(error);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ChatContactsResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(
|
||||
private _chatService: ChatService,
|
||||
private _router: Router,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Contact[]> | any
|
||||
{
|
||||
return this._chatService.getContacts();
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ChatProfileResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(
|
||||
private _chatService: ChatService,
|
||||
private _router: Router,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Profile> | any
|
||||
{
|
||||
return this._chatService.getProfile();
|
||||
}
|
||||
}
|
70
src/app/modules/admin/apps/chat/chat.routes.ts
Normal file
70
src/app/modules/admin/apps/chat/chat.routes.ts
Normal file
|
@ -0,0 +1,70 @@
|
|||
import { inject } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot, Routes } from '@angular/router';
|
||||
import { ChatComponent } from 'app/modules/admin/apps/chat/chat.component';
|
||||
import { ChatService } from 'app/modules/admin/apps/chat/chat.service';
|
||||
import { ChatsComponent } from 'app/modules/admin/apps/chat/chats/chats.component';
|
||||
import { ConversationComponent } from 'app/modules/admin/apps/chat/conversation/conversation.component';
|
||||
import { EmptyConversationComponent } from 'app/modules/admin/apps/chat/empty-conversation/empty-conversation.component';
|
||||
import { catchError, throwError } from 'rxjs';
|
||||
|
||||
/**
|
||||
* Conversation resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
const conversationResolver = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) =>
|
||||
{
|
||||
const chatService = inject(ChatService);
|
||||
const router = inject(Router);
|
||||
|
||||
return chatService.getChatById(route.paramMap.get('id')).pipe(
|
||||
// Error here means the requested chat is not available
|
||||
catchError((error) =>
|
||||
{
|
||||
// Log the error
|
||||
console.error(error);
|
||||
|
||||
// Get the parent url
|
||||
const parentUrl = state.url.split('/').slice(0, -1).join('/');
|
||||
|
||||
// Navigate to there
|
||||
router.navigateByUrl(parentUrl);
|
||||
|
||||
// Throw an error
|
||||
return throwError(error);
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
export default [
|
||||
{
|
||||
path : '',
|
||||
component: ChatComponent,
|
||||
resolve : {
|
||||
chats : () => inject(ChatService).getChats(),
|
||||
contacts: () => inject(ChatService).getContacts(),
|
||||
profile : () => inject(ChatService).getProfile(),
|
||||
},
|
||||
children : [
|
||||
{
|
||||
path : '',
|
||||
component: ChatsComponent,
|
||||
children : [
|
||||
{
|
||||
path : '',
|
||||
pathMatch: 'full',
|
||||
component: EmptyConversationComponent,
|
||||
},
|
||||
{
|
||||
path : ':id',
|
||||
component: ConversationComponent,
|
||||
resolve : {
|
||||
conversation: conversationResolver,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
] as Routes;
|
|
@ -1,38 +0,0 @@
|
|||
import { Route } from '@angular/router';
|
||||
import { ChatComponent } from 'app/modules/admin/apps/chat/chat.component';
|
||||
import { ChatChatResolver, ChatChatsResolver, ChatContactsResolver, ChatProfileResolver } from 'app/modules/admin/apps/chat/chat.resolvers';
|
||||
import { ChatsComponent } from 'app/modules/admin/apps/chat/chats/chats.component';
|
||||
import { ConversationComponent } from 'app/modules/admin/apps/chat/conversation/conversation.component';
|
||||
import { EmptyConversationComponent } from 'app/modules/admin/apps/chat/empty-conversation/empty-conversation.component';
|
||||
|
||||
export const chatRoutes: Route[] = [
|
||||
{
|
||||
path : '',
|
||||
component: ChatComponent,
|
||||
resolve : {
|
||||
chats : ChatChatsResolver,
|
||||
contacts: ChatContactsResolver,
|
||||
profile : ChatProfileResolver,
|
||||
},
|
||||
children : [
|
||||
{
|
||||
path : '',
|
||||
component: ChatsComponent,
|
||||
children : [
|
||||
{
|
||||
path : '',
|
||||
pathMatch: 'full',
|
||||
component: EmptyConversationComponent,
|
||||
},
|
||||
{
|
||||
path : ':id',
|
||||
component: ConversationComponent,
|
||||
resolve : {
|
||||
conversation: ChatChatResolver,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
|
@ -133,7 +133,6 @@ export class ChatService
|
|||
return this._httpClient.get<Chat>('api/apps/chat/chat', {params: {id}}).pipe(
|
||||
map((chat) =>
|
||||
{
|
||||
|
||||
// Update the chat
|
||||
this._chat.next(chat);
|
||||
|
||||
|
@ -142,7 +141,6 @@ export class ChatService
|
|||
}),
|
||||
switchMap((chat) =>
|
||||
{
|
||||
|
||||
if ( !chat )
|
||||
{
|
||||
return throwError('Could not found chat with id of ' + id + '!');
|
||||
|
@ -169,7 +167,6 @@ export class ChatService
|
|||
}).pipe(
|
||||
map((updatedChat) =>
|
||||
{
|
||||
|
||||
// Find the index of the updated chat
|
||||
const index = chats.findIndex(item => item.id === id);
|
||||
|
||||
|
@ -187,7 +184,6 @@ export class ChatService
|
|||
filter(item => item && item.id === id),
|
||||
tap(() =>
|
||||
{
|
||||
|
||||
// Update the chat if it's selected
|
||||
this._chat.next(updatedChat);
|
||||
|
||||
|
|
|
@ -58,10 +58,8 @@ export class ConversationComponent implements OnInit, OnDestroy
|
|||
// This doesn't need to trigger Angular's change detection by itself
|
||||
this._ngZone.runOutsideAngular(() =>
|
||||
{
|
||||
|
||||
setTimeout(() =>
|
||||
{
|
||||
|
||||
// Set the height to 'auto' so we can correctly read the scrollHeight
|
||||
this.messageInput.nativeElement.style.height = 'auto';
|
||||
|
||||
|
@ -102,7 +100,6 @@ export class ConversationComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(({matchingAliases}) =>
|
||||
{
|
||||
|
||||
// Set the drawerMode if the given breakpoint is active
|
||||
if ( matchingAliases.includes('lg') )
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { ChangeDetectionStrategy, Component, ViewEncapsulation } from '@angular/core';
|
||||
import { MatLuxonDateModule } from '@angular/material-luxon-adapter';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, CanDeactivate, RouterStateSnapshot, UrlTree } from '@angular/router';
|
||||
import { ContactsDetailsComponent } from 'app/modules/admin/apps/contacts/details/details.component';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class CanDeactivateContactsDetails implements CanDeactivate<ContactsDetailsComponent>
|
||||
{
|
||||
canDeactivate(
|
||||
component: ContactsDetailsComponent,
|
||||
currentRoute: ActivatedRouteSnapshot,
|
||||
currentState: RouterStateSnapshot,
|
||||
nextState: RouterStateSnapshot,
|
||||
): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree
|
||||
{
|
||||
// Get the next route
|
||||
let nextRoute: ActivatedRouteSnapshot = nextState.root;
|
||||
while ( nextRoute.firstChild )
|
||||
{
|
||||
nextRoute = nextRoute.firstChild;
|
||||
}
|
||||
|
||||
// If the next state doesn't contain '/contacts'
|
||||
// it means we are navigating away from the
|
||||
// contacts app
|
||||
if ( !nextState.url.includes('/contacts') )
|
||||
{
|
||||
// Let it navigate
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we are navigating to another contact...
|
||||
if ( nextRoute.paramMap.get('id') )
|
||||
{
|
||||
// Just navigate
|
||||
return true;
|
||||
}
|
||||
// Otherwise...
|
||||
else
|
||||
{
|
||||
// Close the drawer first, and then navigate
|
||||
return component.closeDrawer().then(() => true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { MatLuxonDateModule } from '@angular/material-luxon-adapter';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MAT_DATE_FORMATS, MatRippleModule } from '@angular/material/core';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
import { MatDividerModule } from '@angular/material/divider';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { MatRadioModule } from '@angular/material/radio';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatSidenavModule } from '@angular/material/sidenav';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { ContactsComponent } from 'app/modules/admin/apps/contacts/contacts.component';
|
||||
|
||||
import { contactsRoutes } from 'app/modules/admin/apps/contacts/contacts.routing';
|
||||
import { ContactsDetailsComponent } from 'app/modules/admin/apps/contacts/details/details.component';
|
||||
import { ContactsListComponent } from 'app/modules/admin/apps/contacts/list/list.component';
|
||||
|
||||
@NgModule({
|
||||
imports : [
|
||||
RouterModule.forChild(contactsRoutes),
|
||||
MatButtonModule,
|
||||
MatCheckboxModule,
|
||||
MatDatepickerModule,
|
||||
MatDividerModule,
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
MatLuxonDateModule,
|
||||
MatMenuModule,
|
||||
MatProgressBarModule,
|
||||
MatRadioModule,
|
||||
MatRippleModule,
|
||||
MatSelectModule,
|
||||
MatSidenavModule,
|
||||
MatTableModule,
|
||||
MatTooltipModule,
|
||||
ContactsComponent,
|
||||
ContactsListComponent,
|
||||
ContactsDetailsComponent,
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide : MAT_DATE_FORMATS,
|
||||
useValue: {
|
||||
parse : {
|
||||
dateInput: 'D',
|
||||
},
|
||||
display: {
|
||||
dateInput : 'DDD',
|
||||
monthYearLabel : 'LLL yyyy',
|
||||
dateA11yLabel : 'DD',
|
||||
monthYearA11yLabel: 'LLLL yyyy',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
export class ContactsModule
|
||||
{
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
|
||||
import { ContactsService } from 'app/modules/admin/apps/contacts/contacts.service';
|
||||
import { Contact, Country, Tag } from 'app/modules/admin/apps/contacts/contacts.types';
|
||||
import { catchError, Observable, throwError } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ContactsResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(private _contactsService: ContactsService)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Contact[]>
|
||||
{
|
||||
return this._contactsService.getContacts();
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ContactsContactResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(
|
||||
private _contactsService: ContactsService,
|
||||
private _router: Router,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Contact>
|
||||
{
|
||||
return this._contactsService.getContactById(route.paramMap.get('id'))
|
||||
.pipe(
|
||||
// Error here means the requested contact is not available
|
||||
catchError((error) =>
|
||||
{
|
||||
|
||||
// Log the error
|
||||
console.error(error);
|
||||
|
||||
// Get the parent url
|
||||
const parentUrl = state.url.split('/').slice(0, -1).join('/');
|
||||
|
||||
// Navigate to there
|
||||
this._router.navigateByUrl(parentUrl);
|
||||
|
||||
// Throw an error
|
||||
return throwError(error);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ContactsCountriesResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(private _contactsService: ContactsService)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Country[]>
|
||||
{
|
||||
return this._contactsService.getCountries();
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ContactsTagsResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(private _contactsService: ContactsService)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Tag[]>
|
||||
{
|
||||
return this._contactsService.getTags();
|
||||
}
|
||||
}
|
110
src/app/modules/admin/apps/contacts/contacts.routes.ts
Normal file
110
src/app/modules/admin/apps/contacts/contacts.routes.ts
Normal file
|
@ -0,0 +1,110 @@
|
|||
import { inject } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot, Routes } from '@angular/router';
|
||||
import { ContactsComponent } from 'app/modules/admin/apps/contacts/contacts.component';
|
||||
import { ContactsService } from 'app/modules/admin/apps/contacts/contacts.service';
|
||||
import { ContactsDetailsComponent } from 'app/modules/admin/apps/contacts/details/details.component';
|
||||
import { ContactsListComponent } from 'app/modules/admin/apps/contacts/list/list.component';
|
||||
import { catchError, throwError } from 'rxjs';
|
||||
|
||||
/**
|
||||
* Contact resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
const contactResolver = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) =>
|
||||
{
|
||||
const contactsService = inject(ContactsService);
|
||||
const router = inject(Router);
|
||||
|
||||
return contactsService.getContactById(route.paramMap.get('id'))
|
||||
.pipe(
|
||||
// Error here means the requested contact is not available
|
||||
catchError((error) =>
|
||||
{
|
||||
// Log the error
|
||||
console.error(error);
|
||||
|
||||
// Get the parent url
|
||||
const parentUrl = state.url.split('/').slice(0, -1).join('/');
|
||||
|
||||
// Navigate to there
|
||||
router.navigateByUrl(parentUrl);
|
||||
|
||||
// Throw an error
|
||||
return throwError(error);
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Can deactivate contacts details
|
||||
*
|
||||
* @param component
|
||||
* @param currentRoute
|
||||
* @param currentState
|
||||
* @param nextState
|
||||
*/
|
||||
const canDeactivateContactsDetails = (
|
||||
component: ContactsDetailsComponent,
|
||||
currentRoute: ActivatedRouteSnapshot,
|
||||
currentState: RouterStateSnapshot,
|
||||
nextState: RouterStateSnapshot) =>
|
||||
{
|
||||
// Get the next route
|
||||
let nextRoute: ActivatedRouteSnapshot = nextState.root;
|
||||
while ( nextRoute.firstChild )
|
||||
{
|
||||
nextRoute = nextRoute.firstChild;
|
||||
}
|
||||
|
||||
// If the next state doesn't contain '/contacts'
|
||||
// it means we are navigating away from the
|
||||
// contacts app
|
||||
if ( !nextState.url.includes('/contacts') )
|
||||
{
|
||||
// Let it navigate
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we are navigating to another contact...
|
||||
if ( nextRoute.paramMap.get('id') )
|
||||
{
|
||||
// Just navigate
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise, close the drawer first, and then navigate
|
||||
return component.closeDrawer().then(() => true);
|
||||
};
|
||||
|
||||
export default [
|
||||
{
|
||||
path : '',
|
||||
component: ContactsComponent,
|
||||
resolve : {
|
||||
tags: () => inject(ContactsService).getTags(),
|
||||
},
|
||||
children : [
|
||||
{
|
||||
path : '',
|
||||
component: ContactsListComponent,
|
||||
resolve : {
|
||||
contacts : () => inject(ContactsService).getContacts(),
|
||||
countries: () => inject(ContactsService).getCountries(),
|
||||
},
|
||||
children : [
|
||||
{
|
||||
path : ':id',
|
||||
component : ContactsDetailsComponent,
|
||||
resolve : {
|
||||
contact : contactResolver,
|
||||
countries: () => inject(ContactsService).getCountries(),
|
||||
},
|
||||
canDeactivate: [canDeactivateContactsDetails],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
] as Routes;
|
|
@ -1,37 +0,0 @@
|
|||
import { Route } from '@angular/router';
|
||||
import { ContactsComponent } from 'app/modules/admin/apps/contacts/contacts.component';
|
||||
import { CanDeactivateContactsDetails } from 'app/modules/admin/apps/contacts/contacts.guards';
|
||||
import { ContactsContactResolver, ContactsCountriesResolver, ContactsResolver, ContactsTagsResolver } from 'app/modules/admin/apps/contacts/contacts.resolvers';
|
||||
import { ContactsDetailsComponent } from 'app/modules/admin/apps/contacts/details/details.component';
|
||||
import { ContactsListComponent } from 'app/modules/admin/apps/contacts/list/list.component';
|
||||
|
||||
export const contactsRoutes: Route[] = [
|
||||
{
|
||||
path : '',
|
||||
component: ContactsComponent,
|
||||
resolve : {
|
||||
tags: ContactsTagsResolver,
|
||||
},
|
||||
children : [
|
||||
{
|
||||
path : '',
|
||||
component: ContactsListComponent,
|
||||
resolve : {
|
||||
contacts : ContactsResolver,
|
||||
countries: ContactsCountriesResolver,
|
||||
},
|
||||
children : [
|
||||
{
|
||||
path : ':id',
|
||||
component : ContactsDetailsComponent,
|
||||
resolve : {
|
||||
contact : ContactsContactResolver,
|
||||
countries: ContactsCountriesResolver,
|
||||
},
|
||||
canDeactivate: [CanDeactivateContactsDetails],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
|
@ -100,7 +100,6 @@ export class ContactsService
|
|||
take(1),
|
||||
map((contacts) =>
|
||||
{
|
||||
|
||||
// Find the contact
|
||||
const contact = contacts.find(item => item.id === id) || null;
|
||||
|
||||
|
@ -112,7 +111,6 @@ export class ContactsService
|
|||
}),
|
||||
switchMap((contact) =>
|
||||
{
|
||||
|
||||
if ( !contact )
|
||||
{
|
||||
return throwError('Could not found contact with id of ' + id + '!');
|
||||
|
@ -133,7 +131,6 @@ export class ContactsService
|
|||
switchMap(contacts => this._httpClient.post<Contact>('api/apps/contacts/contact', {}).pipe(
|
||||
map((newContact) =>
|
||||
{
|
||||
|
||||
// Update the contacts with the new contact
|
||||
this._contacts.next([newContact, ...contacts]);
|
||||
|
||||
|
@ -160,7 +157,6 @@ export class ContactsService
|
|||
}).pipe(
|
||||
map((updatedContact) =>
|
||||
{
|
||||
|
||||
// Find the index of the updated contact
|
||||
const index = contacts.findIndex(item => item.id === id);
|
||||
|
||||
|
@ -178,7 +174,6 @@ export class ContactsService
|
|||
filter(item => item && item.id === id),
|
||||
tap(() =>
|
||||
{
|
||||
|
||||
// Update the contact if it's selected
|
||||
this._contact.next(updatedContact);
|
||||
|
||||
|
@ -202,7 +197,6 @@ export class ContactsService
|
|||
switchMap(contacts => this._httpClient.delete('api/apps/contacts/contact', {params: {id}}).pipe(
|
||||
map((isDeleted: boolean) =>
|
||||
{
|
||||
|
||||
// Find the index of the deleted contact
|
||||
const index = contacts.findIndex(item => item.id === id);
|
||||
|
||||
|
@ -257,7 +251,6 @@ export class ContactsService
|
|||
switchMap(tags => this._httpClient.post<Tag>('api/apps/contacts/tag', {tag}).pipe(
|
||||
map((newTag) =>
|
||||
{
|
||||
|
||||
// Update the tags with the new tag
|
||||
this._tags.next([...tags, newTag]);
|
||||
|
||||
|
@ -284,7 +277,6 @@ export class ContactsService
|
|||
}).pipe(
|
||||
map((updatedTag) =>
|
||||
{
|
||||
|
||||
// Find the index of the updated tag
|
||||
const index = tags.findIndex(item => item.id === id);
|
||||
|
||||
|
@ -313,7 +305,6 @@ export class ContactsService
|
|||
switchMap(tags => this._httpClient.delete('api/apps/contacts/tag', {params: {id}}).pipe(
|
||||
map((isDeleted: boolean) =>
|
||||
{
|
||||
|
||||
// Find the index of the deleted tag
|
||||
const index = tags.findIndex(item => item.id === id);
|
||||
|
||||
|
@ -331,11 +322,9 @@ export class ContactsService
|
|||
take(1),
|
||||
map((contacts) =>
|
||||
{
|
||||
|
||||
// Iterate through the contacts
|
||||
contacts.forEach((contact) =>
|
||||
{
|
||||
|
||||
const tagIndex = contact.tags.findIndex(tag => tag === id);
|
||||
|
||||
// If the contact has the tag, remove it
|
||||
|
@ -374,7 +363,6 @@ export class ContactsService
|
|||
}).pipe(
|
||||
map((updatedContact) =>
|
||||
{
|
||||
|
||||
// Find the index of the updated contact
|
||||
const index = contacts.findIndex(item => item.id === id);
|
||||
|
||||
|
@ -392,7 +380,6 @@ export class ContactsService
|
|||
filter(item => item && item.id === id),
|
||||
tap(() =>
|
||||
{
|
||||
|
||||
// Update the contact if it's selected
|
||||
this._contact.next(updatedContact);
|
||||
|
||||
|
|
|
@ -4,9 +4,10 @@ import { TextFieldModule } from '@angular/cdk/text-field';
|
|||
import { DatePipe, NgClass, NgFor, NgIf } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, OnDestroy, OnInit, Renderer2, TemplateRef, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { MatLuxonDateModule } from '@angular/material-luxon-adapter';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatOptionModule, MatRippleModule } from '@angular/material/core';
|
||||
import { MAT_DATE_FORMATS, MatOptionModule, MatRippleModule } from '@angular/material/core';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
|
@ -28,7 +29,23 @@ import { debounceTime, Subject, takeUntil } from 'rxjs';
|
|||
encapsulation : ViewEncapsulation.None,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone : true,
|
||||
imports : [NgIf, MatButtonModule, MatTooltipModule, RouterLink, MatIconModule, NgFor, FormsModule, ReactiveFormsModule, MatRippleModule, MatFormFieldModule, MatInputModule, MatCheckboxModule, NgClass, MatSelectModule, MatOptionModule, MatDatepickerModule, TextFieldModule, FuseFindByKeyPipe, DatePipe],
|
||||
imports : [NgIf, MatLuxonDateModule, MatButtonModule, MatTooltipModule, RouterLink, MatIconModule, NgFor, FormsModule, ReactiveFormsModule, MatRippleModule, MatFormFieldModule, MatInputModule, MatCheckboxModule, NgClass, MatSelectModule, MatOptionModule, MatDatepickerModule, TextFieldModule, FuseFindByKeyPipe, DatePipe],
|
||||
providers : [
|
||||
{
|
||||
provide : MAT_DATE_FORMATS,
|
||||
useValue: {
|
||||
parse : {
|
||||
dateInput: 'D',
|
||||
},
|
||||
display: {
|
||||
dateInput : 'DDD',
|
||||
monthYearLabel : 'LLL yyyy',
|
||||
dateA11yLabel : 'DD',
|
||||
monthYearA11yLabel: 'LLLL yyyy',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
export class ContactsDetailsComponent implements OnInit, OnDestroy
|
||||
{
|
||||
|
@ -108,7 +125,6 @@ export class ContactsDetailsComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((contact: Contact) =>
|
||||
{
|
||||
|
||||
// Open the drawer in case it is closed
|
||||
this._contactsListComponent.matDrawer.open();
|
||||
|
||||
|
@ -130,7 +146,6 @@ export class ContactsDetailsComponent implements OnInit, OnDestroy
|
|||
// Iterate through them
|
||||
contact.emails.forEach((email) =>
|
||||
{
|
||||
|
||||
// Create an email form group
|
||||
emailFormGroups.push(
|
||||
this._formBuilder.group({
|
||||
|
@ -165,7 +180,6 @@ export class ContactsDetailsComponent implements OnInit, OnDestroy
|
|||
// Iterate through them
|
||||
contact.phoneNumbers.forEach((phoneNumber) =>
|
||||
{
|
||||
|
||||
// Create an email form group
|
||||
phoneNumbersFormGroups.push(
|
||||
this._formBuilder.group({
|
||||
|
@ -289,7 +303,6 @@ export class ContactsDetailsComponent implements OnInit, OnDestroy
|
|||
// Update the contact on the server
|
||||
this._contactsService.updateContact(contact.id, contact).subscribe(() =>
|
||||
{
|
||||
|
||||
// Toggle the edit mode off
|
||||
this.toggleEditMode(false);
|
||||
});
|
||||
|
@ -314,7 +327,6 @@ export class ContactsDetailsComponent implements OnInit, OnDestroy
|
|||
// Subscribe to the confirmation dialog closed action
|
||||
confirmation.afterClosed().subscribe((result) =>
|
||||
{
|
||||
|
||||
// If the confirm button pressed...
|
||||
if ( result === 'confirmed' )
|
||||
{
|
||||
|
@ -330,7 +342,6 @@ export class ContactsDetailsComponent implements OnInit, OnDestroy
|
|||
this._contactsService.deleteContact(id)
|
||||
.subscribe((isDeleted) =>
|
||||
{
|
||||
|
||||
// Return if the contact wasn't deleted...
|
||||
if ( !isDeleted )
|
||||
{
|
||||
|
@ -431,7 +442,6 @@ export class ContactsDetailsComponent implements OnInit, OnDestroy
|
|||
// Subscribe to the attachments observable
|
||||
this._tagsPanelOverlayRef.attachments().subscribe(() =>
|
||||
{
|
||||
|
||||
// Add a class to the origin
|
||||
this._renderer2.addClass(this._tagsPanelOrigin.nativeElement, 'panel-opened');
|
||||
|
||||
|
@ -448,7 +458,6 @@ export class ContactsDetailsComponent implements OnInit, OnDestroy
|
|||
// Subscribe to the backdrop click
|
||||
this._tagsPanelOverlayRef.backdropClick().subscribe(() =>
|
||||
{
|
||||
|
||||
// Remove the class from the origin
|
||||
this._renderer2.removeClass(this._tagsPanelOrigin.nativeElement, 'panel-opened');
|
||||
|
||||
|
@ -554,7 +563,6 @@ export class ContactsDetailsComponent implements OnInit, OnDestroy
|
|||
this._contactsService.createTag(tag)
|
||||
.subscribe((response) =>
|
||||
{
|
||||
|
||||
// Add the tag to the contact
|
||||
this.addTagToContact(response);
|
||||
});
|
||||
|
|
|
@ -63,7 +63,6 @@ export class ContactsListComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((contacts: Contact[]) =>
|
||||
{
|
||||
|
||||
// Update the counts
|
||||
this.contactsCount = contacts.length;
|
||||
|
||||
|
@ -76,7 +75,6 @@ export class ContactsListComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((contact: Contact) =>
|
||||
{
|
||||
|
||||
// Update the selected contact
|
||||
this.selectedContact = contact;
|
||||
|
||||
|
@ -89,7 +87,6 @@ export class ContactsListComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((countries: Country[]) =>
|
||||
{
|
||||
|
||||
// Update the countries
|
||||
this.countries = countries;
|
||||
|
||||
|
@ -127,7 +124,6 @@ export class ContactsListComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(({matchingAliases}) =>
|
||||
{
|
||||
|
||||
// Set the drawerMode if the given breakpoint is active
|
||||
if ( matchingAliases.includes('lg') )
|
||||
{
|
||||
|
@ -191,7 +187,6 @@ export class ContactsListComponent implements OnInit, OnDestroy
|
|||
// Create the contact
|
||||
this._contactsService.createContact().subscribe((newContact) =>
|
||||
{
|
||||
|
||||
// Go to the new contact
|
||||
this._router.navigate(['./', newContact.id], {relativeTo: this._activatedRoute});
|
||||
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatRippleModule } from '@angular/material/core';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||
import { MatSortModule } from '@angular/material/sort';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { ecommerceRoutes } from 'app/modules/admin/apps/ecommerce/ecommerce.routing';
|
||||
|
||||
import { InventoryComponent } from 'app/modules/admin/apps/ecommerce/inventory/inventory.component';
|
||||
import { InventoryListComponent } from 'app/modules/admin/apps/ecommerce/inventory/list/inventory.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild(ecommerceRoutes),
|
||||
MatButtonModule,
|
||||
MatCheckboxModule,
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
MatMenuModule,
|
||||
MatPaginatorModule,
|
||||
MatProgressBarModule,
|
||||
MatRippleModule,
|
||||
MatSortModule,
|
||||
MatSelectModule,
|
||||
MatSlideToggleModule,
|
||||
MatTooltipModule,
|
||||
InventoryComponent,
|
||||
InventoryListComponent,
|
||||
],
|
||||
})
|
||||
export class ECommerceModule
|
||||
{
|
||||
}
|
30
src/app/modules/admin/apps/ecommerce/ecommerce.routes.ts
Normal file
30
src/app/modules/admin/apps/ecommerce/ecommerce.routes.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { inject } from '@angular/core';
|
||||
import { Routes } from '@angular/router';
|
||||
import { InventoryComponent } from 'app/modules/admin/apps/ecommerce/inventory/inventory.component';
|
||||
import { InventoryService } from 'app/modules/admin/apps/ecommerce/inventory/inventory.service';
|
||||
import { InventoryListComponent } from 'app/modules/admin/apps/ecommerce/inventory/list/inventory.component';
|
||||
|
||||
export default [
|
||||
{
|
||||
path : '',
|
||||
pathMatch : 'full',
|
||||
redirectTo: 'inventory',
|
||||
},
|
||||
{
|
||||
path : 'inventory',
|
||||
component: InventoryComponent,
|
||||
children : [
|
||||
{
|
||||
path : '',
|
||||
component: InventoryListComponent,
|
||||
resolve : {
|
||||
brands : () => inject(InventoryService).getBrands(),
|
||||
categories: () => inject(InventoryService).getCategories(),
|
||||
products : () => inject(InventoryService).getProducts(),
|
||||
tags : () => inject(InventoryService).getTags(),
|
||||
vendors : () => inject(InventoryService).getVendors(),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
] as Routes;
|
|
@ -1,50 +0,0 @@
|
|||
import { Route } from '@angular/router';
|
||||
import { InventoryComponent } from 'app/modules/admin/apps/ecommerce/inventory/inventory.component';
|
||||
import { InventoryBrandsResolver, InventoryCategoriesResolver, InventoryProductsResolver, InventoryTagsResolver, InventoryVendorsResolver } from 'app/modules/admin/apps/ecommerce/inventory/inventory.resolvers';
|
||||
import { InventoryListComponent } from 'app/modules/admin/apps/ecommerce/inventory/list/inventory.component';
|
||||
|
||||
export const ecommerceRoutes: Route[] = [
|
||||
{
|
||||
path : '',
|
||||
pathMatch : 'full',
|
||||
redirectTo: 'inventory',
|
||||
},
|
||||
{
|
||||
path : 'inventory',
|
||||
component: InventoryComponent,
|
||||
children : [
|
||||
{
|
||||
path : '',
|
||||
component: InventoryListComponent,
|
||||
resolve : {
|
||||
brands : InventoryBrandsResolver,
|
||||
categories: InventoryCategoriesResolver,
|
||||
products : InventoryProductsResolver,
|
||||
tags : InventoryTagsResolver,
|
||||
vendors : InventoryVendorsResolver,
|
||||
},
|
||||
},
|
||||
],
|
||||
/*children : [
|
||||
{
|
||||
path : '',
|
||||
component: ContactsListComponent,
|
||||
resolve : {
|
||||
tasks : ContactsResolver,
|
||||
countries: ContactsCountriesResolver
|
||||
},
|
||||
children : [
|
||||
{
|
||||
path : ':id',
|
||||
component : ContactsDetailsComponent,
|
||||
resolve : {
|
||||
task : ContactsContactResolver,
|
||||
countries: ContactsCountriesResolver
|
||||
},
|
||||
canDeactivate: [CanDeactivateContactsDetails]
|
||||
}
|
||||
]
|
||||
}
|
||||
]*/
|
||||
},
|
||||
];
|
|
@ -1,194 +0,0 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
|
||||
import { InventoryService } from 'app/modules/admin/apps/ecommerce/inventory/inventory.service';
|
||||
import { InventoryBrand, InventoryCategory, InventoryPagination, InventoryProduct, InventoryTag, InventoryVendor } from 'app/modules/admin/apps/ecommerce/inventory/inventory.types';
|
||||
import { catchError, Observable, throwError } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class InventoryBrandsResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(private _inventoryService: InventoryService)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<InventoryBrand[]>
|
||||
{
|
||||
return this._inventoryService.getBrands();
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class InventoryCategoriesResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(private _inventoryService: InventoryService)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<InventoryCategory[]>
|
||||
{
|
||||
return this._inventoryService.getCategories();
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class InventoryProductResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(
|
||||
private _inventoryService: InventoryService,
|
||||
private _router: Router,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<InventoryProduct>
|
||||
{
|
||||
return this._inventoryService.getProductById(route.paramMap.get('id'))
|
||||
.pipe(
|
||||
// Error here means the requested product is not available
|
||||
catchError((error) =>
|
||||
{
|
||||
|
||||
// Log the error
|
||||
console.error(error);
|
||||
|
||||
// Get the parent url
|
||||
const parentUrl = state.url.split('/').slice(0, -1).join('/');
|
||||
|
||||
// Navigate to there
|
||||
this._router.navigateByUrl(parentUrl);
|
||||
|
||||
// Throw an error
|
||||
return throwError(error);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class InventoryProductsResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(private _inventoryService: InventoryService)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<{ pagination: InventoryPagination; products: InventoryProduct[] }>
|
||||
{
|
||||
return this._inventoryService.getProducts();
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class InventoryTagsResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(private _inventoryService: InventoryService)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<InventoryTag[]>
|
||||
{
|
||||
return this._inventoryService.getTags();
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class InventoryVendorsResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(private _inventoryService: InventoryService)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<InventoryVendor[]>
|
||||
{
|
||||
return this._inventoryService.getVendors();
|
||||
}
|
||||
}
|
|
@ -153,7 +153,6 @@ export class InventoryService
|
|||
take(1),
|
||||
map((products) =>
|
||||
{
|
||||
|
||||
// Find the product
|
||||
const product = products.find(item => item.id === id) || null;
|
||||
|
||||
|
@ -165,7 +164,6 @@ export class InventoryService
|
|||
}),
|
||||
switchMap((product) =>
|
||||
{
|
||||
|
||||
if ( !product )
|
||||
{
|
||||
return throwError('Could not found product with id of ' + id + '!');
|
||||
|
@ -186,7 +184,6 @@ export class InventoryService
|
|||
switchMap(products => this._httpClient.post<InventoryProduct>('api/apps/ecommerce/inventory/product', {}).pipe(
|
||||
map((newProduct) =>
|
||||
{
|
||||
|
||||
// Update the products with the new product
|
||||
this._products.next([newProduct, ...products]);
|
||||
|
||||
|
@ -213,7 +210,6 @@ export class InventoryService
|
|||
}).pipe(
|
||||
map((updatedProduct) =>
|
||||
{
|
||||
|
||||
// Find the index of the updated product
|
||||
const index = products.findIndex(item => item.id === id);
|
||||
|
||||
|
@ -231,7 +227,6 @@ export class InventoryService
|
|||
filter(item => item && item.id === id),
|
||||
tap(() =>
|
||||
{
|
||||
|
||||
// Update the product if it's selected
|
||||
this._product.next(updatedProduct);
|
||||
|
||||
|
@ -255,7 +250,6 @@ export class InventoryService
|
|||
switchMap(products => this._httpClient.delete('api/apps/ecommerce/inventory/product', {params: {id}}).pipe(
|
||||
map((isDeleted: boolean) =>
|
||||
{
|
||||
|
||||
// Find the index of the deleted product
|
||||
const index = products.findIndex(item => item.id === id);
|
||||
|
||||
|
@ -297,7 +291,6 @@ export class InventoryService
|
|||
switchMap(tags => this._httpClient.post<InventoryTag>('api/apps/ecommerce/inventory/tag', {tag}).pipe(
|
||||
map((newTag) =>
|
||||
{
|
||||
|
||||
// Update the tags with the new tag
|
||||
this._tags.next([...tags, newTag]);
|
||||
|
||||
|
@ -324,7 +317,6 @@ export class InventoryService
|
|||
}).pipe(
|
||||
map((updatedTag) =>
|
||||
{
|
||||
|
||||
// Find the index of the updated tag
|
||||
const index = tags.findIndex(item => item.id === id);
|
||||
|
||||
|
@ -353,7 +345,6 @@ export class InventoryService
|
|||
switchMap(tags => this._httpClient.delete('api/apps/ecommerce/inventory/tag', {params: {id}}).pipe(
|
||||
map((isDeleted: boolean) =>
|
||||
{
|
||||
|
||||
// Find the index of the deleted tag
|
||||
const index = tags.findIndex(item => item.id === id);
|
||||
|
||||
|
@ -371,11 +362,9 @@ export class InventoryService
|
|||
take(1),
|
||||
map((products) =>
|
||||
{
|
||||
|
||||
// Iterate through the contacts
|
||||
products.forEach((product) =>
|
||||
{
|
||||
|
||||
const tagIndex = product.tags.findIndex(tag => tag === id);
|
||||
|
||||
// If the contact has the tag, remove it
|
||||
|
@ -405,52 +394,4 @@ export class InventoryService
|
|||
}),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the avatar of the given contact
|
||||
*
|
||||
* @param id
|
||||
* @param avatar
|
||||
*/
|
||||
/*uploadAvatar(id: string, avatar: File): Observable<Contact>
|
||||
{
|
||||
return this.contacts$.pipe(
|
||||
take(1),
|
||||
switchMap(contacts => this._httpClient.post<Contact>('api/apps/contacts/avatar', {
|
||||
id,
|
||||
avatar
|
||||
}, {
|
||||
headers: {
|
||||
'Content-Type': avatar.type
|
||||
}
|
||||
}).pipe(
|
||||
map((updatedContact) => {
|
||||
|
||||
// Find the index of the updated contact
|
||||
const index = contacts.findIndex(item => item.id === id);
|
||||
|
||||
// Update the contact
|
||||
contacts[index] = updatedContact;
|
||||
|
||||
// Update the contacts
|
||||
this._contacts.next(contacts);
|
||||
|
||||
// Return the updated contact
|
||||
return updatedContact;
|
||||
}),
|
||||
switchMap(updatedContact => this.contact$.pipe(
|
||||
take(1),
|
||||
filter(item => item && item.id === id),
|
||||
tap(() => {
|
||||
|
||||
// Update the contact if it's selected
|
||||
this._contact.next(updatedContact);
|
||||
|
||||
// Return the updated contact
|
||||
return updatedContact;
|
||||
})
|
||||
))
|
||||
))
|
||||
);
|
||||
}*/
|
||||
}
|
||||
|
|
|
@ -118,7 +118,6 @@ export class InventoryListComponent implements OnInit, AfterViewInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((brands: InventoryBrand[]) =>
|
||||
{
|
||||
|
||||
// Update the brands
|
||||
this.brands = brands;
|
||||
|
||||
|
@ -131,7 +130,6 @@ export class InventoryListComponent implements OnInit, AfterViewInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((categories: InventoryCategory[]) =>
|
||||
{
|
||||
|
||||
// Update the categories
|
||||
this.categories = categories;
|
||||
|
||||
|
@ -144,7 +142,6 @@ export class InventoryListComponent implements OnInit, AfterViewInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((pagination: InventoryPagination) =>
|
||||
{
|
||||
|
||||
// Update the pagination
|
||||
this.pagination = pagination;
|
||||
|
||||
|
@ -160,7 +157,6 @@ export class InventoryListComponent implements OnInit, AfterViewInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((tags: InventoryTag[]) =>
|
||||
{
|
||||
|
||||
// Update the tags
|
||||
this.tags = tags;
|
||||
this.filteredTags = tags;
|
||||
|
@ -174,7 +170,6 @@ export class InventoryListComponent implements OnInit, AfterViewInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((vendors: InventoryVendor[]) =>
|
||||
{
|
||||
|
||||
// Update the vendors
|
||||
this.vendors = vendors;
|
||||
|
||||
|
@ -279,7 +274,6 @@ export class InventoryListComponent implements OnInit, AfterViewInit, OnDestroy
|
|||
this._inventoryService.getProductById(productId)
|
||||
.subscribe((product) =>
|
||||
{
|
||||
|
||||
// Set the selected product
|
||||
this.selectedProduct = product;
|
||||
|
||||
|
@ -404,7 +398,6 @@ export class InventoryListComponent implements OnInit, AfterViewInit, OnDestroy
|
|||
this._inventoryService.createTag(tag)
|
||||
.subscribe((response) =>
|
||||
{
|
||||
|
||||
// Add the tag to the product
|
||||
this.addTagToProduct(response);
|
||||
});
|
||||
|
@ -514,7 +507,6 @@ export class InventoryListComponent implements OnInit, AfterViewInit, OnDestroy
|
|||
// Create the product
|
||||
this._inventoryService.createProduct().subscribe((newProduct) =>
|
||||
{
|
||||
|
||||
// Go to new product
|
||||
this.selectedProduct = newProduct;
|
||||
|
||||
|
@ -540,7 +532,6 @@ export class InventoryListComponent implements OnInit, AfterViewInit, OnDestroy
|
|||
// Update the product on the server
|
||||
this._inventoryService.updateProduct(product.id, product).subscribe(() =>
|
||||
{
|
||||
|
||||
// Show a success message
|
||||
this.showFlashMessage('success');
|
||||
});
|
||||
|
@ -565,18 +556,15 @@ export class InventoryListComponent implements OnInit, AfterViewInit, OnDestroy
|
|||
// Subscribe to the confirmation dialog closed action
|
||||
confirmation.afterClosed().subscribe((result) =>
|
||||
{
|
||||
|
||||
// If the confirm button pressed...
|
||||
if ( result === 'confirmed' )
|
||||
{
|
||||
|
||||
// Get the product object
|
||||
const product = this.selectedProductForm.getRawValue();
|
||||
|
||||
// Delete the product on the server
|
||||
this._inventoryService.deleteProduct(product.id).subscribe(() =>
|
||||
{
|
||||
|
||||
// Close the details
|
||||
this.closeDetails();
|
||||
});
|
||||
|
@ -598,7 +586,6 @@ export class InventoryListComponent implements OnInit, AfterViewInit, OnDestroy
|
|||
// Hide it after 3 seconds
|
||||
setTimeout(() =>
|
||||
{
|
||||
|
||||
this.flashMessage = null;
|
||||
|
||||
// Mark for check
|
||||
|
|
|
@ -50,7 +50,6 @@ export class FileManagerDetailsComponent implements OnInit, OnDestroy
|
|||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((item: Item) =>
|
||||
{
|
||||
|
||||
// Open the drawer in case it is closed
|
||||
this._fileManagerListComponent.matDrawer.open();
|
||||
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, CanDeactivate, RouterStateSnapshot, UrlTree } from '@angular/router';
|
||||
import { FileManagerDetailsComponent } from 'app/modules/admin/apps/file-manager/details/details.component';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class CanDeactivateFileManagerDetails implements CanDeactivate<FileManagerDetailsComponent>
|
||||
{
|
||||
canDeactivate(
|
||||
component: FileManagerDetailsComponent,
|
||||
currentRoute: ActivatedRouteSnapshot,
|
||||
currentState: RouterStateSnapshot,
|
||||
nextState: RouterStateSnapshot,
|
||||
): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree
|
||||
{
|
||||
// Get the next route
|
||||
let nextRoute: ActivatedRouteSnapshot = nextState.root;
|
||||
while ( nextRoute.firstChild )
|
||||
{
|
||||
nextRoute = nextRoute.firstChild;
|
||||
}
|
||||
|
||||
// If the next state doesn't contain '/file-manager'
|
||||
// it means we are navigating away from the
|
||||
// file manager app
|
||||
if ( !nextState.url.includes('/file-manager') )
|
||||
{
|
||||
// Let it navigate
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we are navigating to another item...
|
||||
if ( nextState.url.includes('/details') )
|
||||
{
|
||||
// Just navigate
|
||||
return true;
|
||||
}
|
||||
// Otherwise...
|
||||
else
|
||||
{
|
||||
// Close the drawer first, and then navigate
|
||||
return component.closeDrawer().then(() => true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatSidenavModule } from '@angular/material/sidenav';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { FileManagerDetailsComponent } from 'app/modules/admin/apps/file-manager/details/details.component';
|
||||
import { FileManagerComponent } from 'app/modules/admin/apps/file-manager/file-manager.component';
|
||||
|
||||
import { fileManagerRoutes } from 'app/modules/admin/apps/file-manager/file-manager.routing';
|
||||
import { FileManagerListComponent } from 'app/modules/admin/apps/file-manager/list/list.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild(fileManagerRoutes),
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
MatSidenavModule,
|
||||
MatTooltipModule,
|
||||
FileManagerComponent,
|
||||
FileManagerDetailsComponent,
|
||||
FileManagerListComponent,
|
||||
],
|
||||
})
|
||||
export class FileManagerModule
|
||||
{
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
|
||||
import { FileManagerService } from 'app/modules/admin/apps/file-manager/file-manager.service';
|
||||
import { Item } from 'app/modules/admin/apps/file-manager/file-manager.types';
|
||||
import { catchError, Observable, throwError } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class FileManagerItemsResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(private _fileManagerService: FileManagerService)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Item[]>
|
||||
{
|
||||
return this._fileManagerService.getItems();
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class FileManagerFolderResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(
|
||||
private _router: Router,
|
||||
private _fileManagerService: FileManagerService,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Item[]>
|
||||
{
|
||||
return this._fileManagerService.getItems(route.paramMap.get('folderId'))
|
||||
.pipe(
|
||||
// Error here means the requested task is not available
|
||||
catchError((error) =>
|
||||
{
|
||||
|
||||
// Log the error
|
||||
console.error(error);
|
||||
|
||||
// Get the parent url
|
||||
const parentUrl = state.url.split('/').slice(0, -1).join('/');
|
||||
|
||||
// Navigate to there
|
||||
this._router.navigateByUrl(parentUrl);
|
||||
|
||||
// Throw an error
|
||||
return throwError(error);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class FileManagerItemResolver implements Resolve<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(
|
||||
private _router: Router,
|
||||
private _fileManagerService: FileManagerService,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resolver
|
||||
*
|
||||
* @param route
|
||||
* @param state
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Item>
|
||||
{
|
||||
return this._fileManagerService.getItemById(route.paramMap.get('id'))
|
||||
.pipe(
|
||||
// Error here means the requested task is not available
|
||||
catchError((error) =>
|
||||
{
|
||||
|
||||
// Log the error
|
||||
console.error(error);
|
||||
|
||||
// Get the parent url
|
||||
const parentUrl = state.url.split('/').slice(0, -1).join('/');
|
||||
|
||||
// Navigate to there
|
||||
this._router.navigateByUrl(parentUrl);
|
||||
|
||||
// Throw an error
|
||||
return throwError(error);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user