diff --git a/apps/sales/src/app/components/header/header.component.ts b/apps/sales/src/app/components/header/header.component.ts index fe3cb31e5..085a597c8 100644 --- a/apps/sales/src/app/components/header/header.component.ts +++ b/apps/sales/src/app/components/header/header.component.ts @@ -48,15 +48,10 @@ export class HeaderComponent implements OnInit, OnDestroy { isFirstSwitchedOn: true }; - this.moduleSwitcherService.moduleSwitcher$ - .pipe( - takeUntil(this.destroy$), - distinctUntilChanged((prev, curr) => (prev && curr ? prev === curr : false)) - ) - .subscribe((activeModule: ModuleSwitcher) => { - this.doubleChoiceSwitch.isFirstSwitchedOn = activeModule === ModuleSwitcher.Customer; - this.module = activeModule; - }); + this.moduleSwitcherService.moduleSwitcher$.pipe(takeUntil(this.destroy$)).subscribe((activeModule: ModuleSwitcher) => { + this.doubleChoiceSwitch.isFirstSwitchedOn = activeModule === ModuleSwitcher.Customer; + this.module = activeModule; + }); } ngOnDestroy() { diff --git a/apps/sales/src/app/components/process-tab/process-tab.component.ts b/apps/sales/src/app/components/process-tab/process-tab.component.ts index e2be45dcb..975ef19c4 100644 --- a/apps/sales/src/app/components/process-tab/process-tab.component.ts +++ b/apps/sales/src/app/components/process-tab/process-tab.component.ts @@ -6,7 +6,7 @@ import { DeleteProcess, PreventProductLoad, ChangeCurrentRoute, - SetProcessNewStatusToFalse, + SetProcessNewStatusToFalse } from '../../core/store/actions/process.actions'; import { Breadcrumb } from '../../core/models/breadcrumb.model'; import { ProcessDeleteDialogComponent } from '../../modules/process/components/process-delete-dialog/process-delete-dialog.component'; @@ -37,13 +37,13 @@ import { ViewRef_ } from '@angular/core/src/view'; style({ transform: 'translateY(10%)', opacity: 1, offset: 0.4 }), style({ transform: 'translateY(0%)', opacity: 1, offset: 0.6 }), style({ transform: 'translateY(5%)', opacity: 1, offset: 0.8 }), - style({ transform: 'translateY(0%)', opacity: 1, offset: 0.99 }), + style({ transform: 'translateY(0%)', opacity: 1, offset: 0.99 }) ]) - ), - ]), - ]), + ) + ]) + ]) ], - changeDetection: ChangeDetectionStrategy.OnPush, + changeDetection: ChangeDetectionStrategy.OnPush }) export class ProcessTabComponent implements OnInit, OnDestroy, AfterViewInit { @Input() process: Process; @@ -165,7 +165,7 @@ export class ProcessTabComponent implements OnInit, OnDestroy, AfterViewInit { this.selectProcess(process); const newBread: Breadcrumb = { name: 'Warenkorb', - path: '/cart/review', + path: '/cart/review' }; this.store.dispatch(new AddBreadcrumb(newBread, 'shoppingCart')); diff --git a/apps/sales/src/app/core/services/app.service.ts b/apps/sales/src/app/core/services/app.service.ts index 3c3a7d30e..708ff361c 100644 --- a/apps/sales/src/app/core/services/app.service.ts +++ b/apps/sales/src/app/core/services/app.service.ts @@ -10,7 +10,7 @@ import { Subject, of, Observable, timer } from 'rxjs'; import { takeUntil, catchError, take, filter, pairwise } from 'rxjs/operators'; import { UserStateService } from './user-state.service'; import { Meta, MetaDefinition } from '@angular/platform-browser'; -import { ActivatedRoute, Router, NavigationEnd, RoutesRecognized } from '@angular/router'; +import { ActivatedRoute, Router, NavigationEnd, RoutesRecognized, NavigationStart } from '@angular/router'; import { HttpClient } from '@angular/common/http'; import { isNullOrUndefined } from 'util'; import smoothscroll from 'smoothscroll-polyfill'; @@ -30,7 +30,7 @@ export const IDLE_REMISSION_REMINDER_MINUTES = 40; export class AppService implements OnDestroy { destroy$ = new Subject(); loader$ = new Subject(); - levingRemission$ = new Subject(); + leavingRemission$ = new Subject(); remissionReminder$ = new Subject(); timerClear$ = new Subject(); constructor( @@ -45,6 +45,11 @@ export class AppService implements OnDestroy { private idle: Idle ) {} + public showLeavingRemissionModal() { + this.leavingRemission$.next(); + this.registerTimedRemissionReminder(NOT_IDLE_REMISSION_REMINDER_MINUTES); + } + public appLoadInitialisations() { // register smooth scroll polyfill smoothscroll.polyfill(); @@ -138,31 +143,11 @@ export class AppService implements OnDestroy { pairwise() ) .subscribe((events: RoutesRecognized[]) => { - const previousUrl = events[0].urlAfterRedirects; const currentUrl = events[1].urlAfterRedirects; this.sendNavigationEventsToGoogleAnalytics(currentUrl); - this.handleRemissionLeavingEvents(previousUrl, currentUrl); }); } - handleRemissionLeavingEvents(previousUrl: string, currentUrl: string) { - if (previousUrl && currentUrl) { - const isCommingFromRemission = previousUrl.includes('remission'), - isGoingAwayFromRemission = !currentUrl.includes('remission'); - (isCommingFromRemission && isGoingAwayFromRemission).ifTrue(() => { - const isRemissionCompleated = this.store.selectSnapshot(RemissionSelectors.getRemissionCompleatedStatus); - // const isRemissionStarted = this.store.selectSnapshot(RemissionSelectors.getRemissionStartedStatus); - (!isRemissionCompleated).ifTrue(() => { - this.levingRemission$.next(); - this.registerTimedRemissionReminder(NOT_IDLE_REMISSION_REMINDER_MINUTES); - }); - }); - (isCommingFromRemission && isGoingAwayFromRemission).ifFalse(() => { - this.timerClear$.next(); - }); - } - } - private shouldRemindForRemissionAtAppStart() { this.store .select(RemissionSelectors.shouldRemindForRemission) diff --git a/apps/sales/src/app/core/services/index.ts b/apps/sales/src/app/core/services/index.ts new file mode 100644 index 000000000..0b62932e1 --- /dev/null +++ b/apps/sales/src/app/core/services/index.ts @@ -0,0 +1,2 @@ +export { AppService } from './app.service'; +export { ModalConfirmationService } from './modal-confirmation.service'; diff --git a/apps/sales/src/app/core/services/modal-confirmation.service.spec.ts b/apps/sales/src/app/core/services/modal-confirmation.service.spec.ts new file mode 100644 index 000000000..71ab42e97 --- /dev/null +++ b/apps/sales/src/app/core/services/modal-confirmation.service.spec.ts @@ -0,0 +1,12 @@ +import { TestBed } from '@angular/core/testing'; + +import { ModalConfirmationService } from './modal-confirmation.service'; + +describe('ModalConfirmationService', () => { + beforeEach(() => TestBed.configureTestingModule({})); + + it('should be created', () => { + const service: ModalConfirmationService = TestBed.get(ModalConfirmationService); + expect(service).toBeTruthy(); + }); +}); diff --git a/apps/sales/src/app/core/services/modal-confirmation.service.ts b/apps/sales/src/app/core/services/modal-confirmation.service.ts new file mode 100644 index 000000000..c2b0d47a5 --- /dev/null +++ b/apps/sales/src/app/core/services/modal-confirmation.service.ts @@ -0,0 +1,20 @@ +import { Injectable } from '@angular/core'; +import { Subject, Observable } from 'rxjs'; +import { take } from 'rxjs/operators'; + +@Injectable({ + providedIn: 'root' +}) +export class ModalConfirmationService { + private readonly _afterClosed = new Subject(); + + constructor() {} + + afterClosed(): Observable { + return this._afterClosed.asObservable().pipe(take(1)); + } + + close(dialogResult = false) { + this._afterClosed.next(dialogResult); + } +} diff --git a/apps/sales/src/app/core/services/module-switcher.service.ts b/apps/sales/src/app/core/services/module-switcher.service.ts index 0a6d6a126..35fd0c1a6 100644 --- a/apps/sales/src/app/core/services/module-switcher.service.ts +++ b/apps/sales/src/app/core/services/module-switcher.service.ts @@ -25,24 +25,30 @@ export class ModuleSwitcherService { this.branchModuleAction(currentProcess as BranchProcess); break; } - this.moduleSwitcher$.next(_module); + // this.moduleSwitcher$.next(_module); } customerModuleAction(currentProcess: Process) { - this.dom.removeBranchModuleDesign(); - this.store.dispatch(new AppSwitchModule(ModuleSwitcher.Customer)); + this.moduleSwitcher$.next(ModuleSwitcher.Branch); + let commands = ['/dashboard'], + extras = {}; if (currentProcess && currentProcess.currentRoute) { + commands = [currentProcess.currentRoute]; if (currentProcess.currentRouteQueryParams) { - this.router.navigate([currentProcess.currentRoute], { queryParams: currentProcess.currentRouteQueryParams }); - } else { - this.router.navigate([currentProcess.currentRoute]); + extras = { queryParams: currentProcess.currentRouteQueryParams }; } - } else { - this.router.navigate(['/dashboard']); } + this.router.navigate(commands, extras).then(resolve => { + if (resolve) { + this.moduleSwitcher$.next(ModuleSwitcher.Customer); + this.dom.removeBranchModuleDesign(); + this.store.dispatch(new AppSwitchModule(ModuleSwitcher.Customer)); + } + }); } branchModuleAction(branchProcess: BranchProcess) { + this.moduleSwitcher$.next(ModuleSwitcher.Branch); this.dom.addBranchModuleDesign(); this.store.dispatch(new AppSwitchModule(ModuleSwitcher.Branch)); if (branchProcess && branchProcess.currentRoute) { diff --git a/apps/sales/src/app/core/store/state/app.state.ts b/apps/sales/src/app/core/store/state/app.state.ts index 81557a3ab..fac5923c2 100644 --- a/apps/sales/src/app/core/store/state/app.state.ts +++ b/apps/sales/src/app/core/store/state/app.state.ts @@ -22,7 +22,7 @@ import { ReloadGoodsIn } from '../actions/goods-in.actions'; import { ReloadBranchProcess } from '../actions/branch-process.actions'; import { ReloadRemission } from '../actions/remission.actions'; -export const SYNC_DATA_VERSION = 120; +export const SYNC_DATA_VERSION = 128; export class AppStateModel { currentProcesssId: number; diff --git a/apps/sales/src/app/modules/remission/components/remission-leave-dialog/remission-leave-dialog.component.html b/apps/sales/src/app/modules/remission/components/remission-leave-dialog/remission-leave-dialog.component.html index 20dd320fe..12080aae1 100644 --- a/apps/sales/src/app/modules/remission/components/remission-leave-dialog/remission-leave-dialog.component.html +++ b/apps/sales/src/app/modules/remission/components/remission-leave-dialog/remission-leave-dialog.component.html @@ -1,7 +1,7 @@ diff --git a/apps/sales/src/app/modules/remission/components/remission-leave-dialog/remission-leave-dialog.component.ts b/apps/sales/src/app/modules/remission/components/remission-leave-dialog/remission-leave-dialog.component.ts index 1aa6c1039..2bf9fbe67 100644 --- a/apps/sales/src/app/modules/remission/components/remission-leave-dialog/remission-leave-dialog.component.ts +++ b/apps/sales/src/app/modules/remission/components/remission-leave-dialog/remission-leave-dialog.component.ts @@ -1,7 +1,10 @@ import { Component, OnInit, Output, EventEmitter } from '@angular/core'; -import { ModalService } from '@libs/ui'; import { Router } from '@angular/router'; import { Store } from '@ngxs/store'; + +import { ModalService } from '@libs/ui'; +import { ModalConfirmationService } from '@sales/core-services'; + import { ResetBreadcrumbsTo } from 'apps/sales/src/app/core/store/actions/breadcrumb.actions'; import { SetBranchProcessCurrentPath } from 'apps/sales/src/app/core/store/actions/branch-process.actions'; import { ModuleSwitcherService } from 'apps/sales/src/app/core/services/module-switcher.service'; @@ -16,6 +19,7 @@ export class RemissionLeaveDialogComponent implements OnInit { id = 'remission-leave-modal'; constructor( private modalService: ModalService, + private modalConfirmationService: ModalConfirmationService, private router: Router, private store: Store, private moduleSwitcher: ModuleSwitcherService @@ -27,14 +31,15 @@ export class RemissionLeaveDialogComponent implements OnInit { this.modalService.open(this.id); } - closeDialog() { - this.modalService.close(this.id); + cancel() { + this.close(); + this.modalConfirmationService.close(); } - toRemission() { - this.closeDialog(); + confirm() { + this.close(); + this.modalConfirmationService.close(true); this.moduleSwitcher.switchToBranch(); - this.navigateRemissionCreateList(); } navigateRemissionCreateList() { @@ -51,4 +56,8 @@ export class RemissionLeaveDialogComponent implements OnInit { this.router.navigate([path]); this.store.dispatch(new SetBranchProcessCurrentPath(path, true)); } + + private close() { + this.modalService.close(this.id); + } } diff --git a/apps/sales/src/app/modules/remission/guard/can-deactivated.guard.spec.ts b/apps/sales/src/app/modules/remission/guard/can-deactivated.guard.spec.ts new file mode 100644 index 000000000..25d2bd72c --- /dev/null +++ b/apps/sales/src/app/modules/remission/guard/can-deactivated.guard.spec.ts @@ -0,0 +1,15 @@ +import { TestBed, async, inject } from '@angular/core/testing'; + +import { CanDeactivated.GuardGuard } from './can-deactivated.guard.guard'; + +describe('CanDeactivated.GuardGuard', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [CanDeactivated.GuardGuard] + }); + }); + + it('should ...', inject([CanDeactivated.GuardGuard], (guard: CanDeactivated.GuardGuard) => { + expect(guard).toBeTruthy(); + })); +}); diff --git a/apps/sales/src/app/modules/remission/guard/can-deactivated.guard.ts b/apps/sales/src/app/modules/remission/guard/can-deactivated.guard.ts new file mode 100644 index 000000000..b4d95899e --- /dev/null +++ b/apps/sales/src/app/modules/remission/guard/can-deactivated.guard.ts @@ -0,0 +1,30 @@ +import { Injectable } from '@angular/core'; +import { CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; +import { Observable } from 'rxjs'; + +import { AppService, ModalConfirmationService } from '@sales/core-services'; + +import { RemissionListStartedComponent } from './../pages/remission-list-started/remission-list-started.component'; +import { RemissionFinishComponent } from './../pages/remission-finish/remission-finish.component'; +import { ROUTES } from './../remission.const'; + +@Injectable({ + providedIn: 'root' +}) +export class CanDeactivatedGuard implements CanDeactivate { + constructor(private appService: AppService, private modalConfirmationService: ModalConfirmationService) {} + + canDeactivate( + component: RemissionListStartedComponent | RemissionFinishComponent, + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot, + nextState: RouterStateSnapshot + ): Observable | boolean { + if (!nextState.url.includes(ROUTES.BASE)) { + this.appService.showLeavingRemissionModal(); + return this.modalConfirmationService.afterClosed(); + } else { + return true; + } + } +} diff --git a/apps/sales/src/app/modules/remission/guard/index.ts b/apps/sales/src/app/modules/remission/guard/index.ts new file mode 100644 index 000000000..3588d819c --- /dev/null +++ b/apps/sales/src/app/modules/remission/guard/index.ts @@ -0,0 +1 @@ +export { CanDeactivatedGuard } from './can-deactivated.guard'; diff --git a/apps/sales/src/app/modules/remission/pages/remission-finish/remission-finish.component.ts b/apps/sales/src/app/modules/remission/pages/remission-finish/remission-finish.component.ts index 09844c3ce..2236d53ca 100644 --- a/apps/sales/src/app/modules/remission/pages/remission-finish/remission-finish.component.ts +++ b/apps/sales/src/app/modules/remission/pages/remission-finish/remission-finish.component.ts @@ -69,7 +69,6 @@ export class RemissionFinishComponent implements OnInit, OnDestroy { .subscribe(status => { this.pageStatus = status; this.cdrf.detectChanges(); - console.log(this.pageStatus); if (this.pageStatus === RemissionFinishingProcessStatus.containerScanned) { this.containerId = this.store.selectSnapshot(RemissionSelectors.getRemissionContainerId); } diff --git a/apps/sales/src/app/modules/remission/remission-client-routing.module.ts b/apps/sales/src/app/modules/remission/remission-client-routing.module.ts index ae323effe..a6e6b1372 100644 --- a/apps/sales/src/app/modules/remission/remission-client-routing.module.ts +++ b/apps/sales/src/app/modules/remission/remission-client-routing.module.ts @@ -8,6 +8,8 @@ import { RemissionAddProductToRemissionListComponent } from './pages/remission-a // tslint:disable-next-line: max-line-length import { RemissionGenerateShippingDocumentComponent } from './components/remission-generate-shipping-document/remission-generate-shipping-document.component'; +import { CanDeactivatedGuard } from './guard'; + const routes: Routes = [ { path: 'create', @@ -15,15 +17,18 @@ const routes: Routes = [ }, { path: 'started', - component: RemissionListStartedComponent + component: RemissionListStartedComponent, + canDeactivate: [CanDeactivatedGuard] }, { path: 'started/:shippingDocumentId', - component: RemissionListStartedComponent + component: RemissionListStartedComponent, + canDeactivate: [CanDeactivatedGuard] }, { path: 'finish', - component: RemissionFinishComponent + component: RemissionFinishComponent, + canDeactivate: [CanDeactivatedGuard] }, { path: 'search', diff --git a/apps/sales/src/app/modules/remission/remission.const.ts b/apps/sales/src/app/modules/remission/remission.const.ts new file mode 100644 index 000000000..f6e1886a5 --- /dev/null +++ b/apps/sales/src/app/modules/remission/remission.const.ts @@ -0,0 +1,3 @@ +export enum ROUTES { + BASE = 'remission' +} diff --git a/apps/sales/src/app/pages/content/content.component.ts b/apps/sales/src/app/pages/content/content.component.ts index 7ebe992e3..21cb72e77 100644 --- a/apps/sales/src/app/pages/content/content.component.ts +++ b/apps/sales/src/app/pages/content/content.component.ts @@ -35,7 +35,7 @@ export class ContentPageComponent implements OnInit, OnDestroy { this.element.openErrorModal(errors); }); - this.appService.levingRemission$.pipe(takeUntil(this.destroy$)).subscribe(() => { + this.appService.leavingRemission$.pipe(takeUntil(this.destroy$)).subscribe(() => { this.remissionLeavingDialog.openDialog(); }); diff --git a/libs/shared/src/lib/barcode-scanner/native-container.service.ts b/libs/shared/src/lib/barcode-scanner/native-container.service.ts index 22322f881..019393a0c 100644 --- a/libs/shared/src/lib/barcode-scanner/native-container.service.ts +++ b/libs/shared/src/lib/barcode-scanner/native-container.service.ts @@ -16,7 +16,6 @@ export class NativeContainerService { this.wm = fromEvent(this.windowRef.nativeWindow, 'message').pipe( map((e: MessageEvent) => { - console.dir(e); return e.data; }) ); @@ -31,7 +30,7 @@ export class NativeContainerService { public openScanner() { const scanRequest = { - scanBook: true, + scanBook: true }; this.windowRef.nativeWindow.postMessage({ status: 'IN_PROGRESS', data: 'Scan Started' }, '*'); diff --git a/tsconfig.json b/tsconfig.json index b232a3d61..7b2f7b81a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -25,7 +25,8 @@ "shared": ["libs/shared/src"], "shared/*": ["libs/shared/src/*"], "sso": ["libs/sso/src/lib"], - "sso/*": ["libs/sso/src/lib/*"] + "sso/*": ["libs/sso/src/lib/*"], + "@sales/core-services": ["apps/sales/src/app/core/services/index.ts"] } } }