@ngrdt/router 0.0.95 → 0.0.97
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ngrdt-router.mjs +100 -23
- package/fesm2022/ngrdt-router.mjs.map +1 -1
- package/index.d.ts +25 -11
- package/package.json +4 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, Injectable, EnvironmentInjector, runInInjectionContext, DestroyRef, Renderer2, ElementRef, Input, Directive, afterNextRender, input, linkedSignal, booleanAttribute, effect } from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, Injectable, EnvironmentInjector, runInInjectionContext, DestroyRef, Renderer2, ElementRef, Input, Directive, afterNextRender, input, linkedSignal, booleanAttribute, computed, effect } from '@angular/core';
|
|
3
3
|
import { defer, of, filter, take, fromEvent } from 'rxjs';
|
|
4
4
|
import { PlatformLocation, Location } from '@angular/common';
|
|
5
5
|
import * as i1 from '@angular/router';
|
|
@@ -36,6 +36,15 @@ class RdtParameters {
|
|
|
36
36
|
this.params[route.absolutePath] = params;
|
|
37
37
|
return this;
|
|
38
38
|
}
|
|
39
|
+
append(route, params) {
|
|
40
|
+
const existing = this.get(route) ?? {};
|
|
41
|
+
this.params[route.absolutePath] = { ...existing, ...params };
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
setAll(params) {
|
|
45
|
+
this.params = { ...this.params, ...params.params };
|
|
46
|
+
return this;
|
|
47
|
+
}
|
|
39
48
|
*[Symbol.iterator]() {
|
|
40
49
|
const keys = Object.keys(this.params);
|
|
41
50
|
keys.sort((a, b) => a.length - b.length);
|
|
@@ -190,13 +199,12 @@ class RdtRouterService {
|
|
|
190
199
|
const parsed = this.parseAbsoluteUrl();
|
|
191
200
|
if (!parsed) {
|
|
192
201
|
console.warn('No route matches current url.');
|
|
193
|
-
return
|
|
202
|
+
return null;
|
|
194
203
|
}
|
|
195
204
|
currentRoute = parsed.route;
|
|
196
205
|
}
|
|
197
206
|
const url = this.location.path();
|
|
198
|
-
|
|
199
|
-
return currentRoute.parseAbsoluteUrl(stripped);
|
|
207
|
+
return currentRoute.parseAbsoluteUrl(url);
|
|
200
208
|
}
|
|
201
209
|
isParentOfCurrentLocation(route) {
|
|
202
210
|
return true;
|
|
@@ -337,7 +345,16 @@ class RdtAngularRoute {
|
|
|
337
345
|
};
|
|
338
346
|
const guard = (route, state) => {
|
|
339
347
|
const injector = inject(EnvironmentInjector);
|
|
340
|
-
|
|
348
|
+
const rdtRouter = inject(RdtRouterService);
|
|
349
|
+
const parsed = rdtRouter.parseAbsoluteUrl(state.url);
|
|
350
|
+
const combinedParams = parsed?.params ?? {
|
|
351
|
+
params: {},
|
|
352
|
+
query: {},
|
|
353
|
+
state: {},
|
|
354
|
+
route: new RdtParameters(),
|
|
355
|
+
};
|
|
356
|
+
combinedParams.query = route.queryParams;
|
|
357
|
+
if (runInInjectionContext(injector, () => this.route.canBeEnteredFn(parsed?.route ?? this.route, combinedParams))) {
|
|
341
358
|
return true;
|
|
342
359
|
}
|
|
343
360
|
else {
|
|
@@ -345,8 +362,7 @@ class RdtAngularRoute {
|
|
|
345
362
|
const location = inject(Location);
|
|
346
363
|
let url = inject(RDT_CANNOT_BE_ENTERED_PROVIDER);
|
|
347
364
|
if (typeof url === 'function') {
|
|
348
|
-
|
|
349
|
-
url = runInInjectionContext(injector, url.bind(url, location.path(), state.url, this.route));
|
|
365
|
+
url = runInInjectionContext(injector, url.bind(url, location.path(), state.url, parsed?.route ?? this.route));
|
|
350
366
|
}
|
|
351
367
|
if (typeof url === 'string') {
|
|
352
368
|
return router.parseUrl(url);
|
|
@@ -622,31 +638,69 @@ class RdtRoute extends RdtRouteBase {
|
|
|
622
638
|
* Meta guard that is used by [rdtRouterLink] and RdtMenu
|
|
623
639
|
* to determine if route can be entered.
|
|
624
640
|
* @param injector Environment or custom injector.
|
|
641
|
+
* @param params Optional parameters to pass to guard function.
|
|
625
642
|
* @returns True if route can be entered.
|
|
626
643
|
*/
|
|
627
|
-
canBeEntered(injector) {
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
644
|
+
canBeEntered(injector, combinedParams = {}) {
|
|
645
|
+
const route = this.getStaticParams();
|
|
646
|
+
let query = this._queryParams;
|
|
647
|
+
let state = this._stateParams;
|
|
648
|
+
if (combinedParams.params) {
|
|
649
|
+
route.set(this, combinedParams.params);
|
|
650
|
+
}
|
|
651
|
+
if (combinedParams.route) {
|
|
652
|
+
route.setAll(combinedParams.route);
|
|
653
|
+
}
|
|
654
|
+
if (combinedParams.query) {
|
|
655
|
+
query = { ...query, ...combinedParams.query };
|
|
656
|
+
}
|
|
657
|
+
if (combinedParams.state) {
|
|
658
|
+
state = { ...state, ...combinedParams.state };
|
|
659
|
+
}
|
|
660
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
661
|
+
let current = this;
|
|
662
|
+
while (current) {
|
|
663
|
+
const combined = {
|
|
664
|
+
params: route.get(current) ?? {},
|
|
665
|
+
route: route,
|
|
666
|
+
query: query,
|
|
667
|
+
state: state,
|
|
668
|
+
};
|
|
669
|
+
if (injector) {
|
|
670
|
+
const c = current;
|
|
671
|
+
if (!runInInjectionContext(injector, () => c._canBeEntered(c, combined))) {
|
|
672
|
+
return false;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
else if (!current._canBeEntered(current, combined)) {
|
|
676
|
+
return false;
|
|
677
|
+
}
|
|
678
|
+
current = current._parent;
|
|
679
|
+
}
|
|
680
|
+
return true;
|
|
681
|
+
}
|
|
682
|
+
get canBeEnteredFn() {
|
|
683
|
+
return this._canBeEntered;
|
|
631
684
|
}
|
|
632
685
|
/**
|
|
633
686
|
* Extracts url parameters from absolute path for this path and each parent.
|
|
634
687
|
*/
|
|
635
688
|
parseAbsoluteUrl(url) {
|
|
689
|
+
const path = RdtStringUtils.stripQueryParams(url);
|
|
636
690
|
const reg = this.absoluteRegex;
|
|
637
|
-
|
|
638
|
-
return null;
|
|
639
|
-
}
|
|
640
|
-
const matches = reg.exec(url);
|
|
691
|
+
const matches = reg.exec(path);
|
|
641
692
|
if (matches) {
|
|
693
|
+
const query = RdtStringUtils.parseQueryParams(url);
|
|
642
694
|
const values = matches.slice(1).reverse();
|
|
643
695
|
const obj = this.fill(values);
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
696
|
+
const route = new RdtParameters(obj);
|
|
697
|
+
const params = route.get(this) ?? {};
|
|
698
|
+
return {
|
|
699
|
+
params: params,
|
|
700
|
+
route: route,
|
|
701
|
+
query: query,
|
|
702
|
+
state: {},
|
|
703
|
+
};
|
|
650
704
|
}
|
|
651
705
|
else {
|
|
652
706
|
return null;
|
|
@@ -766,6 +820,16 @@ class RdtRoute extends RdtRouteBase {
|
|
|
766
820
|
});
|
|
767
821
|
return res;
|
|
768
822
|
}
|
|
823
|
+
getStaticParams() {
|
|
824
|
+
const res = new RdtParameters();
|
|
825
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
826
|
+
let current = this;
|
|
827
|
+
while (current) {
|
|
828
|
+
res.set(current, current._staticParams);
|
|
829
|
+
current = current._parent;
|
|
830
|
+
}
|
|
831
|
+
return res;
|
|
832
|
+
}
|
|
769
833
|
/**
|
|
770
834
|
* @returns New instance of RdtRoute<T> that is clone of
|
|
771
835
|
* this route and its parents (NOT children).
|
|
@@ -1130,6 +1194,19 @@ class RdtRouterLinkDirective {
|
|
|
1130
1194
|
alias: 'rdtDisabled',
|
|
1131
1195
|
transform: booleanAttribute,
|
|
1132
1196
|
});
|
|
1197
|
+
canBeEntered = computed(() => {
|
|
1198
|
+
const route = this.route();
|
|
1199
|
+
const disabled = this.disabled();
|
|
1200
|
+
if (!route || disabled) {
|
|
1201
|
+
return false;
|
|
1202
|
+
}
|
|
1203
|
+
const combinedParams = {
|
|
1204
|
+
params: this.params(),
|
|
1205
|
+
query: this.queryParams(),
|
|
1206
|
+
state: this.stateParams(),
|
|
1207
|
+
};
|
|
1208
|
+
return route.canBeEntered(this.envInjector, combinedParams);
|
|
1209
|
+
});
|
|
1133
1210
|
updateEffect = effect(() => {
|
|
1134
1211
|
if (this.buttonRef) {
|
|
1135
1212
|
this.updateButton();
|
|
@@ -1144,7 +1221,7 @@ class RdtRouterLinkDirective {
|
|
|
1144
1221
|
this.clearButtonLink();
|
|
1145
1222
|
return;
|
|
1146
1223
|
}
|
|
1147
|
-
if (
|
|
1224
|
+
if (this.canBeEntered()) {
|
|
1148
1225
|
this.setButtonLink(route);
|
|
1149
1226
|
}
|
|
1150
1227
|
else {
|
|
@@ -1182,7 +1259,7 @@ class RdtRouterLinkDirective {
|
|
|
1182
1259
|
if (!route) {
|
|
1183
1260
|
this.clearRouterLink();
|
|
1184
1261
|
}
|
|
1185
|
-
else if (
|
|
1262
|
+
else if (this.canBeEntered()) {
|
|
1186
1263
|
this.setRouterLink(route);
|
|
1187
1264
|
}
|
|
1188
1265
|
else {
|