@coolon/angular-ui-powerups 12.3.1 → 12.4.0-alpha.1

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.
Files changed (113) hide show
  1. package/bundles/coolon-angular-ui-powerups-cypress.umd.js +299 -93
  2. package/bundles/coolon-angular-ui-powerups-cypress.umd.js.map +1 -1
  3. package/bundles/coolon-angular-ui-powerups.umd.js +315 -200
  4. package/bundles/coolon-angular-ui-powerups.umd.js.map +1 -1
  5. package/coolon-angular-ui-powerups.metadata.json +1 -1
  6. package/cypress/components/aup-command-face.d.ts +2 -5
  7. package/cypress/components/aup-command.d.ts +18 -4
  8. package/cypress/components/aup-navigation.d.ts +0 -1
  9. package/cypress/components/aup-popup-menu.d.ts +2 -0
  10. package/cypress/components/aup-table.d.ts +19 -0
  11. package/cypress/components/button-mixin.d.ts +17 -0
  12. package/cypress/components/button.d.ts +17 -3
  13. package/cypress/coolon-angular-ui-powerups-cypress.d.ts +1 -0
  14. package/cypress/coolon-angular-ui-powerups-cypress.metadata.json +1 -1
  15. package/cypress/exports.d.ts +3 -0
  16. package/cypress/page-element.d.ts +11 -2
  17. package/cypress/page.d.ts +20 -13
  18. package/cypress/path.d.ts +26 -0
  19. package/cypress/section.d.ts +8 -1
  20. package/esm2015/cypress/components/aup-command-face.js +20 -11
  21. package/esm2015/cypress/components/aup-command-face.js.map +1 -1
  22. package/esm2015/cypress/components/aup-command-face.metadata.json +1 -1
  23. package/esm2015/cypress/components/aup-command.js +10 -7
  24. package/esm2015/cypress/components/aup-command.js.map +1 -1
  25. package/esm2015/cypress/components/aup-command.metadata.json +1 -1
  26. package/esm2015/cypress/components/aup-more-menu.js +1 -2
  27. package/esm2015/cypress/components/aup-more-menu.js.map +1 -1
  28. package/esm2015/cypress/components/aup-more-menu.metadata.json +1 -1
  29. package/esm2015/cypress/components/aup-navigation.js +1 -5
  30. package/esm2015/cypress/components/aup-navigation.js.map +1 -1
  31. package/esm2015/cypress/components/aup-popup-menu.js +12 -3
  32. package/esm2015/cypress/components/aup-popup-menu.js.map +1 -1
  33. package/esm2015/cypress/components/aup-popup-menu.metadata.json +1 -1
  34. package/esm2015/cypress/components/aup-table.js +36 -0
  35. package/esm2015/cypress/components/aup-table.js.map +1 -0
  36. package/esm2015/cypress/components/aup-table.metadata.json +1 -0
  37. package/esm2015/cypress/components/button-mixin.js +15 -0
  38. package/esm2015/cypress/components/button-mixin.js.map +1 -0
  39. package/esm2015/cypress/components/button-mixin.metadata.json +1 -0
  40. package/esm2015/cypress/components/button.js +11 -7
  41. package/esm2015/cypress/components/button.js.map +1 -1
  42. package/esm2015/cypress/components/button.metadata.json +1 -1
  43. package/esm2015/cypress/coolon-angular-ui-powerups-cypress.js.map +1 -1
  44. package/esm2015/cypress/coolon-angular-ui-powerups-cypress.metadata.json +1 -1
  45. package/esm2015/cypress/exports.js +3 -0
  46. package/esm2015/cypress/exports.js.map +1 -1
  47. package/esm2015/cypress/exports.metadata.json +1 -1
  48. package/esm2015/cypress/page-element.js +21 -5
  49. package/esm2015/cypress/page-element.js.map +1 -1
  50. package/esm2015/cypress/page-element.metadata.json +1 -1
  51. package/esm2015/cypress/page.js +34 -22
  52. package/esm2015/cypress/page.js.map +1 -1
  53. package/esm2015/cypress/page.metadata.json +1 -1
  54. package/esm2015/cypress/path.js +61 -0
  55. package/esm2015/cypress/path.js.map +1 -0
  56. package/esm2015/cypress/path.metadata.json +1 -0
  57. package/esm2015/cypress/section.js +20 -10
  58. package/esm2015/cypress/section.js.map +1 -1
  59. package/esm2015/lib/components/switch-case/switch-case.component.js +7 -0
  60. package/esm2015/lib/components/switch-case/switch-case.component.js.map +1 -1
  61. package/esm2015/lib/components/switch-case/switch-case.component.metadata.json +1 -1
  62. package/esm2015/lib/components/tables/table/table.component.js +1 -1
  63. package/esm2015/lib/components/tables/table/table.component.js.map +1 -1
  64. package/esm2015/lib/components/tables/table/table.component.metadata.json +1 -1
  65. package/esm2015/lib/components/tables/tree-table/tree-table-component.js +1 -1
  66. package/esm2015/lib/components/tables/tree-table/tree-table-component.js.map +1 -1
  67. package/esm2015/lib/components/tables/tree-table/tree-table-component.metadata.json +1 -1
  68. package/esm2015/lib/place/components/place-outlet/place-outlet.component.js.map +1 -1
  69. package/esm2015/lib/place/components/place-outlet/place-outlet.component.metadata.json +1 -1
  70. package/esm2015/lib/place/guards/consolidated-param-map.js +7 -2
  71. package/esm2015/lib/place/guards/consolidated-param-map.js.map +1 -1
  72. package/esm2015/lib/place/guards/consolidated-param-map.metadata.json +1 -1
  73. package/esm2015/lib/place/guards/place.guard.js +1 -22
  74. package/esm2015/lib/place/guards/place.guard.js.map +1 -1
  75. package/esm2015/lib/place/navigation/place-component-deactivation-handler.js +15 -11
  76. package/esm2015/lib/place/navigation/place-component-deactivation-handler.js.map +1 -1
  77. package/esm2015/lib/place/navigation/place-component-deactivation-handler.metadata.json +1 -1
  78. package/esm2015/lib/place/navigation/session/interactions/synchronise-interaction-context-ids-with-route.js.map +1 -1
  79. package/esm2015/lib/place/navigation/session/interactions/synchronise-interaction-context-ids-with-route.metadata.json +1 -1
  80. package/esm2015/lib/place/place-component.js +67 -5
  81. package/esm2015/lib/place/place-component.js.map +1 -1
  82. package/esm2015/lib/place/place-component.metadata.json +1 -1
  83. package/esm2015/lib/place/place-definition.js +3 -3
  84. package/esm2015/lib/place/place-definition.js.map +1 -1
  85. package/esm2015/lib/place/place-router.js +9 -4
  86. package/esm2015/lib/place/place-router.js.map +1 -1
  87. package/esm2015/lib/place/place-router.metadata.json +1 -1
  88. package/esm2015/lib/place/route/parameter-decorators.js +13 -14
  89. package/esm2015/lib/place/route/parameter-decorators.js.map +1 -1
  90. package/esm2015/lib/place/route/parameter-decorators.metadata.json +1 -1
  91. package/esm2015/lib/place/route/parameter-definition.js +21 -3
  92. package/esm2015/lib/place/route/parameter-definition.js.map +1 -1
  93. package/esm2015/lib/place/route/parameter-definition.metadata.json +1 -1
  94. package/esm2015/lib/place/route/visit-sanitiser.js +1 -1
  95. package/esm2015/lib/place/route/visit-sanitiser.js.map +1 -1
  96. package/esm2015/lib/place/url-snapshot.js +30 -7
  97. package/esm2015/lib/place/url-snapshot.js.map +1 -1
  98. package/esm2015/lib/place/url-snapshot.metadata.json +1 -1
  99. package/esm2015/lib/place/visit.js +7 -7
  100. package/esm2015/lib/place/visit.js.map +1 -1
  101. package/esm2015/lib/place/visit.metadata.json +1 -1
  102. package/fesm2015/coolon-angular-ui-powerups-cypress.js +237 -74
  103. package/fesm2015/coolon-angular-ui-powerups-cypress.js.map +1 -1
  104. package/fesm2015/coolon-angular-ui-powerups.js +275 -180
  105. package/fesm2015/coolon-angular-ui-powerups.js.map +1 -1
  106. package/lib/components/switch-case/switch-case.component.d.ts +7 -0
  107. package/lib/place/guards/consolidated-param-map.d.ts +2 -2
  108. package/lib/place/navigation/place-component-deactivation-handler.d.ts +3 -1
  109. package/lib/place/place-component.d.ts +26 -3
  110. package/lib/place/route/parameter-definition.d.ts +8 -0
  111. package/lib/place/url-snapshot.d.ts +1 -0
  112. package/lib/place/visit.d.ts +4 -4
  113. package/package.json +1 -1
@@ -21,7 +21,7 @@ import { MatTableModule } from '@angular/material/table';
21
21
  import { MatTooltipModule } from '@angular/material/tooltip';
22
22
  import { FontAwesomeModule, FaIconLibrary } from '@fortawesome/angular-fontawesome';
23
23
  import { fas } from '@fortawesome/free-solid-svg-icons';
24
- import { GarbageCollector, DelegatingValueModel, assert, UnaryCommand, lang, Dsl, Logger, TrackExternal, ValueModel, StoreInValueModel, Command, MutableListModel, StoreInListModel, Disposable, MutableValueModel, DelegatingListModel, FocusManager, EventListenerList, Form, Guard, Binding, DebugContext, ListModel, MultipleSelectionModel, DelegatingSelectionModel, AbstractComputedListModel, DirtyTrackingForm, ComputedListModel, PageController, Deferred, Functions } from '@coolon/pectin';
24
+ import { GarbageCollector, DelegatingValueModel, assert, UnaryCommand, lang, Dsl, Logger, TrackExternal, ValueModel, StoreInValueModel, Command, MutableListModel, StoreInListModel, Disposable, MutableValueModel, DelegatingListModel, FocusManager, EventListenerList, Form, Guard, Binding, DebugContext, ListModel, MultipleSelectionModel, DelegatingSelectionModel, AbstractComputedListModel, DirtyTrackingForm, ComputedListModel, PageController, Deferred, Trace, Functions } from '@coolon/pectin';
25
25
  import { __decorate, __metadata, __awaiter } from 'tslib';
26
26
  import { DomSanitizer } from '@angular/platform-browser';
27
27
  import * as _ from 'lodash';
@@ -1846,6 +1846,13 @@ SwitchCaseDefaultDirective.decorators = [
1846
1846
  SwitchCaseDefaultDirective.ctorParameters = () => [
1847
1847
  { type: TemplateRef }
1848
1848
  ];
1849
+ /**
1850
+ * @example
1851
+ * <aup-switch-case [switchModel]="booleanModel">
1852
+ * <div *aupSwitchCaseWhen="true"></div>
1853
+ * <div *aupSwitchCaseDefault>The default content</div>
1854
+ * </aup-switch-case>
1855
+ */
1849
1856
  class SwitchCaseComponent extends DisposableComponent {
1850
1857
  constructor(cdr) {
1851
1858
  super();
@@ -3205,7 +3212,7 @@ class TableComponent extends AbstractTableComponent {
3205
3212
  TableComponent.decorators = [
3206
3213
  { type: Component, args: [{
3207
3214
  selector: 'aup-table',
3208
- template: "<div class=\"scroll-container\">\n <table mat-table [dataSource]=\"getModel().dataSource.value\" [trackBy]=\"getModel().trackBy\">\n\n <ng-container *ngFor=\"let column of columns.value; index as index; first as first; last as last\"\n matColumnDef=\"{{column.columnId}}\">\n <th mat-header-cell *matHeaderCellDef [class.flex]=\"column.isFlex()\" [class.hide]=\"!column.isVisible()\">\n <aup-table-header-cell-renderer [column]=\"column\"\n [attr.column-index]=\"index\"\n [attr.column-id]=\"column.columnId\"\n [class]=\"getColumnClasses(column.columnId)\"\n ></aup-table-header-cell-renderer>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"notifyCellClicked(column, row)\"\n [class.enable-cursor]=\"getModel().isCursorEnabled(column)\"\n [class.flex]=\"column.isFlex()\"\n [class.hide]=\"!column.isVisible()\"\n >\n <aup-table-cell-renderer [column]=\"column\"\n [row]=\"row\"\n [tableModel]=\"getModel()\"\n [editSession]=\"getModel().getEditSessionFor(row)\"\n [attr.column-index]=\"index\"\n [attr.column-id]=\"column.columnId\"\n [class]=\"getColumnClasses(column.columnId)\"\n ></aup-table-cell-renderer>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"columnIds.value\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: columnIds.value; let i = index\"\n [ngClass]=\"getModel().getRowClasses(row)\" [class.enable-hover]=\"getModel().isHoverEnabled()\"\n [attr.trackBy]=\"getModel().trackBy(i, row)\"\n ></tr>\n\n </table>\n</div>\n",
3215
+ template: "<div class=\"scroll-container\">\n <table mat-table [dataSource]=\"getModel().dataSource.value\" [trackBy]=\"getModel().trackBy\">\n\n <ng-container *ngFor=\"let column of columns.value; index as index; first as first; last as last\"\n matColumnDef=\"{{column.columnId}}\">\n <th mat-header-cell *matHeaderCellDef [class.flex]=\"column.isFlex()\" [class.hide]=\"!column.isVisible()\">\n <aup-table-header-cell-renderer [column]=\"column\"\n [attr.column-index]=\"index\"\n [attr.column-id]=\"column.columnId\"\n [class]=\"getColumnClasses(column.columnId)\"\n ></aup-table-header-cell-renderer>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"notifyCellClicked(column, row)\"\n [class.enable-cursor]=\"getModel().isCursorEnabled(column)\"\n [class.flex]=\"column.isFlex()\"\n [class.hide]=\"!column.isVisible()\"\n >\n <aup-table-cell-renderer [column]=\"column\"\n [row]=\"row\"\n [tableModel]=\"getModel()\"\n [editSession]=\"getModel().getEditSessionFor(row)\"\n [attr.column-index]=\"index\"\n [attr.column-id]=\"column.columnId\"\n [class]=\"getColumnClasses(column.columnId)\"\n ></aup-table-cell-renderer>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"columnIds.value\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: columnIds.value; let i = index\"\n [ngClass]=\"getModel().getRowClasses(row)\" [class.enable-hover]=\"getModel().isHoverEnabled()\"\n [attr.aup-row-id]=\"getModel().trackBy(i, row)\"\n ></tr>\n\n </table>\n</div>\n",
3209
3216
  providers: [
3210
3217
  { provide: AbstractTableComponent, useExisting: TableComponent }
3211
3218
  ],
@@ -3795,7 +3802,7 @@ class TreeTableComponent extends AbstractTableComponent {
3795
3802
  TreeTableComponent.decorators = [
3796
3803
  { type: Component, args: [{
3797
3804
  selector: 'aup-tree-table',
3798
- template: "<div class=\"scroll-container\">\n <table mat-table [dataSource]=\"getModel().dataSource.value\" [trackBy]=\"getModel().trackBy\">\n\n <ng-container *ngFor=\"let column of columns.value; index as index; first as first; last as last\"\n matColumnDef=\"{{column.columnId}}\">\n <th mat-header-cell *matHeaderCellDef [class.flex]=\"column.isFlex()\" [class.hide]=\"!column.isVisible()\">\n <aup-table-header-cell-renderer [column]=\"column\"\n [attr.column-index]=\"index\"\n [attr.column-id]=\"column.columnId\"\n [class]=\"getColumnClasses(column.columnId)\"\n ></aup-table-header-cell-renderer>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"notifyCellClicked(column, row)\"\n [class.enable-cursor]=\"getModel().isCursorEnabled(column)\"\n [class.flex]=\"column.isFlex()\"\n [class.hide]=\"!column.isVisible()\"\n >\n <aup-table-cell-renderer [column]=\"column\"\n [row]=\"row\"\n [tableModel]=\"getModel()\"\n [editSession]=\"getModel().getEditSessionFor(row)\"\n [attr.column-index]=\"index\"\n [attr.column-id]=\"column.columnId\"\n [class]=\"getColumnClasses(column.columnId)\"\n ></aup-table-cell-renderer>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"columnIds.value\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: columnIds.value; let i = index\"\n [ngClass]=\"getModel().getRowClasses(row)\" [class.enable-hover]=\"getModel().isHoverEnabled()\"\n [attr.trackBy]=\"getModel().trackBy(i, row)\"\n ></tr>\n\n </table>\n</div>\n",
3805
+ template: "<div class=\"scroll-container\">\n <table mat-table [dataSource]=\"getModel().dataSource.value\" [trackBy]=\"getModel().trackBy\">\n\n <ng-container *ngFor=\"let column of columns.value; index as index; first as first; last as last\"\n matColumnDef=\"{{column.columnId}}\">\n <th mat-header-cell *matHeaderCellDef [class.flex]=\"column.isFlex()\" [class.hide]=\"!column.isVisible()\">\n <aup-table-header-cell-renderer [column]=\"column\"\n [attr.column-index]=\"index\"\n [attr.column-id]=\"column.columnId\"\n [class]=\"getColumnClasses(column.columnId)\"\n ></aup-table-header-cell-renderer>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"notifyCellClicked(column, row)\"\n [class.enable-cursor]=\"getModel().isCursorEnabled(column)\"\n [class.flex]=\"column.isFlex()\"\n [class.hide]=\"!column.isVisible()\"\n >\n <aup-table-cell-renderer [column]=\"column\"\n [row]=\"row\"\n [tableModel]=\"getModel()\"\n [editSession]=\"getModel().getEditSessionFor(row)\"\n [attr.column-index]=\"index\"\n [attr.column-id]=\"column.columnId\"\n [class]=\"getColumnClasses(column.columnId)\"\n ></aup-table-cell-renderer>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"columnIds.value\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: columnIds.value; let i = index\"\n [ngClass]=\"getModel().getRowClasses(row)\" [class.enable-hover]=\"getModel().isHoverEnabled()\"\n [attr.aup-row-id]=\"getModel().trackBy(i, row)\"\n ></tr>\n\n </table>\n</div>\n",
3799
3806
  providers: [
3800
3807
  { provide: AbstractTableComponent, useExisting: TreeTableComponent }
3801
3808
  ],
@@ -5568,6 +5575,7 @@ InteractionModule.decorators = [
5568
5575
  },] }
5569
5576
  ];
5570
5577
 
5578
+ const PARAMETER_DEFINITION_KEY = Symbol("parameterDefinition");
5571
5579
  class ParameterDefinition {
5572
5580
  constructor(propertyName, options, urlFormat) {
5573
5581
  this.propertyName = propertyName;
@@ -5583,6 +5591,11 @@ class ParameterDefinition {
5583
5591
  get isRouteParameter() {
5584
5592
  return !!this.urlFormat;
5585
5593
  }
5594
+ createBackingModel() {
5595
+ const model = this.backingModelFactory();
5596
+ model[PARAMETER_DEFINITION_KEY] = this;
5597
+ return model;
5598
+ }
5586
5599
  getOptionValue(key) {
5587
5600
  return this.options.getOptional(key, null);
5588
5601
  }
@@ -5594,7 +5607,7 @@ class ParameterDefinition {
5594
5607
  if (returningFromSomewhereElse) {
5595
5608
  const lastKnownVisit = placeHistory.getMostRecentVisitFor(visit.placeDefinition);
5596
5609
  if (this.remember && lastKnownVisit) {
5597
- value = lastKnownVisit.getParameter(this.name);
5610
+ value = lastKnownVisit.getParameterValue(this);
5598
5611
  }
5599
5612
  return this.isEmptyValue(value) ? this.defaultValue : value;
5600
5613
  }
@@ -5604,7 +5617,7 @@ class ParameterDefinition {
5604
5617
  });
5605
5618
  }
5606
5619
  isMissingFrom(visit) {
5607
- return !visit.hasParameter(this.name);
5620
+ return !visit.hasParameter(this);
5608
5621
  }
5609
5622
  }
5610
5623
  (function (ParameterDefinition) {
@@ -5613,6 +5626,7 @@ class ParameterDefinition {
5613
5626
  super(...arguments);
5614
5627
  this.isRouteId = true;
5615
5628
  this.isArray = false;
5629
+ this.backingModelFactory = () => new MutableValueModel();
5616
5630
  }
5617
5631
  isEmptyValue(value) {
5618
5632
  return ___default.isNil(value);
@@ -5627,6 +5641,7 @@ class ParameterDefinition {
5627
5641
  super(...arguments);
5628
5642
  this.isRouteId = false;
5629
5643
  this.isArray = false;
5644
+ this.backingModelFactory = () => new MutableValueModel();
5630
5645
  }
5631
5646
  isEmptyValue(value) {
5632
5647
  return ___default.isNil(value);
@@ -5641,6 +5656,7 @@ class ParameterDefinition {
5641
5656
  super(parameterName, options, urlFormat);
5642
5657
  this.isRouteId = false;
5643
5658
  this.isArray = true;
5659
+ this.backingModelFactory = () => new MutableListModel();
5644
5660
  }
5645
5661
  isEmptyValue(value) {
5646
5662
  return ___default.isNil(value) || value.length < 1;
@@ -5650,6 +5666,14 @@ class ParameterDefinition {
5650
5666
  }
5651
5667
  }
5652
5668
  ParameterDefinition.ArrayParameter = ArrayParameter;
5669
+ function get(model) {
5670
+ const parameterDefinition = model[PARAMETER_DEFINITION_KEY];
5671
+ if (!parameterDefinition) {
5672
+ lang$1.illegalArgument("model hasn't been annotated with @VisitParameter, @VisitParameterList or @RouteId");
5673
+ }
5674
+ return parameterDefinition;
5675
+ }
5676
+ ParameterDefinition.get = get;
5653
5677
  })(ParameterDefinition || (ParameterDefinition = {}));
5654
5678
 
5655
5679
  class PlaceDefinition {
@@ -5699,7 +5723,7 @@ class PlaceDefinition {
5699
5723
  }
5700
5724
  getRouteIdFrom(visit) {
5701
5725
  const routeIdParameterDef = this.getRouteIdParameterDef();
5702
- return routeIdParameterDef ? visit.getParameter(routeIdParameterDef.name) : null;
5726
+ return routeIdParameterDef ? visit.getParameterValue(routeIdParameterDef) : null;
5703
5727
  }
5704
5728
  getFormattedRouteId(visit) {
5705
5729
  // Note: RouteIds are always present in the url and are just empty strings when not defined. This is
@@ -5713,7 +5737,7 @@ class PlaceDefinition {
5713
5737
  this.getVisitParameterDefs({
5714
5738
  includeRouteId, includeRouteParameters: true
5715
5739
  }).forEach(def => {
5716
- const value = visit.getParameter(def.name);
5740
+ const value = visit.getParameterValue(def);
5717
5741
  if (!def.isEmptyValue(value)) {
5718
5742
  if (def.isArray) {
5719
5743
  assert.isArray(value);
@@ -5730,7 +5754,7 @@ class PlaceDefinition {
5730
5754
  getNonRouteParameters(visit) {
5731
5755
  const result = {};
5732
5756
  this.getVisitParameterDefs({ includeNonRouteParameters: true }).forEach(def => {
5733
- const value = visit.getParameter(def.name);
5757
+ const value = visit.getParameterValue(def);
5734
5758
  if (!def.isEmptyValue(value)) {
5735
5759
  result[def.name] = value;
5736
5760
  }
@@ -5794,14 +5818,25 @@ __decorate([
5794
5818
  const DEFINITION_META_DATA_KEY = 'PLACE_DEFINITION_OPTIONS';
5795
5819
  // this one seems ok.
5796
5820
  const ROUTE_PARAMETER_LIST_KEY = Symbol('place:route:parameters');
5821
+ class ParameterChangeInterceptor {
5822
+ constructor(parameterDef, model, callback, options) {
5823
+ }
5824
+ canProceed(nextState, interactionContext) {
5825
+ return __awaiter(this, void 0, void 0, function* () {
5826
+ return true;
5827
+ });
5828
+ }
5829
+ }
5797
5830
  class PlaceComponent extends DisposableComponent {
5798
5831
  constructor() {
5799
5832
  super();
5833
+ this._placeReadyCallbacks = [];
5800
5834
  this.visitModel = new MutableValueModel();
5801
5835
  this._inVisitUpdate = new Guard();
5802
5836
  this._active = new MutableValueModel(false);
5837
+ this._parameterChangeInterceptors = [];
5803
5838
  const { chain, valueOf, before, when, after, observe, switchOn } = Dsl.disposeWith(this);
5804
- when(this._active).becomesTruthy(() => this.onPlaceReady());
5839
+ when(this._active).becomesTruthy(() => this._notifyPlaceReady());
5805
5840
  this.childPlaces = this.placeDefinition.children.map(d => d.component);
5806
5841
  }
5807
5842
  // @Trace()
@@ -5831,7 +5866,7 @@ class PlaceComponent extends DisposableComponent {
5831
5866
  DebugContext.tag(model, `${this.placeDefinition.component.name}.${parameterDef.propertyName}`);
5832
5867
  const binding = this.registerDisposable(new Binding(this.visitModel, model, {
5833
5868
  toRight(visit) {
5834
- const value = visit.getParameter(parameterDef.name);
5869
+ const value = visit.getParameterValue(parameterDef);
5835
5870
  // console.log('push to component', { name: parameterDef.name, value, visit });
5836
5871
  return value;
5837
5872
  },
@@ -5843,18 +5878,68 @@ class PlaceComponent extends DisposableComponent {
5843
5878
  binding.writeRight();
5844
5879
  }
5845
5880
  get placeDefinition() {
5846
- return PlaceComponent.getDefinition(this.constructor);
5881
+ const definition = PlaceComponent.getDefinition(this.constructor);
5882
+ if (!definition) {
5883
+ lang.illegalState(`${this.constructor.name} extends PlaceComponent but doesn't have @Place({..}) decorator.`);
5884
+ }
5885
+ return definition;
5847
5886
  }
5848
5887
  get active() {
5849
5888
  return this._active.readonly;
5850
5889
  }
5890
+ /**
5891
+ * Called by the router to see if this component can deactivate. This isn't called for route parameter changes.
5892
+ * @param interactionContext
5893
+ */
5894
+ _canLeavePlace(interactionContext) {
5895
+ return __awaiter(this, void 0, void 0, function* () {
5896
+ return this.canDeactivate ? this.canDeactivate(interactionContext) : true;
5897
+ });
5898
+ }
5899
+ /**
5900
+ * Called by the router to see if this component can deactivate. This isn't called for route parameter changes.
5901
+ * @param interactionContext
5902
+ * @param nextState
5903
+ */
5904
+ _canChangeRouteParameters(interactionContext, nextState) {
5905
+ return __awaiter(this, void 0, void 0, function* () {
5906
+ if (this._parameterChangeInterceptors.length > 0) {
5907
+ const visit = nextState.createVisitFor(this.placeDefinition);
5908
+ for (let i = 0; i < this._parameterChangeInterceptors.length; i++) {
5909
+ const interceptor = this._parameterChangeInterceptors[i];
5910
+ const keepGoing = yield interceptor.canProceed(visit, interactionContext);
5911
+ if (!keepGoing) {
5912
+ return false;
5913
+ }
5914
+ }
5915
+ }
5916
+ return true;
5917
+ });
5918
+ }
5851
5919
  /**
5852
5920
  * Called by the router when the place is ready to interact after any animations have run.
5853
5921
  */
5854
5922
  _notifyActive(active) {
5855
5923
  this._active.value = active;
5856
5924
  }
5857
- onPlaceReady() {
5925
+ /**
5926
+ * Called by the router when the place is ready to interact after any animations have run.
5927
+ */
5928
+ _notifyPlaceReady() {
5929
+ if (this.onPlaceReady.length === 1) {
5930
+ this._placeReadyCallbacks.forEach(callback => callback());
5931
+ }
5932
+ else {
5933
+ console.warn('Overriding PlaceComponent.onPlaceReady has been deprecated. Use PlaceComponent.onPlaceReady(() => {... do stuff...}) instead.');
5934
+ this.onPlaceReady(undefined);
5935
+ }
5936
+ }
5937
+ onPlaceReady(callback) {
5938
+ this._placeReadyCallbacks.push(callback);
5939
+ }
5940
+ interceptVisitParameterChange(model, callback, options) {
5941
+ const parameterDef = ParameterDefinition.get(model);
5942
+ this._parameterChangeInterceptors.push(new ParameterChangeInterceptor(parameterDef, model, callback, options));
5858
5943
  }
5859
5944
  }
5860
5945
  PlaceComponent.decorators = [
@@ -5914,6 +5999,9 @@ class PlaceComponentDeactivationHandler {
5914
5999
  get urlService() {
5915
6000
  return this.navigationSession.urlService;
5916
6001
  }
6002
+ get placeDefinition() {
6003
+ return this.component.placeDefinition;
6004
+ }
5917
6005
  // @Trace()
5918
6006
  canDeactivate(currentUrl, nextState) {
5919
6007
  return __awaiter(this, void 0, void 0, function* () {
@@ -5949,25 +6037,26 @@ class PlaceComponentDeactivationHandler {
5949
6037
  }
5950
6038
  }
5951
6039
  }
5952
- // Ok, so now we're really leaving, so we ask the component if we should.;
5953
- if (this.isNotJustAChangeInRouteId(nextState)) {
5954
- if (this.component.canDeactivate) {
5955
- // No interaction in progress, so ask the component .
5956
- // This may start an interaction, hence checking the interaction context before now. I.e. if the place pops up the dialog, and
5957
- // the user clicks back again, we'll re-enter here and go bang when the component tries to open another dialog.
5958
- return this.component.canDeactivate(this.navigationSession.canDeactivateInteractionContext);
5959
- }
6040
+ // No interaction in progress, so ask the component .
6041
+ // This may start an interaction, hence checking the interaction context before now. I.e. if the place pops up the dialog, and
6042
+ // the user clicks back again, we'll re-enter here and go bang when the component tries to open another dialog.
6043
+ if (this.isGoingToADifferentPlace(nextState)) {
6044
+ const canLeave = yield this.component._canLeavePlace(this.navigationSession.canDeactivateInteractionContext);
5960
6045
  // The component has an active interaction but no deactivation hook. Rather than guessing what to do
5961
6046
  // we'll just cancel the navigation and print a warning.
5962
- if (this.routerInteractionAdapter.isComponentInteracting(this.component)) {
6047
+ if (canLeave && this.routerInteractionAdapter.isComponentInteracting(this.component)) {
5963
6048
  console.warn('Route changed while component has active interaction, cancelling navigation');
5964
6049
  return false;
5965
6050
  }
6051
+ return canLeave;
6052
+ }
6053
+ else {
6054
+ // either an interaction or visit parameter change.
6055
+ return yield this.component._canChangeRouteParameters(this.navigationSession.canDeactivateInteractionContext, nextState);
5966
6056
  }
5967
- return true;
5968
6057
  });
5969
6058
  }
5970
- isNotJustAChangeInRouteId(nextState) {
6059
+ isGoingToADifferentPlace(nextState) {
5971
6060
  // Because places with a route-id cover two route segments we get asked to deactivate
5972
6061
  // if the route id is added or removed. So if our path is still present the url
5973
6062
  // then we shouldn't deactivate the place.
@@ -6803,6 +6892,126 @@ PlaceHistory.ctorParameters = () => [];
6803
6892
  // }
6804
6893
  })(PlaceHistory || (PlaceHistory = {}));
6805
6894
 
6895
+ /**
6896
+ * This a work around for the fact that an activated route with multiple segments doesn't
6897
+ * include the segment params in the paramMap as well as each segment returns an empty
6898
+ * param map even when `parameter`s has content.
6899
+ */
6900
+ class ConsolidatedParameterMap {
6901
+ constructor(urlSegments, paramMap) {
6902
+ this.paramMaps = [];
6903
+ // TODO: can we get all our params from teh url segments? If so we can drop the paramMap altogether.
6904
+ const segmentParams = (urlSegments || []).map(s => new ParamMapAdapter(s.parameters));
6905
+ this.paramMaps = segmentParams
6906
+ .concat(paramMap)
6907
+ .filter(m => !!m); // the activated route param map can be null
6908
+ }
6909
+ get(name) {
6910
+ const paramMap = this.paramMaps.find(m => m.has(name));
6911
+ return paramMap.get(name);
6912
+ }
6913
+ getAll(name) {
6914
+ const paramMap = this.paramMaps.find(m => m.has(name));
6915
+ return paramMap.getAll(name);
6916
+ }
6917
+ has(name) {
6918
+ return !!this.paramMaps.find(m => m.has(name));
6919
+ }
6920
+ get keys() {
6921
+ return this.paramMaps.reduce((result, params) => result.concat(params.keys), []);
6922
+ }
6923
+ }
6924
+ __decorate([
6925
+ Memoize(),
6926
+ __metadata("design:type", Array),
6927
+ __metadata("design:paramtypes", [])
6928
+ ], ConsolidatedParameterMap.prototype, "keys", null);
6929
+ class ParamMapAdapter {
6930
+ constructor(params) {
6931
+ this.params = params;
6932
+ }
6933
+ get(name) {
6934
+ return this.params[name];
6935
+ }
6936
+ getAll(name) {
6937
+ const value = this.get(name);
6938
+ return Array.isArray(value) ? value : [value];
6939
+ }
6940
+ has(name) {
6941
+ return this.keys.includes(name);
6942
+ }
6943
+ get keys() {
6944
+ return Object.keys(this.params);
6945
+ }
6946
+ }
6947
+
6948
+ class Visit {
6949
+ constructor(placeDefinition, visitParameters = {}) {
6950
+ this.placeDefinition = placeDefinition;
6951
+ this.visitParameters = visitParameters;
6952
+ }
6953
+ // @Trace()
6954
+ getRouteId() {
6955
+ return this.placeDefinition.getRouteIdFrom(this);
6956
+ }
6957
+ // @Trace()
6958
+ hasRouteId() {
6959
+ return !_.isNil(this.getRouteId());
6960
+ }
6961
+ /**
6962
+ * Returns the value of the place parameter with the specified name. The parameter
6963
+ * name is taken from the `as` option, e.g. {as: 'aCustomName'} otherwise it is the
6964
+ * same as the the ValueModel property name.
6965
+ * @param parameterDef the visit parameter definition
6966
+ */
6967
+ getParameterValue(parameterDef) {
6968
+ return this.visitParameters[parameterDef.name];
6969
+ }
6970
+ // @Trace()
6971
+ hasParameter(parameterDef) {
6972
+ return Object.keys(this.visitParameters).includes(parameterDef.name);
6973
+ }
6974
+ replace(parameter, value) {
6975
+ return new Visit(this.placeDefinition, Object.assign(Object.assign({}, this.visitParameters), { [parameter.name]: value }));
6976
+ }
6977
+ mergeRouteParameters(routeParams) {
6978
+ // todo: whitelist parameters.
6979
+ const routeParameterKeys = Object.keys(routeParams);
6980
+ const params = {};
6981
+ this.placeDefinition.getVisitParameterDefs().forEach(def => {
6982
+ if (def.isRouteId || def.isRouteParameter) {
6983
+ if (routeParameterKeys.includes(def.name)) {
6984
+ params[def.name] = routeParams[def.name];
6985
+ }
6986
+ }
6987
+ else {
6988
+ // copy non route params as is, but only if they already exist otherwise we'll inject nil values and break the
6989
+ // defaults and remember sanitisation process.
6990
+ const value = this.getParameterValue(def);
6991
+ if (this.hasParameter(def)) {
6992
+ params[def.name] = value;
6993
+ }
6994
+ }
6995
+ });
6996
+ return new Visit(this.placeDefinition, params);
6997
+ }
6998
+ hasRoutingChangedFrom(other) {
6999
+ const samePlace = other.placeDefinition === this.placeDefinition;
7000
+ const sameRouteParameters = _.isEqual(this.placeDefinition.getFormattedRouteParameters(this, true), this.placeDefinition.getFormattedRouteParameters(other, true));
7001
+ return !samePlace || !sameRouteParameters;
7002
+ }
7003
+ hasChangedFrom(other) {
7004
+ const sameNonRouteParameters = _.isEqual(this.placeDefinition.getNonRouteParameters(this), this.placeDefinition.getNonRouteParameters(other));
7005
+ return !sameNonRouteParameters || this.hasRoutingChangedFrom(other);
7006
+ }
7007
+ toDebugString() {
7008
+ return Object.keys(this.visitParameters).map(k => `${k}=${this.visitParameters[k]}`).join(',');
7009
+ }
7010
+ }
7011
+
7012
+ function extractPrimarySegments(urlTree) {
7013
+ return urlTree.root.children.primary.segments;
7014
+ }
6806
7015
  class UrlSnapshot {
6807
7016
  // TODO: Update this accept a url Parser so it can be immutable and generate new trees on mutation using toString() are parseUrl.
6808
7017
  constructor(urlSerializer, url) {
@@ -6811,18 +7020,18 @@ class UrlSnapshot {
6811
7020
  this.urlTree = urlSerializer.parse(url);
6812
7021
  }
6813
7022
  updateVisitSegments(visit) {
6814
- const urlTree = this.urlSerializer.parse(this.url);
7023
+ const newUrlTree = this.urlSerializer.parse(this.url);
6815
7024
  // Ugly, but it works for now.
6816
- const segments = [...this.getPrimarySegments(urlTree)];
7025
+ const segments = [...extractPrimarySegments(newUrlTree)];
6817
7026
  const visitSegments = this.getSegmentsFor(visit);
6818
7027
  const replaceAt = segments.findIndex(segment => segment.path === visitSegments[0].path);
6819
7028
  // do not use the return value, it's the items that were removed!
6820
7029
  segments.splice(replaceAt, visitSegments.length, ...visitSegments);
6821
- urlTree.root.children.primary.segments = segments;
6822
- return new UrlSnapshot(this.urlSerializer, urlTree.toString());
7030
+ newUrlTree.root.children.primary.segments = segments;
7031
+ return new UrlSnapshot(this.urlSerializer, newUrlTree.toString());
6823
7032
  }
6824
- getPrimarySegments(urlTree) {
6825
- return this.urlTree.root.children.primary.segments;
7033
+ getPrimarySegments() {
7034
+ return extractPrimarySegments(this.urlTree);
6826
7035
  }
6827
7036
  /**
6828
7037
  * Converts the visit into segments. Please not that these segments are not e
@@ -6843,7 +7052,10 @@ class UrlSnapshot {
6843
7052
  ];
6844
7053
  }
6845
7054
  includesPathOf(placeDef) {
6846
- return this.getPrimarySegments(this.urlTree).find(s => s.path === placeDef.path);
7055
+ return this.getPrimarySegments().find(s => s.path === placeDef.path);
7056
+ }
7057
+ createVisitFor(placeDef) {
7058
+ return new Visit(placeDef, new ConsolidatedParameterMap(this.getPrimarySegments()));
6847
7059
  }
6848
7060
  getInteractionIds() {
6849
7061
  const queryParam = this.urlTree.queryParams[UrlSnapshot.INTERACTION_QUERY_PARAM];
@@ -6883,6 +7095,18 @@ class UrlSnapshot {
6883
7095
  return `UrlSnapshot(${this.url})`;
6884
7096
  }
6885
7097
  }
7098
+ __decorate([
7099
+ Trace(),
7100
+ __metadata("design:type", Function),
7101
+ __metadata("design:paramtypes", [Visit]),
7102
+ __metadata("design:returntype", UrlSnapshot)
7103
+ ], UrlSnapshot.prototype, "updateVisitSegments", null);
7104
+ __decorate([
7105
+ Memoize(),
7106
+ __metadata("design:type", Function),
7107
+ __metadata("design:paramtypes", []),
7108
+ __metadata("design:returntype", Array)
7109
+ ], UrlSnapshot.prototype, "getPrimarySegments", null);
6886
7110
  (function (UrlSnapshot) {
6887
7111
  UrlSnapshot.INTERACTION_QUERY_PARAM = 'aup-interactions';
6888
7112
  UrlSnapshot.INTERACTION_ID_SEPARATOR = '--';
@@ -7152,7 +7376,7 @@ class PlaceRouter extends GarbageCollector {
7152
7376
  });
7153
7377
  }
7154
7378
  navigateByUrl(urlSnapshot, navigationExtras) {
7155
- // console.log(`### navigationByUrl -> ${urlSnapshot.urlTree.toString()}`);
7379
+ console.log(`### navigationByUrl -> ${urlSnapshot.urlTree.toString()}`);
7156
7380
  return this.angularRouter.navigateByUrl(urlSnapshot.urlTree, navigationExtras);
7157
7381
  }
7158
7382
  get activeVisits() {
@@ -7218,7 +7442,6 @@ class PlaceRouter extends GarbageCollector {
7218
7442
  * to be able to capture the back button on the first page. If we don't then the back click will exit
7219
7443
  * the app directly and we don't get to ask.
7220
7444
  */
7221
- // @Trace()
7222
7445
  syncInteractionContextIdsWithRouter() {
7223
7446
  if (this.navigationSession) {
7224
7447
  // console.log(`Navigation active -> ${this.navigationSession.toString()}, sync delayed until finished.`);
@@ -7260,6 +7483,12 @@ PlaceRouter.ctorParameters = () => [
7260
7483
  { type: UrlService },
7261
7484
  { type: PlaceHistory }
7262
7485
  ];
7486
+ __decorate([
7487
+ Trace(),
7488
+ __metadata("design:type", Function),
7489
+ __metadata("design:paramtypes", []),
7490
+ __metadata("design:returntype", Promise)
7491
+ ], PlaceRouter.prototype, "syncInteractionContextIdsWithRouter", null);
7263
7492
  (function (PlaceRouter) {
7264
7493
  class State {
7265
7494
  constructor(activeVisits) {
@@ -7275,70 +7504,6 @@ PlaceRouter.ctorParameters = () => [
7275
7504
  PlaceRouter.State = State;
7276
7505
  })(PlaceRouter || (PlaceRouter = {}));
7277
7506
 
7278
- class Visit {
7279
- constructor(placeDefinition, visitParameters = {}) {
7280
- this.placeDefinition = placeDefinition;
7281
- this.visitParameters = visitParameters;
7282
- }
7283
- // @Trace()
7284
- getRouteId() {
7285
- return this.placeDefinition.getRouteIdFrom(this);
7286
- }
7287
- // @Trace()
7288
- hasRouteId() {
7289
- return !_.isNil(this.getRouteId());
7290
- }
7291
- /**
7292
- * Returns the value of the place parameter with the specified name. The parameter
7293
- * name is taken from the `as` option, e.g. {as: 'aCustomName'} otherwise it is the
7294
- * same as the the ValueModel property name.
7295
- * @param parameterName the field name of the property model or the `as` option if specified.
7296
- */
7297
- getParameter(parameterName) {
7298
- return this.visitParameters[parameterName];
7299
- }
7300
- // @Trace()
7301
- hasParameter(parameterName) {
7302
- return Object.keys(this.visitParameters).includes(parameterName);
7303
- }
7304
- replace(parameter, value) {
7305
- return new Visit(this.placeDefinition, Object.assign(Object.assign({}, this.visitParameters), { [parameter.name]: value }));
7306
- }
7307
- mergeRouteParameters(routeParams) {
7308
- // todo: whitelist parameters.
7309
- const routeParameterKeys = Object.keys(routeParams);
7310
- const params = {};
7311
- this.placeDefinition.getVisitParameterDefs().forEach(def => {
7312
- if (def.isRouteId || def.isRouteParameter) {
7313
- if (routeParameterKeys.includes(def.name)) {
7314
- params[def.name] = routeParams[def.name];
7315
- }
7316
- }
7317
- else {
7318
- // copy non route params as is, but only if they already exist otherwise we'll inject nil values and break the
7319
- // defaults and remember sanitisation process.
7320
- const value = this.getParameter(def.name);
7321
- if (this.hasParameter(def.name)) {
7322
- params[def.name] = value;
7323
- }
7324
- }
7325
- });
7326
- return new Visit(this.placeDefinition, params);
7327
- }
7328
- hasRoutingChangedFrom(other) {
7329
- const samePlace = other.placeDefinition === this.placeDefinition;
7330
- const sameRouteParameters = _.isEqual(this.placeDefinition.getFormattedRouteParameters(this, true), this.placeDefinition.getFormattedRouteParameters(other, true));
7331
- return !samePlace || !sameRouteParameters;
7332
- }
7333
- hasChangedFrom(other) {
7334
- const sameNonRouteParameters = _.isEqual(this.placeDefinition.getNonRouteParameters(this), this.placeDefinition.getNonRouteParameters(other));
7335
- return !sameNonRouteParameters || this.hasRoutingChangedFrom(other);
7336
- }
7337
- toDebugString() {
7338
- return Object.keys(this.visitParameters).map(k => `${k}=${this.visitParameters[k]}`).join(',');
7339
- }
7340
- }
7341
-
7342
7507
  const AUP_PLACE_CONFIG = new InjectionToken('AUP_PLACE_CONFIG');
7343
7508
 
7344
7509
  class NotAuthorisedNoticeComponent {
@@ -8000,54 +8165,6 @@ function Place(options) {
8000
8165
  };
8001
8166
  }
8002
8167
 
8003
- /**
8004
- * This a work around for the fact that an activated route with multiple segments doesn't
8005
- * include the segment params in the paramMap as well as each segment returns an empty
8006
- * param map even when `parameter`s has content.
8007
- */
8008
- class ConsolidatedParameterMap {
8009
- constructor(paramMap, urlSegments) {
8010
- this.paramMaps = [paramMap].concat((urlSegments || []).map(s => new ParamMapAdapter(s.parameters))).filter(m => !!m); // the activated route param map can be null
8011
- }
8012
- get(name) {
8013
- const paramMap = this.paramMaps.find(m => m.has(name));
8014
- return paramMap.get(name);
8015
- }
8016
- getAll(name) {
8017
- const paramMap = this.paramMaps.find(m => m.has(name));
8018
- return paramMap.getAll(name);
8019
- }
8020
- has(name) {
8021
- return !!this.paramMaps.find(m => m.has(name));
8022
- }
8023
- get keys() {
8024
- return this.paramMaps.reduce((result, params) => result.concat(params.keys), []);
8025
- }
8026
- }
8027
- __decorate([
8028
- Memoize(),
8029
- __metadata("design:type", Array),
8030
- __metadata("design:paramtypes", [])
8031
- ], ConsolidatedParameterMap.prototype, "keys", null);
8032
- class ParamMapAdapter {
8033
- constructor(params) {
8034
- this.params = params;
8035
- }
8036
- get(name) {
8037
- return this.params[name];
8038
- }
8039
- getAll(name) {
8040
- const value = this.get(name);
8041
- return Array.isArray(value) ? value : [value];
8042
- }
8043
- has(name) {
8044
- return this.keys.includes(name);
8045
- }
8046
- get keys() {
8047
- return Object.keys(this.params);
8048
- }
8049
- }
8050
-
8051
8168
  class NoopAuthGuard {
8052
8169
  constructor() {
8053
8170
  }
@@ -8097,7 +8214,7 @@ class VisitSanitiser {
8097
8214
  let sanitisedVisit = visit;
8098
8215
  for (let i = 0; i < parameterDefs.length; i++) {
8099
8216
  const def = parameterDefs[i];
8100
- const value = visit.getParameter(def.name);
8217
+ const value = visit.getParameterValue(def);
8101
8218
  const sanitisedValue = yield def.sanitise(value, sanitisedVisit, this.placeHistory, this.injector, this.navigationSession.isPopState);
8102
8219
  if (def.hasChanged(value, sanitisedValue)) {
8103
8220
  sanitisedVisit = sanitisedVisit.replace(def, sanitisedValue);
@@ -8134,7 +8251,7 @@ class PlaceGuard {
8134
8251
  }
8135
8252
  const result = yield this.cleanInteractionState(activatedRoute, state, () => __awaiter(this, void 0, void 0, function* () {
8136
8253
  // Parse our route params.
8137
- const params = new ConsolidatedParameterMap(activatedRoute.paramMap, activatedRoute.url);
8254
+ const params = new ConsolidatedParameterMap(activatedRoute.url, activatedRoute.paramMap);
8138
8255
  const parsedParams = placeDefinition.parseRouteParams(params);
8139
8256
  const navigationSession = this.placeRouter.navigationSession;
8140
8257
  const initialVisit = navigationSession.getVisitFor(placeDefinition) || new Visit(placeDefinition, parsedParams);
@@ -8182,27 +8299,6 @@ class PlaceGuard {
8182
8299
  const visit = result instanceof Visit ? result : new Visit(PlaceComponent.getDefinition(result), {});
8183
8300
  return this.urlService.createUrlSnapshot(visit).urlTree;
8184
8301
  }
8185
- // protected async ensureAuthenticatedThen(activatedRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot, next: (placeDefinition: PlaceDefinition) => Promise<boolean | UrlTree>): Promise<boolean | UrlTree> {
8186
- // const authoriseResult = placeDefinition.authenticate ? await this.isAuthorised(activatedRoute, state) : true;
8187
- // if (authoriseResult === true) {
8188
- // // we're authorised, now run the place guards.
8189
- // return next(placeDefinition);
8190
- // } else {
8191
- // console.log('not authorised result', authoriseResult);
8192
- // return authoriseResult;
8193
- // }
8194
- // }
8195
- //
8196
- // // @Trace()
8197
- // protected async ensureAuthorisedThen(activatedRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot, next: (placeDefinition: PlaceDefinition) => Promise<boolean | UrlTree>): Promise<boolean | UrlTree> {
8198
- //
8199
- // }
8200
- // @Trace()
8201
- // async isAuthorised(activatedRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean | UrlTree> {
8202
- // const authorised = this.getAuthGuard(this.injector).canActivate(activatedRoute, state);
8203
- // return (authorised instanceof Observable) ? authorised.toPromise() : authorised;
8204
- // }
8205
- // abstract getAuthGuard(injector: Injector): CanActivate;
8206
8302
  // @Trace()
8207
8303
  cleanInteractionState(route, state, next) {
8208
8304
  return __awaiter(this, void 0, void 0, function* () {
@@ -8263,12 +8359,14 @@ var Formatter;
8263
8359
  Formatter.BOOLEAN = new BooleanType();
8264
8360
  })(Formatter || (Formatter = {}));
8265
8361
 
8266
- function installMechanics(prototype, propertyKey, backingModelFactory, tagPrefix, isEmpty) {
8362
+ function installMechanics(parameterDef, prototype, propertyKey, tagPrefix) {
8363
+ Klass.get(prototype).addToOwnMetadataList(ROUTE_PARAMETER_LIST_KEY, parameterDef);
8267
8364
  function getMechanics(instance, propertyName) {
8268
8365
  const key = `__mechanics_${propertyName.toString()}`;
8269
8366
  if (!instance[key]) {
8367
+ const backingModel = parameterDef.createBackingModel();
8270
8368
  instance[key] = {
8271
- backingModel: backingModelFactory(),
8369
+ backingModel: backingModel,
8272
8370
  binding: null
8273
8371
  };
8274
8372
  const tag = `${tagPrefix}(${prototype.constructor.name}.${propertyKey.toString()})`;
@@ -8292,12 +8390,12 @@ function installMechanics(prototype, propertyKey, backingModelFactory, tagPrefix
8292
8390
  toLeft: Functions.identity,
8293
8391
  toRight: Functions.identity
8294
8392
  });
8295
- if (isEmpty(userModel)) {
8393
+ if (parameterDef.isEmptyValue(userModel.value)) {
8296
8394
  // console.log(`Push visit to model for ${tag}`, {value: mechanics.backingModel.value});
8297
8395
  mechanics.binding.writeRight(); // push the visit into the user model;
8298
8396
  }
8299
8397
  else {
8300
- if (!isEmpty(mechanics.backingModel)) {
8398
+ if (!parameterDef.isEmptyValue(mechanics.backingModel.value)) {
8301
8399
  console.warn('Assigning a visit model with an existing value to a visit parameter with an existing value. Visit parameter will be overridden');
8302
8400
  }
8303
8401
  mechanics.binding.writeLeft(); // push the user model into the visit
@@ -8308,25 +8406,22 @@ function installMechanics(prototype, propertyKey, backingModelFactory, tagPrefix
8308
8406
  }
8309
8407
  function RouteId(type, options) {
8310
8408
  return (prototype, propertyKey) => {
8311
- const param = new ParameterDefinition.RouteId(propertyKey.toString(), options, type);
8312
- Klass.get(prototype).addToOwnMetadataList(ROUTE_PARAMETER_LIST_KEY, param);
8313
- installMechanics(prototype, propertyKey, () => new MutableValueModel(), '@RouteId', m => m.query().isNil());
8409
+ const parameterDef = new ParameterDefinition.RouteId(propertyKey.toString(), options, type);
8410
+ installMechanics(parameterDef, prototype, propertyKey, '@RouteId');
8314
8411
  };
8315
8412
  }
8316
8413
  function VisitParameter(options) {
8317
8414
  const opts = Opts.get(options);
8318
8415
  return (prototype, propertyKey) => {
8319
- const param = new ParameterDefinition.ValueParameter(propertyKey.toString(), options, opts.getOptional('storeInUrl', null));
8320
- Klass.get(prototype).addToOwnMetadataList(ROUTE_PARAMETER_LIST_KEY, param);
8321
- installMechanics(prototype, propertyKey, () => new MutableValueModel(), '@VisitParameter', m => m.query().isNil());
8416
+ const parameterDef = new ParameterDefinition.ValueParameter(propertyKey.toString(), options, opts.getOptional('storeInUrl', null));
8417
+ installMechanics(parameterDef, prototype, propertyKey, '@VisitParameter');
8322
8418
  };
8323
8419
  }
8324
8420
  function VisitParameterList(options) {
8325
8421
  const opts = Opts.get(options);
8326
8422
  return (prototype, propertyKey) => {
8327
- const param = new ParameterDefinition.ArrayParameter(propertyKey.toString(), options, opts.getOptional('storeInUrl', null));
8328
- Klass.get(prototype).addToOwnMetadataList(ROUTE_PARAMETER_LIST_KEY, param);
8329
- installMechanics(prototype, propertyKey, () => new MutableListModel(), '@VisitParameterList', m => m.query().isEmpty());
8423
+ const parameterDef = new ParameterDefinition.ArrayParameter(propertyKey.toString(), options, opts.getOptional('storeInUrl', null));
8424
+ installMechanics(parameterDef, prototype, propertyKey, '@VisitParameterList');
8330
8425
  };
8331
8426
  }
8332
8427