Browse Source

Change method and property names in the routes.service.ts

pull/19440/head
Mustafa Daglioglu 2 years ago
parent
commit
9ebfe62ee7
  1. 8
      docs/en/UI/Angular/Modifying-the-Menu.md
  2. 81
      npm/ng-packs/packages/core/src/lib/services/routes.service.ts
  3. 37
      npm/ng-packs/packages/core/src/lib/tests/routes.service.spec.ts

8
docs/en/UI/Angular/Modifying-the-Menu.md

@ -153,7 +153,7 @@ export class AppModule {}
``` ```
**Note:** **Note:**
Route items's `name` property is must be a unique key. If there are multiple items with the same name, the last one will be displayed in the menu. If you want to display multiple items with the same name, you can call the `disableFiltering` method of the `RoutesService` to disable the filtering. Route items's `name` property is must be a unique key. If there are multiple items with the same name, the last one will be displayed in the menu. If you want to display multiple items with the same name, you can call the `setSingularizeStatus(false)` method of the `RoutesService` to disable the singularization of the names. This method should be called before adding the routes. If you want to enable the singularization of the names, you can call the `setSingularizeStatus(true)` method of the `RoutesService` to enable the singularization of the names. This method should be called before adding the routes. The default value of the singularization status is `true`. The default value of the singularization status is `true`.
```typescript ```typescript
import { RoutesService } from '@abp/ng.core'; import { RoutesService } from '@abp/ng.core';
@ -162,7 +162,7 @@ import { Component } from '@angular/core';
@Component(/* component metadata */) @Component(/* component metadata */)
export class AppComponent { export class AppComponent {
constructor(private routes: RoutesService) { constructor(private routes: RoutesService) {
routes.disableFiltering(); routes.setSingularizeStatus(false);
} }
} }
``` ```
@ -241,7 +241,7 @@ After adding the `routes` property as described above, the navigation menu looks
## How to Patch or Remove a Navigation Element ## How to Patch or Remove a Navigation Element
The `patch` method of `RoutesService` finds a route by its name and replaces its configuration with the new configuration passed as the second parameter. Similarly, `remove` method finds a route and removes it along with its children. Also you can use `delete` method to delete the routes with given properties. The `patch` method of `RoutesService` finds a route by its name and replaces its configuration with the new configuration passed as the second parameter. Similarly, `remove` method finds a route and removes it along with its children. Also you can use `removeByParams` method to delete the routes with given properties.
```js ```js
// this.routes is instance of RoutesService // this.routes is instance of RoutesService
@ -266,7 +266,7 @@ this.routes.patch('::Menu:Home', newHomeRouteConfig);
this.routes.remove(['Your navigation']); this.routes.remove(['Your navigation']);
// or // or
this.routes.delete({ name: 'Your navigation' }); this.routes.removeByParams({ name: 'Your navigation' });
``` ```
- Moved the _Home_ navigation under the _Administration_ dropdown based on given `parentName`. - Moved the _Home_ navigation under the _Administration_ dropdown based on given `parentName`.

81
npm/ng-packs/packages/core/src/lib/services/routes.service.ts

@ -26,7 +26,7 @@ export abstract class AbstractTreeService<T extends { [key: string | number | sy
private _visible$ = new BehaviorSubject<TreeNode<T>[]>([]); private _visible$ = new BehaviorSubject<TreeNode<T>[]>([]);
protected othersGroup: string; protected othersGroup: string;
private filterRoutesEnabled = true; protected shouldSingularizeRoutes = true;
get flat(): T[] { get flat(): T[] {
return this._flat$.value; return this._flat$.value;
@ -94,53 +94,25 @@ export abstract class AbstractTreeService<T extends { [key: string | number | sy
} }
add(items: T[]): T[] { add(items: T[]): T[] {
if (this.filterRoutesEnabled) { let flatItems: T[] = [];
const map = new Map<string, T>();
items.forEach(item => map.set(item[this.id], item));
const flatItems = this.filterWith(map);
map.forEach(pushValueTo(flatItems));
flatItems.sort(this.sort); if (!this.shouldSingularizeRoutes) {
return this.publish(flatItems); flatItems = [...this.flat, ...items];
} else {
const flatItems = this.flat.concat(items);
flatItems.sort(this.sort);
return this.publish(flatItems);
} }
}
delete(params: Partial<T>): T[] {
const willRemoveItems = this.flat.filter(item => {
const keys = Object.keys(params) as Array<keyof Partial<T>>;
const isValid = keys.every(key => item[key] === params[key]);
return isValid;
});
if (willRemoveItems?.length) {
willRemoveItems.forEach(item => {
this.delete({
[this.parentId]: item[this.id],
} as Partial<T>);
});
const flatItems = this.flat.filter(item => !willRemoveItems.includes(item)); if (this.shouldSingularizeRoutes) {
return this.publish(flatItems); const map = new Map<string, T>();
items.forEach(item => map.set(item[this.id], item));
flatItems = this.filterWith(map);
map.forEach(pushValueTo(flatItems));
} }
return this.flat; flatItems.sort(this.sort);
}
disableFiltering(): void {
this.filterRoutesEnabled = false;
}
enableFiltering(): void { return this.publish(flatItems);
this.filterRoutesEnabled = true;
} }
find(predicate: (item: TreeNode<T>) => boolean, tree = this.tree): TreeNode<T> | null { find(predicate: (item: TreeNode<T>) => boolean, tree = this.tree): TreeNode<T> | null {
return tree.reduce<TreeNode<T> | null>((acc, node) => { return tree.reduce<TreeNode<T> | null>((acc, node) => {
if (acc) { if (acc) {
return acc; return acc;
@ -180,6 +152,29 @@ export abstract class AbstractTreeService<T extends { [key: string | number | sy
return this.publish(flatItems); return this.publish(flatItems);
} }
removeByParams(params: Partial<T>): T[] | null {
if (!params) {
return null;
}
const keys = Object.keys(params) as Array<keyof Partial<T>>;
if (keys.length === 0) {
return null;
}
const excludedList = this.flat.filter(item => keys.every(key => item[key] === params[key]));
if (!excludedList?.length) {
return null;
}
for (const item of excludedList) {
this.removeByParams({ [this.parentId]: item[this.id] } as Partial<T>);
}
const flatItems = this.flat.filter(item => !excludedList.includes(item));
return this.publish(flatItems);
}
search(params: Partial<T>, tree = this.tree): TreeNode<T> | null { search(params: Partial<T>, tree = this.tree): TreeNode<T> | null {
const searchKeys = Object.keys(params) as Array<keyof Partial<T>>; const searchKeys = Object.keys(params) as Array<keyof Partial<T>>;
@ -188,13 +183,17 @@ export abstract class AbstractTreeService<T extends { [key: string | number | sy
return acc; return acc;
} }
if (searchKeys.every(key => node.item[key] === params[key])) { if (searchKeys.every(key => node[key] === params[key])) {
return node; return node;
} }
return this.search(params, node.children); return this.search(params, node.children);
}, null); }, null);
} }
setSingularizeStatus(singularize = true): void {
this.shouldSingularizeRoutes = singularize;
}
} }
@Injectable() @Injectable()

37
npm/ng-packs/packages/core/src/lib/tests/routes.service.spec.ts

@ -172,9 +172,9 @@ describe('Routes Service', () => {
}); });
}); });
describe('#disableFiltering', () => { describe('#setSingularizeStatus', () => {
it('should allow to duplicate routes', () => { it('should allow to duplicate routes when called with false', () => {
service.disableFiltering(); service.setSingularizeStatus(false);
service.add(routes); service.add(routes);
@ -183,8 +183,8 @@ describe('Routes Service', () => {
expect(flat.length).toBe(routes.length); expect(flat.length).toBe(routes.length);
}); });
it('should allow to duplicate routes with the same name', () => { it('should allow to duplicate routes with the same name when called with false', () => {
service.disableFiltering(); service.setSingularizeStatus(false);
service.add([...routes, { path: '/foo/bar/test', name: 'bar', parentName: 'foo', order: 2 }]); service.add([...routes, { path: '/foo/bar/test', name: 'bar', parentName: 'foo', order: 2 }]);
@ -193,8 +193,8 @@ describe('Routes Service', () => {
expect(flat.length).toBe(routes.length + 1); expect(flat.length).toBe(routes.length + 1);
}); });
it('should allow to routes with the same name but different parentName', () => { it('should allow to routes with the same name but different parentName when called with false', () => {
service.disableFiltering(); service.setSingularizeStatus(false);
service.add([ service.add([
{ path: '/foo/bar', name: 'bar', parentName: 'foo', order: 2 }, { path: '/foo/bar', name: 'bar', parentName: 'foo', order: 2 },
@ -205,15 +205,13 @@ describe('Routes Service', () => {
expect(flat.length).toBe(2); expect(flat.length).toBe(2);
}); });
});
describe('#enableFiltering', () => { it('should not allow to duplicate routes when called with true', () => {
it('should not allow to duplicate routes', () => { service.setSingularizeStatus(false);
service.disableFiltering();
service.add(routes); service.add(routes);
service.enableFiltering(); service.setSingularizeStatus(true);
service.add(routes); service.add(routes);
@ -222,8 +220,8 @@ describe('Routes Service', () => {
expect(flat.length).toBe(5); expect(flat.length).toBe(5);
}); });
it('should not allow to duplicate routes with the same name', () => { it('should not allow to duplicate routes with the same name when called with true', () => {
service.enableFiltering(); service.setSingularizeStatus(true);
service.add([...routes, { path: '/foo/bar/test', name: 'bar', parentName: 'any', order: 2 }]); service.add([...routes, { path: '/foo/bar/test', name: 'bar', parentName: 'any', order: 2 }]);
const flat = service.flat; const flat = service.flat;
@ -302,11 +300,11 @@ describe('Routes Service', () => {
}); });
}); });
describe('#delete', () => { describe('#removeByParams', () => {
it('should remove route based on given route', () => { it('should remove route based on given route', () => {
service.add(routes); service.add(routes);
service.delete({ service.removeByParams({
name: 'bar', name: 'bar',
parentName: 'foo', parentName: 'foo',
}); });
@ -321,7 +319,7 @@ describe('Routes Service', () => {
}); });
it('should remove if more than one route has the same properties', () => { it('should remove if more than one route has the same properties', () => {
service.disableFiltering(); service.setSingularizeStatus(false);
service.add([ service.add([
...routes, ...routes,
@ -335,7 +333,7 @@ describe('Routes Service', () => {
}, },
]); ]);
service.delete({ service.removeByParams({
path: '/foo/bar', path: '/foo/bar',
name: 'bar', name: 'bar',
parentName: 'foo', parentName: 'foo',
@ -345,7 +343,6 @@ describe('Routes Service', () => {
}); });
const flat = service.flat; const flat = service.flat;
console.log(flat);
expect(flat.length).toBe(5); expect(flat.length).toBe(5);
const notFound = service.search({ const notFound = service.search({
@ -363,7 +360,7 @@ describe('Routes Service', () => {
service.add(routes); service.add(routes);
const flatLengthBeforeRemove = service.flat.length; const flatLengthBeforeRemove = service.flat.length;
service.delete({ service.removeByParams({
name: 'bar', name: 'bar',
parentName: 'baz', parentName: 'baz',
}); });

Loading…
Cancel
Save