-
Notifications
You must be signed in to change notification settings - Fork 528
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8005 from ever-co/fix/page-route-service
[Feat] Registered Page Routes Dynamically
- Loading branch information
Showing
9 changed files
with
308 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { Route } from '@angular/router'; | ||
import { PageRouteService } from '@gauzy/ui-core/core'; | ||
import { JobLayoutComponent } from './job-layout/job-layout.component'; | ||
|
||
/** | ||
* Creates jobs routes for the application | ||
* @param _pageRouteService An instance of PageRouteService | ||
* @returns An array of Route objects | ||
*/ | ||
export const createRoutes = (_pageRouteService: PageRouteService): Route[] => [ | ||
{ | ||
path: '', | ||
component: JobLayoutComponent, | ||
children: [ | ||
{ | ||
path: '', | ||
redirectTo: 'employee', | ||
pathMatch: 'full' | ||
}, | ||
..._pageRouteService.getPageLocationRoutes('jobs') | ||
] | ||
} | ||
]; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,95 @@ | ||
import { NgModule } from '@angular/core'; | ||
import { CommonModule } from '@angular/common'; | ||
import { JobSearchUiModule } from '@gauzy/plugins/job-search-ui'; | ||
import { RouterModule, ROUTES } from '@angular/router'; | ||
import { SharedModule } from '@gauzy/ui-core/shared'; | ||
import { JobsRoutingModule } from './jobs-routing.module'; | ||
import { PageRouteService } from '@gauzy/ui-core/core'; | ||
import { JobLayoutComponent } from './job-layout/job-layout.component'; | ||
import { JobTableComponentsModule } from './table-components/job-table-components.module'; | ||
import { createRoutes } from './job.routes'; | ||
|
||
@NgModule({ | ||
declarations: [JobLayoutComponent], | ||
imports: [CommonModule, JobsRoutingModule, SharedModule, JobTableComponentsModule, JobSearchUiModule] | ||
imports: [CommonModule, RouterModule.forChild([]), SharedModule, JobTableComponentsModule], | ||
providers: [ | ||
{ | ||
provide: ROUTES, | ||
useFactory: (pageRouteService: PageRouteService) => createRoutes(pageRouteService), | ||
deps: [PageRouteService], | ||
multi: true | ||
} | ||
] | ||
}) | ||
export class JobsModule {} | ||
export class JobsModule { | ||
constructor(readonly _pageRouteService: PageRouteService) { | ||
// Register Job Browser Page Routes | ||
_pageRouteService.registerPageRoute({ | ||
// Register the location 'jobs' | ||
location: 'jobs', | ||
// Register the path 'search' | ||
path: 'search', | ||
// Register the loadChildren function to load the MatchingModule lazy module | ||
loadChildren: () => import('./search/search.module').then((m) => m.SearchModule), | ||
// Register the data object | ||
data: { | ||
selectors: { | ||
date: true, | ||
employee: true, | ||
project: false, | ||
team: false | ||
} | ||
} | ||
}); | ||
// Register Job Matching Page Routes | ||
_pageRouteService.registerPageRoute({ | ||
// Register the location 'jobs' | ||
location: 'jobs', | ||
// Register the path 'matching' | ||
path: 'matching', | ||
// Register the loadChildren function to load the MatchingModule lazy module | ||
loadChildren: () => import('./matching/matching.module').then((m) => m.MatchingModule), | ||
// Register the data object | ||
data: { | ||
selectors: { | ||
date: true, | ||
employee: true, | ||
project: false, | ||
team: false | ||
} | ||
} | ||
}); | ||
// Register Job Proposal Template Page Routes | ||
_pageRouteService.registerPageRoute({ | ||
// Register the location 'jobs' | ||
location: 'jobs', | ||
// Register the path 'proposal-template' | ||
path: 'proposal-template', | ||
// Register the loadChildren function to load the ProposalTemplateModule lazy module | ||
loadChildren: () => | ||
import('./proposal-template/proposal-template.module').then((m) => m.ProposalTemplateModule), | ||
// Register the data object | ||
data: { | ||
selectors: { | ||
project: false | ||
} | ||
} | ||
}); | ||
// Register Job Employee Page Routes | ||
_pageRouteService.registerPageRoute({ | ||
// Register the location 'jobs' | ||
location: 'jobs', | ||
// Register the path 'employee' | ||
path: 'employee', | ||
// Register the loadChildren function to load the EmployeesModule lazy module | ||
loadChildren: () => import('./employees/employees.module').then((m) => m.EmployeesModule), | ||
// Register the data object | ||
data: { | ||
selectors: { | ||
date: true, | ||
employee: true, | ||
project: false, | ||
team: false | ||
} | ||
} | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { Route } from '@angular/router'; | ||
import { PageRouteService } from '@gauzy/ui-core/core'; | ||
|
||
/** | ||
* Creates jobs browse routes for the application | ||
* @param _pageRouteService An instance of PageRouteService | ||
* @returns An array of Route objects | ||
*/ | ||
export const createRoutes = (_pageRouteService: PageRouteService): Route[] => []; |
14 changes: 14 additions & 0 deletions
14
packages/ui-core/core/src/lib/common/component-registry-types.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/** | ||
* @description | ||
* Type representing the possible page locations for dynamic routes and tabs. | ||
* | ||
* This type is used to identify different sections of the application where dynamic | ||
* routes and tabs can be registered. Each value corresponds to a specific page or | ||
* section in the application. This allows for flexible and dynamic routing based | ||
* on the context and requirements of the application. | ||
* | ||
* Possible values: | ||
* - 'dashboard': The main dashboard page of the application. | ||
* - 'jobs': The jobs or job search section of the application. | ||
*/ | ||
export type PageRouteLocationId = 'dashboard' | 'jobs'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './page-route.service'; | ||
export * from './page-route.types'; |
131 changes: 131 additions & 0 deletions
131
packages/ui-core/core/src/lib/services/page/page-route.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
import { Injectable } from '@angular/core'; | ||
import { Route } from '@angular/router'; | ||
import { PageRouteLocationConfig } from './page-route.types'; | ||
import { PageRouteLocationId } from '../../common/component-registry-types'; | ||
|
||
@Injectable({ | ||
providedIn: 'root' | ||
}) | ||
export class PageRouteService { | ||
/** | ||
* Registry for storing page route configurations. | ||
* | ||
* This Map stores arrays of PageRouteConfig objects, keyed by PageRouteLocationId. | ||
*/ | ||
private readonly registry = new Map<PageRouteLocationId, PageRouteLocationConfig[]>(); | ||
|
||
/** | ||
* Register a single page route configuration. | ||
* | ||
* This method registers a new page route configuration in the service's internal registry. | ||
* It ensures that the configuration has a valid location property and checks if a route | ||
* with the same location already exists to prevent duplicate entries. If the configuration | ||
* is valid and unique, it adds it to the registry. | ||
* | ||
* @param config The configuration for the page route. | ||
* @throws Will throw an error if the configuration does not have a location property. | ||
* @throws Will throw an error if a route with the same location has already been registered. | ||
*/ | ||
registerPageRoute(config: PageRouteLocationConfig): void { | ||
// Check if the configuration has a location property | ||
if (!config.location) { | ||
throw new Error('Page route configuration must have a location property'); | ||
} | ||
|
||
// Get all registered routes for the specified location | ||
const routes = this.registry.get(config.location) || []; | ||
|
||
// Check if a route with the same location and path already exists | ||
const isMatchingRoute = routes.some( | ||
(route: PageRouteLocationConfig) => route.location === config.location && route.path === config.path | ||
); | ||
|
||
// Check if a route with the same location already exists | ||
if (isMatchingRoute) { | ||
throw new Error( | ||
`A page with the location "${config.location}" and path "${config.path}" has already been registered` | ||
); | ||
} | ||
|
||
// Add the new route configuration to the list of routes for the specified location | ||
routes.push(config); | ||
|
||
// Update the registry with the new list of routes for the specified location | ||
this.registry.set(config.location, routes); | ||
} | ||
|
||
/** | ||
* Register multiple page route configurations. | ||
* | ||
* This method registers multiple new page route configurations in the service's internal registry. | ||
* It ensures that each configuration has a valid location property and checks if a route with the same | ||
* location already exists to prevent duplicate entries. If the configurations are valid and unique, | ||
* it adds them to the registry. | ||
* | ||
* @param configs The array of configurations for the page routes. | ||
* @throws Will throw an error if a route with the same location and path has already been registered. | ||
*/ | ||
registerPageRoutes(configs: PageRouteLocationConfig[]): void { | ||
configs.forEach((config) => this.registerPageRoute(config)); | ||
} | ||
|
||
/** | ||
* Get all registered routes for a specific location. | ||
* | ||
* This method retrieves all registered route configurations for a specified location identifier. | ||
* It maps the internal route configurations to Angular Route objects. | ||
* | ||
* @param location The page location identifier. | ||
* @returns The array of registered routes for the specified location. | ||
*/ | ||
getPageLocationRoutes(location: PageRouteLocationId): Route[] { | ||
// Get all registered routes for the specified location | ||
let configs = this.registry.get(location) || []; | ||
|
||
// Use a Set to track unique location-path combinations | ||
const locationPaths = new Set<string>(); | ||
|
||
// Create a unique identifier for the combination of location and path | ||
configs = configs.filter((config: PageRouteLocationConfig) => { | ||
// Create a unique identifier for the combination of location and path | ||
const identifier = `${config.location}-${config.path}`; | ||
|
||
// Check if the unique identifier is already in the Set | ||
if (locationPaths.has(identifier)) { | ||
return false; // Duplicate found, filter it out | ||
} | ||
|
||
// Add the unique identifier to the Set | ||
locationPaths.add(identifier); | ||
return true; // Not a duplicate, keep it | ||
}); | ||
|
||
// Map each route configuration to a route object | ||
return configs.map((config: PageRouteLocationConfig) => { | ||
// Create a new route object | ||
const route: Route = { | ||
path: config.path, | ||
pathMatch: config.path ? 'prefix' : 'full', | ||
data: config.data || {}, | ||
canActivate: config.canActivate || [] | ||
}; | ||
|
||
// Check if the route configuration has a component or loadChildren property | ||
if (config.component) { | ||
// Set the component property to the config object | ||
route.component = config.component; | ||
} else if (config.loadChildren) { | ||
// Set the loadChildren property to the config object | ||
route.loadChildren = config.loadChildren; | ||
} | ||
|
||
// Check if the route configuration has additional route options | ||
if (config.route) { | ||
Object.assign(route, config.route); | ||
} | ||
|
||
// Return the route object | ||
return route; | ||
}); | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
packages/ui-core/core/src/lib/services/page/page-route.types.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { Route } from '@angular/router'; | ||
import { PageRouteLocationId } from '../../common/component-registry-types'; | ||
|
||
/** | ||
* Page route configuration. | ||
*/ | ||
export interface PageRouteLocationConfig { | ||
/** | ||
* The location identifier for the page route. | ||
*/ | ||
location: PageRouteLocationId; | ||
|
||
/** | ||
* The path to navigate to when the page is selected. | ||
*/ | ||
path: string; | ||
|
||
/** | ||
* Optional component to render for the route. | ||
*/ | ||
component?: any; | ||
|
||
/** | ||
* Optional loadChildren function to load a module lazily. | ||
*/ | ||
loadChildren?: () => Promise<any>; | ||
|
||
/** | ||
* Optional data to associate with the route. | ||
*/ | ||
data?: any; | ||
|
||
/** | ||
* Optional guards to apply to the route. | ||
*/ | ||
canActivate?: any[]; | ||
|
||
/** | ||
* Additional route configuration options. | ||
*/ | ||
route?: Route; | ||
} |