@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.
@@ -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 new RdtParameters();
202
+ return null;
194
203
  }
195
204
  currentRoute = parsed.route;
196
205
  }
197
206
  const url = this.location.path();
198
- const stripped = RdtStringUtils.stripQueryParams(url);
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
- if (runInInjectionContext(injector, this.route.canBeEntered.bind(this.route))) {
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
- //console.error(this.route.absolutePath);
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
- return injector
629
- ? runInInjectionContext(injector, this._canBeEntered)
630
- : this._canBeEntered();
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
- if (!reg.test(url)) {
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
- if (obj) {
645
- return new RdtParameters(obj);
646
- }
647
- else {
648
- return null;
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 (route.canBeEntered(this.envInjector)) {
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 (route.canBeEntered(this.envInjector) && !this.disabled()) {
1262
+ else if (this.canBeEntered()) {
1186
1263
  this.setRouterLink(route);
1187
1264
  }
1188
1265
  else {