@coolon/angular-ui-powerups 0.0.71 → 0.0.74

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 (102) hide show
  1. package/bundles/coolon-angular-ui-powerups.umd.js +1514 -1260
  2. package/bundles/coolon-angular-ui-powerups.umd.js.map +1 -1
  3. package/bundles/coolon-angular-ui-powerups.umd.min.js +1 -1
  4. package/bundles/coolon-angular-ui-powerups.umd.min.js.map +1 -1
  5. package/coolon-angular-ui-powerups.d.ts +34 -32
  6. package/coolon-angular-ui-powerups.metadata.json +1 -1
  7. package/esm2015/coolon-angular-ui-powerups.js +34 -32
  8. package/esm2015/index.js +2 -2
  9. package/esm2015/lib/angular-ui-powerups.module.js +8 -22
  10. package/esm2015/lib/components/components.module.js +47 -0
  11. package/esm2015/lib/components/forms/number-input/number-input.component.js +2 -2
  12. package/esm2015/lib/components/forms/password-input/password-input.component.js +2 -2
  13. package/esm2015/lib/components/forms/select-input/select-input.component.js +2 -2
  14. package/esm2015/lib/components/forms/string-input/string-input.component.js +2 -2
  15. package/esm2015/lib/components/index.js +2 -1
  16. package/esm2015/lib/components/noop/noop.component.js +2 -2
  17. package/esm2015/lib/directives/directives.module.js +36 -0
  18. package/esm2015/lib/directives/index.js +2 -1
  19. package/esm2015/lib/interaction/components/activity-container/activity-container.component.js +3 -3
  20. package/esm2015/lib/interaction/components/activity-outlet/activity-outlet.component.js +2 -2
  21. package/esm2015/lib/interaction/components/alert-dialog/alert-dialog.component.js +3 -3
  22. package/esm2015/lib/interaction/components/confirm-then-dialog/confirm-then-dialog.component.js +3 -3
  23. package/esm2015/lib/interaction/components/confirmation-dialog/confirmation-dialog.component.js +3 -3
  24. package/esm2015/lib/interaction/components/interaction-outlet/interaction-outlet.component.js +2 -2
  25. package/esm2015/lib/interaction/services/dialog-interaction.service.js +3 -1
  26. package/esm2015/lib/place/components/abstract-place-navigation.component.js +38 -3
  27. package/esm2015/lib/place/components/busy-overlay/busy-overlay.component.js +2 -2
  28. package/esm2015/lib/place/components/empty-state/empty-state.component.js +3 -3
  29. package/esm2015/lib/place/components/list-place-nav/list-place-nav.component.js +3 -3
  30. package/esm2015/lib/place/components/place-outlet/place-outlet.component.js +64 -29
  31. package/esm2015/lib/place/components/tabbed-place-navigation/tabbed-place-navigation.component.js +3 -3
  32. package/esm2015/lib/place/index.js +2 -2
  33. package/esm2015/lib/place/place-definition.js +2 -6
  34. package/esm2015/lib/place/place-router.js +7 -9
  35. package/esm2015/lib/place/place.decorator.js +4 -4
  36. package/esm2015/lib/place/place.module.js +4 -2
  37. package/esm2015/lib/place/route/guards/enter-place-guard.service.js +283 -0
  38. package/esm2015/lib/place/route/guards/leave-place.guard.js +70 -50
  39. package/esm2015/lib/place/visit.js +10 -1
  40. package/esm2015/public_api.js +4 -4
  41. package/esm5/coolon-angular-ui-powerups.js +34 -32
  42. package/esm5/index.js +2 -2
  43. package/esm5/lib/angular-ui-powerups.module.js +8 -22
  44. package/esm5/lib/components/components.module.js +51 -0
  45. package/esm5/lib/components/forms/number-input/number-input.component.js +2 -2
  46. package/esm5/lib/components/forms/password-input/password-input.component.js +2 -2
  47. package/esm5/lib/components/forms/select-input/select-input.component.js +2 -2
  48. package/esm5/lib/components/forms/string-input/string-input.component.js +2 -2
  49. package/esm5/lib/components/index.js +2 -1
  50. package/esm5/lib/components/noop/noop.component.js +2 -2
  51. package/esm5/lib/directives/directives.module.js +40 -0
  52. package/esm5/lib/directives/index.js +2 -1
  53. package/esm5/lib/interaction/components/activity-container/activity-container.component.js +3 -3
  54. package/esm5/lib/interaction/components/activity-outlet/activity-outlet.component.js +2 -2
  55. package/esm5/lib/interaction/components/alert-dialog/alert-dialog.component.js +3 -3
  56. package/esm5/lib/interaction/components/confirm-then-dialog/confirm-then-dialog.component.js +3 -3
  57. package/esm5/lib/interaction/components/confirmation-dialog/confirmation-dialog.component.js +3 -3
  58. package/esm5/lib/interaction/components/interaction-outlet/interaction-outlet.component.js +2 -2
  59. package/esm5/lib/interaction/services/dialog-interaction.service.js +3 -1
  60. package/esm5/lib/place/components/abstract-place-navigation.component.js +38 -3
  61. package/esm5/lib/place/components/busy-overlay/busy-overlay.component.js +2 -2
  62. package/esm5/lib/place/components/empty-state/empty-state.component.js +3 -3
  63. package/esm5/lib/place/components/list-place-nav/list-place-nav.component.js +3 -3
  64. package/esm5/lib/place/components/place-outlet/place-outlet.component.js +72 -34
  65. package/esm5/lib/place/components/tabbed-place-navigation/tabbed-place-navigation.component.js +3 -3
  66. package/esm5/lib/place/index.js +2 -2
  67. package/esm5/lib/place/place-definition.js +2 -5
  68. package/esm5/lib/place/place-router.js +11 -10
  69. package/esm5/lib/place/place.decorator.js +4 -4
  70. package/esm5/lib/place/place.module.js +4 -2
  71. package/esm5/lib/place/route/guards/enter-place-guard.service.js +319 -0
  72. package/esm5/lib/place/route/guards/leave-place.guard.js +72 -8
  73. package/esm5/lib/place/visit.js +13 -1
  74. package/esm5/public_api.js +4 -4
  75. package/fesm2015/coolon-angular-ui-powerups.js +1176 -992
  76. package/fesm2015/coolon-angular-ui-powerups.js.map +1 -1
  77. package/fesm5/coolon-angular-ui-powerups.js +1444 -1194
  78. package/fesm5/coolon-angular-ui-powerups.js.map +1 -1
  79. package/lib/components/components.module.d.ts +2 -0
  80. package/lib/components/index.d.ts +1 -0
  81. package/lib/directives/directives.module.d.ts +2 -0
  82. package/lib/directives/index.d.ts +1 -0
  83. package/lib/place/components/abstract-place-navigation.component.d.ts +7 -1
  84. package/lib/place/components/place-outlet/place-outlet.component.d.ts +7 -5
  85. package/lib/place/index.d.ts +1 -1
  86. package/lib/place/place-definition.d.ts +1 -2
  87. package/lib/place/place.decorator.d.ts +1 -1
  88. package/lib/place/route/guards/{place-route.guard.d.ts → enter-place-guard.service.d.ts} +6 -4
  89. package/lib/place/visit.d.ts +2 -0
  90. package/package.json +1 -1
  91. package/schematics/place-routes/place-builder.js +0 -1
  92. package/schematics/place-routes/place-builder.js.map +1 -1
  93. package/schematics/place-routes/place-class-scanner.d.ts +1 -0
  94. package/schematics/place-routes/place-class-scanner.js +7 -2
  95. package/schematics/place-routes/place-class-scanner.js.map +1 -1
  96. package/schematics/place-routes/place-def.d.ts +4 -3
  97. package/schematics/place-routes/place-def.js +40 -25
  98. package/schematics/place-routes/place-def.js.map +1 -1
  99. package/schematics/place-routes/templates/place-routes.ts.template +1 -1
  100. package/styles/styles.scss +1 -1
  101. package/esm2015/lib/place/route/guards/place-route.guard.js +0 -243
  102. package/esm5/lib/place/route/guards/place-route.guard.js +0 -273
@@ -1,13 +1,13 @@
1
- import { DOCUMENT, Location, CommonModule } from '@angular/common';
2
- import { EventEmitter, Input, Output, HostListener, Component, Directive, ElementRef, Inject, NgZone, InjectionToken, Injector, ComponentFactoryResolver, ViewContainerRef, ViewChild, ViewChildren, Injectable, Optional, ɵɵdefineInjectable, ɵɵinject, NgModule, HostBinding, SkipSelf, INJECTOR } from '@angular/core';
1
+ import { DOCUMENT, CommonModule, Location } from '@angular/common';
2
+ import { Directive, ElementRef, Inject, Input, HostListener, NgZone, NgModule, EventEmitter, Output, Component, InjectionToken, Injector, ComponentFactoryResolver, ViewContainerRef, ViewChild, ViewChildren, Injectable, Optional, ɵɵdefineInjectable, ɵɵinject, SkipSelf, HostBinding, INJECTOR } from '@angular/core';
3
3
  import { FormsModule } from '@angular/forms';
4
- import { MatDialog, MatButtonModule, MatDialogModule, MatTabsModule, MatProgressSpinnerModule, MatInputModule, MatFormFieldModule, MatSelectModule } from '@angular/material';
5
- import { MatTabsModule as MatTabsModule$1 } from '@angular/material/tabs';
4
+ import { MatInputModule, MatFormFieldModule, MatSelectModule, MatDialog, MatButtonModule, MatDialogModule, MatTabsModule as MatTabsModule$1, MatProgressSpinnerModule } from '@angular/material';
5
+ import { MatTabsModule } from '@angular/material/tabs';
6
6
  import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
7
+ import { GarbageCollector, assert, UnaryCommand, lang, Dsl, Logger, DelegatingFormValueModel, UseDelegate, ValueModel, ListModel, StoreInListModel, DelegatingValueModel, MutableStream, MutableListModel, DelegatingListModel, StoreInValueModel, Binding, MutableValueModel, Trace, Guard as Guard$1, Command, OptionsHelper, ValueHolder } from '@coolon/pectin';
7
8
  import { __decorate, __metadata, __awaiter } from 'tslib';
8
- import { GarbageCollector, DelegatingFormValueModel, UseDelegate, ValueModel, ListModel, StoreInListModel, assert, UnaryCommand, lang, Dsl, Logger, DelegatingValueModel, MutableStream, MutableListModel, DelegatingListModel, StoreInValueModel, Binding, MutableValueModel, Trace, Guard as Guard$1, OptionsHelper, ValueHolder } from '@coolon/pectin';
9
9
  import { PortalModule } from '@angular/cdk/portal';
10
- import { Router, RouterModule, NavigationStart, NavigationEnd, NavigationError, ActivatedRoute, RouterOutlet, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
10
+ import { Router, RouterModule, UrlSegment, NavigationStart, NavigationEnd, NavigationError, RouterOutlet, ActivatedRouteSnapshot, RouterStateSnapshot, UrlSerializer } from '@angular/router';
11
11
  import ___default, { last, isNil, isEqual } from 'lodash';
12
12
  import { assert as assert$1, Opts, Klass } from '@coolon/typescript-utilities';
13
13
  import { MatDialogConfig, MAT_DIALOG_DEFAULT_OPTIONS, MatDialog as MatDialog$1 } from '@angular/material/dialog';
@@ -25,98 +25,179 @@ import ResizeObserver from 'resize-observer-polyfill';
25
25
  * @fileoverview added by tsickle
26
26
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
27
27
  */
28
- class DisposableComponent extends GarbageCollector {
28
+ /**
29
+ * @template P
30
+ */
31
+ class CommandDirective extends GarbageCollector {
32
+ /**
33
+ * @param {?} elementRef
34
+ */
35
+ constructor(elementRef) {
36
+ super();
37
+ this.elementRef = elementRef;
38
+ this._commandParameterProvided = false;
39
+ }
29
40
  /**
41
+ * @param {?} value
30
42
  * @return {?}
31
43
  */
32
- ngOnDestroy() {
33
- this.dispose();
44
+ set commandParameter(value) {
45
+ this._commandParameterProvided = true;
46
+ this._commandParameter = value;
34
47
  }
35
- }
36
-
37
- /**
38
- * @fileoverview added by tsickle
39
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
40
- */
41
- /**
42
- * @abstract
43
- * @template T
44
- */
45
- class AbstractInputComponent extends DisposableComponent {
46
- constructor() {
47
- super();
48
- this.valueModel = new DelegatingFormValueModel();
49
- // TODO: fix this.
50
- // tslint:disable-next-line:no-output-native
51
- this.focus = new EventEmitter();
52
- // tslint:disable-next-line:no-output-native
53
- this.blur = new EventEmitter();
54
- // tslint:disable-next-line:no-output-native
55
- this.enterKey = new EventEmitter();
56
- // tslint:disable-next-line:no-output-native
57
- this.escapeKey = new EventEmitter();
58
- /** @type {?} */
59
- const self = this;
60
- this.errorStateMatcher = {
61
- /**
62
- * @param {?} control
63
- * @param {?} form
64
- * @return {?}
65
- */
66
- isErrorState(control, form) {
67
- return self.hasErrors();
68
- }
69
- };
48
+ /**
49
+ * @return {?}
50
+ */
51
+ get commandParameter() {
52
+ return this._commandParameter;
70
53
  }
71
54
  /**
72
- * @param {?} model
73
55
  * @return {?}
74
56
  */
75
- set userValueModel(model) {
76
- this.valueModel.setDelegate(model);
57
+ ngOnInit() {
58
+ assert.notNil(this.pectinCommand);
59
+ if (this.pectinCommand instanceof UnaryCommand) {
60
+ if (!this._commandParameterProvided) {
61
+ lang.illegalState('UnaryCommands required the command parameter to be specified.');
62
+ }
63
+ }
64
+ else {
65
+ if (this._commandParameterProvided) {
66
+ lang.illegalState('command parameters are only supported by UnaryCommands');
67
+ }
68
+ }
77
69
  }
78
70
  /**
79
71
  * @return {?}
80
72
  */
81
- notifyClick() {
82
- this.safelyInvoke(this.clickCommand);
73
+ ngAfterViewInit() {
74
+ // for some reason mat-buttons kills the disabled host binding. It works on a regular button but for now
75
+ // we need to do this.
76
+ const { chain } = Dsl.disposeWith(this);
77
+ chain(this.pectinCommand.enabled).subscribe((/**
78
+ * @param {?} enabled
79
+ * @return {?}
80
+ */
81
+ enabled => {
82
+ if (enabled) {
83
+ this.elementRef.nativeElement.removeAttribute('disabled');
84
+ if (this.elementRef.nativeElement.tagName === 'A') {
85
+ this.elementRef.nativeElement.setAttribute('href', 'javascript:void');
86
+ }
87
+ }
88
+ else {
89
+ this.elementRef.nativeElement.setAttribute('disabled', 'disabled');
90
+ if (this.elementRef.nativeElement.tagName === 'A') {
91
+ this.elementRef.nativeElement.removeAttribute('href');
92
+ }
93
+ }
94
+ }));
83
95
  }
84
96
  /**
85
97
  * @return {?}
86
98
  */
87
- notifyFocusIn() {
88
- this.safelyInvoke(this.focusCommand);
89
- this.focus.emit();
99
+ ngOnDestroy() {
100
+ this.dispose();
90
101
  }
91
102
  /**
103
+ * @param {?} $event
92
104
  * @return {?}
93
105
  */
94
- notifyFocusOut() {
95
- this.safelyInvoke(this.blurCommand);
96
- this.blur.emit();
106
+ notifyClick($event) {
107
+ $event.preventDefault();
108
+ $event.stopPropagation();
109
+ if (this.pectinCommand.enabled.value) {
110
+ if (this.pectinCommand instanceof UnaryCommand) {
111
+ this.pectinCommand.withContext({ event: $event }).execute(this.commandParameter);
112
+ }
113
+ else {
114
+ this.pectinCommand.withContext({ event: $event }).execute();
115
+ }
116
+ }
117
+ else {
118
+ console.warn('disabled command clicked, ignoring.');
119
+ }
97
120
  }
121
+ }
122
+ CommandDirective.decorators = [
123
+ { type: Directive, args: [{
124
+ // tslint:disable-next-line:directive-selector
125
+ selector: '[pectinCommand]'
126
+ },] }
127
+ ];
128
+ /** @nocollapse */
129
+ CommandDirective.ctorParameters = () => [
130
+ { type: ElementRef, decorators: [{ type: Inject, args: [ElementRef,] }] }
131
+ ];
132
+ CommandDirective.propDecorators = {
133
+ pectinCommand: [{ type: Input }],
134
+ commandParameter: [{ type: Input }],
135
+ notifyClick: [{ type: HostListener, args: ['click', ['$event'],] }]
136
+ };
137
+ if (false) {
138
+ /** @type {?} */
139
+ CommandDirective.prototype.pectinCommand;
140
+ /**
141
+ * @type {?}
142
+ * @private
143
+ */
144
+ CommandDirective.prototype._commandParameter;
145
+ /**
146
+ * @type {?}
147
+ * @private
148
+ */
149
+ CommandDirective.prototype._commandParameterProvided;
150
+ /**
151
+ * @type {?}
152
+ * @private
153
+ */
154
+ CommandDirective.prototype.elementRef;
155
+ }
156
+
157
+ /**
158
+ * @fileoverview added by tsickle
159
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
160
+ */
161
+ class DisposableComponent extends GarbageCollector {
98
162
  /**
99
163
  * @return {?}
100
164
  */
101
- notifyEnterKey() {
102
- this.safelyInvoke(this.enterCommand);
103
- this.enterKey.emit();
165
+ ngOnDestroy() {
166
+ this.dispose();
167
+ }
168
+ }
169
+
170
+ /**
171
+ * @fileoverview added by tsickle
172
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
173
+ */
174
+ class FocusBindingDirective extends DisposableComponent {
175
+ /**
176
+ * @param {?} el
177
+ * @param {?} ngZone
178
+ * @param {?} document
179
+ */
180
+ constructor(el, ngZone, document) {
181
+ super();
182
+ this.el = el;
183
+ this.ngZone = ngZone;
184
+ // @see https://stackoverflow.com/questions/49513359/could-not-resolve-type-document-in-angular5/53715642#53715642
185
+ this.document = (/** @type {?} */ (document));
104
186
  }
105
187
  /**
106
188
  * @return {?}
107
189
  */
108
- notifyEscapeKey() {
109
- this.safelyInvoke(this.escapeCommand);
110
- this.escapeKey.emit();
190
+ onFocusIn() {
191
+ if (this.hasBinding()) {
192
+ this.pectinFocusBinding.focusContext.notifyFocusIn();
193
+ }
111
194
  }
112
195
  /**
113
- * @protected
114
- * @param {?} command
115
196
  * @return {?}
116
197
  */
117
- safelyInvoke(command) {
118
- if (command && command.enabled.value) {
119
- command.execute();
198
+ onFocusOut() {
199
+ if (this.hasBinding()) {
200
+ this.pectinFocusBinding.focusContext.notifyFocusOut();
120
201
  }
121
202
  }
122
203
  /**
@@ -127,401 +208,251 @@ class AbstractInputComponent extends DisposableComponent {
127
208
  /**
128
209
  * @return {?}
129
210
  */
130
- isEnabled() {
131
- return this.enabled.value;
211
+ ngAfterViewInit() {
212
+ // TODO: Make this also track the current enabled/disabled state.
213
+ if (this.hasBinding()) {
214
+ const { chain } = Dsl.disposeWith(this);
215
+ chain(this.pectinFocusBinding.focusContext.focused).subscribe((/**
216
+ * @param {?} focused
217
+ * @return {?}
218
+ */
219
+ (focused) => {
220
+ if (focused && !this.alreadyHasFocus()) {
221
+ this.tryAndFocus();
222
+ }
223
+ }));
224
+ }
225
+ else {
226
+ Logger.get(this).warn('pectinFocusBinding was nil');
227
+ }
132
228
  }
133
229
  /**
230
+ * @private
134
231
  * @return {?}
135
232
  */
136
- get enabled() {
137
- return this.valueModel.enabled;
233
+ hasBinding() {
234
+ return !!this.pectinFocusBinding && !!this.pectinFocusBinding.focusContext;
138
235
  }
236
+ // Hook method for debugging via tracing.
139
237
  /**
140
238
  * @return {?}
141
239
  */
142
- hasErrors() {
143
- return !this.errorList.query().isEmpty();
240
+ alreadyHasFocus() {
241
+ return this.isFocused(this.focusTarget);
144
242
  }
243
+ // Hook method for debugging via tracing.
145
244
  /**
245
+ * @param {?} element
146
246
  * @return {?}
147
247
  */
148
- get errorList() {
149
- return this.valueModel.errorList;
248
+ isFocused(element) {
249
+ return this.document.activeElement === element;
150
250
  }
151
251
  /**
252
+ * @param {?=} retries
152
253
  * @return {?}
153
254
  */
154
- get firstError() {
155
- return this.hasErrors() ? this.errorList.value[0] : null;
156
- }
157
- }
158
- AbstractInputComponent.propDecorators = {
159
- userValueModel: [{ type: Input, args: ['valueModel',] }],
160
- label: [{ type: Input }],
161
- floatLabel: [{ type: Input }],
162
- hint: [{ type: Input }],
163
- placeholder: [{ type: Input }],
164
- focusCommand: [{ type: Input, args: ['command.focus',] }],
165
- blurCommand: [{ type: Input, args: ['command.blur',] }],
166
- enterCommand: [{ type: Input, args: ['command.enter',] }],
167
- escapeCommand: [{ type: Input, args: ['command.escape',] }],
168
- clickCommand: [{ type: Input, args: ['command.click',] }],
169
- focus: [{ type: Output }],
170
- blur: [{ type: Output }],
171
- enterKey: [{ type: Output }],
172
- escapeKey: [{ type: Output }],
173
- notifyClick: [{ type: HostListener, args: ['click',] }],
174
- notifyFocusIn: [{ type: HostListener, args: ['focusin',] }],
175
- notifyFocusOut: [{ type: HostListener, args: ['focusout',] }]
176
- };
177
- __decorate([
178
- UseDelegate(),
179
- __metadata("design:type", ValueModel),
180
- __metadata("design:paramtypes", [ValueModel])
181
- ], AbstractInputComponent.prototype, "userValueModel", null);
182
- if (false) {
183
- /** @type {?} */
184
- AbstractInputComponent.prototype.valueModel;
185
- /** @type {?} */
186
- AbstractInputComponent.prototype.label;
187
- /** @type {?} */
188
- AbstractInputComponent.prototype.floatLabel;
189
- /** @type {?} */
190
- AbstractInputComponent.prototype.hint;
191
- /** @type {?} */
192
- AbstractInputComponent.prototype.placeholder;
193
- /** @type {?} */
194
- AbstractInputComponent.prototype.focusCommand;
195
- /** @type {?} */
196
- AbstractInputComponent.prototype.blurCommand;
197
- /** @type {?} */
198
- AbstractInputComponent.prototype.enterCommand;
199
- /** @type {?} */
200
- AbstractInputComponent.prototype.escapeCommand;
201
- /** @type {?} */
202
- AbstractInputComponent.prototype.clickCommand;
203
- /** @type {?} */
204
- AbstractInputComponent.prototype.focus;
205
- /** @type {?} */
206
- AbstractInputComponent.prototype.blur;
207
- /** @type {?} */
208
- AbstractInputComponent.prototype.enterKey;
209
- /** @type {?} */
210
- AbstractInputComponent.prototype.escapeKey;
211
- /** @type {?} */
212
- AbstractInputComponent.prototype.errorStateMatcher;
213
- }
214
-
215
- /**
216
- * @fileoverview added by tsickle
217
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
218
- */
219
- class NumberInputComponent extends AbstractInputComponent {
220
- constructor() {
221
- super();
222
- }
223
- /**
224
- * @return {?}
225
- */
226
- ngOnInit() {
227
- }
228
- }
229
- NumberInputComponent.decorators = [
230
- { type: Component, args: [{
231
- selector: 'angular-ui-powerups-number-input',
232
- template: "<mat-form-field appearance=\"standard\" [floatLabel]=\"floatLabel\">\n <mat-label *ngIf=\"label\">{{label}}</mat-label>\n <input type=\"number\"\n matInput\n placeholder=\"{{placeholder}}\"\n [(ngModel)]=\"valueModel.value\"\n [disabled]=\"!enabled.value\"\n (keydown.enter)=\"notifyEnterKey()\"\n (keydown.escape)=\"notifyEscapeKey()\"\n [pectinFocusBinding]=\"valueModel\"\n [errorStateMatcher]=\"errorStateMatcher\"\n >\n <mat-hint *ngIf=\"hint\">{{hint}}</mat-hint>\n <mat-error *ngIf=\"hasErrors\">{{firstError}}</mat-error>\n</mat-form-field>\n",
233
- styles: [":host{display:block}input,mat-form-field{width:100%}input mat-hint.faux-error,mat-form-field mat-hint.faux-error{color:#f44336}"]
234
- }] }
235
- ];
236
- /** @nocollapse */
237
- NumberInputComponent.ctorParameters = () => [];
238
-
239
- /**
240
- * @fileoverview added by tsickle
241
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
242
- */
243
- class PasswordInputComponent extends AbstractInputComponent {
244
- constructor() {
245
- super();
246
- }
247
- /**
248
- * @return {?}
249
- */
250
- ngOnInit() {
251
- }
252
- }
253
- PasswordInputComponent.decorators = [
254
- { type: Component, args: [{
255
- selector: 'angular-ui-powerups-password-input',
256
- template: "<mat-form-field appearance=\"standard\" [floatLabel]=\"floatLabel\">\n <mat-label *ngIf=\"label\">{{label}}</mat-label>\n <input type=\"password\"\n matInput\n placeholder=\"{{placeholder}}\"\n [(ngModel)]=\"valueModel.value\"\n [disabled]=\"!enabled.value\"\n (keydown.enter)=\"notifyEnterKey()\"\n (keydown.escape)=\"notifyEscapeKey()\"\n [pectinFocusBinding]=\"valueModel\"\n [errorStateMatcher]=\"errorStateMatcher\"\n >\n <mat-hint *ngIf=\"hint\">{{hint}}</mat-hint>\n <mat-error *ngIf=\"hasErrors\">{{firstError}}</mat-error>\n</mat-form-field>\n\n",
257
- styles: [":host{display:block}input,mat-form-field{width:100%}input mat-hint.faux-error,mat-form-field mat-hint.faux-error{color:#f44336}"]
258
- }] }
259
- ];
260
- /** @nocollapse */
261
- PasswordInputComponent.ctorParameters = () => [];
262
-
263
- /**
264
- * @fileoverview added by tsickle
265
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
266
- */
267
- /**
268
- * @template T
269
- */
270
- class SelectInputComponent extends AbstractInputComponent {
271
- constructor() {
272
- super();
273
- this.optionLabelFormat = (/**
274
- * @param {?} option
275
- * @return {?}
276
- */
277
- (option) => (option && this.optionLabel) ? option[this.optionLabel] : option);
278
- }
279
- /**
280
- * @return {?}
281
- */
282
- ngOnInit() {
283
- }
284
- }
285
- SelectInputComponent.decorators = [
286
- { type: Component, args: [{
287
- selector: 'angular-ui-powerups-select-input',
288
- template: "<mat-form-field appearance=\"standard\" [floatLabel]=\"floatLabel\">\n <mat-label *ngIf=\"label\">{{label}}</mat-label>\n <mat-select placeholder=\"{{placeholder}}\"\n [(ngModel)]=\"valueModel.value\"\n [disabled]=\"!enabled.value\"\n (keydown.enter)=\"notifyEnterKey()\"\n (keydown.escape)=\"notifyEscapeKey()\"\n [pectinFocusBinding]=\"valueModel\"\n [errorStateMatcher]=\"errorStateMatcher\"\n >\n <mat-option *ngFor=\"let option of optionsModel.value\" [value]=\"option\">{{optionLabelFormat(option)}}\n </mat-option>\n </mat-select>\n <mat-hint *ngIf=\"hint\">{{hint}}</mat-hint>\n <mat-error *ngIf=\"hasErrors\">{{firstError}}</mat-error>\n</mat-form-field>\n",
289
- styles: [":host{display:inline-block}mat-form-field{width:100%}"]
290
- }] }
291
- ];
292
- /** @nocollapse */
293
- SelectInputComponent.ctorParameters = () => [];
294
- SelectInputComponent.propDecorators = {
295
- optionsModel: [{ type: Input }],
296
- options: [{ type: Input }],
297
- optionLabel: [{ type: Input }],
298
- optionLabelFormat: [{ type: Input }]
299
- };
300
- __decorate([
301
- UseDelegate(),
302
- __metadata("design:type", ListModel)
303
- ], SelectInputComponent.prototype, "optionsModel", void 0);
304
- __decorate([
305
- StoreInListModel('optionsModel'),
306
- __metadata("design:type", Array)
307
- ], SelectInputComponent.prototype, "options", void 0);
308
- if (false) {
309
- /** @type {?} */
310
- SelectInputComponent.prototype.optionsModel;
311
- /** @type {?} */
312
- SelectInputComponent.prototype.options;
313
- /** @type {?} */
314
- SelectInputComponent.prototype.optionLabel;
315
- /** @type {?} */
316
- SelectInputComponent.prototype.optionLabelFormat;
317
- }
318
-
319
- /**
320
- * @fileoverview added by tsickle
321
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
322
- */
323
- class StringInputComponent extends AbstractInputComponent {
324
- constructor() {
325
- super();
326
- }
327
- /**
328
- * @return {?}
329
- */
330
- ngOnInit() {
331
- }
332
- }
333
- StringInputComponent.decorators = [
334
- { type: Component, args: [{
335
- selector: 'angular-ui-powerups-string-input',
336
- template: "<mat-form-field appearance=\"standard\" [floatLabel]=\"floatLabel\">\n <mat-label *ngIf=\"label\">{{label}}</mat-label>\n <input matInput\n placeholder=\"{{placeholder}}\"\n [(ngModel)]=\"valueModel.value\"\n [disabled]=\"!enabled.value\"\n (keydown.enter)=\"notifyEnterKey()\"\n (keydown.escape)=\"notifyEscapeKey()\"\n [pectinFocusBinding]=\"valueModel\"\n [errorStateMatcher]=\"errorStateMatcher\"\n >\n <mat-hint *ngIf=\"hint\">{{hint}}</mat-hint>\n <mat-error *ngIf=\"hasErrors\">{{firstError}}</mat-error>\n</mat-form-field>\n\n",
337
- styles: [":host{display:block}input,mat-form-field{width:100%}input mat-hint.faux-error,mat-form-field mat-hint.faux-error{color:#f44336}"]
338
- }] }
339
- ];
340
- /** @nocollapse */
341
- StringInputComponent.ctorParameters = () => [];
342
-
343
- /**
344
- * @fileoverview added by tsickle
345
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
346
- */
347
- class NoopComponent {
348
- constructor() {
349
- }
350
- }
351
- NoopComponent.decorators = [
352
- { type: Component, args: [{
353
- selector: 'angular-ui-powerups-noop',
354
- template: "",
355
- styles: [":host{display:block}"]
356
- }] }
357
- ];
358
- /** @nocollapse */
359
- NoopComponent.ctorParameters = () => [];
360
-
361
- /**
362
- * @fileoverview added by tsickle
363
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
364
- */
365
- /**
366
- * @template P
367
- */
368
- class CommandDirective extends GarbageCollector {
369
- /**
370
- * @param {?} elementRef
371
- */
372
- constructor(elementRef) {
373
- super();
374
- this.elementRef = elementRef;
375
- this._commandParameterProvided = false;
376
- }
377
- /**
378
- * @param {?} value
379
- * @return {?}
380
- */
381
- set commandParameter(value) {
382
- this._commandParameterProvided = true;
383
- this._commandParameter = value;
384
- }
385
- /**
386
- * @return {?}
387
- */
388
- get commandParameter() {
389
- return this._commandParameter;
390
- }
391
- /**
392
- * @return {?}
393
- */
394
- ngOnInit() {
395
- assert.notNil(this.pectinCommand);
396
- if (this.pectinCommand instanceof UnaryCommand) {
397
- if (!this._commandParameterProvided) {
398
- lang.illegalState('UnaryCommands required the command parameter to be specified.');
255
+ tryAndFocus(retries = 5) {
256
+ if (this.modelShouldStillHaveFocus() && this.canFocus()) {
257
+ if (!this.alreadyHasFocus()) {
258
+ this.focusTarget.focus();
399
259
  }
400
- }
401
- else {
402
- if (this._commandParameterProvided) {
403
- lang.illegalState('command parameters are only supported by UnaryCommands');
260
+ // if we didn't get the focus we try again later.
261
+ if (!this.alreadyHasFocus()) {
262
+ Logger.get(this).log(`focus failed, trying ${retries} more times`);
263
+ if (retries > 0) {
264
+ // try again on the next paint
265
+ // TODO: is there an angular way of doing this without calling a window function.
266
+ requestAnimationFrame((/**
267
+ * @return {?}
268
+ */
269
+ () => {
270
+ this.tryAndFocus(retries - 1);
271
+ }));
272
+ }
273
+ else {
274
+ Logger.get(this).warn(`Tried to focus but gave up as the component wasn't enabled or visible.`);
275
+ }
404
276
  }
405
277
  }
406
278
  }
407
279
  /**
408
280
  * @return {?}
409
281
  */
410
- ngAfterViewInit() {
411
- // for some reason mat-buttons kills the disabled host binding. It works on a regular button but for now
412
- // we need to do this.
413
- const { chain } = Dsl.disposeWith(this);
414
- chain(this.pectinCommand.enabled).subscribe((/**
415
- * @param {?} enabled
416
- * @return {?}
417
- */
418
- enabled => {
419
- if (enabled) {
420
- this.elementRef.nativeElement.removeAttribute('disabled');
421
- if (this.elementRef.nativeElement.tagName === 'A') {
422
- this.elementRef.nativeElement.setAttribute('href', 'javascript:void');
423
- }
424
- }
425
- else {
426
- this.elementRef.nativeElement.setAttribute('disabled', 'disabled');
427
- if (this.elementRef.nativeElement.tagName === 'A') {
428
- this.elementRef.nativeElement.removeAttribute('href');
429
- }
430
- }
431
- }));
282
+ get focusTarget() {
283
+ return this.focusBindingTarget || this.el.nativeElement;
432
284
  }
285
+ // Hook method for debugging via tracing.
433
286
  /**
434
287
  * @return {?}
435
288
  */
436
- ngOnDestroy() {
437
- this.dispose();
289
+ modelShouldStillHaveFocus() {
290
+ return this.hasBinding() && this.pectinFocusBinding.focusContext.focused.value;
438
291
  }
292
+ // Hook method for debugging via tracing.
439
293
  /**
440
- * @param {?} $event
441
294
  * @return {?}
442
295
  */
443
- notifyClick($event) {
444
- $event.preventDefault();
445
- $event.stopPropagation();
446
- if (this.pectinCommand.enabled.value) {
447
- if (this.pectinCommand instanceof UnaryCommand) {
448
- this.pectinCommand.withContext({ event: $event }).execute(this.commandParameter);
449
- }
450
- else {
451
- this.pectinCommand.withContext({ event: $event }).execute();
452
- }
453
- }
454
- else {
455
- console.warn('disabled command clicked, ignoring.');
456
- }
296
+ canFocus() {
297
+ /** @type {?} */
298
+ const dimension = this.focusTarget.getBoundingClientRect();
299
+ /** @type {?} */
300
+ const hasSize = dimension.height >= 0 && dimension.height >= 0;
301
+ // tslint:disable-next-line:no-string-literal
302
+ return hasSize && !this.focusTarget['disabled'];
457
303
  }
458
304
  }
459
- CommandDirective.decorators = [
305
+ FocusBindingDirective.decorators = [
460
306
  { type: Directive, args: [{
461
307
  // tslint:disable-next-line:directive-selector
462
- selector: '[pectinCommand]'
308
+ selector: '[pectinFocusBinding]'
463
309
  },] }
464
310
  ];
465
311
  /** @nocollapse */
466
- CommandDirective.ctorParameters = () => [
467
- { type: ElementRef, decorators: [{ type: Inject, args: [ElementRef,] }] }
312
+ FocusBindingDirective.ctorParameters = () => [
313
+ { type: ElementRef, decorators: [{ type: Inject, args: [ElementRef,] }] },
314
+ { type: NgZone, decorators: [{ type: Inject, args: [NgZone,] }] },
315
+ { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
468
316
  ];
469
- CommandDirective.propDecorators = {
470
- pectinCommand: [{ type: Input }],
471
- commandParameter: [{ type: Input }],
472
- notifyClick: [{ type: HostListener, args: ['click', ['$event'],] }]
317
+ FocusBindingDirective.propDecorators = {
318
+ pectinFocusBinding: [{ type: Input }],
319
+ focusBindingTarget: [{ type: Input }],
320
+ onFocusIn: [{ type: HostListener, args: ['focusin',] }],
321
+ onFocusOut: [{ type: HostListener, args: ['focusout',] }]
473
322
  };
474
323
  if (false) {
475
- /** @type {?} */
476
- CommandDirective.prototype.pectinCommand;
477
324
  /**
478
325
  * @type {?}
479
326
  * @private
480
327
  */
481
- CommandDirective.prototype._commandParameter;
328
+ FocusBindingDirective.prototype.document;
329
+ /** @type {?} */
330
+ FocusBindingDirective.prototype.pectinFocusBinding;
331
+ /** @type {?} */
332
+ FocusBindingDirective.prototype.focusBindingTarget;
482
333
  /**
483
334
  * @type {?}
484
335
  * @private
485
336
  */
486
- CommandDirective.prototype._commandParameterProvided;
337
+ FocusBindingDirective.prototype.el;
487
338
  /**
488
339
  * @type {?}
489
340
  * @private
490
341
  */
491
- CommandDirective.prototype.elementRef;
342
+ FocusBindingDirective.prototype.ngZone;
492
343
  }
493
344
 
494
345
  /**
495
346
  * @fileoverview added by tsickle
496
347
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
497
348
  */
498
- class FocusBindingDirective extends DisposableComponent {
349
+ class DirectivesModule {
350
+ }
351
+ DirectivesModule.decorators = [
352
+ { type: NgModule, args: [{
353
+ declarations: [
354
+ CommandDirective,
355
+ FocusBindingDirective
356
+ ],
357
+ imports: [
358
+ CommonModule,
359
+ BrowserAnimationsModule,
360
+ FormsModule,
361
+ MatInputModule,
362
+ MatFormFieldModule,
363
+ MatSelectModule,
364
+ MatTabsModule
365
+ ],
366
+ exports: [
367
+ CommandDirective,
368
+ FocusBindingDirective
369
+ ]
370
+ },] }
371
+ ];
372
+
373
+ /**
374
+ * @fileoverview added by tsickle
375
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
376
+ */
377
+ /**
378
+ * @abstract
379
+ * @template T
380
+ */
381
+ class AbstractInputComponent extends DisposableComponent {
382
+ constructor() {
383
+ super();
384
+ this.valueModel = new DelegatingFormValueModel();
385
+ // TODO: fix this.
386
+ // tslint:disable-next-line:no-output-native
387
+ this.focus = new EventEmitter();
388
+ // tslint:disable-next-line:no-output-native
389
+ this.blur = new EventEmitter();
390
+ // tslint:disable-next-line:no-output-native
391
+ this.enterKey = new EventEmitter();
392
+ // tslint:disable-next-line:no-output-native
393
+ this.escapeKey = new EventEmitter();
394
+ /** @type {?} */
395
+ const self = this;
396
+ this.errorStateMatcher = {
397
+ /**
398
+ * @param {?} control
399
+ * @param {?} form
400
+ * @return {?}
401
+ */
402
+ isErrorState(control, form) {
403
+ return self.hasErrors();
404
+ }
405
+ };
406
+ }
499
407
  /**
500
- * @param {?} el
501
- * @param {?} ngZone
502
- * @param {?} document
408
+ * @param {?} model
409
+ * @return {?}
503
410
  */
504
- constructor(el, ngZone, document) {
505
- super();
506
- this.el = el;
507
- this.ngZone = ngZone;
508
- // @see https://stackoverflow.com/questions/49513359/could-not-resolve-type-document-in-angular5/53715642#53715642
509
- this.document = (/** @type {?} */ (document));
411
+ set userValueModel(model) {
412
+ this.valueModel.setDelegate(model);
510
413
  }
511
414
  /**
512
415
  * @return {?}
513
416
  */
514
- onFocusIn() {
515
- if (this.hasBinding()) {
516
- this.pectinFocusBinding.focusContext.notifyFocusIn();
517
- }
417
+ notifyClick() {
418
+ this.safelyInvoke(this.clickCommand);
518
419
  }
519
420
  /**
520
421
  * @return {?}
521
422
  */
522
- onFocusOut() {
523
- if (this.hasBinding()) {
524
- this.pectinFocusBinding.focusContext.notifyFocusOut();
423
+ notifyFocusIn() {
424
+ this.safelyInvoke(this.focusCommand);
425
+ this.focus.emit();
426
+ }
427
+ /**
428
+ * @return {?}
429
+ */
430
+ notifyFocusOut() {
431
+ this.safelyInvoke(this.blurCommand);
432
+ this.blur.emit();
433
+ }
434
+ /**
435
+ * @return {?}
436
+ */
437
+ notifyEnterKey() {
438
+ this.safelyInvoke(this.enterCommand);
439
+ this.enterKey.emit();
440
+ }
441
+ /**
442
+ * @return {?}
443
+ */
444
+ notifyEscapeKey() {
445
+ this.safelyInvoke(this.escapeCommand);
446
+ this.escapeKey.emit();
447
+ }
448
+ /**
449
+ * @protected
450
+ * @param {?} command
451
+ * @return {?}
452
+ */
453
+ safelyInvoke(command) {
454
+ if (command && command.enabled.value) {
455
+ command.execute();
525
456
  }
526
457
  }
527
458
  /**
@@ -532,139 +463,271 @@ class FocusBindingDirective extends DisposableComponent {
532
463
  /**
533
464
  * @return {?}
534
465
  */
535
- ngAfterViewInit() {
536
- // TODO: Make this also track the current enabled/disabled state.
537
- if (this.hasBinding()) {
538
- const { chain } = Dsl.disposeWith(this);
539
- chain(this.pectinFocusBinding.focusContext.focused).subscribe((/**
540
- * @param {?} focused
541
- * @return {?}
542
- */
543
- (focused) => {
544
- if (focused && !this.alreadyHasFocus()) {
545
- this.tryAndFocus();
546
- }
547
- }));
548
- }
549
- else {
550
- Logger.get(this).warn('pectinFocusBinding was nil');
551
- }
466
+ isEnabled() {
467
+ return this.enabled.value;
552
468
  }
553
469
  /**
554
- * @private
555
470
  * @return {?}
556
471
  */
557
- hasBinding() {
558
- return !!this.pectinFocusBinding && !!this.pectinFocusBinding.focusContext;
472
+ get enabled() {
473
+ return this.valueModel.enabled;
559
474
  }
560
- // Hook method for debugging via tracing.
561
475
  /**
562
476
  * @return {?}
563
477
  */
564
- alreadyHasFocus() {
565
- return this.isFocused(this.focusTarget);
478
+ hasErrors() {
479
+ return !this.errorList.query().isEmpty();
566
480
  }
567
- // Hook method for debugging via tracing.
568
481
  /**
569
- * @param {?} element
570
482
  * @return {?}
571
483
  */
572
- isFocused(element) {
573
- return this.document.activeElement === element;
484
+ get errorList() {
485
+ return this.valueModel.errorList;
574
486
  }
575
487
  /**
576
- * @param {?=} retries
577
488
  * @return {?}
578
489
  */
579
- tryAndFocus(retries = 5) {
580
- if (this.modelShouldStillHaveFocus() && this.canFocus()) {
581
- if (!this.alreadyHasFocus()) {
582
- this.focusTarget.focus();
583
- }
584
- // if we didn't get the focus we try again later.
585
- if (!this.alreadyHasFocus()) {
586
- Logger.get(this).log(`focus failed, trying ${retries} more times`);
587
- if (retries > 0) {
588
- // try again on the next paint
589
- // TODO: is there an angular way of doing this without calling a window function.
590
- requestAnimationFrame((/**
591
- * @return {?}
592
- */
593
- () => {
594
- this.tryAndFocus(retries - 1);
595
- }));
596
- }
597
- else {
598
- Logger.get(this).warn(`Tried to focus but gave up as the component wasn't enabled or visible.`);
599
- }
600
- }
601
- }
490
+ get firstError() {
491
+ return this.hasErrors() ? this.errorList.value[0] : null;
492
+ }
493
+ }
494
+ AbstractInputComponent.propDecorators = {
495
+ userValueModel: [{ type: Input, args: ['valueModel',] }],
496
+ label: [{ type: Input }],
497
+ floatLabel: [{ type: Input }],
498
+ hint: [{ type: Input }],
499
+ placeholder: [{ type: Input }],
500
+ focusCommand: [{ type: Input, args: ['command.focus',] }],
501
+ blurCommand: [{ type: Input, args: ['command.blur',] }],
502
+ enterCommand: [{ type: Input, args: ['command.enter',] }],
503
+ escapeCommand: [{ type: Input, args: ['command.escape',] }],
504
+ clickCommand: [{ type: Input, args: ['command.click',] }],
505
+ focus: [{ type: Output }],
506
+ blur: [{ type: Output }],
507
+ enterKey: [{ type: Output }],
508
+ escapeKey: [{ type: Output }],
509
+ notifyClick: [{ type: HostListener, args: ['click',] }],
510
+ notifyFocusIn: [{ type: HostListener, args: ['focusin',] }],
511
+ notifyFocusOut: [{ type: HostListener, args: ['focusout',] }]
512
+ };
513
+ __decorate([
514
+ UseDelegate(),
515
+ __metadata("design:type", ValueModel),
516
+ __metadata("design:paramtypes", [ValueModel])
517
+ ], AbstractInputComponent.prototype, "userValueModel", null);
518
+ if (false) {
519
+ /** @type {?} */
520
+ AbstractInputComponent.prototype.valueModel;
521
+ /** @type {?} */
522
+ AbstractInputComponent.prototype.label;
523
+ /** @type {?} */
524
+ AbstractInputComponent.prototype.floatLabel;
525
+ /** @type {?} */
526
+ AbstractInputComponent.prototype.hint;
527
+ /** @type {?} */
528
+ AbstractInputComponent.prototype.placeholder;
529
+ /** @type {?} */
530
+ AbstractInputComponent.prototype.focusCommand;
531
+ /** @type {?} */
532
+ AbstractInputComponent.prototype.blurCommand;
533
+ /** @type {?} */
534
+ AbstractInputComponent.prototype.enterCommand;
535
+ /** @type {?} */
536
+ AbstractInputComponent.prototype.escapeCommand;
537
+ /** @type {?} */
538
+ AbstractInputComponent.prototype.clickCommand;
539
+ /** @type {?} */
540
+ AbstractInputComponent.prototype.focus;
541
+ /** @type {?} */
542
+ AbstractInputComponent.prototype.blur;
543
+ /** @type {?} */
544
+ AbstractInputComponent.prototype.enterKey;
545
+ /** @type {?} */
546
+ AbstractInputComponent.prototype.escapeKey;
547
+ /** @type {?} */
548
+ AbstractInputComponent.prototype.errorStateMatcher;
549
+ }
550
+
551
+ /**
552
+ * @fileoverview added by tsickle
553
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
554
+ */
555
+ class NumberInputComponent extends AbstractInputComponent {
556
+ constructor() {
557
+ super();
602
558
  }
603
559
  /**
604
560
  * @return {?}
605
561
  */
606
- get focusTarget() {
607
- return this.focusBindingTarget || this.el.nativeElement;
562
+ ngOnInit() {
563
+ }
564
+ }
565
+ NumberInputComponent.decorators = [
566
+ { type: Component, args: [{
567
+ selector: 'aup-number-input',
568
+ template: "<mat-form-field appearance=\"standard\" [floatLabel]=\"floatLabel\">\n <mat-label *ngIf=\"label\">{{label}}</mat-label>\n <input type=\"number\"\n matInput\n placeholder=\"{{placeholder}}\"\n [(ngModel)]=\"valueModel.value\"\n [disabled]=\"!enabled.value\"\n (keydown.enter)=\"notifyEnterKey()\"\n (keydown.escape)=\"notifyEscapeKey()\"\n [pectinFocusBinding]=\"valueModel\"\n [errorStateMatcher]=\"errorStateMatcher\"\n >\n <mat-hint *ngIf=\"hint\">{{hint}}</mat-hint>\n <mat-error *ngIf=\"hasErrors\">{{firstError}}</mat-error>\n</mat-form-field>\n",
569
+ styles: [":host{display:block}input,mat-form-field{width:100%}input mat-hint.faux-error,mat-form-field mat-hint.faux-error{color:#f44336}"]
570
+ }] }
571
+ ];
572
+ /** @nocollapse */
573
+ NumberInputComponent.ctorParameters = () => [];
574
+
575
+ /**
576
+ * @fileoverview added by tsickle
577
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
578
+ */
579
+ class PasswordInputComponent extends AbstractInputComponent {
580
+ constructor() {
581
+ super();
608
582
  }
609
- // Hook method for debugging via tracing.
610
583
  /**
611
584
  * @return {?}
612
585
  */
613
- modelShouldStillHaveFocus() {
614
- return this.hasBinding() && this.pectinFocusBinding.focusContext.focused.value;
586
+ ngOnInit() {
587
+ }
588
+ }
589
+ PasswordInputComponent.decorators = [
590
+ { type: Component, args: [{
591
+ selector: 'aup-password-input',
592
+ template: "<mat-form-field appearance=\"standard\" [floatLabel]=\"floatLabel\">\n <mat-label *ngIf=\"label\">{{label}}</mat-label>\n <input type=\"password\"\n matInput\n placeholder=\"{{placeholder}}\"\n [(ngModel)]=\"valueModel.value\"\n [disabled]=\"!enabled.value\"\n (keydown.enter)=\"notifyEnterKey()\"\n (keydown.escape)=\"notifyEscapeKey()\"\n [pectinFocusBinding]=\"valueModel\"\n [errorStateMatcher]=\"errorStateMatcher\"\n >\n <mat-hint *ngIf=\"hint\">{{hint}}</mat-hint>\n <mat-error *ngIf=\"hasErrors\">{{firstError}}</mat-error>\n</mat-form-field>\n\n",
593
+ styles: [":host{display:block}input,mat-form-field{width:100%}input mat-hint.faux-error,mat-form-field mat-hint.faux-error{color:#f44336}"]
594
+ }] }
595
+ ];
596
+ /** @nocollapse */
597
+ PasswordInputComponent.ctorParameters = () => [];
598
+
599
+ /**
600
+ * @fileoverview added by tsickle
601
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
602
+ */
603
+ /**
604
+ * @template T
605
+ */
606
+ class SelectInputComponent extends AbstractInputComponent {
607
+ constructor() {
608
+ super();
609
+ this.optionLabelFormat = (/**
610
+ * @param {?} option
611
+ * @return {?}
612
+ */
613
+ (option) => (option && this.optionLabel) ? option[this.optionLabel] : option);
615
614
  }
616
- // Hook method for debugging via tracing.
617
615
  /**
618
616
  * @return {?}
619
617
  */
620
- canFocus() {
621
- /** @type {?} */
622
- const dimension = this.focusTarget.getBoundingClientRect();
623
- /** @type {?} */
624
- const hasSize = dimension.height >= 0 && dimension.height >= 0;
625
- // tslint:disable-next-line:no-string-literal
626
- return hasSize && !this.focusTarget['disabled'];
618
+ ngOnInit() {
627
619
  }
628
620
  }
629
- FocusBindingDirective.decorators = [
630
- { type: Directive, args: [{
631
- // tslint:disable-next-line:directive-selector
632
- selector: '[pectinFocusBinding]'
633
- },] }
621
+ SelectInputComponent.decorators = [
622
+ { type: Component, args: [{
623
+ selector: 'aup-select-input',
624
+ template: "<mat-form-field appearance=\"standard\" [floatLabel]=\"floatLabel\">\n <mat-label *ngIf=\"label\">{{label}}</mat-label>\n <mat-select placeholder=\"{{placeholder}}\"\n [(ngModel)]=\"valueModel.value\"\n [disabled]=\"!enabled.value\"\n (keydown.enter)=\"notifyEnterKey()\"\n (keydown.escape)=\"notifyEscapeKey()\"\n [pectinFocusBinding]=\"valueModel\"\n [errorStateMatcher]=\"errorStateMatcher\"\n >\n <mat-option *ngFor=\"let option of optionsModel.value\" [value]=\"option\">{{optionLabelFormat(option)}}\n </mat-option>\n </mat-select>\n <mat-hint *ngIf=\"hint\">{{hint}}</mat-hint>\n <mat-error *ngIf=\"hasErrors\">{{firstError}}</mat-error>\n</mat-form-field>\n",
625
+ styles: [":host{display:inline-block}mat-form-field{width:100%}"]
626
+ }] }
634
627
  ];
635
628
  /** @nocollapse */
636
- FocusBindingDirective.ctorParameters = () => [
637
- { type: ElementRef, decorators: [{ type: Inject, args: [ElementRef,] }] },
638
- { type: NgZone, decorators: [{ type: Inject, args: [NgZone,] }] },
639
- { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
640
- ];
641
- FocusBindingDirective.propDecorators = {
642
- pectinFocusBinding: [{ type: Input }],
643
- focusBindingTarget: [{ type: Input }],
644
- onFocusIn: [{ type: HostListener, args: ['focusin',] }],
645
- onFocusOut: [{ type: HostListener, args: ['focusout',] }]
629
+ SelectInputComponent.ctorParameters = () => [];
630
+ SelectInputComponent.propDecorators = {
631
+ optionsModel: [{ type: Input }],
632
+ options: [{ type: Input }],
633
+ optionLabel: [{ type: Input }],
634
+ optionLabelFormat: [{ type: Input }]
646
635
  };
636
+ __decorate([
637
+ UseDelegate(),
638
+ __metadata("design:type", ListModel)
639
+ ], SelectInputComponent.prototype, "optionsModel", void 0);
640
+ __decorate([
641
+ StoreInListModel('optionsModel'),
642
+ __metadata("design:type", Array)
643
+ ], SelectInputComponent.prototype, "options", void 0);
647
644
  if (false) {
648
- /**
649
- * @type {?}
650
- * @private
651
- */
652
- FocusBindingDirective.prototype.document;
653
645
  /** @type {?} */
654
- FocusBindingDirective.prototype.pectinFocusBinding;
646
+ SelectInputComponent.prototype.optionsModel;
655
647
  /** @type {?} */
656
- FocusBindingDirective.prototype.focusBindingTarget;
657
- /**
658
- * @type {?}
659
- * @private
660
- */
661
- FocusBindingDirective.prototype.el;
648
+ SelectInputComponent.prototype.options;
649
+ /** @type {?} */
650
+ SelectInputComponent.prototype.optionLabel;
651
+ /** @type {?} */
652
+ SelectInputComponent.prototype.optionLabelFormat;
653
+ }
654
+
655
+ /**
656
+ * @fileoverview added by tsickle
657
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
658
+ */
659
+ class StringInputComponent extends AbstractInputComponent {
660
+ constructor() {
661
+ super();
662
+ }
662
663
  /**
663
- * @type {?}
664
- * @private
664
+ * @return {?}
665
665
  */
666
- FocusBindingDirective.prototype.ngZone;
666
+ ngOnInit() {
667
+ }
668
+ }
669
+ StringInputComponent.decorators = [
670
+ { type: Component, args: [{
671
+ selector: 'aup-string-input',
672
+ template: "<mat-form-field appearance=\"standard\" [floatLabel]=\"floatLabel\">\n <mat-label *ngIf=\"label\">{{label}}</mat-label>\n <input matInput\n placeholder=\"{{placeholder}}\"\n [(ngModel)]=\"valueModel.value\"\n [disabled]=\"!enabled.value\"\n (keydown.enter)=\"notifyEnterKey()\"\n (keydown.escape)=\"notifyEscapeKey()\"\n [pectinFocusBinding]=\"valueModel\"\n [errorStateMatcher]=\"errorStateMatcher\"\n >\n <mat-hint *ngIf=\"hint\">{{hint}}</mat-hint>\n <mat-error *ngIf=\"hasErrors\">{{firstError}}</mat-error>\n</mat-form-field>\n\n",
673
+ styles: [":host{display:block}input,mat-form-field{width:100%}input mat-hint.faux-error,mat-form-field mat-hint.faux-error{color:#f44336}"]
674
+ }] }
675
+ ];
676
+ /** @nocollapse */
677
+ StringInputComponent.ctorParameters = () => [];
678
+
679
+ /**
680
+ * @fileoverview added by tsickle
681
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
682
+ */
683
+ class NoopComponent {
684
+ constructor() {
685
+ }
686
+ }
687
+ NoopComponent.decorators = [
688
+ { type: Component, args: [{
689
+ selector: 'aup-noop',
690
+ template: "",
691
+ styles: [":host{display:block}"]
692
+ }] }
693
+ ];
694
+ /** @nocollapse */
695
+ NoopComponent.ctorParameters = () => [];
696
+
697
+ /**
698
+ * @fileoverview added by tsickle
699
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
700
+ */
701
+ class ComponentsModule {
667
702
  }
703
+ ComponentsModule.decorators = [
704
+ { type: NgModule, args: [{
705
+ declarations: [
706
+ NumberInputComponent,
707
+ StringInputComponent,
708
+ PasswordInputComponent,
709
+ SelectInputComponent,
710
+ NoopComponent
711
+ ],
712
+ imports: [
713
+ CommonModule,
714
+ BrowserAnimationsModule,
715
+ FormsModule,
716
+ MatInputModule,
717
+ MatFormFieldModule,
718
+ MatSelectModule,
719
+ MatTabsModule,
720
+ DirectivesModule
721
+ ],
722
+ exports: [
723
+ NumberInputComponent,
724
+ StringInputComponent,
725
+ PasswordInputComponent,
726
+ SelectInputComponent,
727
+ NoopComponent
728
+ ]
729
+ },] }
730
+ ];
668
731
 
669
732
  /**
670
733
  * @fileoverview added by tsickle
@@ -902,7 +965,7 @@ class ActivityOutletComponent {
902
965
  }
903
966
  ActivityOutletComponent.decorators = [
904
967
  { type: Component, args: [{
905
- selector: 'angular-ui-powerups-activity-outlet',
968
+ selector: 'aup-activity-outlet',
906
969
  template: '',
907
970
  styles: [":host{display:block}"]
908
971
  }] }
@@ -980,9 +1043,9 @@ class AlertDialogComponent extends AbstractActivity {
980
1043
  }
981
1044
  AlertDialogComponent.decorators = [
982
1045
  { type: Component, args: [{
983
- selector: 'angular-ui-powerups-alert-dialog',
1046
+ selector: 'aup-alert-dialog',
984
1047
  template: "<h3 matDialogTitle *ngIf=\"alert.title\">{{alert.title()}}</h3>\n<div matDialogContent>\n <p *ngFor=\"let line of alert.content()\">{{line}}</p>\n</div>\n<p matDialogActions>\n <button mat-raised-button color=\"primary\" (click)=\"done()\" data-cy=\"close-button\">{{alert.ok()}}</button>\n</p>\n",
985
- styles: [":host{display:block;padding:var(--angular-ui-powerups-default-padding)}.mat-dialog-actions{justify-content:flex-end}"]
1048
+ styles: [":host{display:block;padding:var(--aup-default-padding)}.mat-dialog-actions{justify-content:flex-end}"]
986
1049
  }] }
987
1050
  ];
988
1051
  /** @nocollapse */
@@ -1048,9 +1111,9 @@ class ConfirmThenDialogComponent extends AbstractActivity {
1048
1111
  }
1049
1112
  ConfirmThenDialogComponent.decorators = [
1050
1113
  { type: Component, args: [{
1051
- selector: 'angular-ui-powerups-confirmation-dialog',
1114
+ selector: 'aup-confirmation-dialog',
1052
1115
  template: "<h3 matDialogTitle *ngIf=\"confirm.title\">{{confirm.title()}}</h3>\n<div matDialogContent>\n <p *ngFor=\"let line of confirm.content()\">{{line}}</p>\n</div>\n<p matDialogActions>\n <button mat-button (click)=\"cancel()\" data-cy=\"cancel-button\">{{confirm.cancel()}}</button>\n <button mat-raised-button [color]=\"isDestructive() ? 'warn' : 'primary'\"\n (click)=\"onConfirm()\" data-cy=\"confirm-button\">{{confirm.ok()}}</button>\n</p>\n\n",
1053
- styles: [":host{display:block;padding:var(--angular-ui-powerups-default-padding)}.mat-dialog-actions{justify-content:flex-end}"]
1116
+ styles: [":host{display:block;padding:var(--aup-default-padding)}.mat-dialog-actions{justify-content:flex-end}"]
1054
1117
  }] }
1055
1118
  ];
1056
1119
  /** @nocollapse */
@@ -1108,9 +1171,9 @@ class ConfirmationDialogComponent extends AbstractActivity {
1108
1171
  }
1109
1172
  ConfirmationDialogComponent.decorators = [
1110
1173
  { type: Component, args: [{
1111
- selector: 'angular-ui-powerups-confirmation-dialog',
1174
+ selector: 'aup-confirmation-dialog',
1112
1175
  template: "<h3 matDialogTitle *ngIf=\"confirm.title\">{{confirm.title()}}</h3>\n<div matDialogContent>\n <p *ngFor=\"let line of confirm.content()\">{{line}}</p>\n</div>\n<p matDialogActions>\n <button mat-button (click)=\"cancel()\" data-cy=\"cancel-button\">{{confirm.cancel()}}</button>\n <button mat-raised-button [color]=\"isDestructive() ? 'warn' : 'primary'\"\n (click)=\"done()\" data-cy=\"confirm-button\">{{confirm.ok()}}</button>\n</p>\n\n",
1113
- styles: [":host{display:block;padding:var(--angular-ui-powerups-default-padding)}.mat-dialog-actions{justify-content:flex-end}"]
1176
+ styles: [":host{display:block;padding:var(--aup-default-padding)}.mat-dialog-actions{justify-content:flex-end}"]
1114
1177
  }] }
1115
1178
  ];
1116
1179
  /** @nocollapse */
@@ -1443,8 +1506,8 @@ class ActivityContainerComponent extends InteractionContext {
1443
1506
  }
1444
1507
  ActivityContainerComponent.decorators = [
1445
1508
  { type: Component, args: [{
1446
- selector: 'angular-ui-powerups-activity-container',
1447
- template: "<mat-tab-group #tabs no-tab-header [dynamicHeight]=\"true\">\n <mat-tab *ngFor=\"let tab of activityTabs.value\">\n <angular-ui-powerups-activity-outlet [interactionContext]=\"this\"\n [activityContext]=\"tab\"></angular-ui-powerups-activity-outlet>\n </mat-tab>\n</mat-tab-group>\n",
1509
+ selector: 'aup-activity-container',
1510
+ template: "<mat-tab-group #tabs no-tab-header [dynamicHeight]=\"true\">\n <mat-tab *ngFor=\"let tab of activityTabs.value\">\n <aup-activity-outlet [interactionContext]=\"this\"\n [activityContext]=\"tab\"></aup-activity-outlet>\n </mat-tab>\n</mat-tab-group>\n",
1448
1511
  styles: [":host{display:block}"]
1449
1512
  }] }
1450
1513
  ];
@@ -1492,7 +1555,7 @@ class InteractionOutletComponent {
1492
1555
  }
1493
1556
  InteractionOutletComponent.decorators = [
1494
1557
  { type: Component, args: [{
1495
- selector: 'angular-ui-powerups-interaction-outlet',
1558
+ selector: 'aup-interaction-outlet',
1496
1559
  template: "<router-outlet name=\"interaction-context\"></router-outlet>\n",
1497
1560
  styles: [":host{display:block}"]
1498
1561
  }] }
@@ -1606,6 +1669,7 @@ class DialogInteractionService extends InteractionContext {
1606
1669
  * @return {?}
1607
1670
  */
1608
1671
  () => {
1672
+ console.log("###### STARTING");
1609
1673
  this.currentActivityId = v1();
1610
1674
  // this.location.go(this.router.routerState.snapshot.url, "aup");
1611
1675
  /** @type {?} */
@@ -1662,6 +1726,7 @@ class DialogInteractionService extends InteractionContext {
1662
1726
  * @return {?}
1663
1727
  */
1664
1728
  () => {
1729
+ console.log("###### FINISHED");
1665
1730
  this.currentActivityId = null;
1666
1731
  self.safelyUpdateActivityListDelegate(null);
1667
1732
  }));
@@ -1765,7 +1830,7 @@ InteractionModule.decorators = [
1765
1830
  CommonModule,
1766
1831
  MatButtonModule,
1767
1832
  MatDialogModule,
1768
- MatTabsModule,
1833
+ MatTabsModule$1,
1769
1834
  PortalModule,
1770
1835
  RouterModule
1771
1836
  ],
@@ -1809,7 +1874,7 @@ class BusyOverlayComponent {
1809
1874
  }
1810
1875
  BusyOverlayComponent.decorators = [
1811
1876
  { type: Component, args: [{
1812
- selector: 'angular-ui-powerups-busy-overlay',
1877
+ selector: 'aup-busy-overlay',
1813
1878
  template: "<ng-content></ng-content>\n<div class=\"busy-overlay-backdrop\" *ngIf=\"busyModel.value\">\n <mat-progress-spinner mode=\"indeterminate\" [diameter]=\"52\"></mat-progress-spinner>\n</div>\n",
1814
1879
  styles: [":host{position:relative}div.busy-overlay-backdrop{position:absolute;background-color:rgba(0,0,0,.2);top:0;left:0;bottom:0;right:0;display:-ms-grid;display:grid;-ms-grid-columns:auto;grid-template-columns:auto;-ms-grid-rows:auto;grid-template-rows:auto;place-content:center}"]
1815
1880
  }] }
@@ -1850,13 +1915,13 @@ class EmptyStateComponent {
1850
1915
  }
1851
1916
  EmptyStateComponent.decorators = [
1852
1917
  { type: Component, args: [{
1853
- selector: 'angular-ui-powerups-empty-state',
1918
+ selector: 'aup-empty-state',
1854
1919
  template: `
1855
1920
  <div class="container">
1856
1921
  <ng-content></ng-content>
1857
1922
  </div>
1858
1923
  `,
1859
- styles: [":host{display:flex;flex-direction:column;justify-content:center;align-items:center}.container{padding:var(--angular-ui-powerups-default-padding);border:2px dashed rgba(0,0,0,.2);border-radius:5px;font-size:14px;font-weight:300}"]
1924
+ styles: [":host{display:flex;flex-direction:column;justify-content:center;align-items:center}.container{padding:var(--aup-default-padding);border:2px dashed rgba(0,0,0,.2);border-radius:5px;font-size:14px;font-weight:300}"]
1860
1925
  }] }
1861
1926
  ];
1862
1927
  /** @nocollapse */
@@ -2099,16 +2164,14 @@ class PlaceDefinition {
2099
2164
  * @param {?} component
2100
2165
  * @param {?} path
2101
2166
  * @param {?} authenticate
2102
- * @param {?} order
2103
2167
  * @param {?} data
2104
2168
  * @param {?} routeParameters
2105
2169
  * @param {?} children
2106
2170
  */
2107
- constructor(component, path, authenticate, order, data, routeParameters, children) {
2171
+ constructor(component, path, authenticate, data, routeParameters, children) {
2108
2172
  this.component = component;
2109
2173
  this.path = path;
2110
2174
  this.authenticate = authenticate;
2111
- this.order = order;
2112
2175
  this.data = data;
2113
2176
  this.routeParameters = routeParameters;
2114
2177
  this.children = children;
@@ -2341,8 +2404,6 @@ if (false) {
2341
2404
  /** @type {?} */
2342
2405
  PlaceDefinition.prototype.authenticate;
2343
2406
  /** @type {?} */
2344
- PlaceDefinition.prototype.order;
2345
- /** @type {?} */
2346
2407
  PlaceDefinition.prototype.data;
2347
2408
  /** @type {?} */
2348
2409
  PlaceDefinition.prototype.routeParameters;
@@ -2506,114 +2567,128 @@ if (false) {
2506
2567
  * @fileoverview added by tsickle
2507
2568
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2508
2569
  */
2509
- class AbstractPlaceNavigationComponent extends DisposableComponent {
2510
- constructor() {
2511
- super();
2512
- const { chain, valueOf, before, when, after, observe, switchOn } = Dsl.disposeWith(this);
2513
- this.placeDefinitions = chain(this.placesModel).map((/**
2514
- * @param {?} c
2515
- * @return {?}
2516
- */
2517
- c => PlaceComponent.getDefinition(c)));
2570
+ /**
2571
+ * @record
2572
+ */
2573
+ function Params() { }
2574
+ class Visit {
2575
+ /**
2576
+ * @param {?} placeDefinition
2577
+ * @param {?=} visitParameters
2578
+ */
2579
+ constructor(placeDefinition, visitParameters = {}) {
2580
+ this.placeDefinition = placeDefinition;
2581
+ this.visitParameters = visitParameters;
2518
2582
  }
2583
+ // @Trace()
2519
2584
  /**
2520
- * @param {?} placeDef
2521
2585
  * @return {?}
2522
2586
  */
2523
- getNav(placeDef) {
2524
- /** @type {?} */
2525
- const navItem = (/** @type {?} */ (placeDef.getPlaceData('nav')));
2526
- return {
2527
- title: (/**
2528
- * @return {?}
2529
- */
2530
- () => navItem ? navItem.title() : placeDef.searchPlaceData(['navTitle', 'title'])),
2531
- tooltip: (/**
2532
- * @return {?}
2533
- */
2534
- () => navItem && navItem.tooltip ? navItem.tooltip() : placeDef.getPlaceData('navTooltip', null)),
2535
- icon: (/**
2536
- * @return {?}
2537
- */
2538
- () => navItem && navItem.icon ? navItem.icon() : placeDef.getPlaceData('navIcon', null))
2539
- };
2587
+ getRouteId() {
2588
+ return this.placeDefinition.getRouteIdFrom(this);
2589
+ }
2590
+ // @Trace()
2591
+ /**
2592
+ * @return {?}
2593
+ */
2594
+ hasRouteId() {
2595
+ return !isNil(this.getRouteId());
2596
+ }
2597
+ /**
2598
+ * Returns the value of the place parameter with the specified name. The parameter
2599
+ * name is taken from the `as` option, e.g. {as: 'aCustomName'} otherwise it is the
2600
+ * same as the the ValueModel property name.
2601
+ * @param {?} parameterName the field name of the property model or the `as` option if specified.
2602
+ * @return {?}
2603
+ */
2604
+ getParameter(parameterName) {
2605
+ return this.visitParameters[parameterName];
2606
+ }
2607
+ // @Trace()
2608
+ /**
2609
+ * @param {?} parameterName
2610
+ * @return {?}
2611
+ */
2612
+ hasParameter(parameterName) {
2613
+ return Object.keys(this.visitParameters).includes(parameterName);
2540
2614
  }
2541
2615
  /**
2616
+ * @template S
2617
+ * @param {?} parameter
2618
+ * @param {?} value
2542
2619
  * @return {?}
2543
2620
  */
2544
- ngOnInit() {
2621
+ replace(parameter, value) {
2622
+ return new Visit(this.placeDefinition, Object.assign({}, this.visitParameters, { [parameter.name]: value }));
2545
2623
  }
2546
- }
2547
- AbstractPlaceNavigationComponent.propDecorators = {
2548
- places: [{ type: Input }],
2549
- placesModel: [{ type: Input }]
2550
- };
2551
- __decorate([
2552
- StoreInListModel('placesModel'),
2553
- __metadata("design:type", Array)
2554
- ], AbstractPlaceNavigationComponent.prototype, "places", void 0);
2555
- __decorate([
2556
- UseDelegate(),
2557
- __metadata("design:type", ListModel)
2558
- ], AbstractPlaceNavigationComponent.prototype, "placesModel", void 0);
2559
- __decorate([
2560
- Memoize(),
2561
- __metadata("design:type", Function),
2562
- __metadata("design:paramtypes", [PlaceDefinition]),
2563
- __metadata("design:returntype", Object)
2564
- ], AbstractPlaceNavigationComponent.prototype, "getNav", null);
2565
- if (false) {
2566
- /** @type {?} */
2567
- AbstractPlaceNavigationComponent.prototype.places;
2568
- /** @type {?} */
2569
- AbstractPlaceNavigationComponent.prototype.placesModel;
2570
- /** @type {?} */
2571
- AbstractPlaceNavigationComponent.prototype.placeDefinitions;
2572
- }
2573
-
2574
- /**
2575
- * @fileoverview added by tsickle
2576
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2577
- */
2578
- class ListPlaceNavComponent extends AbstractPlaceNavigationComponent {
2579
- constructor() {
2580
- super();
2581
- this.expanded = true;
2624
+ /**
2625
+ * @template S
2626
+ * @param {?} routeParams
2627
+ * @return {?}
2628
+ */
2629
+ mergeRouteParameters(routeParams) {
2630
+ // todo: whitelist parameters.
2631
+ /** @type {?} */
2632
+ const routeParameterKeys = Object.keys(routeParams);
2633
+ /** @type {?} */
2634
+ const params = {};
2635
+ this.placeDefinition.getVisitParameterDefs().forEach((/**
2636
+ * @param {?} def
2637
+ * @return {?}
2638
+ */
2639
+ def => {
2640
+ if (def.isRouteId || def.isRouteParameter) {
2641
+ if (routeParameterKeys.includes(def.name)) {
2642
+ params[def.name] = routeParams[def.name];
2643
+ }
2644
+ }
2645
+ else {
2646
+ // copy non route params as is, but only if they already exist otherwise we'll inject nil values and break the
2647
+ // defaults and remember sanitisation process.
2648
+ if (this.hasParameter(def.name)) {
2649
+ params[def.name] = this.getParameter(def.name);
2650
+ }
2651
+ }
2652
+ }));
2653
+ return new Visit(this.placeDefinition, params);
2582
2654
  }
2583
2655
  /**
2656
+ * @param {?} other
2584
2657
  * @return {?}
2585
2658
  */
2586
- expandMenu() {
2587
- this.expanded = true;
2659
+ hasRoutingChangedFrom(other) {
2660
+ /** @type {?} */
2661
+ const samePlace = other.placeDefinition === this.placeDefinition;
2662
+ /** @type {?} */
2663
+ const sameRouteParameters = isEqual(this.placeDefinition.getFormattedRouteParameters(this, true), this.placeDefinition.getFormattedRouteParameters(other, true));
2664
+ return !samePlace || !sameRouteParameters;
2588
2665
  }
2589
2666
  /**
2667
+ * @param {?} other
2590
2668
  * @return {?}
2591
2669
  */
2592
- collapseMenu() {
2593
- this.expanded = false;
2670
+ hasChangedFrom(other) {
2671
+ /** @type {?} */
2672
+ const sameNonRouteParameters = isEqual(this.placeDefinition.getNonRouteParameters(this), this.placeDefinition.getNonRouteParameters(other));
2673
+ return !sameNonRouteParameters || this.hasRoutingChangedFrom(other);
2594
2674
  }
2595
2675
  /**
2596
2676
  * @return {?}
2597
2677
  */
2598
- toggleMenu() {
2599
- this.expanded = !this.expanded;
2678
+ getUrlSegments() {
2679
+ return this.placeDefinition.hasRouteId() ?
2680
+ [new UrlSegment(this.placeDefinition.path, {}), new UrlSegment(this.placeDefinition.getFormattedRouteId(this), this.placeDefinition.getFormattedRouteParameters(this))] :
2681
+ [new UrlSegment(this.placeDefinition.path, this.placeDefinition.getFormattedRouteParameters(this))];
2600
2682
  }
2601
2683
  }
2602
- ListPlaceNavComponent.decorators = [
2603
- { type: Component, args: [{
2604
- selector: 'angular-ui-powerups-list-place-nav',
2605
- template: "<mat-nav-list class=\"app-menu\">\n <a mat-list-item *ngFor=\"let place of placeDefinitions.value\"\n [routerLink]='place.path'\n [replaceUrl]=\"true\"\n routerLinkActive #rla=\"routerLinkActive\"\n [matTooltip]=\"getNav(place).tooltip()\">\n <mat-icon *ngIf=\"getNav(place).icon()\">{{getNav(place).icon()}}</mat-icon>\n <span class=\"expanded-only\">{{getNav(place).title()}}</span>\n </a>\n</mat-nav-list>\n",
2606
- styles: [":host{display:flex;flex-direction:column;--expanded-width:235px;--nav-item-width:var(--nav-bar-height);width:var(--nav-item-width);transition:width 125ms linear}:host.expanded{width:var(--expanded-width);max-width:var(--expanded-width)}.expanded-only{max-width:0;overflow:hidden}.collapsed-only{max-width:100%;overflow:hidden}.header{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;height:var(--nav-bar-height);border-bottom:var(--pinstripe-border);cursor:pointer}.header .menu{flex:1}.header button{color:inherit;width:var(--nav-item-width);height:var(--nav-bar-height)}mat-nav-list{flex:1;display:flex;flex-direction:column}.mat-list-item{width:var(--nav-item-width);height:var(--nav-bar-height);color:inherit}mat-icon{color:inherit}mat-icon.flip-horizontal{transform:scaleX(-1)}:host-context(.expanded) .expanded-only{max-width:100%}:host-context(.expanded) .collapsed-only{max-width:0}:host-context(.expanded) .mat-list-item mat-icon{margin-right:12px}:host-context(.expanded) .mat-list-item span{text-wrap:none;white-space:nowrap}a[ng-reflect-router-link=manage-instruments] mat-icon{transform:rotate(90deg)}.app-menu{padding-top:0}"]
2607
- }] }
2608
- ];
2609
- /** @nocollapse */
2610
- ListPlaceNavComponent.ctorParameters = () => [];
2611
- ListPlaceNavComponent.propDecorators = {
2612
- expanded: [{ type: HostBinding, args: ['class.expanded',] }]
2613
- };
2614
2684
  if (false) {
2615
2685
  /** @type {?} */
2616
- ListPlaceNavComponent.prototype.expanded;
2686
+ Visit.prototype.placeDefinition;
2687
+ /**
2688
+ * @type {?}
2689
+ * @private
2690
+ */
2691
+ Visit.prototype.visitParameters;
2617
2692
  }
2618
2693
 
2619
2694
  /**
@@ -2836,126 +2911,6 @@ if (false) {
2836
2911
  PlaceHistory.prototype.router;
2837
2912
  }
2838
2913
 
2839
- /**
2840
- * @fileoverview added by tsickle
2841
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2842
- */
2843
- /**
2844
- * @record
2845
- */
2846
- function Params() { }
2847
- class Visit {
2848
- /**
2849
- * @param {?} placeDefinition
2850
- * @param {?=} visitParameters
2851
- */
2852
- constructor(placeDefinition, visitParameters = {}) {
2853
- this.placeDefinition = placeDefinition;
2854
- this.visitParameters = visitParameters;
2855
- }
2856
- // @Trace()
2857
- /**
2858
- * @return {?}
2859
- */
2860
- getRouteId() {
2861
- return this.placeDefinition.getRouteIdFrom(this);
2862
- }
2863
- // @Trace()
2864
- /**
2865
- * @return {?}
2866
- */
2867
- hasRouteId() {
2868
- return !isNil(this.getRouteId());
2869
- }
2870
- /**
2871
- * Returns the value of the place parameter with the specified name. The parameter
2872
- * name is taken from the `as` option, e.g. {as: 'aCustomName'} otherwise it is the
2873
- * same as the the ValueModel property name.
2874
- * @param {?} parameterName the field name of the property model or the `as` option if specified.
2875
- * @return {?}
2876
- */
2877
- getParameter(parameterName) {
2878
- return this.visitParameters[parameterName];
2879
- }
2880
- // @Trace()
2881
- /**
2882
- * @param {?} parameterName
2883
- * @return {?}
2884
- */
2885
- hasParameter(parameterName) {
2886
- return Object.keys(this.visitParameters).includes(parameterName);
2887
- }
2888
- /**
2889
- * @template S
2890
- * @param {?} parameter
2891
- * @param {?} value
2892
- * @return {?}
2893
- */
2894
- replace(parameter, value) {
2895
- return new Visit(this.placeDefinition, Object.assign({}, this.visitParameters, { [parameter.name]: value }));
2896
- }
2897
- /**
2898
- * @template S
2899
- * @param {?} routeParams
2900
- * @return {?}
2901
- */
2902
- mergeRouteParameters(routeParams) {
2903
- // todo: whitelist parameters.
2904
- /** @type {?} */
2905
- const routeParameterKeys = Object.keys(routeParams);
2906
- /** @type {?} */
2907
- const params = {};
2908
- this.placeDefinition.getVisitParameterDefs().forEach((/**
2909
- * @param {?} def
2910
- * @return {?}
2911
- */
2912
- def => {
2913
- if (def.isRouteId || def.isRouteParameter) {
2914
- if (routeParameterKeys.includes(def.name)) {
2915
- params[def.name] = routeParams[def.name];
2916
- }
2917
- }
2918
- else {
2919
- // copy non route params as is, but only if they already exist otherwise we'll inject nil values and break the
2920
- // defaults and remember sanitisation process.
2921
- if (this.hasParameter(def.name)) {
2922
- params[def.name] = this.getParameter(def.name);
2923
- }
2924
- }
2925
- }));
2926
- return new Visit(this.placeDefinition, params);
2927
- }
2928
- /**
2929
- * @param {?} other
2930
- * @return {?}
2931
- */
2932
- hasRoutingChangedFrom(other) {
2933
- /** @type {?} */
2934
- const samePlace = other.placeDefinition === this.placeDefinition;
2935
- /** @type {?} */
2936
- const sameRouteParameters = isEqual(this.placeDefinition.getFormattedRouteParameters(this, true), this.placeDefinition.getFormattedRouteParameters(other, true));
2937
- return !samePlace || !sameRouteParameters;
2938
- }
2939
- /**
2940
- * @param {?} other
2941
- * @return {?}
2942
- */
2943
- hasChangedFrom(other) {
2944
- /** @type {?} */
2945
- const sameNonRouteParameters = isEqual(this.placeDefinition.getNonRouteParameters(this), this.placeDefinition.getNonRouteParameters(other));
2946
- return !sameNonRouteParameters || this.hasRoutingChangedFrom(other);
2947
- }
2948
- }
2949
- if (false) {
2950
- /** @type {?} */
2951
- Visit.prototype.placeDefinition;
2952
- /**
2953
- * @type {?}
2954
- * @private
2955
- */
2956
- Visit.prototype.visitParameters;
2957
- }
2958
-
2959
2914
  /**
2960
2915
  * @fileoverview added by tsickle
2961
2916
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
@@ -3055,6 +3010,7 @@ class PlaceRouter extends GarbageCollector {
3055
3010
  })));
3056
3011
  });
3057
3012
  }
3013
+ // @Trace()
3058
3014
  /**
3059
3015
  * @param {?} activatedRoute
3060
3016
  * @param {?} previous
@@ -3073,6 +3029,9 @@ class PlaceRouter extends GarbageCollector {
3073
3029
  * @return {?}
3074
3030
  */
3075
3031
  router => {
3032
+ // we have to to use the definition for route id as our redirection always includes
3033
+ // the id in the url segements (but leaves it blank when there's no id). I.e. in the
3034
+ // no id case we're doing the following redirect [<placePath>, ""] -> ["..", <id>]
3076
3035
  /** @type {?} */
3077
3036
  const relativePath = !!previous.placeDefinition.hasRouteId() ? '..' : '.';
3078
3037
  /** @type {?} */
@@ -3081,7 +3040,7 @@ class PlaceRouter extends GarbageCollector {
3081
3040
  ...this.createRouteParameters(next),
3082
3041
  ...this.extractChildPath(activatedRoute.snapshot)
3083
3042
  ];
3084
- console.log('### Redirect', commands);
3043
+ console.log('### Push Changes to route Redirect', { commands, relativeTo: activatedRoute.snapshot.url });
3085
3044
  return router.navigate(commands, {
3086
3045
  relativeTo: activatedRoute
3087
3046
  });
@@ -3189,12 +3148,6 @@ __decorate([
3189
3148
  __metadata("design:paramtypes", [Visit, Object]),
3190
3149
  __metadata("design:returntype", Promise)
3191
3150
  ], PlaceRouter.prototype, "navigate", null);
3192
- __decorate([
3193
- Trace(),
3194
- __metadata("design:type", Function),
3195
- __metadata("design:paramtypes", [ActivatedRoute, Visit, Visit]),
3196
- __metadata("design:returntype", Promise)
3197
- ], PlaceRouter.prototype, "pushVisitChangesToRoute", null);
3198
3151
  if (false) {
3199
3152
  /**
3200
3153
  * @type {?}
@@ -3310,29 +3263,51 @@ class PlaceOutletComponent extends DisposableComponent {
3310
3263
  super();
3311
3264
  this.router = router;
3312
3265
  this.placeRouter = placeRouter;
3313
- this.parentOutlet = parentOutlet;
3314
3266
  this.animate = true;
3315
3267
  this.placeChanged = new EventEmitter();
3316
3268
  this._activePlace = new MutableValueModel();
3269
+ this._placeVisit = new MutableValueModel();
3317
3270
  this._inOutletUpdate = new Guard$1();
3318
3271
  this._activatedRouteModel = new MutableValueModel();
3319
3272
  this._placeDefinition = new MutableValueModel();
3320
- /**
3321
- * TODO: This is now really a visit
3322
- */
3323
- this._placeVisit = new MutableValueModel();
3324
3273
  const { chain, valueOf, before, when, after, observe, switchOn } = Dsl.disposeWith(this);
3325
- // Handle incoming route changes.
3274
+ this.parentOutletModel = new MutableValueModel(parentOutlet);
3326
3275
  /** @type {?} */
3327
- const inRouteVisitUpdate = new Guard$1();
3276
+ const defaultPlaceAnimationOrder = chain(this.parentOutletModel)
3277
+ .pullValueModel((/**
3278
+ * @param {?} o
3279
+ * @return {?}
3280
+ */
3281
+ o => o.activePlaceModel))
3282
+ .pluck("placeDefinition")
3283
+ .pluckList("children")
3284
+ .pluck("component");
3285
+ /** @type {?} */
3286
+ const activatePlaceType = chain(this.activePlaceModel).map((/**
3287
+ * @param {?} p
3288
+ * @return {?}
3289
+ */
3290
+ p => (/** @type {?} */ (p.constructor))));
3291
+ this.placeAnimationOrder = chain(this.customPlaceAnimationOrderModel)
3292
+ .otherwise(defaultPlaceAnimationOrder)
3293
+ .indexOf(activatePlaceType)
3294
+ .map((/**
3295
+ * @param {?} order
3296
+ * @return {?}
3297
+ */
3298
+ order => Math.max(order, 0))); // we get -1 on the first load which triggers an animation to the first page, so alway pin it to 0.
3299
+ // we get -1 on the first load which triggers an animation to the first page, so alway pin it to 0.
3300
+ // Push incoming changes into the component
3328
3301
  /** @type {?} */
3329
3302
  const routeVisit = chain(this._activePlace).pluck('placeDefinition').findIn(placeRouter.activeVisitIndex);
3303
+ /** @type {?} */
3304
+ const inRouteVisitUpdate = new Guard$1();
3330
3305
  when.valueOf(routeVisit).changes((/**
3331
3306
  * @param {?} visit
3332
3307
  * @return {?}
3333
3308
  */
3334
3309
  (visit) => {
3335
- if (visit) {
3310
+ if (visit) { // can be null while the place and index sync up
3336
3311
  inRouteVisitUpdate.whileTrue((/**
3337
3312
  * @return {?}
3338
3313
  */
@@ -3377,6 +3352,12 @@ class PlaceOutletComponent extends DisposableComponent {
3377
3352
  relativeTo: this.parentOutlet ? this.parentOutlet.activatedRouteModel.value : null
3378
3353
  });
3379
3354
  }
3355
+ /**
3356
+ * @return {?}
3357
+ */
3358
+ get parentOutlet() {
3359
+ return this.parentOutletModel.value;
3360
+ }
3380
3361
  /**
3381
3362
  * @param {?} next
3382
3363
  * @param {?} previous
@@ -3424,6 +3405,7 @@ class PlaceOutletComponent extends DisposableComponent {
3424
3405
  this.animationDone();
3425
3406
  }
3426
3407
  }
3408
+ // @Trace()
3427
3409
  /**
3428
3410
  * @param {?} routerOutlet
3429
3411
  * @param {?} $event
@@ -3437,14 +3419,7 @@ class PlaceOutletComponent extends DisposableComponent {
3437
3419
  this._activePlace.value = null;
3438
3420
  this._activatedRouteModel.value = null;
3439
3421
  this._placeDefinition.value = null;
3440
- }));
3441
- }
3442
- /**
3443
- * @param {?} outlet
3444
- * @return {?}
3445
- */
3446
- getPlaceOrder(outlet) {
3447
- return this.animate && outlet && outlet.activatedRouteData && outlet.activatedRouteData['placeOrder'];
3422
+ }));
3448
3423
  }
3449
3424
  /**
3450
3425
  * @return {?}
@@ -3457,8 +3432,8 @@ class PlaceOutletComponent extends DisposableComponent {
3457
3432
  }
3458
3433
  PlaceOutletComponent.decorators = [
3459
3434
  { type: Component, args: [{
3460
- selector: 'angular-ui-powerups-place-outlet',
3461
- template: "<div class=\"router-outlet-container\"\n [@routeAnimations]=\"getPlaceOrder(routerOutlet)\"\n (@routeAnimations.done)=\"animationDone()\"\n>\n <router-outlet #routerOutlet=\"outlet\"\n (activate)=\"onOutletActivated(routerOutlet, $event)\"\n (deactivate)=\"onOutletDeactivated(routerOutlet, $event)\">\n </router-outlet>\n</div>\n\n",
3435
+ selector: 'aup-place-outlet',
3436
+ template: "<div class=\"router-outlet-container\"\n [@routeAnimations]=\"placeAnimationOrder.value\"\n (@routeAnimations.done)=\"animationDone()\"\n>\n <router-outlet #routerOutlet=\"outlet\"\n (activate)=\"onOutletActivated(routerOutlet, $event)\"\n (deactivate)=\"onOutletDeactivated(routerOutlet, $event)\">\n </router-outlet>\n</div>\n\n",
3462
3437
  animations: [LEFT_RIGHT_PLACE_ANIMATION],
3463
3438
  styles: [":host{display:flex;flex-direction:column;min-height:0}.router-outlet-container{flex:1;display:block;position:relative;min-height:0}router-outlet{display:none}"]
3464
3439
  }] }
@@ -3471,9 +3446,19 @@ PlaceOutletComponent.ctorParameters = () => [
3471
3446
  ];
3472
3447
  PlaceOutletComponent.propDecorators = {
3473
3448
  animate: [{ type: Input }],
3449
+ customPlaceAnimationOrderModel: [{ type: Input, args: ['placeAnimationOrderModel',] }],
3450
+ customPlaceAnimationOrder: [{ type: Input, args: ['placeAnimationOrder',] }],
3474
3451
  placeChanged: [{ type: Output }],
3475
3452
  routerOut: [{ type: ViewChild, args: ['routeOutlet', { static: true },] }]
3476
3453
  };
3454
+ __decorate([
3455
+ UseDelegate(),
3456
+ __metadata("design:type", ListModel)
3457
+ ], PlaceOutletComponent.prototype, "customPlaceAnimationOrderModel", void 0);
3458
+ __decorate([
3459
+ StoreInListModel("customPlaceAnimationOrderModel"),
3460
+ __metadata("design:type", Array)
3461
+ ], PlaceOutletComponent.prototype, "customPlaceAnimationOrder", void 0);
3477
3462
  __decorate([
3478
3463
  Trace(),
3479
3464
  __metadata("design:type", Function),
@@ -3486,16 +3471,14 @@ __decorate([
3486
3471
  __metadata("design:paramtypes", [RouterOutlet, PlaceComponent]),
3487
3472
  __metadata("design:returntype", void 0)
3488
3473
  ], PlaceOutletComponent.prototype, "onOutletActivated", null);
3489
- __decorate([
3490
- Trace(),
3491
- __metadata("design:type", Function),
3492
- __metadata("design:paramtypes", [RouterOutlet, Object]),
3493
- __metadata("design:returntype", void 0)
3494
- ], PlaceOutletComponent.prototype, "onOutletDeactivated", null);
3495
3474
  if (false) {
3496
3475
  /** @type {?} */
3497
3476
  PlaceOutletComponent.prototype.animate;
3498
3477
  /** @type {?} */
3478
+ PlaceOutletComponent.prototype.customPlaceAnimationOrderModel;
3479
+ /** @type {?} */
3480
+ PlaceOutletComponent.prototype.customPlaceAnimationOrder;
3481
+ /** @type {?} */
3499
3482
  PlaceOutletComponent.prototype.placeChanged;
3500
3483
  /** @type {?} */
3501
3484
  PlaceOutletComponent.prototype.routerOut;
@@ -3504,6 +3487,11 @@ if (false) {
3504
3487
  * @private
3505
3488
  */
3506
3489
  PlaceOutletComponent.prototype._activePlace;
3490
+ /**
3491
+ * @type {?}
3492
+ * @private
3493
+ */
3494
+ PlaceOutletComponent.prototype._placeVisit;
3507
3495
  /**
3508
3496
  * @type {?}
3509
3497
  * @private
@@ -3520,10 +3508,12 @@ if (false) {
3520
3508
  */
3521
3509
  PlaceOutletComponent.prototype._placeDefinition;
3522
3510
  /**
3523
- * TODO: This is now really a visit
3524
3511
  * @type {?}
3512
+ * @private
3525
3513
  */
3526
- PlaceOutletComponent.prototype._placeVisit;
3514
+ PlaceOutletComponent.prototype.parentOutletModel;
3515
+ /** @type {?} */
3516
+ PlaceOutletComponent.prototype.placeAnimationOrder;
3527
3517
  /**
3528
3518
  * @type {?}
3529
3519
  * @private
@@ -3534,8 +3524,153 @@ if (false) {
3534
3524
  * @private
3535
3525
  */
3536
3526
  PlaceOutletComponent.prototype.placeRouter;
3527
+ }
3528
+
3529
+ /**
3530
+ * @fileoverview added by tsickle
3531
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
3532
+ */
3533
+ class AbstractPlaceNavigationComponent extends DisposableComponent {
3534
+ constructor() {
3535
+ super();
3536
+ const { chain, valueOf, before, when, after, observe, switchOn } = Dsl.disposeWith(this);
3537
+ this.placeDefinitions = chain(this.placesModel).map((/**
3538
+ * @param {?} c
3539
+ * @return {?}
3540
+ */
3541
+ c => PlaceComponent.getDefinition(c)));
3542
+ this.relativeToModel = chain(this.placeOutletModel).pullValueModel((/**
3543
+ * @param {?} o
3544
+ * @return {?}
3545
+ */
3546
+ o => o.activatedRouteModel));
3547
+ this.commandFactory = Command.createFactory((/**
3548
+ * @param {?} placeDefinition
3549
+ * @return {?}
3550
+ */
3551
+ (placeDefinition) => {
3552
+ this.placeOutlet.navigate(new Visit(placeDefinition));
3553
+ }));
3554
+ }
3555
+ /**
3556
+ * @param {?} placeDef
3557
+ * @return {?}
3558
+ */
3559
+ getNav(placeDef) {
3560
+ /** @type {?} */
3561
+ const navItem = (/** @type {?} */ (placeDef.getPlaceData('nav')));
3562
+ return {
3563
+ title: (/**
3564
+ * @return {?}
3565
+ */
3566
+ () => navItem ? navItem.title() : placeDef.searchPlaceData(['navTitle', 'title'])),
3567
+ tooltip: (/**
3568
+ * @return {?}
3569
+ */
3570
+ () => navItem && navItem.tooltip ? navItem.tooltip() : placeDef.getPlaceData('navTooltip', null)),
3571
+ icon: (/**
3572
+ * @return {?}
3573
+ */
3574
+ () => navItem && navItem.icon ? navItem.icon() : placeDef.getPlaceData('navIcon', null))
3575
+ };
3576
+ }
3577
+ /**
3578
+ * @return {?}
3579
+ */
3580
+ ngOnInit() {
3581
+ }
3582
+ }
3583
+ AbstractPlaceNavigationComponent.propDecorators = {
3584
+ places: [{ type: Input }],
3585
+ placesModel: [{ type: Input }],
3586
+ placeOutlet: [{ type: Input }],
3587
+ placeOutletModel: [{ type: Input }]
3588
+ };
3589
+ __decorate([
3590
+ StoreInListModel('placesModel'),
3591
+ __metadata("design:type", Array)
3592
+ ], AbstractPlaceNavigationComponent.prototype, "places", void 0);
3593
+ __decorate([
3594
+ UseDelegate(),
3595
+ __metadata("design:type", ListModel)
3596
+ ], AbstractPlaceNavigationComponent.prototype, "placesModel", void 0);
3597
+ __decorate([
3598
+ StoreInValueModel('placeOutletModel'),
3599
+ __metadata("design:type", PlaceOutletComponent)
3600
+ ], AbstractPlaceNavigationComponent.prototype, "placeOutlet", void 0);
3601
+ __decorate([
3602
+ UseDelegate(),
3603
+ __metadata("design:type", ValueModel)
3604
+ ], AbstractPlaceNavigationComponent.prototype, "placeOutletModel", void 0);
3605
+ __decorate([
3606
+ Memoize(),
3607
+ __metadata("design:type", Function),
3608
+ __metadata("design:paramtypes", [PlaceDefinition]),
3609
+ __metadata("design:returntype", Object)
3610
+ ], AbstractPlaceNavigationComponent.prototype, "getNav", null);
3611
+ if (false) {
3612
+ /** @type {?} */
3613
+ AbstractPlaceNavigationComponent.prototype.places;
3614
+ /** @type {?} */
3615
+ AbstractPlaceNavigationComponent.prototype.placesModel;
3616
+ /** @type {?} */
3617
+ AbstractPlaceNavigationComponent.prototype.placeOutlet;
3618
+ /** @type {?} */
3619
+ AbstractPlaceNavigationComponent.prototype.placeOutletModel;
3620
+ /** @type {?} */
3621
+ AbstractPlaceNavigationComponent.prototype.placeDefinitions;
3622
+ /**
3623
+ * @type {?}
3624
+ * @protected
3625
+ */
3626
+ AbstractPlaceNavigationComponent.prototype.relativeToModel;
3627
+ /** @type {?} */
3628
+ AbstractPlaceNavigationComponent.prototype.commandFactory;
3629
+ }
3630
+
3631
+ /**
3632
+ * @fileoverview added by tsickle
3633
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
3634
+ */
3635
+ class ListPlaceNavComponent extends AbstractPlaceNavigationComponent {
3636
+ constructor() {
3637
+ super();
3638
+ this.expanded = true;
3639
+ }
3640
+ /**
3641
+ * @return {?}
3642
+ */
3643
+ expandMenu() {
3644
+ this.expanded = true;
3645
+ }
3646
+ /**
3647
+ * @return {?}
3648
+ */
3649
+ collapseMenu() {
3650
+ this.expanded = false;
3651
+ }
3652
+ /**
3653
+ * @return {?}
3654
+ */
3655
+ toggleMenu() {
3656
+ this.expanded = !this.expanded;
3657
+ }
3658
+ }
3659
+ ListPlaceNavComponent.decorators = [
3660
+ { type: Component, args: [{
3661
+ selector: 'aup-list-place-nav',
3662
+ template: "<mat-nav-list class=\"app-menu\">\n <a mat-list-item *ngFor=\"let place of placeDefinitions.value\"\n [pectinCommand]=\"commandFactory.create(place)\"\n routerLinkActive #rla=\"routerLinkActive\"\n [matTooltip]=\"getNav(place).tooltip()\">\n <mat-icon *ngIf=\"getNav(place).icon()\">{{getNav(place).icon()}}</mat-icon>\n <span class=\"expanded-only\">{{getNav(place).title()}}</span>\n </a>\n</mat-nav-list>\n",
3663
+ styles: [":host{display:flex;flex-direction:column;--expanded-width:235px;--nav-item-width:var(--nav-bar-height);width:var(--nav-item-width);transition:width 125ms linear}:host.expanded{width:var(--expanded-width);max-width:var(--expanded-width)}.expanded-only{max-width:0;overflow:hidden}.collapsed-only{max-width:100%;overflow:hidden}.header{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;height:var(--nav-bar-height);border-bottom:var(--pinstripe-border);cursor:pointer}.header .menu{flex:1}.header button{color:inherit;width:var(--nav-item-width);height:var(--nav-bar-height)}mat-nav-list{flex:1;display:flex;flex-direction:column}.mat-list-item{width:var(--nav-item-width);height:var(--nav-bar-height);color:inherit}mat-icon{color:inherit}mat-icon.flip-horizontal{transform:scaleX(-1)}:host-context(.expanded) .expanded-only{max-width:100%}:host-context(.expanded) .collapsed-only{max-width:0}:host-context(.expanded) .mat-list-item mat-icon{margin-right:12px}:host-context(.expanded) .mat-list-item span{text-wrap:none;white-space:nowrap}a[ng-reflect-router-link=manage-instruments] mat-icon{transform:rotate(90deg)}.app-menu{padding-top:0}"]
3664
+ }] }
3665
+ ];
3666
+ /** @nocollapse */
3667
+ ListPlaceNavComponent.ctorParameters = () => [];
3668
+ ListPlaceNavComponent.propDecorators = {
3669
+ expanded: [{ type: HostBinding, args: ['class.expanded',] }]
3670
+ };
3671
+ if (false) {
3537
3672
  /** @type {?} */
3538
- PlaceOutletComponent.prototype.parentOutlet;
3673
+ ListPlaceNavComponent.prototype.expanded;
3539
3674
  }
3540
3675
 
3541
3676
  /**
@@ -3549,8 +3684,8 @@ class TabbedPlaceNavigationComponent extends AbstractPlaceNavigationComponent {
3549
3684
  }
3550
3685
  TabbedPlaceNavigationComponent.decorators = [
3551
3686
  { type: Component, args: [{
3552
- selector: 'angular-ui-powerups-tabbed-place-navigation',
3553
- template: "<nav mat-tab-nav-bar>\n <a mat-tab-link *ngFor=\"let place of placeDefinitions.value\"\n [routerLink]='place.path'\n [replaceUrl]=\"true\"\n routerLinkActive #rla=\"routerLinkActive\"\n [active]=\"rla.isActive\"\n [matTooltip]=\"getNav(place).tooltip()\">\n <mat-icon *ngIf=\"getNav(place).icon()\">{{getNav(place).icon()}}</mat-icon>\n <span>{{getNav(place).title()}}</span>\n </a>\n</nav>\n",
3687
+ selector: 'aup-tabbed-place-navigation',
3688
+ template: "<nav mat-tab-nav-bar>\n <a mat-tab-link *ngFor=\"let place of placeDefinitions.value\"\n [pectinCommand]=\"commandFactory.create(place)\"\n routerLinkActive #rla=\"routerLinkActive\"\n [active]=\"rla.isActive\"\n [matTooltip]=\"getNav(place).tooltip()\">\n <mat-icon *ngIf=\"getNav(place).icon()\">{{getNav(place).icon()}}</mat-icon>\n <span>{{getNav(place).title()}}</span>\n </a>\n</nav>\n",
3554
3689
  styles: [""]
3555
3690
  }] }
3556
3691
  ];
@@ -3570,10 +3705,11 @@ PlaceModule.decorators = [
3570
3705
  BrowserAnimationsModule,
3571
3706
  MatProgressSpinnerModule,
3572
3707
  RouterModule,
3573
- MatTabsModule$1,
3708
+ MatTabsModule,
3574
3709
  MatListModule,
3575
3710
  MatTooltipModule,
3576
- MatIconModule
3711
+ MatIconModule,
3712
+ DirectivesModule
3577
3713
  ],
3578
3714
  declarations: [
3579
3715
  EmptyStateComponent,
@@ -3602,15 +3738,7 @@ class AngularUiPowerupsModule {
3602
3738
  }
3603
3739
  AngularUiPowerupsModule.decorators = [
3604
3740
  { type: NgModule, args: [{
3605
- declarations: [
3606
- CommandDirective,
3607
- FocusBindingDirective,
3608
- NumberInputComponent,
3609
- StringInputComponent,
3610
- PasswordInputComponent,
3611
- SelectInputComponent,
3612
- NoopComponent
3613
- ],
3741
+ declarations: [],
3614
3742
  imports: [
3615
3743
  CommonModule,
3616
3744
  BrowserAnimationsModule,
@@ -3618,19 +3746,17 @@ AngularUiPowerupsModule.decorators = [
3618
3746
  MatInputModule,
3619
3747
  MatFormFieldModule,
3620
3748
  MatSelectModule,
3621
- MatTabsModule$1,
3749
+ MatTabsModule,
3750
+ DirectivesModule,
3751
+ ComponentsModule,
3622
3752
  PlaceModule,
3623
3753
  InteractionModule
3624
3754
  ],
3625
3755
  exports: [
3626
- CommandDirective,
3627
- FocusBindingDirective,
3628
- NumberInputComponent,
3629
- StringInputComponent,
3630
- PasswordInputComponent,
3631
- SelectInputComponent,
3632
3756
  InteractionModule,
3633
3757
  PlaceModule,
3758
+ DirectivesModule,
3759
+ ComponentsModule,
3634
3760
  NoopComponent
3635
3761
  ]
3636
3762
  },] }
@@ -4086,7 +4212,7 @@ function Place(options) {
4086
4212
  */
4087
4213
  (target) => {
4088
4214
  if (PlaceComponent.isPlaceComponentConstructor(target)) {
4089
- PlaceComponent.injectDefinition(target, new PlaceDefinition(target, options.path, isNil(options.authenticate) ? false : options.authenticate, options.order, options.data, PlaceComponent.getRouteParameters(target), (options.children || []).map((/**
4215
+ PlaceComponent.injectDefinition(target, new PlaceDefinition(target, options.path, isNil(options.authenticate) ? false : options.authenticate, options.data, PlaceComponent.getRouteParameters(target), (options.children || []).map((/**
4090
4216
  * @param {?} c
4091
4217
  * @return {?}
4092
4218
  */
@@ -4106,14 +4232,14 @@ function Place(options) {
4106
4232
  if (false) {
4107
4233
  /** @type {?} */
4108
4234
  Options.prototype.path;
4109
- /** @type {?} */
4110
- Options.prototype.order;
4111
4235
  /** @type {?|undefined} */
4112
4236
  Options.prototype.data;
4113
4237
  /** @type {?|undefined} */
4114
4238
  Options.prototype.authenticate;
4115
4239
  /** @type {?|undefined} */
4116
4240
  Options.prototype.children;
4241
+ /** @type {?|undefined} */
4242
+ Options.prototype.defaultChild;
4117
4243
  }
4118
4244
  })(Place || (Place = {}));
4119
4245
 
@@ -4383,249 +4509,69 @@ class VisitSanitiser {
4383
4509
  // if the route id has changed we redirect immediately as other
4384
4510
  // parameter sanitisers might use it.
4385
4511
  return visit.replace(routeIdDef, sanitisedValue);
4386
- }
4387
- }
4388
- // if we didn't replace the routeId we continue the url present parameters.
4389
- /** @type {?} */
4390
- const parameterDefs = placeDef.getVisitParameterDefs({
4391
- includeRouteParameters: true,
4392
- includeNonRouteParameters: true
4393
- });
4394
- /** @type {?} */
4395
- let sanitisedVisit = visit;
4396
- for (let i = 0; i < parameterDefs.length; i++) {
4397
- /** @type {?} */
4398
- const def = parameterDefs[i];
4399
- /** @type {?} */
4400
- const value = visit.getParameter(def.name);
4401
- /** @type {?} */
4402
- const sanitisedValue = yield def.sanitise(value, sanitisedVisit, this.placeHistory, this.injector);
4403
- if (def.hasChanged(value, sanitisedValue)) {
4404
- sanitisedVisit = sanitisedVisit.replace(def, sanitisedValue);
4405
- }
4406
- }
4407
- return sanitisedVisit.hasChangedFrom(visit) ? sanitisedVisit : visit;
4408
- });
4409
- }
4410
- }
4411
- if (false) {
4412
- /**
4413
- * @type {?}
4414
- * @private
4415
- */
4416
- VisitSanitiser.prototype.activatedRoute;
4417
- /**
4418
- * @type {?}
4419
- * @private
4420
- */
4421
- VisitSanitiser.prototype.router;
4422
- /**
4423
- * @type {?}
4424
- * @private
4425
- */
4426
- VisitSanitiser.prototype.placeHistory;
4427
- /**
4428
- * @type {?}
4429
- * @private
4430
- */
4431
- VisitSanitiser.prototype.injector;
4432
- }
4433
-
4434
- /**
4435
- * @fileoverview added by tsickle
4436
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
4437
- */
4438
- class LeavePlaceGuard {
4439
- /**
4440
- * @param {?} router
4441
- * @param {?} injector
4442
- * @param {?} placeRouter
4443
- * @param {?} interactionContext
4444
- * @param {?} angularLocation
4445
- */
4446
- constructor(router, injector, placeRouter, interactionContext, angularLocation) {
4447
- this.router = router;
4448
- this.injector = injector;
4449
- this.placeRouter = placeRouter;
4450
- this.interactionContext = interactionContext;
4451
- this.angularLocation = angularLocation;
4452
- }
4453
- /**
4454
- * @private
4455
- * @param {?} nextState
4456
- * @param {?} placeDefinitionPath
4457
- * @return {?}
4458
- */
4459
- isLeavingTheCurrentPlace(nextState, placeDefinitionPath) {
4460
- // TODO: this will break with child routes... need to examine the router states properly.
4461
- return !nextState.url.startsWith(placeDefinitionPath);
4462
- }
4463
- /**
4464
- * @param {?} component
4465
- * @param {?} currentRoute
4466
- * @param {?} currentState
4467
- * @param {?=} nextState
4468
- * @return {?}
4469
- */
4470
- canDeactivate(component, currentRoute, currentState, nextState) {
4471
- return __awaiter(this, void 0, void 0, function* () {
4472
- /** @type {?} */
4473
- const placeDefinitionPath = `/${component.placeDefinition.path}`;
4474
- // console.log('canDeactivate', {
4475
- // staticPath: placeDefinitionPath,
4476
- // currentStateUrl: currentState.url,
4477
- // nextStateUrl: nextState.url
4478
- // // alreadyDeclined: this._alreadyAccepted
4479
- // });
4480
- // Example of the above when navigating to a different child route.
4481
- // canDeactivate {staticPath: "/hero-details",
4482
- // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-details",
4483
- // nextStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats"
4484
- // }
4485
- // Example clicking on router tab of the parent component (de-activates the parent due to route param changes)
4486
- // canDeactivate {
4487
- // staticPath: "/hero-stats",
4488
- // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
4489
- // nextStateUrl: "/route-parameters/"
4490
- // }
4491
- // canDeactivate {
4492
- // staticPath: "/route-parameters",
4493
- // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
4494
- // nextStateUrl: "/route-parameters/"
4495
- // }
4496
- // logger.class.js:54 ParameterSnapshot.sanitise -> {idModel: -1, pv: undefined, pl: Array(0), dv: undefined, dl: Array(0), …}
4497
- // parameter-snapshot.ts:20 {name: "idModel", mine: -1, theirs: null}
4498
- // place-router.ts:28 redirect path (3) ["route-parameters", "-1", {…}]
4499
- // canDeactivate {
4500
- // staticPath: "/hero-stats",
4501
- // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
4502
- // nextStateUrl: "/route-parameters/-1"
4503
- // }
4504
- // canDeactivate {
4505
- // staticPath: "/route-parameters",
4506
- // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
4507
- // nextStateUrl: "/route-parameters/-1"
4508
- // }
4509
- // logger.class.js:54 ParameterSnapshot.sanitise -> {idModel: -1, pv: undefined, pl: Array(0), dv: "A", dl: Array(3), …}
4510
- // parameter-snapshot.ts:20 {name: "dv", mine: "A", theirs: undefined}
4511
- // place-router.ts:28 redirect path (3) ["route-parameters", "-1", {…}]
4512
- // canDeactivate {
4513
- // staticPath: "/hero-stats",
4514
- // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
4515
- // nextStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c"
4516
- // }
4517
- // TODO: Add tests
4518
- if (this.placeRouter.navigationSession.alreadyAccepted(component)) {
4519
- // We'll get called multiple times if there's any parameter sanitisation so
4520
- // we always return true if we accepted on a previous cycle of the current
4521
- // navigation session.
4522
- return true;
4512
+ }
4523
4513
  }
4524
- else {
4514
+ // if we didn't replace the routeId we continue the url present parameters.
4515
+ /** @type {?} */
4516
+ const parameterDefs = placeDef.getVisitParameterDefs({
4517
+ includeRouteParameters: true,
4518
+ includeNonRouteParameters: true
4519
+ });
4520
+ /** @type {?} */
4521
+ let sanitisedVisit = visit;
4522
+ for (let i = 0; i < parameterDefs.length; i++) {
4525
4523
  /** @type {?} */
4526
- const self = this;
4524
+ const def = parameterDefs[i];
4527
4525
  /** @type {?} */
4528
- let canLeave = true;
4529
- if (this.isLeavingTheCurrentPlace(nextState, placeDefinitionPath)) {
4530
- // we check the interaction first, so that components that don't need to check if they're in an
4531
- // interaction during the canDeactivate cycle.
4532
- // TODO: Add tests: show dialog -> hit back -> same route
4533
- if (this.interactionContext.isActive()) {
4534
- canLeave = false;
4535
- console.log('cancelling', { activity: this.interactionContext.currentActivity });
4536
- this.interactionContext.currentActivity.cancel(null);
4537
- }
4538
- // No interaction in progress, so ask the component .
4539
- // This may start an interaction, hence checking the interaction context above. I.e. if the place pops up the dialog, and
4540
- // the user clicks back again, we'll re-enter here and go bang when the component tries to open another
4541
- // dialog.
4542
- if (canLeave) {
4543
- // TODO: Add tests: hit back -> confirm leave dialog -> hit back -> close dialog -> hit back -> confirm leave dialog.
4544
- canLeave = yield component.canDeactivate();
4545
- }
4546
- // We also block back button parameter changes while the dialog is open.
4547
- // NOTE: Now that I'm catching parameter changes I could possibly retry using a fragment or
4548
- // query parameter to track the dialog being open. Previously I was just checking this on
4549
- // path changes... if that worked it'd fix the case where the back button breaks with an activity
4550
- // open on the first page: https://coolon.atlassian.net/browse/AUP-33
4551
- }
4552
- else {
4553
- if (this.interactionContext.isActive()) {
4554
- console.log('cancelling', { activity: this.interactionContext.currentActivity });
4555
- this.interactionContext.currentActivity.cancel(null);
4556
- canLeave = false;
4557
- }
4558
- else {
4559
- canLeave = true;
4560
- }
4561
- }
4562
- if (canLeave) {
4563
- // We'll get called multiple times if there's any parameter sanitisation so
4564
- // we remember the acceptance for the duration of the current navigation session.
4565
- self.placeRouter.navigationSession.rememberAcceptanceOf(component);
4566
- }
4567
- else {
4568
- // Angular doesn't preserve the url when a guard cancels the back button.
4569
- // See https://github.com/angular/angular/issues/13586#issuecomment-432795720
4570
- if (this.placeRouter.navigationSession.isPopState) {
4571
- console.log('cancelled during popstate');
4572
- this.angularLocation.go(this.placeRouter.navigationSession.popStateReturnUrl);
4573
- }
4526
+ const value = visit.getParameter(def.name);
4527
+ /** @type {?} */
4528
+ const sanitisedValue = yield def.sanitise(value, sanitisedVisit, this.placeHistory, this.injector);
4529
+ if (def.hasChanged(value, sanitisedValue)) {
4530
+ sanitisedVisit = sanitisedVisit.replace(def, sanitisedValue);
4574
4531
  }
4575
- return canLeave;
4576
4532
  }
4533
+ return sanitisedVisit.hasChangedFrom(visit) ? sanitisedVisit : visit;
4577
4534
  });
4578
4535
  }
4579
4536
  }
4580
- LeavePlaceGuard.decorators = [
4581
- { type: Injectable, args: [{
4582
- providedIn: 'root'
4583
- },] }
4584
- ];
4585
- /** @nocollapse */
4586
- LeavePlaceGuard.ctorParameters = () => [
4587
- { type: Router },
4588
- { type: Injector },
4589
- { type: PlaceRouter },
4590
- { type: InteractionContext },
4591
- { type: Location }
4592
- ];
4593
- /** @nocollapse */ LeavePlaceGuard.ngInjectableDef = ɵɵdefineInjectable({ factory: function LeavePlaceGuard_Factory() { return new LeavePlaceGuard(ɵɵinject(Router), ɵɵinject(INJECTOR), ɵɵinject(PlaceRouter), ɵɵinject(InteractionContext), ɵɵinject(Location)); }, token: LeavePlaceGuard, providedIn: "root" });
4594
4537
  if (false) {
4595
4538
  /**
4596
4539
  * @type {?}
4597
4540
  * @private
4598
4541
  */
4599
- LeavePlaceGuard.prototype.router;
4542
+ VisitSanitiser.prototype.activatedRoute;
4600
4543
  /**
4601
4544
  * @type {?}
4602
4545
  * @private
4603
4546
  */
4604
- LeavePlaceGuard.prototype.injector;
4547
+ VisitSanitiser.prototype.router;
4605
4548
  /**
4606
4549
  * @type {?}
4607
4550
  * @private
4608
4551
  */
4609
- LeavePlaceGuard.prototype.placeRouter;
4610
- /** @type {?} */
4611
- LeavePlaceGuard.prototype.interactionContext;
4612
- /** @type {?} */
4613
- LeavePlaceGuard.prototype.angularLocation;
4552
+ VisitSanitiser.prototype.placeHistory;
4553
+ /**
4554
+ * @type {?}
4555
+ * @private
4556
+ */
4557
+ VisitSanitiser.prototype.injector;
4614
4558
  }
4615
4559
 
4616
4560
  /**
4617
4561
  * @fileoverview added by tsickle
4618
4562
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
4619
4563
  */
4620
- class PlaceRouteGuard {
4564
+ class EnterPlaceGuard {
4621
4565
  /**
4622
4566
  * @param {?} router
4567
+ * @param {?} urlSerializer
4623
4568
  * @param {?} placeRouter
4624
4569
  * @param {?} placeHistory
4625
4570
  * @param {?} injector
4626
4571
  */
4627
- constructor(router, placeRouter, placeHistory, injector) {
4572
+ constructor(router, urlSerializer, placeRouter, placeHistory, injector) {
4628
4573
  this.router = router;
4574
+ this.urlSerializer = urlSerializer;
4629
4575
  this.placeRouter = placeRouter;
4630
4576
  this.placeHistory = placeHistory;
4631
4577
  this.injector = injector;
@@ -4643,7 +4589,7 @@ class PlaceRouteGuard {
4643
4589
  const placeDefinition = PlaceComponent.getDefinition(activatedRoute.component);
4644
4590
  // Parse our route params.
4645
4591
  /** @type {?} */
4646
- const params = new PlaceRouteGuard.ConsolidatedParameterMap(activatedRoute.paramMap, activatedRoute.url);
4592
+ const params = new EnterPlaceGuard.ConsolidatedParameterMap(activatedRoute.paramMap, activatedRoute.url);
4647
4593
  /** @type {?} */
4648
4594
  const parsedParams = placeDefinition.parseRouteParams(params);
4649
4595
  /** @type {?} */
@@ -4656,12 +4602,10 @@ class PlaceRouteGuard {
4656
4602
  this.placeRouter.navigationSession.storeVisit(sanitisedVisit);
4657
4603
  if (initialVisit.hasRoutingChangedFrom(sanitisedVisit)) {
4658
4604
  /** @type {?} */
4659
- const parameterCommands = sanitisedVisit.hasRouteId() ?
4660
- [placeDefinition.getFormattedRouteId(sanitisedVisit), placeDefinition.getFormattedRouteParameters(sanitisedVisit)] :
4661
- [placeDefinition.getFormattedRouteParameters(sanitisedVisit)];
4662
- /** @type {?} */
4663
- const commands = [(activatedRoute.url[0].path)].concat(parameterCommands, this.placeRouter.extractChildPath(activatedRoute));
4664
- console.log('##### Redirect', commands);
4605
+ const routerStateUrlTree = this.urlSerializer.parse(state.url);
4606
+ // Regenerate the url
4607
+ const { commands } = this.createRedirectCommands(sanitisedVisit, [...routerStateUrlTree.root.children.primary.segments]);
4608
+ console.log('##### Place Guard Redirect', commands);
4665
4609
  return this.router.createUrlTree(commands, {
4666
4610
  replaceUrl: true,
4667
4611
  skipLocationChange: false
@@ -4676,43 +4620,83 @@ class PlaceRouteGuard {
4676
4620
  }
4677
4621
  });
4678
4622
  }
4623
+ /**
4624
+ * @private
4625
+ * @param {?} sanitisedVisit
4626
+ * @param {?} path
4627
+ * @return {?}
4628
+ */
4629
+ createRedirectCommands(sanitisedVisit, path) {
4630
+ // Ugly, but it works for now.
4631
+ /** @type {?} */
4632
+ const newSegments = sanitisedVisit.getUrlSegments();
4633
+ /** @type {?} */
4634
+ const replaceAt = path.findIndex((/**
4635
+ * @param {?} segment
4636
+ * @return {?}
4637
+ */
4638
+ segment => segment.path === newSegments[0].path));
4639
+ /** @type {?} */
4640
+ const newPath = [...path];
4641
+ newPath.splice(replaceAt, newSegments.length, ...newSegments); // do not use the return value, it's the items that were removed!
4642
+ // do not use the return value, it's the items that were removed!
4643
+ /** @type {?} */
4644
+ const commands = [];
4645
+ newPath.forEach((/**
4646
+ * @param {?} s
4647
+ * @return {?}
4648
+ */
4649
+ s => {
4650
+ commands.push(s.path);
4651
+ if (s.parameterMap.keys.length > 0) {
4652
+ commands.push(s.parameters);
4653
+ }
4654
+ }));
4655
+ return { newPath, commands };
4656
+ }
4679
4657
  }
4680
- PlaceRouteGuard.decorators = [
4658
+ EnterPlaceGuard.decorators = [
4681
4659
  { type: Injectable, args: [{
4682
4660
  providedIn: 'root'
4683
4661
  },] }
4684
4662
  ];
4685
4663
  /** @nocollapse */
4686
- PlaceRouteGuard.ctorParameters = () => [
4664
+ EnterPlaceGuard.ctorParameters = () => [
4687
4665
  { type: Router },
4666
+ { type: UrlSerializer },
4688
4667
  { type: PlaceRouter },
4689
4668
  { type: PlaceHistory },
4690
4669
  { type: Injector }
4691
4670
  ];
4692
- /** @nocollapse */ PlaceRouteGuard.ngInjectableDef = ɵɵdefineInjectable({ factory: function PlaceRouteGuard_Factory() { return new PlaceRouteGuard(ɵɵinject(Router), ɵɵinject(PlaceRouter), ɵɵinject(PlaceHistory), ɵɵinject(INJECTOR)); }, token: PlaceRouteGuard, providedIn: "root" });
4671
+ /** @nocollapse */ EnterPlaceGuard.ngInjectableDef = ɵɵdefineInjectable({ factory: function EnterPlaceGuard_Factory() { return new EnterPlaceGuard(ɵɵinject(Router), ɵɵinject(UrlSerializer), ɵɵinject(PlaceRouter), ɵɵinject(PlaceHistory), ɵɵinject(INJECTOR)); }, token: EnterPlaceGuard, providedIn: "root" });
4693
4672
  if (false) {
4694
4673
  /**
4695
4674
  * @type {?}
4696
4675
  * @private
4697
4676
  */
4698
- PlaceRouteGuard.prototype.router;
4677
+ EnterPlaceGuard.prototype.router;
4678
+ /**
4679
+ * @type {?}
4680
+ * @private
4681
+ */
4682
+ EnterPlaceGuard.prototype.urlSerializer;
4699
4683
  /**
4700
4684
  * @type {?}
4701
4685
  * @private
4702
4686
  */
4703
- PlaceRouteGuard.prototype.placeRouter;
4687
+ EnterPlaceGuard.prototype.placeRouter;
4704
4688
  /**
4705
4689
  * @type {?}
4706
4690
  * @private
4707
4691
  */
4708
- PlaceRouteGuard.prototype.placeHistory;
4692
+ EnterPlaceGuard.prototype.placeHistory;
4709
4693
  /**
4710
4694
  * @type {?}
4711
4695
  * @private
4712
4696
  */
4713
- PlaceRouteGuard.prototype.injector;
4697
+ EnterPlaceGuard.prototype.injector;
4714
4698
  }
4715
- (function (PlaceRouteGuard) {
4699
+ (function (EnterPlaceGuard) {
4716
4700
  /**
4717
4701
  * This a work around for the fact that an activated route with multiple segments doesn't
4718
4702
  * include the segment params in the paramMap as well as each segment returns an empty
@@ -4788,7 +4772,7 @@ if (false) {
4788
4772
  __metadata("design:type", Array),
4789
4773
  __metadata("design:paramtypes", [])
4790
4774
  ], ConsolidatedParameterMap.prototype, "keys", null);
4791
- PlaceRouteGuard.ConsolidatedParameterMap = ConsolidatedParameterMap;
4775
+ EnterPlaceGuard.ConsolidatedParameterMap = ConsolidatedParameterMap;
4792
4776
  if (false) {
4793
4777
  /**
4794
4778
  * @type {?}
@@ -4840,7 +4824,207 @@ if (false) {
4840
4824
  */
4841
4825
  ParamMapAdapter.prototype.params;
4842
4826
  }
4843
- })(PlaceRouteGuard || (PlaceRouteGuard = {}));
4827
+ })(EnterPlaceGuard || (EnterPlaceGuard = {}));
4828
+
4829
+ /**
4830
+ * @fileoverview added by tsickle
4831
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
4832
+ */
4833
+ class LeavePlaceGuard {
4834
+ /**
4835
+ * @param {?} router
4836
+ * @param {?} injector
4837
+ * @param {?} placeRouter
4838
+ * @param {?} interactionContext
4839
+ * @param {?} angularLocation
4840
+ */
4841
+ constructor(router, injector, placeRouter, interactionContext, angularLocation) {
4842
+ this.router = router;
4843
+ this.injector = injector;
4844
+ this.placeRouter = placeRouter;
4845
+ this.interactionContext = interactionContext;
4846
+ this.angularLocation = angularLocation;
4847
+ }
4848
+ /**
4849
+ * @private
4850
+ * @param {?} nextState
4851
+ * @param {?} placeDefinition
4852
+ * @return {?}
4853
+ */
4854
+ isLeavingTheCurrentPlace(nextState, placeDefinition) {
4855
+ // TODO: this will break with child routes... need to examine the router states properly.
4856
+ // console.log('canDeactivate', {
4857
+ // staticPath: placeDefinitionPath,
4858
+ // currentStateUrl: currentState.url,
4859
+ // nextStateUrl: nextState.url
4860
+ // // alreadyDeclined: this._alreadyAccepted
4861
+ // });
4862
+ // Example of the above when navigating to a different child route.
4863
+ // canDeactivate {staticPath: "/hero-details",
4864
+ // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-details",
4865
+ // nextStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats"
4866
+ // }
4867
+ // TODO: this will break with child routes... need to examine the router states properly.
4868
+ // console.log('canDeactivate', {
4869
+ // staticPath: placeDefinitionPath,
4870
+ // currentStateUrl: currentState.url,
4871
+ // nextStateUrl: nextState.url
4872
+ // // alreadyDeclined: this._alreadyAccepted
4873
+ // });
4874
+ // Example of the above when navigating to a different child route.
4875
+ // canDeactivate {staticPath: "/hero-details",
4876
+ // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-details",
4877
+ // nextStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats"
4878
+ // }
4879
+ // Example clicking on router tab of the parent component (de-activates the parent due to route param changes)
4880
+ // canDeactivate {
4881
+ // staticPath: "/hero-stats",
4882
+ // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
4883
+ // nextStateUrl: "/route-parameters/"
4884
+ // }
4885
+ // canDeactivate {
4886
+ // staticPath: "/route-parameters",
4887
+ // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
4888
+ // nextStateUrl: "/route-parameters/"
4889
+ // }
4890
+ // logger.class.js:54 ParameterSnapshot.sanitise -> {idModel: -1, pv: undefined, pl: Array(0), dv: undefined, dl: Array(0), …}
4891
+ // parameter-snapshot.ts:20 {name: "idModel", mine: -1, theirs: null}
4892
+ // place-router.ts:28 redirect path (3) ["route-parameters", "-1", {…}]
4893
+ // canDeactivate {
4894
+ // staticPath: "/hero-stats",
4895
+ // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
4896
+ // nextStateUrl: "/route-parameters/-1"
4897
+ // }
4898
+ // canDeactivate {
4899
+ // staticPath: "/route-parameters",
4900
+ // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
4901
+ // nextStateUrl: "/route-parameters/-1"
4902
+ // }
4903
+ // logger.class.js:54 ParameterSnapshot.sanitise -> {idModel: -1, pv: undefined, pl: Array(0), dv: "A", dl: Array(3), …}
4904
+ // parameter-snapshot.ts:20 {name: "dv", mine: "A", theirs: undefined}
4905
+ // place-router.ts:28 redirect path (3) ["route-parameters", "-1", {…}]
4906
+ // canDeactivate {
4907
+ // staticPath: "/hero-stats",
4908
+ // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
4909
+ // nextStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c"
4910
+ // }
4911
+ /** @type {?} */
4912
+ const placeDefinitionPath = `/${placeDefinition.path}`;
4913
+ return !nextState.url.startsWith(placeDefinitionPath);
4914
+ }
4915
+ /**
4916
+ * @param {?} component
4917
+ * @param {?} currentRoute
4918
+ * @param {?} currentState
4919
+ * @param {?=} nextState
4920
+ * @return {?}
4921
+ */
4922
+ canDeactivate(component, currentRoute, currentState, nextState) {
4923
+ return __awaiter(this, void 0, void 0, function* () {
4924
+ // TODO: Add tests
4925
+ if (this.placeRouter.navigationSession.alreadyAccepted(component)) {
4926
+ // We'll get called multiple times if there's any parameter sanitisation so
4927
+ // we always return true if we accepted on a previous cycle of the current
4928
+ // navigation session.
4929
+ return true;
4930
+ }
4931
+ else {
4932
+ /** @type {?} */
4933
+ const self = this;
4934
+ /** @type {?} */
4935
+ let canLeave = true;
4936
+ if (this.isLeavingTheCurrentPlace(nextState, component.placeDefinition)) {
4937
+ // we check the interaction first, so that components that don't need to check if they're in an
4938
+ // interaction during the canDeactivate cycle.
4939
+ // TODO: Add tests: show dialog -> hit back -> same route
4940
+ if (this.interactionContext.isActive()) {
4941
+ canLeave = false;
4942
+ console.log('cancelling', { activity: this.interactionContext.currentActivity });
4943
+ this.interactionContext.currentActivity.cancel(null);
4944
+ }
4945
+ // No interaction in progress, so ask the component .
4946
+ // This may start an interaction, hence checking the interaction context above. I.e. if the place pops up the dialog, and
4947
+ // the user clicks back again, we'll re-enter here and go bang when the component tries to open another
4948
+ // dialog.
4949
+ if (canLeave) {
4950
+ // TODO: Add tests: hit back -> confirm leave dialog -> hit back -> close dialog -> hit back -> confirm leave dialog.
4951
+ canLeave = yield component.canDeactivate();
4952
+ }
4953
+ // We also block back button parameter changes while the dialog is open.
4954
+ // NOTE: Now that I'm catching parameter changes I could possibly retry using a fragment or
4955
+ // query parameter to track the dialog being open. Previously I was just checking this on
4956
+ // path changes... if that worked it'd fix the case where the back button breaks with an activity
4957
+ // open on the first page: https://coolon.atlassian.net/browse/AUP-33
4958
+ }
4959
+ else {
4960
+ if (this.interactionContext.isActive()) {
4961
+ console.log('cancelling', { activity: this.interactionContext.currentActivity });
4962
+ this.interactionContext.currentActivity.cancel(null);
4963
+ canLeave = false;
4964
+ }
4965
+ else {
4966
+ canLeave = true;
4967
+ }
4968
+ }
4969
+ if (canLeave) {
4970
+ // We'll get called multiple times if there's any parameter sanitisation so
4971
+ // we remember the acceptance for the duration of the current navigation session.
4972
+ self.placeRouter.navigationSession.rememberAcceptanceOf(component);
4973
+ }
4974
+ else {
4975
+ // Angular doesn't preserve the url when a guard cancels the back button.
4976
+ // See https://github.com/angular/angular/issues/13586#issuecomment-432795720
4977
+ if (this.placeRouter.navigationSession.isPopState) {
4978
+ console.log('cancelled during popstate');
4979
+ this.angularLocation.go(this.placeRouter.navigationSession.popStateReturnUrl);
4980
+ }
4981
+ }
4982
+ return canLeave;
4983
+ }
4984
+ });
4985
+ }
4986
+ }
4987
+ LeavePlaceGuard.decorators = [
4988
+ { type: Injectable, args: [{
4989
+ providedIn: 'root'
4990
+ },] }
4991
+ ];
4992
+ /** @nocollapse */
4993
+ LeavePlaceGuard.ctorParameters = () => [
4994
+ { type: Router },
4995
+ { type: Injector },
4996
+ { type: PlaceRouter },
4997
+ { type: InteractionContext },
4998
+ { type: Location }
4999
+ ];
5000
+ /** @nocollapse */ LeavePlaceGuard.ngInjectableDef = ɵɵdefineInjectable({ factory: function LeavePlaceGuard_Factory() { return new LeavePlaceGuard(ɵɵinject(Router), ɵɵinject(INJECTOR), ɵɵinject(PlaceRouter), ɵɵinject(InteractionContext), ɵɵinject(Location)); }, token: LeavePlaceGuard, providedIn: "root" });
5001
+ __decorate([
5002
+ Trace(),
5003
+ __metadata("design:type", Function),
5004
+ __metadata("design:paramtypes", [RouterStateSnapshot, PlaceDefinition]),
5005
+ __metadata("design:returntype", void 0)
5006
+ ], LeavePlaceGuard.prototype, "isLeavingTheCurrentPlace", null);
5007
+ if (false) {
5008
+ /**
5009
+ * @type {?}
5010
+ * @private
5011
+ */
5012
+ LeavePlaceGuard.prototype.router;
5013
+ /**
5014
+ * @type {?}
5015
+ * @private
5016
+ */
5017
+ LeavePlaceGuard.prototype.injector;
5018
+ /**
5019
+ * @type {?}
5020
+ * @private
5021
+ */
5022
+ LeavePlaceGuard.prototype.placeRouter;
5023
+ /** @type {?} */
5024
+ LeavePlaceGuard.prototype.interactionContext;
5025
+ /** @type {?} */
5026
+ LeavePlaceGuard.prototype.angularLocation;
5027
+ }
4844
5028
 
4845
5029
  /**
4846
5030
  * @fileoverview added by tsickle
@@ -4862,5 +5046,5 @@ if (false) {
4862
5046
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
4863
5047
  */
4864
5048
 
4865
- export { ACTIVITY_DATA, AbstractActivity, AbstractInputComponent, AbstractPlaceNavigationComponent, Activity, ActivityContainerComponent, ActivityOutletComponent, AlertDialogComponent, AngularUiPowerupsModule, Bounds, BusyOverlayComponent, CommandDirective, ConfirmThenDialogComponent, ConfirmationDialogComponent, DEFINITION_META_DATA_KEY, DIALOG_INTERACTION_SERVICE_DEFAULTS, DialogInteractionService, Dimension, DisposableComponent, EmptyStateComponent, FocusBindingDirective, Formatter, InteractionContext, InteractionGuard, InteractionModule, InteractionOutletComponent, LEFT_RIGHT_PLACE_ANIMATION, LeavePlaceGuard, ListPlaceNavComponent, NavigationSession, NoopComponent, NumberInputComponent, ParameterDefinition, PasswordInputComponent, Place, PlaceComponent, PlaceDefinition, PlaceHistory, PlaceModule, PlaceOutletComponent, PlaceRouteGuard, PlaceRouter, Point, ROUTE_PARAMETER_LIST_KEY, ResizeAwareComponent, RouteId, SelectInputComponent, StringInputComponent, TabbedPlaceNavigationComponent, Visit, VisitParameter, VisitParameterList, VisitSanitiser, leftRightPlaceAnimation, slideDownAndUpAnimation, CommandDirective as ɵa, FocusBindingDirective as ɵb, ACTIVITY_DATA as ɵba, Activity as ɵbb, ConfirmThenDialogComponent as ɵbd, AlertDialogComponent as ɵbe, InteractionOutletComponent as ɵbg, DIALOG_INTERACTION_SERVICE_DEFAULTS as ɵbh, DialogInteractionService as ɵbi, DisposableComponent as ɵc, NumberInputComponent as ɵd, AbstractInputComponent as ɵe, StringInputComponent as ɵf, PasswordInputComponent as ɵg, SelectInputComponent as ɵh, NoopComponent as ɵi, PlaceModule as ɵj, EmptyStateComponent as ɵk, BusyOverlayComponent as ɵl, PlaceOutletComponent as ɵm, leftRightPlaceAnimation as ɵn, LEFT_RIGHT_PLACE_ANIMATION as ɵo, PlaceRouter as ɵp, PlaceHistory as ɵq, TabbedPlaceNavigationComponent as ɵr, AbstractPlaceNavigationComponent as ɵs, ListPlaceNavComponent as ɵt, InteractionModule as ɵu, ActivityContainerComponent as ɵv, InteractionContext as ɵw, ActivityOutletComponent as ɵx, ConfirmationDialogComponent as ɵy, AbstractActivity as ɵz };
5049
+ export { ACTIVITY_DATA, AbstractActivity, AbstractInputComponent, AbstractPlaceNavigationComponent, Activity, ActivityContainerComponent, ActivityOutletComponent, AlertDialogComponent, AngularUiPowerupsModule, Bounds, BusyOverlayComponent, CommandDirective, ComponentsModule, ConfirmThenDialogComponent, ConfirmationDialogComponent, DEFINITION_META_DATA_KEY, DIALOG_INTERACTION_SERVICE_DEFAULTS, DialogInteractionService, Dimension, DirectivesModule, DisposableComponent, EmptyStateComponent, EnterPlaceGuard, FocusBindingDirective, Formatter, InteractionContext, InteractionGuard, InteractionModule, InteractionOutletComponent, LEFT_RIGHT_PLACE_ANIMATION, LeavePlaceGuard, ListPlaceNavComponent, NavigationSession, NoopComponent, NumberInputComponent, ParameterDefinition, PasswordInputComponent, Place, PlaceComponent, PlaceDefinition, PlaceHistory, PlaceModule, PlaceOutletComponent, PlaceRouter, Point, ROUTE_PARAMETER_LIST_KEY, ResizeAwareComponent, RouteId, SelectInputComponent, StringInputComponent, TabbedPlaceNavigationComponent, Visit, VisitParameter, VisitParameterList, VisitSanitiser, leftRightPlaceAnimation, slideDownAndUpAnimation, DirectivesModule as ɵa, CommandDirective as ɵb, ConfirmationDialogComponent as ɵba, AbstractActivity as ɵbb, ACTIVITY_DATA as ɵbc, Activity as ɵbd, ConfirmThenDialogComponent as ɵbf, AlertDialogComponent as ɵbg, InteractionOutletComponent as ɵbi, DIALOG_INTERACTION_SERVICE_DEFAULTS as ɵbj, DialogInteractionService as ɵbk, FocusBindingDirective as ɵc, DisposableComponent as ɵd, ComponentsModule as ɵe, NumberInputComponent as ɵf, AbstractInputComponent as ɵg, StringInputComponent as ɵh, PasswordInputComponent as ɵi, SelectInputComponent as ɵj, NoopComponent as ɵk, PlaceModule as ɵl, EmptyStateComponent as ɵm, BusyOverlayComponent as ɵn, PlaceOutletComponent as ɵo, leftRightPlaceAnimation as ɵp, LEFT_RIGHT_PLACE_ANIMATION as ɵq, PlaceRouter as ɵr, PlaceHistory as ɵs, TabbedPlaceNavigationComponent as ɵt, AbstractPlaceNavigationComponent as ɵu, ListPlaceNavComponent as ɵv, InteractionModule as ɵw, ActivityContainerComponent as ɵx, InteractionContext as ɵy, ActivityOutletComponent as ɵz };
4866
5050
  //# sourceMappingURL=coolon-angular-ui-powerups.js.map