Skip to content

Commit

Permalink
fix(admin-ui): Do not run CanDeactivateGuard when switching tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbromley committed May 2, 2019
1 parent f8521db commit d8e6258
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { normalizeString } from 'shared/normalize-string';
import { CustomFieldConfig } from 'shared/shared-types';
import { notNullOrUndefined } from 'shared/shared-utils';
import { unique } from 'shared/unique';
import { IGNORE_CAN_DEACTIVATE_GUARD } from 'src/app/shared/providers/routing/can-deactivate-detail-guard';

import { BaseDetailComponent } from '../../../common/base-detail.component';
import { createUpdatedTranslatable } from '../../../common/utilities/create-updated-translatable';
Expand Down Expand Up @@ -138,6 +139,9 @@ export class ProductDetailComponent extends BaseDetailComponent<ProductWithVaria
navigateToTab(tabName: TabName) {
this.router.navigate(['./', { tab: tabName }], {
relativeTo: this.route,
state: {
[IGNORE_CAN_DEACTIVATE_GUARD]: true,
},
});
}

Expand Down Expand Up @@ -315,6 +319,7 @@ export class ProductDetailComponent extends BaseDetailComponent<ProductWithVaria
this.notificationService.success(_('common.notify-update-success'), {
entity: 'Product',
});
this.changeDetector.markForCheck();
},
err => {
this.notificationService.error(_('common.notify-update-error'), {
Expand Down
16 changes: 10 additions & 6 deletions admin-ui/src/app/common/base-detail.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { FormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { ActivatedRoute, Data, Router } from '@angular/router';
import { combineLatest, Observable, of, Subject } from 'rxjs';
import { map, shareReplay, switchMap, takeUntil, tap } from 'rxjs/operators';
import { distinctUntilChanged, map, share, shareReplay, switchMap, takeUntil, tap } from 'rxjs/operators';
import { LanguageCode } from 'shared/generated-types';
import { CustomFieldConfig, CustomFields } from 'shared/shared-types';

Expand All @@ -26,8 +26,10 @@ export abstract class BaseDetailComponent<Entity extends { id: string }> {

init() {
this.entity$ = this.route.data.pipe(
switchMap(data => data.entity),
tap<any>(entity => (this.id = entity.id)),
switchMap<Data, Entity>(data => data.entity),
distinctUntilChanged((a, b) => a.id === b.id),
tap(entity => (this.id = entity.id)),
shareReplay(1),
);
this.isNew$ = this.entity$.pipe(
map(entity => entity.id === ''),
Expand All @@ -36,14 +38,16 @@ export abstract class BaseDetailComponent<Entity extends { id: string }> {
this.languageCode$ = this.route.paramMap.pipe(
map(paramMap => paramMap.get('lang')),
map(lang => (!lang ? getDefaultLanguage() : (lang as LanguageCode))),
distinctUntilChanged(),
shareReplay(1),
);

this.availableLanguages$ = this.serverConfigService.getAvailableLanguages();

combineLatest(this.entity$, this.languageCode$)
.pipe(takeUntil(this.destroy$))
.subscribe(([facet, languageCode]) => {
this.setFormValues(facet, languageCode);
.subscribe(([entity, languageCode]) => {
this.setFormValues(entity, languageCode);
this.detailForm.markAsPristine();
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
background-color: $color-grey-1;
position: sticky;
top: -24px;
z-index: 5;
z-index: 25;
border-bottom: 1px solid $color-grey-3;
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanDeactivate, RouterStateSnapshot } from '@angular/router';
import { ActivatedRouteSnapshot, CanDeactivate, Router, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { _ } from 'src/app/core/providers/i18n/mark-for-extraction';

import { BaseDetailComponent } from '../../../common/base-detail.component';
import { ModalService } from '../modal/modal.service';

/**
* When added to the [state object](https://angular.io/api/router/NavigationExtras#state), this will
* skip the CanDeactivateDetailGuard.
*/
export const IGNORE_CAN_DEACTIVATE_GUARD = 'IGNORE_CAN_DEACTIVATE_GUARD';

@Injectable()
export class CanDeactivateDetailGuard implements CanDeactivate<BaseDetailComponent<any>> {
constructor(private modalService: ModalService) {}
constructor(private modalService: ModalService, private router: Router) {}

canDeactivate(
component: BaseDetailComponent<any>,
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot,
nextState?: RouterStateSnapshot,
): boolean | Observable<boolean> {
const nav = this.router.getCurrentNavigation();
if (nav) {
if (nav.extras.state && nav.extras.state[IGNORE_CAN_DEACTIVATE_GUARD] != null) {
return true;
}
}
if (component.detailForm && component.detailForm.dirty) {
return this.modalService
.dialog({
Expand Down

0 comments on commit d8e6258

Please sign in to comment.