Skip to content

Commit

Permalink
Merge pull request #8446 from ever-co/fix/#8442-import-export-page
Browse files Browse the repository at this point in the history
[Fix] Import/Export Page Not Working
  • Loading branch information
rahul-rocket authored Oct 17, 2024
2 parents f33e8f6 + a7d17af commit 2975fe6
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Component, OnInit } from '@angular/core';

@Component({
selector: 'ngx-external-redirect',
template: ''
})
export class ExternalRedirectComponent implements OnInit {
constructor() {}

ngOnInit() {
console.log('Redirecting to external URL');
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { InjectionToken, NgModule } from '@angular/core';
import { Routes, RouterModule, ActivatedRouteSnapshot } from '@angular/router';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { PermissionsEnum } from '@gauzy/contracts';
import { PermissionsGuard } from '@gauzy/ui-core/core';
import { ExternalRedirectGuard, PermissionsGuard } from '@gauzy/ui-core/core';
import { ImportExportComponent } from './import-export.component';

const externalUrlProvider = new InjectionToken('externalUrlRedirectResolver');
import { ExternalRedirectComponent } from './external-redirect/external-redirect.component';

const routes: Routes = [
{
Expand All @@ -28,24 +27,13 @@ const routes: Routes = [
},
{
path: 'external-redirect',
resolve: {
url: externalUrlProvider
},
canActivate: [externalUrlProvider]
component: ExternalRedirectComponent,
canActivate: [ExternalRedirectGuard]
}
];

@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
providers: [
{
provide: externalUrlProvider,
useValue: (route: ActivatedRouteSnapshot) => {
const externalUrl = route.paramMap.get('redirect');
window.open(externalUrl, '_blank');
}
}
]
exports: [RouterModule]
})
export class ImportExportRoutingModule {}
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,19 @@ import {
} from '@gauzy/contracts';
import { Environment, environment } from '@gauzy/ui-config';
import { TranslationBaseComponent } from '@gauzy/ui-core/i18n';
import { ErrorHandlingService, Store, ToastrService, UsersOrganizationsService } from '@gauzy/ui-core/core';
import { ExportAllService, GauzyCloudService } from '@gauzy/ui-core/core';
import {
ErrorHandlingService,
ExportAllService,
GauzyCloudService,
Store,
ToastrService,
UsersOrganizationsService
} from '@gauzy/ui-core/core';

@UntilDestroy({ checkProperties: true })
@Component({
selector: 'ngx-import-export',
templateUrl: './import-export.html',
templateUrl: './import-export.component.html',
styleUrls: ['./import-export.component.scss']
})
export class ImportExportComponent extends TranslationBaseComponent implements OnInit {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { DialogsModule } from '@gauzy/ui-core/shared';
import { ImportExportRoutingModule } from './import-export-routing.module';
import { ImportExportComponent } from './import-export.component';
import { ExternalRedirectComponent } from './external-redirect/external-redirect.component';

@NgModule({
imports: [
Expand All @@ -19,7 +20,7 @@ import { ImportExportComponent } from './import-export.component';
NgxPermissionsModule.forChild(),
TranslateModule.forChild()
],
declarations: [ImportExportComponent],
declarations: [ImportExportComponent, ExternalRedirectComponent],
providers: []
})
export class ImportExportModule {}
25 changes: 25 additions & 0 deletions packages/ui-core/core/src/lib/guards/external-redirect.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';

@Injectable({
providedIn: 'root'
})
export class ExternalRedirectGuard {
/**
* Checks if navigation can proceed.
*
* @param route - The activated route snapshot containing route parameters.
* @returns {boolean} - Returns false to prevent navigation to the route and true to allow navigation.
*/
canActivate(route: ActivatedRouteSnapshot): boolean {
const externalUrl = route.paramMap.get('redirect');

// If an external URL is provided in the route parameters
if (externalUrl) {
window.open(externalUrl, '_blank'); // Open the URL in a new tab
return false; // Prevent navigation to the current route
}

return true; // Allow navigation if no external URL is found
}
}
1 change: 1 addition & 0 deletions packages/ui-core/core/src/lib/guards/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './invite.guard';
export * from './permission.guard';
export * from './role.guard';
export * from './external-redirect.guard';
79 changes: 65 additions & 14 deletions packages/ui-core/core/src/lib/guards/permission.guard.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// src/app/permissions.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router, CanActivateChild } from '@angular/router';
import { Observable, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable, catchError, map, of } from 'rxjs';
import { PermissionsEnum } from '@gauzy/contracts';
import { AuthService } from '../services';

@Injectable({
providedIn: 'root'
})
export class PermissionsGuard implements CanActivate, CanActivateChild {
export class PermissionsGuard {
constructor(private readonly _authService: AuthService, private readonly _router: Router) {}

/**
Expand Down Expand Up @@ -42,30 +42,81 @@ export class PermissionsGuard implements CanActivate, CanActivateChild {
*/
private _hasPermissions(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
const permissions = route.data['permissions'];
const defaultRedirectTo = '/pages/dashboard'; // Default redirection path

// No permissions required, allow access
if (!permissions || (permissions.only && permissions.only.length === 0)) {
return of(true); // No permissions required, allow access
return of(true);
}

// Check if the user has the necessary permissions
const isFunction = typeof permissions.redirectTo === 'function';
const redirectTo = isFunction ? permissions.redirectTo(route, state) : permissions.redirectTo;
// Retrieve required permissions from route
const requiredPermissions = this.getRequiredPermissions(permissions, route);
// Check if required permissions are valid
if (!requiredPermissions) {
return of(false); // Block access if permissions aren't valid
}

// Determine redirect path
const redirectTo = this.getRedirectPath(permissions, route, state);

// Check if the user has the necessary permissions
return this._authService.hasPermissions(...permissions.only).pipe(
return this._authService.hasPermissions(...requiredPermissions).pipe(
map((hasPermission) => {
if (hasPermission) {
return true;
} else {
this._router.navigate([redirectTo || defaultRedirectTo]);
return false;
}
this._router.navigate([redirectTo]);
return false;
}),
catchError(() => {
this._router.navigate([redirectTo || defaultRedirectTo]);
this._router.navigate([redirectTo]);
return of(false);
})
);
}

/**
* Retrieve the required permissions from the route.
*
* @param {any} permissions - The permissions object from the route.
* @param {ActivatedRouteSnapshot} route - The current route.
* @returns {PermissionsEnum[] | null} - An array of required permissions or null if invalid.
*/
private getRequiredPermissions(permissions: any, route: ActivatedRouteSnapshot): PermissionsEnum[] | null {
let requiredPermissions: PermissionsEnum[] | null = null;

// Check if permissions.only is a function
if (typeof permissions.only === 'function') {
requiredPermissions = permissions.only(route) || [];
} else {
requiredPermissions = permissions.only || [];
}

// Ensure it's an array
if (!Array.isArray(requiredPermissions)) {
console.error('Expected permissions.only to be an array but received:', requiredPermissions);
return null; // Block access if permissions aren't valid
}

return requiredPermissions;
}

/**
* Determine the redirect path based on permissions configuration.
*
* @param {any} permissions - The permissions object from the route.
* @param {ActivatedRouteSnapshot} route - The current route.
* @param {RouterStateSnapshot} state - The current state of the router.
* @returns {string} - The redirect path or the default redirection path.
*/
private getRedirectPath(permissions: any, route: ActivatedRouteSnapshot, state: RouterStateSnapshot): string {
const defaultRedirectTo = '/pages/dashboard'; // Default redirection path

// Check if redirectTo is a function and call it
if (typeof permissions.redirectTo === 'function') {
return permissions.redirectTo(route, state) || defaultRedirectTo; // Fallback to default
}

// Return the specified redirectTo or the default
return permissions.redirectTo || defaultRedirectTo;
}
}

0 comments on commit 2975fe6

Please sign in to comment.