Skip to content

Commit

Permalink
fix(admin-ui): Fix support for canDeactivate guard on angular routes
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbromley committed Jun 27, 2024
1 parent 74a8c05 commit 6d9af1d
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,59 @@
import { Component, inject } from '@angular/core';
import {
Component,
ComponentRef,
EventEmitter,
inject,
Input,
OnInit,
Output,
ViewContainerRef,
} from '@angular/core';
import { SharedModule } from '../../shared/shared.module';
import { ROUTE_COMPONENT_OPTIONS, RouteComponent } from './route.component';

/**
* @description
* This component is used internally to allow us to dynamically load a component
* like with `*ngComponentOutlet`, but with the ability to get a reference to the
* created ComponentRef. This can then be used to delegate lifecycle events like
* `canDeactivate` to the loaded component.
*/
@Component({
selector: 'vdr-dynamic-component-loader',
template: ``,
standalone: true,
imports: [SharedModule],
})
export class DynamicComponentLoaderComponent implements OnInit {
@Input() componentType: any;
@Output() loaded = new EventEmitter<ComponentRef<any>>();
constructor(private viewContainer: ViewContainerRef) {}

ngOnInit() {
const componentRef = this.viewContainer.createComponent(this.componentType);
this.loaded.emit(componentRef);
}
}

@Component({
selector: 'vdr-angular-route-component',
template: ` <vdr-route-component><ng-container *ngComponentOutlet="component" /></vdr-route-component> `,
template: `
<vdr-route-component>
<vdr-dynamic-component-loader [componentType]="component" (loaded)="componentLoaded($event)" />
</vdr-route-component>
`,
standalone: true,
imports: [SharedModule, RouteComponent],
imports: [SharedModule, RouteComponent, DynamicComponentLoaderComponent],
})
export class AngularRouteComponent {
protected component = inject(ROUTE_COMPONENT_OPTIONS).component;
protected componentRef: ComponentRef<any>;

componentLoaded(componentRef: ComponentRef<any>) {
this.componentRef = componentRef;
}

canDeactivate() {
return this.componentRef?.instance?.canDeactivate?.();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
Expand All @@ -8,16 +7,11 @@ import { DeactivateAware } from '../../../common/deactivate-aware';
import { ModalService } from '../../../providers/modal/modal.service';

@Injectable()
export class CanDeactivateDetailGuard {
constructor(private modalService: ModalService, private router: Router) {}
export class CanDeactivateDetailGuard {
constructor(private modalService: ModalService) {}

canDeactivate(
component: DeactivateAware,
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot,
nextState?: RouterStateSnapshot,
): boolean | Observable<boolean> {
if (!component.canDeactivate()) {
canDeactivate(component: DeactivateAware): boolean | Observable<boolean> {
if (typeof component.canDeactivate === 'function' && !component.canDeactivate()) {
return this.modalService
.dialog({
title: _('common.confirm-navigation'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ export class AngularUiComponent {
private pageMetadataService: PageMetadataService,
) {}

canDeactivate() {
return this.pageTitleControl.pristine;
}

updateTitle() {
const title = this.pageTitleControl.value;
if (title) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { registerRouteComponent } from '@vendure/admin-ui/core';
import { CanDeactivateDetailGuard, registerRouteComponent } from '@vendure/admin-ui/core';
import { registerReactRouteComponent } from '@vendure/admin-ui/react';

import { AngularUiComponent } from './angular-components/angular-ui/angular-ui.component';
Expand All @@ -14,5 +14,8 @@ export default [
path: 'angular-ui',
component: AngularUiComponent,
title: 'Angular UI',
routeConfig: {
canDeactivate: [CanDeactivateDetailGuard],
},
}),
];

0 comments on commit 6d9af1d

Please sign in to comment.