@coolon/angular-ui-powerups 0.0.62 → 0.0.65

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 (46) hide show
  1. package/bundles/coolon-angular-ui-powerups.umd.js +738 -582
  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 +10 -10
  6. package/coolon-angular-ui-powerups.metadata.json +1 -1
  7. package/esm2015/coolon-angular-ui-powerups.js +10 -10
  8. package/esm2015/index.js +2 -2
  9. package/esm2015/lib/interaction/abstract-activity.js +5 -68
  10. package/esm2015/lib/interaction/activity.js +71 -11
  11. package/esm2015/lib/interaction/components/activity-container/activity-container.component.js +213 -120
  12. package/esm2015/lib/interaction/components/activity-outlet/activity-outlet-context.js +6 -7
  13. package/esm2015/lib/interaction/components/activity-outlet/activity-outlet.component.js +19 -43
  14. package/esm2015/lib/interaction/index.js +2 -2
  15. package/esm2015/lib/interaction/interaction-context.js +15 -10
  16. package/esm2015/lib/interaction/services/dialog-interaction.service.js +99 -86
  17. package/esm2015/lib/place/guards/leave-place.guard.js +95 -115
  18. package/esm2015/lib/place/place-router.js +87 -6
  19. package/esm2015/public_api.js +2 -2
  20. package/esm5/coolon-angular-ui-powerups.js +10 -10
  21. package/esm5/index.js +2 -2
  22. package/esm5/lib/interaction/abstract-activity.js +10 -96
  23. package/esm5/lib/interaction/activity.js +110 -11
  24. package/esm5/lib/interaction/components/activity-container/activity-container.component.js +285 -143
  25. package/esm5/lib/interaction/components/activity-outlet/activity-outlet-context.js +6 -7
  26. package/esm5/lib/interaction/components/activity-outlet/activity-outlet.component.js +19 -67
  27. package/esm5/lib/interaction/index.js +2 -2
  28. package/esm5/lib/interaction/interaction-context.js +24 -21
  29. package/esm5/lib/interaction/services/dialog-interaction.service.js +120 -85
  30. package/esm5/lib/place/guards/leave-place.guard.js +53 -123
  31. package/esm5/lib/place/place-router.js +96 -6
  32. package/esm5/public_api.js +2 -2
  33. package/fesm2015/coolon-angular-ui-powerups.js +591 -449
  34. package/fesm2015/coolon-angular-ui-powerups.js.map +1 -1
  35. package/fesm5/coolon-angular-ui-powerups.js +711 -556
  36. package/fesm5/coolon-angular-ui-powerups.js.map +1 -1
  37. package/lib/interaction/abstract-activity.d.ts +4 -13
  38. package/lib/interaction/activity.d.ts +13 -6
  39. package/lib/interaction/components/activity-container/activity-container.component.d.ts +37 -25
  40. package/lib/interaction/components/activity-outlet/activity-outlet-context.d.ts +2 -5
  41. package/lib/interaction/components/activity-outlet/activity-outlet.component.d.ts +1 -10
  42. package/lib/interaction/interaction-context.d.ts +7 -7
  43. package/lib/interaction/services/dialog-interaction.service.d.ts +5 -6
  44. package/lib/place/guards/leave-place.guard.d.ts +6 -7
  45. package/lib/place/place-router.d.ts +14 -1
  46. package/package.json +1 -1
@@ -5,18 +5,19 @@ import { MatDialog, MatButtonModule, MatDialogModule, MatTabsModule, MatProgress
5
5
  import { MatTabsModule as MatTabsModule$1 } from '@angular/material/tabs';
6
6
  import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
7
7
  import { __decorate, __metadata, __awaiter } from 'tslib';
8
- import { GarbageCollector, DelegatingFormValueModel, UseDelegate, ValueModel, ListModel, StoreInListModel, assert, UnaryCommand, lang, Dsl, Logger, DelegatingValueModel, MutableListModel, DelegatingListModel, StoreInValueModel, Binding, MutableValueModel, Guard, OptionsHelper, ValueHolder, Trace } from '@coolon/pectin';
8
+ import { GarbageCollector, DelegatingFormValueModel, UseDelegate, ValueModel, ListModel, StoreInListModel, assert, UnaryCommand, lang, Dsl, Logger, DelegatingValueModel, MutableStream, MutableListModel, DelegatingListModel, StoreInValueModel, Binding, MutableValueModel, Guard as Guard$1, OptionsHelper, ValueHolder } from '@coolon/pectin';
9
9
  import { PortalModule } from '@angular/cdk/portal';
10
+ import ___default, { last, isNil } from 'lodash';
10
11
  import { assert as assert$1, Klass, Opts } from '@coolon/typescript-utilities';
11
12
  import { MatDialogConfig, MAT_DIALOG_DEFAULT_OPTIONS, MatDialog as MatDialog$1 } from '@angular/material/dialog';
12
- import { Router, RouterModule, NavigationEnd, NavigationError } from '@angular/router';
13
+ import { v1 } from 'uuid';
13
14
  import { MatIconModule } from '@angular/material/icon';
14
15
  import { MatListModule } from '@angular/material/list';
15
16
  import { MatTooltipModule } from '@angular/material/tooltip';
17
+ import { Router, NavigationStart, NavigationEnd, NavigationError, RouterModule } from '@angular/router';
16
18
  import { Memoize as Memoize$1 } from '@typescript-plus/fast-memoize-decorator/dist/src';
17
19
  import { Memoize } from '@typescript-plus/fast-memoize-decorator';
18
20
  import 'reflect-metadata';
19
- import ___default, { isNil } from 'lodash';
20
21
  import { style, query, group, animate, trigger, transition } from '@angular/animations';
21
22
  import ResizeObserver from 'resize-observer-polyfill';
22
23
 
@@ -655,30 +656,34 @@ if (false) {
655
656
  * @abstract
656
657
  */
657
658
  class InteractionContext extends GarbageCollector {
659
+ /**
660
+ * @protected
661
+ */
658
662
  constructor() {
659
663
  super();
660
664
  }
661
665
  /**
662
- * Returns true if an activity is currently running.
666
+ * Returns the activity that is currently active.
667
+ * This model is only updated in the next tick after the view has been updated.
663
668
  * @return {?}
664
669
  */
665
- isActive() {
666
- return this.activityList.length > 0;
670
+ get currentActivity() {
671
+ return last(this.activityList.value);
667
672
  }
668
673
  }
669
674
  if (false) {
670
- /**
671
- * Returns the activity that is currently active.
672
- * This model is only updated in the next tick after the view has been updated.
673
- * @type {?}
674
- */
675
- InteractionContext.prototype.currentActivity;
676
675
  /**
677
676
  * Returns the current list of activities that are in progress.
678
677
  * This model is only updated in the next tick after the view has been updated.
679
678
  * @type {?}
680
679
  */
681
680
  InteractionContext.prototype.activityList;
681
+ /**
682
+ * Returns true if an activity is currently running.
683
+ * @abstract
684
+ * @return {?}
685
+ */
686
+ InteractionContext.prototype.isActive = function () { };
682
687
  /**
683
688
  * @abstract
684
689
  * @template D, R, E
@@ -718,29 +723,87 @@ if (false) {
718
723
  /** @type {?} */
719
724
  const ACTIVITY_DATA = new InjectionToken('InteractionActivityData');
720
725
  /**
721
- * @record
726
+ * @abstract
722
727
  * @template D, R, E
723
728
  */
724
- function Activity() { }
725
- if (false) {
726
- /** @type {?} */
727
- Activity.prototype.busy;
729
+ class Activity {
730
+ constructor() {
731
+ this._busyModel = new DelegatingValueModel().withDefault(false);
732
+ }
728
733
  /**
729
734
  * @param {?} activityContext
730
735
  * @return {?}
731
736
  */
732
- Activity.prototype.initialise = function (activityContext) { };
737
+ initialise(activityContext) {
738
+ assert$1.isNil(this._activityContext);
739
+ this._activityContext = activityContext;
740
+ }
741
+ /**
742
+ * @param {?=} result
743
+ * @return {?}
744
+ */
745
+ done(result) {
746
+ return this._activityContext.onDone(result);
747
+ }
748
+ /**
749
+ * @param {?=} error
750
+ * @return {?}
751
+ */
752
+ cancel(error) {
753
+ this._activityContext.onCancel(error);
754
+ }
755
+ // @Trace()
756
+ /**
757
+ * @return {?}
758
+ */
759
+ onActivityReady() {
760
+ }
733
761
  /**
734
- * @param {?} result
735
762
  * @return {?}
736
763
  */
737
- Activity.prototype.done = function (result) { };
764
+ get busy() {
765
+ return this._busyModel.readonly;
766
+ }
738
767
  /**
739
- * @param {?} e
768
+ * @param {?} busyModel
740
769
  * @return {?}
741
770
  */
742
- Activity.prototype.cancel = function (e) { };
771
+ busyWhile(busyModel) {
772
+ this._busyModel.setDelegate(busyModel);
773
+ }
774
+ /**
775
+ * @return {?}
776
+ */
777
+ isBusy() {
778
+ return this._busyModel.value;
779
+ }
743
780
  }
781
+ if (false) {
782
+ /**
783
+ * @type {?}
784
+ * @private
785
+ */
786
+ Activity.prototype._busyModel;
787
+ /**
788
+ * @type {?}
789
+ * @private
790
+ */
791
+ Activity.prototype._activityContext;
792
+ }
793
+ (function (Activity) {
794
+ /**
795
+ * @record
796
+ * @template R, E
797
+ */
798
+ function Callbacks() { }
799
+ Activity.Callbacks = Callbacks;
800
+ if (false) {
801
+ /** @type {?} */
802
+ Callbacks.prototype.onDone;
803
+ /** @type {?} */
804
+ Callbacks.prototype.onCancel;
805
+ }
806
+ })(Activity || (Activity = {}));
744
807
 
745
808
  /**
746
809
  * @fileoverview added by tsickle
@@ -770,9 +833,17 @@ class ActivityOutletComponent {
770
833
  * @return {?}
771
834
  */
772
835
  set activityContext(activityContext) {
836
+ assert.isNil(this._activityContext);
837
+ this._activityContext = activityContext;
773
838
  this.loadActivity(activityContext);
774
839
  }
775
840
  ;
841
+ /**
842
+ * @return {?}
843
+ */
844
+ get activityContext() {
845
+ return this._activityContext;
846
+ }
776
847
  /**
777
848
  * @return {?}
778
849
  */
@@ -788,7 +859,7 @@ class ActivityOutletComponent {
788
859
  providers: [
789
860
  {
790
861
  provide: InteractionContext,
791
- useValue: this
862
+ useValue: this.interactionContext
792
863
  },
793
864
  { provide: ACTIVITY_DATA, useValue: activityContext.activityData }
794
865
  ],
@@ -799,6 +870,9 @@ class ActivityOutletComponent {
799
870
  this.viewContainerRef.clear();
800
871
  this.activityComponentRef = this.viewContainerRef.createComponent(componentFactory, 0, injector);
801
872
  this.activityComponentRef.instance.initialise(activityContext);
873
+ if (this.activityContext.componentReady) {
874
+ this.activityContext.componentReady(this.component);
875
+ }
802
876
  }
803
877
  /**
804
878
  * @return {?}
@@ -806,47 +880,6 @@ class ActivityOutletComponent {
806
880
  get component() {
807
881
  return this.activityComponentRef.instance;
808
882
  }
809
- /**
810
- * @param {?} alert
811
- * @return {?}
812
- */
813
- alert(alert) {
814
- return this.interactionContext.alert(alert);
815
- }
816
- /**
817
- * @param {?} confirm
818
- * @return {?}
819
- */
820
- confirm(confirm) {
821
- return this.interactionContext.confirm(confirm);
822
- }
823
- /**
824
- * @template D1, R1, E1
825
- * @param {?} confirm
826
- * @param {?} activityType
827
- * @param {?=} data
828
- * @return {?}
829
- */
830
- confirmThen(confirm, activityType, data) {
831
- return this.interactionContext.confirmThen(confirm, activityType, data);
832
- }
833
- /**
834
- * @template D1, R1, E1
835
- * @param {?} activityType
836
- * @param {?=} data
837
- * @return {?}
838
- */
839
- startActivity(activityType, data) {
840
- return this.interactionContext.startActivity(activityType, data);
841
- }
842
- /**
843
- * @return {?}
844
- */
845
- notifyReady() {
846
- if (this.activityComponentRef.instance['onActivityReady']) {
847
- this.activityComponentRef.instance['onActivityReady']();
848
- }
849
- }
850
883
  }
851
884
  ActivityOutletComponent.decorators = [
852
885
  { type: Component, args: [{
@@ -868,6 +901,11 @@ ActivityOutletComponent.propDecorators = {
868
901
  if (false) {
869
902
  /** @type {?} */
870
903
  ActivityOutletComponent.prototype.interactionContext;
904
+ /**
905
+ * @type {?}
906
+ * @private
907
+ */
908
+ ActivityOutletComponent.prototype._activityContext;
871
909
  /**
872
910
  * @type {?}
873
911
  * @private
@@ -896,72 +934,11 @@ if (false) {
896
934
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
897
935
  */
898
936
  /**
937
+ * Deprecated. You can now extend the Activity class directly.
938
+ * @abstract
899
939
  * @template D, R, E
900
940
  */
901
- class AbstractActivity extends DisposableComponent {
902
- constructor() {
903
- super(...arguments);
904
- this._busyModel = new DelegatingValueModel().withDefault(false);
905
- }
906
- /**
907
- * @param {?} activityContext
908
- * @return {?}
909
- */
910
- initialise(activityContext) {
911
- assert$1.isNil(this.activityContext);
912
- this.activityContext = activityContext;
913
- }
914
- /**
915
- * @param {?=} result
916
- * @return {?}
917
- */
918
- done(result) {
919
- return this.activityContext.onDone(result);
920
- }
921
- /**
922
- * @param {?=} error
923
- * @return {?}
924
- */
925
- cancel(error) {
926
- this.activityContext.onCancel(error);
927
- }
928
- // @Trace()
929
- /**
930
- * @return {?}
931
- */
932
- onActivityReady() {
933
- }
934
- /**
935
- * @return {?}
936
- */
937
- get busy() {
938
- return this._busyModel.readonly;
939
- }
940
- /**
941
- * @param {?} busyModel
942
- * @return {?}
943
- */
944
- busyWhile(busyModel) {
945
- this._busyModel.setDelegate(busyModel);
946
- }
947
- /**
948
- * @return {?}
949
- */
950
- isBusy() {
951
- return this._busyModel.value;
952
- }
953
- }
954
- if (false) {
955
- /**
956
- * @type {?}
957
- * @private
958
- */
959
- AbstractActivity.prototype._busyModel;
960
- /**
961
- * @type {?}
962
- * @private
963
- */
964
- AbstractActivity.prototype.activityContext;
941
+ class AbstractActivity extends Activity {
965
942
  }
966
943
 
967
944
  /**
@@ -1130,101 +1107,175 @@ if (false) {
1130
1107
  * @fileoverview added by tsickle
1131
1108
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
1132
1109
  */
1133
- class ActivityContainerComponent extends DisposableComponent {
1134
- constructor() {
1135
- super();
1136
- this.activityOutletTabs = new MutableListModel();
1137
- this.obsoleteTabs = [];
1138
- this.finished = false;
1139
- this._activityList = new MutableListModel();
1110
+ /**
1111
+ * Note: this class is mutable and is stored in a list model. This is normally a big no no but
1112
+ * we're manually deriving other models from the list after view state changes. I.e. we not
1113
+ * using pectin chains on any of the mutable fields.
1114
+ * @template D, R, E
1115
+ */
1116
+ class TabContext {
1117
+ /**
1118
+ * @param {?} activityData
1119
+ * @param {?} activityClass
1120
+ * @param {?} interactionContext
1121
+ * @param {?} activityCallbacks
1122
+ */
1123
+ constructor(activityData, activityClass, interactionContext, activityCallbacks) {
1124
+ this.activityData = activityData;
1125
+ this.activityClass = activityClass;
1126
+ this.interactionContext = interactionContext;
1127
+ this.activityCallbacks = activityCallbacks;
1128
+ this._complete = false;
1140
1129
  }
1141
1130
  /**
1142
1131
  * @return {?}
1143
1132
  */
1144
- isActive() {
1145
- return this.parentInteractionContext.isActive();
1133
+ isComponentRealised() {
1134
+ return !!this._component;
1146
1135
  }
1147
1136
  /**
1148
1137
  * @return {?}
1149
1138
  */
1150
- get activityList() {
1151
- return this._activityList.readonly;
1139
+ isComplete() {
1140
+ return this._complete;
1152
1141
  }
1153
1142
  /**
1143
+ * @param {?} component
1154
1144
  * @return {?}
1155
1145
  */
1156
- ngOnInit() {
1146
+ componentReady(component) {
1147
+ assert.isNil(this._component);
1148
+ this._component = component;
1157
1149
  }
1158
1150
  /**
1159
1151
  * @return {?}
1160
1152
  */
1161
- ngAfterViewInit() {
1162
- const { observe } = Dsl.disposeWith(this);
1163
- this._activityList.value = this.outlets.toArray().map((/**
1164
- * @param {?} c
1165
- * @return {?}
1166
- */
1167
- c => c.component));
1168
- observe.valuesFrom(this.outlets.changes).subscribe((/**
1169
- * @param {?} change
1170
- * @return {?}
1171
- */
1172
- (change) => {
1173
- this.safelyUpdateActivityList(change.map((/**
1174
- * @param {?} c
1175
- * @return {?}
1176
- */
1177
- c => c.component)));
1178
- }));
1179
- observe.valuesFrom(this.tabs.animationDone).subscribe((/**
1180
- * @return {?}
1181
- */
1182
- () => this.onAnimationFinished()));
1153
+ get component() {
1154
+ return this._component;
1183
1155
  }
1156
+ // @Trace()
1184
1157
  /**
1185
- * Update in the next tick to avoid changing state in the current change detection cycle.
1186
- * @private
1187
- * @param {?} activities
1158
+ * @param {?} result
1188
1159
  * @return {?}
1189
1160
  */
1190
- safelyUpdateActivityList(activities) {
1191
- setTimeout((/**
1161
+ onDone(result) {
1162
+ this._complete = true;
1163
+ this.activityCallbacks.onDone(result);
1164
+ }
1165
+ // @Trace()
1166
+ /**
1167
+ * @param {?} error
1168
+ * @return {?}
1169
+ */
1170
+ onCancel(error) {
1171
+ this._complete = true;
1172
+ this.activityCallbacks.onCancel(error);
1173
+ }
1174
+ }
1175
+ if (false) {
1176
+ /**
1177
+ * @type {?}
1178
+ * @private
1179
+ */
1180
+ TabContext.prototype._complete;
1181
+ /**
1182
+ * @type {?}
1183
+ * @private
1184
+ */
1185
+ TabContext.prototype._component;
1186
+ /** @type {?} */
1187
+ TabContext.prototype.activityData;
1188
+ /** @type {?} */
1189
+ TabContext.prototype.activityClass;
1190
+ /** @type {?} */
1191
+ TabContext.prototype.interactionContext;
1192
+ /** @type {?} */
1193
+ TabContext.prototype.activityCallbacks;
1194
+ }
1195
+ /**
1196
+ * @template D, R, E
1197
+ */
1198
+ class ActivityContainerComponent extends InteractionContext {
1199
+ constructor() {
1200
+ super();
1201
+ this.activityFinishedEvents = new MutableStream();
1202
+ this.activityTabs = new MutableListModel();
1203
+ this.finished = false;
1204
+ this._activityList = new MutableListModel();
1205
+ const { chain, valueOf, before, when, after, observe, switchOn } = Dsl.disposeWith(this);
1206
+ chain(this.activityFinishedEvents).throttle(50).subscribe((/**
1192
1207
  * @return {?}
1193
1208
  */
1194
- () => this._activityList.value = activities));
1209
+ () => this.onActivityFinished()));
1195
1210
  }
1196
1211
  /**
1197
- * @template D, R, E
1198
1212
  * @param {?} initialContext
1199
1213
  * @return {?}
1200
1214
  */
1201
- initialise(initialContext) {
1202
- /** @type {?} */
1203
- const self = this;
1204
- this.initialActivityOutletContext = {
1205
- activityClass: initialContext.activityClass,
1206
- activityData: initialContext.activityData,
1215
+ set initialActivityOutletContext(initialContext) {
1216
+ assert.isNil(this.initialActivityOutletContext);
1217
+ this.activityTabs.push(new TabContext(initialContext.activityData, initialContext.activityClass, this, {
1207
1218
  onDone: (/**
1208
1219
  * @param {?} result
1209
1220
  * @return {?}
1210
1221
  */
1211
- function (result) {
1212
- self.finished = true;
1222
+ (result) => {
1223
+ this.finished = true;
1213
1224
  return initialContext.onDone(result);
1214
1225
  }),
1215
1226
  onCancel: (/**
1216
1227
  * @param {?} error
1217
1228
  * @return {?}
1218
1229
  */
1219
- function (error) {
1220
- self.finished = true;
1230
+ (error) => {
1231
+ this.finished = true;
1221
1232
  return initialContext.onCancel(error);
1222
- }),
1223
- interactionContext: this
1224
- };
1233
+ })
1234
+ }));
1235
+ }
1236
+ /**
1237
+ * @return {?}
1238
+ */
1239
+ get initialActivityOutletContext() {
1240
+ return this.activityTabs.length > 0 ? this.activityTabs.value[0] : null;
1241
+ }
1242
+ /**
1243
+ * @return {?}
1244
+ */
1245
+ isActive() {
1246
+ return this.parentInteractionContext.isActive();
1247
+ }
1248
+ /**
1249
+ * @return {?}
1250
+ */
1251
+ get activityList() {
1252
+ return this._activityList.readonly;
1253
+ }
1254
+ /**
1255
+ * @return {?}
1256
+ */
1257
+ ngOnInit() {
1258
+ }
1259
+ /**
1260
+ * @return {?}
1261
+ */
1262
+ ngAfterViewInit() {
1263
+ const { chain, observe } = Dsl.disposeWith(this);
1264
+ observe.valuesFrom(this.outlets.changes).subscribe((/**
1265
+ * @return {?}
1266
+ */
1267
+ () => setTimeout((/**
1268
+ * @return {?}
1269
+ */
1270
+ () => this.updateActivityList()))));
1271
+ observe.valuesFrom(this.tabs.animationDone).subscribe((/**
1272
+ * @return {?}
1273
+ */
1274
+ () => this.onAnimationFinished()));
1275
+ this.updateActivityList();
1225
1276
  }
1226
1277
  /**
1227
- * @template D, R, E
1278
+ * @template D1, R1, E1
1228
1279
  * @param {?} activityType
1229
1280
  * @param {?=} data
1230
1281
  * @return {?}
@@ -1239,41 +1290,26 @@ class ActivityContainerComponent extends DisposableComponent {
1239
1290
  */
1240
1291
  (resolve, reject) => {
1241
1292
  /** @type {?} */
1242
- const context = {
1243
- interactionContext: self,
1244
- activityClass: activityType,
1245
- activityData: data,
1293
+ const context = new TabContext(data, activityType, self, {
1246
1294
  onDone: (/**
1247
1295
  * @param {?} result
1248
1296
  * @return {?}
1249
1297
  */
1250
1298
  function (result) {
1251
- self.obsoleteTabs.push(context);
1252
- // animating on the next tick gives chained done's a chance to
1253
- // finished before we start an animations
1254
1299
  resolve(result);
1255
- setTimeout((/**
1256
- * @return {?}
1257
- */
1258
- () => self.animateTabs()));
1300
+ self.activityFinishedEvents.publish({});
1259
1301
  }),
1260
1302
  onCancel: (/**
1261
1303
  * @param {?} error
1262
1304
  * @return {?}
1263
1305
  */
1264
1306
  function (error) {
1265
- self.obsoleteTabs.push(context);
1266
- // finished before we start an animations
1267
1307
  reject(error);
1268
- // animating on the next tick gives chained done's a chance to complete before we animate
1269
- setTimeout((/**
1270
- * @return {?}
1271
- */
1272
- () => self.animateTabs()));
1308
+ self.activityFinishedEvents.publish({});
1273
1309
  })
1274
- };
1275
- self.activityOutletTabs.push(context);
1276
- self.tabs.selectedIndex = this.activityOutletTabs.length;
1310
+ });
1311
+ self.activityTabs.push(context);
1312
+ self.tabs.selectedIndex = this.activityTabs.length;
1277
1313
  }));
1278
1314
  }
1279
1315
  /**
@@ -1291,7 +1327,7 @@ class ActivityContainerComponent extends DisposableComponent {
1291
1327
  return this.startActivity(ConfirmationDialogComponent, confirm);
1292
1328
  }
1293
1329
  /**
1294
- * @template D, R, E
1330
+ * @template D1, R1, E1
1295
1331
  * @param {?} confirm
1296
1332
  * @param {?} activityType
1297
1333
  * @param {?=} data
@@ -1304,35 +1340,92 @@ class ActivityContainerComponent extends DisposableComponent {
1304
1340
  data: data
1305
1341
  });
1306
1342
  }
1343
+ // @Trace()
1344
+ /**
1345
+ * @private
1346
+ * @return {?}
1347
+ */
1348
+ onActivityFinished() {
1349
+ // don't do anything if job already queued up.
1350
+ if (!this.finished) {
1351
+ if (this.synchroniseSelectedTabIndex()) {
1352
+ this.cleanupStaleActivities();
1353
+ }
1354
+ this.updateActivityList();
1355
+ }
1356
+ }
1357
+ // @Trace()
1358
+ /**
1359
+ * @private
1360
+ * @return {?}
1361
+ */
1362
+ cleanupStaleActivities() {
1363
+ // clean up old tabs
1364
+ if (this.tabs.selectedIndex < this.activityTabs.length - 1) {
1365
+ this.activityTabs.runInTransaction((/**
1366
+ * @param {?} draft
1367
+ * @return {?}
1368
+ */
1369
+ draft => {
1370
+ draft.value = draft.value.slice(0, 1 + this.tabs.selectedIndex);
1371
+ }));
1372
+ }
1373
+ }
1374
+ /**
1375
+ * Synchronises the selected tab index. Returns true if there was no change to the selected index.
1376
+ * @private
1377
+ * @return {?}
1378
+ */
1379
+ // @Trace()
1380
+ synchroniseSelectedTabIndex() {
1381
+ /** @type {?} */
1382
+ const previousIndex = this.tabs.selectedIndex;
1383
+ /** @type {?} */
1384
+ const newIndex = this.activityTabs.query().findIndex((/**
1385
+ * @param {?} t
1386
+ * @return {?}
1387
+ */
1388
+ t => t.isComplete())) - 1;
1389
+ this.tabs.selectedIndex = newIndex;
1390
+ return previousIndex === newIndex;
1391
+ }
1392
+ // @Trace()
1307
1393
  /**
1308
1394
  * @private
1309
1395
  * @return {?}
1310
1396
  */
1311
1397
  onAnimationFinished() {
1312
- this.activityOutletTabs.value = this.activityOutletTabs.value.filter((/**
1313
- * @param {?} tab
1398
+ this.getSelectedOutlet().component.onActivityReady();
1399
+ this.cleanupStaleActivities();
1400
+ this.updateActivityList();
1401
+ }
1402
+ /**
1403
+ * @private
1404
+ * @return {?}
1405
+ */
1406
+ updateActivityList() {
1407
+ this._activityList.value = this.activityTabs.value.filter((/**
1408
+ * @param {?} t
1314
1409
  * @return {?}
1315
1410
  */
1316
- tab => {
1317
- return !this.obsoleteTabs.includes(tab);
1318
- }));
1319
- this.obsoleteTabs = [];
1320
- this.outlets.toArray()[this.tabs.selectedIndex].notifyReady();
1411
+ t => !t.isComplete() && t.isComponentRealised())).map((/**
1412
+ * @param {?} t
1413
+ * @return {?}
1414
+ */
1415
+ t => t.component));
1321
1416
  }
1322
1417
  /**
1323
1418
  * @private
1324
1419
  * @return {?}
1325
1420
  */
1326
- animateTabs() {
1327
- if (!this.finished) {
1328
- this.tabs.selectedIndex = this.activityOutletTabs.length - this.obsoleteTabs.length;
1329
- }
1421
+ getSelectedOutlet() {
1422
+ return this.outlets.toArray()[this.tabs.selectedIndex];
1330
1423
  }
1331
1424
  }
1332
1425
  ActivityContainerComponent.decorators = [
1333
1426
  { type: Component, args: [{
1334
1427
  selector: 'angular-ui-powerups-activity-container',
1335
- template: "<mat-tab-group #tabs no-tab-header [dynamicHeight]=\"true\">\n <mat-tab>\n <angular-ui-powerups-activity-outlet [interactionContext]=\"this\"\n [activityContext]=\"initialActivityOutletContext\"></angular-ui-powerups-activity-outlet>\n </mat-tab>\n <mat-tab *ngFor=\"let tab of activityOutletTabs.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",
1428
+ 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",
1336
1429
  styles: [":host{display:block}"]
1337
1430
  }] }
1338
1431
  ];
@@ -1345,23 +1438,19 @@ ActivityContainerComponent.propDecorators = {
1345
1438
  outlets: [{ type: ViewChildren, args: [ActivityOutletComponent,] }]
1346
1439
  };
1347
1440
  if (false) {
1441
+ /**
1442
+ * @type {?}
1443
+ * @private
1444
+ */
1445
+ ActivityContainerComponent.prototype.activityFinishedEvents;
1348
1446
  /** @type {?} */
1349
1447
  ActivityContainerComponent.prototype.parentInteractionContext;
1350
1448
  /** @type {?} */
1351
- ActivityContainerComponent.prototype.initialActivityOutletContext;
1352
- /** @type {?} */
1353
- ActivityContainerComponent.prototype.currentActivity;
1354
- /** @type {?} */
1355
1449
  ActivityContainerComponent.prototype.tabs;
1356
1450
  /** @type {?} */
1357
1451
  ActivityContainerComponent.prototype.outlets;
1358
1452
  /** @type {?} */
1359
- ActivityContainerComponent.prototype.activityOutletTabs;
1360
- /**
1361
- * @type {?}
1362
- * @private
1363
- */
1364
- ActivityContainerComponent.prototype.obsoleteTabs;
1453
+ ActivityContainerComponent.prototype.activityTabs;
1365
1454
  /**
1366
1455
  * @type {?}
1367
1456
  * @private
@@ -1373,24 +1462,6 @@ if (false) {
1373
1462
  */
1374
1463
  ActivityContainerComponent.prototype._activityList;
1375
1464
  }
1376
- (function (ActivityContainerComponent) {
1377
- /**
1378
- * @record
1379
- * @template D, R, E
1380
- */
1381
- function ActivityContext() { }
1382
- ActivityContainerComponent.ActivityContext = ActivityContext;
1383
- if (false) {
1384
- /** @type {?} */
1385
- ActivityContext.prototype.activityClass;
1386
- /** @type {?} */
1387
- ActivityContext.prototype.activityData;
1388
- /** @type {?} */
1389
- ActivityContext.prototype.onDone;
1390
- /** @type {?} */
1391
- ActivityContext.prototype.onCancel;
1392
- }
1393
- })(ActivityContainerComponent || (ActivityContainerComponent = {}));
1394
1465
 
1395
1466
  /**
1396
1467
  * @fileoverview added by tsickle
@@ -1398,52 +1469,66 @@ if (false) {
1398
1469
  */
1399
1470
  /** @type {?} */
1400
1471
  const DIALOG_INTERACTION_SERVICE_DEFAULTS = new InjectionToken('DIALOG_INTERACTION_SERVICE_DEFAULTS');
1472
+ class Guard extends ValueModel {
1473
+ constructor() {
1474
+ super({ initialValue: false });
1475
+ }
1476
+ /**
1477
+ * @return {?}
1478
+ */
1479
+ get value() {
1480
+ return this.store.read();
1481
+ }
1482
+ /**
1483
+ * @template R
1484
+ * @param {?} fun
1485
+ * @return {?}
1486
+ */
1487
+ whileTrue(fun) {
1488
+ this.startTransaction().commit(true);
1489
+ try {
1490
+ return fun();
1491
+ }
1492
+ finally {
1493
+ this.startTransaction().commit(false);
1494
+ }
1495
+ }
1496
+ /**
1497
+ * @template R
1498
+ * @param {?} fun
1499
+ * @param {?=} defaultValue
1500
+ * @return {?}
1501
+ */
1502
+ runIfFalse(fun, defaultValue = null) {
1503
+ return !this.value ? fun() : defaultValue;
1504
+ }
1505
+ }
1401
1506
  class DialogInteractionService extends InteractionContext {
1402
1507
  /**
1403
1508
  * @param {?} dialogService
1404
- * @param {?} router
1405
1509
  * @param {?} dialogServiceDefaults
1406
1510
  * @param {?} matDialogDefaultConfig
1407
1511
  */
1408
- constructor(dialogService, router, dialogServiceDefaults, matDialogDefaultConfig) {
1512
+ constructor(dialogService, dialogServiceDefaults, matDialogDefaultConfig) {
1409
1513
  super();
1410
1514
  this.dialogService = dialogService;
1411
- this.router = router;
1412
1515
  this.dialogServiceDefaults = dialogServiceDefaults;
1413
1516
  this.matDialogDefaultConfig = matDialogDefaultConfig;
1414
1517
  this._activityList = new DelegatingListModel();
1415
- this._active = false;
1518
+ this.startingGuard = new Guard();
1416
1519
  assert$1.notNil(dialogService);
1417
- const { chain, observe } = Dsl.disposeWith(this);
1418
- this.currentActivity = chain(this.activityList).last();
1419
- // observe.valuesFrom(this.router.events)
1420
- // .tap((event:RouterEvent) => {
1421
- // const nav = router.getCurrentNavigation();
1422
- // console.log({
1423
- // previousUrl: nav.previousNavigation && nav.previousNavigation.finalUrl,
1424
- // initialUrl: nav.initialUrl,
1425
- // finalUrl: nav.finalUrl,
1426
- // });
1427
- //
1428
- // })
1429
- // .filter(event => event instanceof NavigationStart)
1430
- // .subscribe((event: NavigationStart) => {
1431
- // console.log(event.navigationTrigger);
1432
- // if (event.navigationTrigger === 'popstate' && this.isActive()) {
1433
- // const prev = router.getCurrentNavigation().previousNavigation.finalUrl;
1434
- // // this.router.navigateByUrl(prev.toString(), {
1435
- // // replaceUrl: true,
1436
- // // skipLocationChange: false
1437
- // // });
1438
- // // this.cancelActivity();
1439
- // }
1440
- // });
1520
+ }
1521
+ /**
1522
+ * @return {?}
1523
+ */
1524
+ isActive() {
1525
+ return !!this.currentActivityId;
1441
1526
  }
1442
1527
  /**
1443
1528
  * @return {?}
1444
1529
  */
1445
1530
  cancelActivity() {
1446
- this.currentActivity.value.cancel(null);
1531
+ this.currentActivity.cancel(null);
1447
1532
  }
1448
1533
  /**
1449
1534
  * @return {?}
@@ -1476,56 +1561,59 @@ class DialogInteractionService extends InteractionContext {
1476
1561
  */
1477
1562
  a => a.constructor.name)).join(', ')}`);
1478
1563
  }
1479
- this._active = true;
1480
- /** @type {?} */
1481
- const self = this;
1482
- /** @type {?} */
1483
- const config = Object.assign({ autoFocus: false, hasBackdrop: true, closeOnNavigation: false }, this.matDialogDefaultConfig, this.dialogServiceDefaults, {
1484
- data,
1485
- disableClose,
1486
- panelClass: 'dialog-interaction-service'
1487
- });
1488
- /** @type {?} */
1489
- const matDialogRef = (/** @type {?} */ (this.dialogService.open(ActivityContainerComponent, config)));
1490
- return new Promise((/**
1491
- * @param {?} resolve
1492
- * @param {?} reject
1564
+ return this.startingGuard.whileTrue((/**
1493
1565
  * @return {?}
1494
1566
  */
1495
- (resolve, reject) => {
1567
+ () => {
1568
+ this.currentActivityId = v1();
1496
1569
  /** @type {?} */
1497
- const activityContainer = matDialogRef.componentInstance;
1498
- activityContainer.parentInteractionContext = this;
1499
- self.safelyUpdateActivityListDelegate(activityContainer.activityList);
1500
- activityContainer.initialise({
1501
- activityClass: activityType,
1502
- activityData: data,
1503
- /**
1504
- * @param {?} result
1505
- * @return {?}
1506
- */
1507
- onDone(result) {
1508
- // TODO: should I be calling resolve after close?
1509
- resolve(result);
1510
- matDialogRef.close(result);
1511
- },
1512
- /**
1513
- * @param {?} error
1514
- * @return {?}
1515
- */
1516
- onCancel(error) {
1517
- // TODO: should I be calling reject after close?
1518
- reject(error);
1519
- matDialogRef.close(error);
1520
- }
1570
+ const self = this;
1571
+ /** @type {?} */
1572
+ const config = Object.assign({ autoFocus: false, hasBackdrop: true, closeOnNavigation: false }, this.matDialogDefaultConfig, this.dialogServiceDefaults, {
1573
+ data,
1574
+ disableClose,
1575
+ panelClass: 'dialog-interaction-service'
1521
1576
  });
1522
- matDialogRef.updateSize();
1523
- })).finally((/**
1524
- * @return {?}
1525
- */
1526
- () => {
1527
- self.safelyUpdateActivityListDelegate(null);
1528
- self._active = false;
1577
+ /** @type {?} */
1578
+ const matDialogRef = (/** @type {?} */ (this.dialogService.open(ActivityContainerComponent, config)));
1579
+ return new Promise((/**
1580
+ * @param {?} resolve
1581
+ * @param {?} reject
1582
+ * @return {?}
1583
+ */
1584
+ (resolve, reject) => {
1585
+ /** @type {?} */
1586
+ const activityContainer = matDialogRef.componentInstance;
1587
+ activityContainer.parentInteractionContext = this;
1588
+ self.safelyUpdateActivityListDelegate(activityContainer.activityList);
1589
+ activityContainer.initialActivityOutletContext = {
1590
+ activityClass: activityType,
1591
+ activityData: data,
1592
+ /**
1593
+ * @param {?} result
1594
+ * @return {?}
1595
+ */
1596
+ onDone(result) {
1597
+ resolve(result);
1598
+ matDialogRef.close(result);
1599
+ },
1600
+ /**
1601
+ * @param {?} error
1602
+ * @return {?}
1603
+ */
1604
+ onCancel(error) {
1605
+ reject(error);
1606
+ matDialogRef.close(error);
1607
+ }
1608
+ };
1609
+ matDialogRef.updateSize();
1610
+ })).finally((/**
1611
+ * @return {?}
1612
+ */
1613
+ () => {
1614
+ this.currentActivityId = null;
1615
+ self.safelyUpdateActivityListDelegate(null);
1616
+ }));
1529
1617
  }));
1530
1618
  }
1531
1619
  /**
@@ -1576,14 +1664,11 @@ DialogInteractionService.decorators = [
1576
1664
  /** @nocollapse */
1577
1665
  DialogInteractionService.ctorParameters = () => [
1578
1666
  { type: MatDialog },
1579
- { type: Router },
1580
1667
  { type: MatDialogConfig, decorators: [{ type: Optional }, { type: Inject, args: [DIALOG_INTERACTION_SERVICE_DEFAULTS,] }] },
1581
1668
  { type: MatDialogConfig, decorators: [{ type: Optional }, { type: Inject, args: [MAT_DIALOG_DEFAULT_OPTIONS,] }] }
1582
1669
  ];
1583
- /** @nocollapse */ DialogInteractionService.ngInjectableDef = ɵɵdefineInjectable({ factory: function DialogInteractionService_Factory() { return new DialogInteractionService(ɵɵinject(MatDialog$1), ɵɵinject(Router), ɵɵinject(DIALOG_INTERACTION_SERVICE_DEFAULTS, 8), ɵɵinject(MAT_DIALOG_DEFAULT_OPTIONS, 8)); }, token: DialogInteractionService, providedIn: "root" });
1670
+ /** @nocollapse */ DialogInteractionService.ngInjectableDef = ɵɵdefineInjectable({ factory: function DialogInteractionService_Factory() { return new DialogInteractionService(ɵɵinject(MatDialog$1), ɵɵinject(DIALOG_INTERACTION_SERVICE_DEFAULTS, 8), ɵɵinject(MAT_DIALOG_DEFAULT_OPTIONS, 8)); }, token: DialogInteractionService, providedIn: "root" });
1584
1671
  if (false) {
1585
- /** @type {?} */
1586
- DialogInteractionService.prototype.currentActivity;
1587
1672
  /**
1588
1673
  * @type {?}
1589
1674
  * @private
@@ -1593,17 +1678,17 @@ if (false) {
1593
1678
  * @type {?}
1594
1679
  * @private
1595
1680
  */
1596
- DialogInteractionService.prototype._active;
1681
+ DialogInteractionService.prototype.startingGuard;
1597
1682
  /**
1598
1683
  * @type {?}
1599
1684
  * @private
1600
1685
  */
1601
- DialogInteractionService.prototype.dialogService;
1686
+ DialogInteractionService.prototype.currentActivityId;
1602
1687
  /**
1603
1688
  * @type {?}
1604
1689
  * @private
1605
1690
  */
1606
- DialogInteractionService.prototype.router;
1691
+ DialogInteractionService.prototype.dialogService;
1607
1692
  /** @type {?} */
1608
1693
  DialogInteractionService.prototype.dialogServiceDefaults;
1609
1694
  /** @type {?} */
@@ -2117,12 +2202,85 @@ if (false) {
2117
2202
  * @fileoverview added by tsickle
2118
2203
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2119
2204
  */
2205
+ class NavigationSession {
2206
+ /**
2207
+ * @param {?} isPopState
2208
+ * @param {?} initialUrl
2209
+ */
2210
+ constructor(isPopState, initialUrl) {
2211
+ this.isPopState = isPopState;
2212
+ this.initialUrl = initialUrl;
2213
+ this._alreadyAccepted = [];
2214
+ console.log('NavigationSession', { isPopState, initialUrl });
2215
+ }
2216
+ /**
2217
+ * @param {?} placeComponent
2218
+ * @return {?}
2219
+ */
2220
+ alreadyAccepted(placeComponent) {
2221
+ return this._alreadyAccepted.includes(placeComponent);
2222
+ }
2223
+ /**
2224
+ * @param {?} component
2225
+ * @return {?}
2226
+ */
2227
+ rememberAcceptanceOf(component) {
2228
+ this._alreadyAccepted.push(component);
2229
+ }
2230
+ }
2231
+ if (false) {
2232
+ /**
2233
+ * @type {?}
2234
+ * @private
2235
+ */
2236
+ NavigationSession.prototype._alreadyAccepted;
2237
+ /** @type {?} */
2238
+ NavigationSession.prototype.isPopState;
2239
+ /** @type {?} */
2240
+ NavigationSession.prototype.initialUrl;
2241
+ }
2120
2242
  class PlaceRouter {
2121
2243
  /**
2122
2244
  * @param {?} router
2245
+ * @param {?} angularLocation
2123
2246
  */
2124
- constructor(router) {
2247
+ constructor(router, angularLocation) {
2125
2248
  this.router = router;
2249
+ this._navigationSession = new MutableValueModel();
2250
+ angularLocation.onUrlChange((/**
2251
+ * @param {?} url
2252
+ * @return {?}
2253
+ */
2254
+ url => {
2255
+ console.log(`### ${url}`);
2256
+ }));
2257
+ this.router.events.subscribe((/**
2258
+ * @param {?} event
2259
+ * @return {?}
2260
+ */
2261
+ event => {
2262
+ // console.log(`${event.constructor.name}`, location.pathname, angularLocation.getState());
2263
+ // NavigationStart -> .... -> NavigationCancel === redirect (so don't ask again)
2264
+ // NavigationStart -> .... -> NavigationEnd === navigated (so ask next time)
2265
+ // NavigationStart -> .... -> NavigationError === canceled (guard cancelled so ask next time)
2266
+ if (event instanceof NavigationStart && !this.navigationSession) {
2267
+ this._navigationSession.value = new NavigationSession(event.navigationTrigger === 'popstate', this.router.routerState.snapshot.url);
2268
+ }
2269
+ if (event instanceof NavigationEnd) {
2270
+ console.log('navigation ended');
2271
+ this._navigationSession.value = null;
2272
+ }
2273
+ if (event instanceof NavigationError) {
2274
+ console.log('navigation errored');
2275
+ this._navigationSession.value = null;
2276
+ }
2277
+ }));
2278
+ }
2279
+ /**
2280
+ * @return {?}
2281
+ */
2282
+ get navigationSession() {
2283
+ return this._navigationSession.value;
2126
2284
  }
2127
2285
  /**
2128
2286
  * @param {?} activatedRoute
@@ -2152,7 +2310,6 @@ class PlaceRouter {
2152
2310
  const commands = (weHaveARouteId) ?
2153
2311
  [urlSegments[0].path, sanitised.getFormattedRouteId(), sanitised.getFormattedParameters()] :
2154
2312
  [urlSegments[0].path, sanitised.getFormattedParameters()];
2155
- console.log("redirect path", commands);
2156
2313
  return this.router.createUrlTree(commands);
2157
2314
  }
2158
2315
  /**
@@ -2187,10 +2344,16 @@ PlaceRouter.decorators = [
2187
2344
  ];
2188
2345
  /** @nocollapse */
2189
2346
  PlaceRouter.ctorParameters = () => [
2190
- { type: Router }
2347
+ { type: Router },
2348
+ { type: Location }
2191
2349
  ];
2192
- /** @nocollapse */ PlaceRouter.ngInjectableDef = ɵɵdefineInjectable({ factory: function PlaceRouter_Factory() { return new PlaceRouter(ɵɵinject(Router)); }, token: PlaceRouter, providedIn: "root" });
2350
+ /** @nocollapse */ PlaceRouter.ngInjectableDef = ɵɵdefineInjectable({ factory: function PlaceRouter_Factory() { return new PlaceRouter(ɵɵinject(Router), ɵɵinject(Location)); }, token: PlaceRouter, providedIn: "root" });
2193
2351
  if (false) {
2352
+ /**
2353
+ * @type {?}
2354
+ * @private
2355
+ */
2356
+ PlaceRouter.prototype._navigationSession;
2194
2357
  /**
2195
2358
  * @type {?}
2196
2359
  * @private
@@ -3071,8 +3234,8 @@ class PlaceOutletComponent extends DisposableComponent {
3071
3234
  this.placeHistory = placeHistory;
3072
3235
  this.animate = true;
3073
3236
  this._activePlace = new MutableValueModel();
3074
- this._incomingRouteChange = new Guard();
3075
- this._inOutletUpdate = new Guard();
3237
+ this._incomingRouteChange = new Guard$1();
3238
+ this._inOutletUpdate = new Guard$1();
3076
3239
  this._activatedRouteModel = new MutableValueModel();
3077
3240
  this._placeDefinition = new MutableValueModel();
3078
3241
  this._resolvedParameters = new MutableValueModel();
@@ -3695,16 +3858,15 @@ function Result() { }
3695
3858
  */
3696
3859
  function ActivityOutletContext() { }
3697
3860
  if (false) {
3698
- /** @type {?} */
3699
- ActivityOutletContext.prototype.interactionContext;
3700
3861
  /** @type {?} */
3701
3862
  ActivityOutletContext.prototype.activityClass;
3702
3863
  /** @type {?} */
3703
3864
  ActivityOutletContext.prototype.activityData;
3704
- /** @type {?} */
3705
- ActivityOutletContext.prototype.onDone;
3706
- /** @type {?} */
3707
- ActivityOutletContext.prototype.onCancel;
3865
+ /**
3866
+ * @param {?} component
3867
+ * @return {?}
3868
+ */
3869
+ ActivityOutletContext.prototype.componentReady = function (component) { };
3708
3870
  }
3709
3871
 
3710
3872
  /**
@@ -3867,36 +4029,16 @@ class LeavePlaceGuard {
3867
4029
  /**
3868
4030
  * @param {?} router
3869
4031
  * @param {?} injector
4032
+ * @param {?} placeRouter
3870
4033
  * @param {?} interactionContext
3871
- * @param {?} location
4034
+ * @param {?} angularLocation
3872
4035
  */
3873
- constructor(router, injector, interactionContext, location) {
4036
+ constructor(router, injector, placeRouter, interactionContext, angularLocation) {
3874
4037
  this.router = router;
3875
4038
  this.injector = injector;
4039
+ this.placeRouter = placeRouter;
3876
4040
  this.interactionContext = interactionContext;
3877
- this.location = location;
3878
- // TODO: should probably replace this with a RouteTracker thingy.
3879
- this._alreadyAccepted = [];
3880
- console.log('***** Created new guard ******');
3881
- /** @type {?} */
3882
- const self = this;
3883
- this.router.events.subscribe((/**
3884
- * @param {?} event
3885
- * @return {?}
3886
- */
3887
- event => {
3888
- // NavigationStart -> .... -> NavigationCancel === redirect (so don't ask again)
3889
- // NavigationStart -> .... -> NavigationEnd === navigated (so ask next time)
3890
- // NavigationStart -> .... -> NavigationError === canceled (guard cancelled so ask next time)
3891
- if (event instanceof NavigationEnd) {
3892
- console.log("navigation ended");
3893
- self._alreadyAccepted = [];
3894
- }
3895
- if (event instanceof NavigationError) {
3896
- console.log("navigation errored");
3897
- self._alreadyAccepted = [];
3898
- }
3899
- }));
4041
+ this.angularLocation = angularLocation;
3900
4042
  }
3901
4043
  /**
3902
4044
  * @param {?} component
@@ -3906,84 +4048,89 @@ class LeavePlaceGuard {
3906
4048
  * @return {?}
3907
4049
  */
3908
4050
  canDeactivate(component, currentRoute, currentState, nextState) {
3909
- /** @type {?} */
3910
- const placeDefinitionPath = `/${component.placeDefinition.path}`;
3911
- console.log('canDeactivate', {
3912
- staticPath: placeDefinitionPath,
3913
- currentStateUrl: currentState.url,
3914
- nextStateUrl: nextState.url,
3915
- alreadyDeclined: this._alreadyAccepted
3916
- });
3917
- // Example of the above when navigating to a different child route.
3918
- // canDeactivate {staticPath: "/hero-details",
3919
- // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-details",
3920
- // nextStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats"
3921
- // }
3922
- // Example clicking on router tab of the parent component (de-activates the parent due to route param changes)
3923
- // canDeactivate {
3924
- // staticPath: "/hero-stats",
3925
- // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
3926
- // nextStateUrl: "/route-parameters/"
3927
- // }
3928
- // canDeactivate {
3929
- // staticPath: "/route-parameters",
3930
- // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
3931
- // nextStateUrl: "/route-parameters/"
3932
- // }
3933
- // logger.class.js:54 ParameterSnapshot.sanitise -> {idModel: -1, pv: undefined, pl: Array(0), dv: undefined, dl: Array(0), …}
3934
- // parameter-snapshot.ts:20 {name: "idModel", mine: -1, theirs: null}
3935
- // place-router.ts:28 redirect path (3) ["route-parameters", "-1", {…}]
3936
- // canDeactivate {
3937
- // staticPath: "/hero-stats",
3938
- // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
3939
- // nextStateUrl: "/route-parameters/-1"
3940
- // }
3941
- // canDeactivate {
3942
- // staticPath: "/route-parameters",
3943
- // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
3944
- // nextStateUrl: "/route-parameters/-1"
3945
- // }
3946
- // logger.class.js:54 ParameterSnapshot.sanitise -> {idModel: -1, pv: undefined, pl: Array(0), dv: "A", dl: Array(3), …}
3947
- // parameter-snapshot.ts:20 {name: "dv", mine: "A", theirs: undefined}
3948
- // place-router.ts:28 redirect path (3) ["route-parameters", "-1", {…}]
3949
- // canDeactivate {
3950
- // staticPath: "/hero-stats",
3951
- // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
3952
- // nextStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c"
3953
- // }
3954
- // HACK: this will break with child routes...
3955
- if (this.alreadyAccepted(component)) {
3956
- return true;
3957
- }
3958
- else {
3959
- if (!nextState.url.startsWith(placeDefinitionPath)) {
3960
- /** @type {?} */
3961
- const self = this;
3962
- return Promise.resolve(component.canDeactivate()).then((/**
3963
- * @param {?} canLeave
3964
- * @return {?}
3965
- */
3966
- canLeave => {
3967
- if (!canLeave) {
3968
- // Angular doesn't preserve the url when a guard cancels the back button.
3969
- // See https://github.com/angular/angular/issues/13586#issuecomment-432795720
3970
- this.location.go(currentState.url);
4051
+ return __awaiter(this, void 0, void 0, function* () {
4052
+ /** @type {?} */
4053
+ const placeDefinitionPath = `/${component.placeDefinition.path}`;
4054
+ // console.log('canDeactivate', {
4055
+ // staticPath: placeDefinitionPath,
4056
+ // currentStateUrl: currentState.url,
4057
+ // nextStateUrl: nextState.url
4058
+ // // alreadyDeclined: this._alreadyAccepted
4059
+ // });
4060
+ // Example of the above when navigating to a different child route.
4061
+ // canDeactivate {staticPath: "/hero-details",
4062
+ // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-details",
4063
+ // nextStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats"
4064
+ // }
4065
+ // Example clicking on router tab of the parent component (de-activates the parent due to route param changes)
4066
+ // canDeactivate {
4067
+ // staticPath: "/hero-stats",
4068
+ // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
4069
+ // nextStateUrl: "/route-parameters/"
4070
+ // }
4071
+ // canDeactivate {
4072
+ // staticPath: "/route-parameters",
4073
+ // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
4074
+ // nextStateUrl: "/route-parameters/"
4075
+ // }
4076
+ // logger.class.js:54 ParameterSnapshot.sanitise -> {idModel: -1, pv: undefined, pl: Array(0), dv: undefined, dl: Array(0), …}
4077
+ // parameter-snapshot.ts:20 {name: "idModel", mine: -1, theirs: null}
4078
+ // place-router.ts:28 redirect path (3) ["route-parameters", "-1", {…}]
4079
+ // canDeactivate {
4080
+ // staticPath: "/hero-stats",
4081
+ // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
4082
+ // nextStateUrl: "/route-parameters/-1"
4083
+ // }
4084
+ // canDeactivate {
4085
+ // staticPath: "/route-parameters",
4086
+ // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
4087
+ // nextStateUrl: "/route-parameters/-1"
4088
+ // }
4089
+ // logger.class.js:54 ParameterSnapshot.sanitise -> {idModel: -1, pv: undefined, pl: Array(0), dv: "A", dl: Array(3), …}
4090
+ // parameter-snapshot.ts:20 {name: "dv", mine: "A", theirs: undefined}
4091
+ // place-router.ts:28 redirect path (3) ["route-parameters", "-1", {…}]
4092
+ // canDeactivate {
4093
+ // staticPath: "/hero-stats",
4094
+ // currentStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c/hero-stats",
4095
+ // nextStateUrl: "/route-parameters/-1;dv=A;dl=a,b,c;rdv=A;rdl=a,b,c"
4096
+ // }
4097
+ if (this.placeRouter.navigationSession.alreadyAccepted(component)) {
4098
+ return true;
4099
+ }
4100
+ else {
4101
+ // TODO: this will break with child routes... need to examine the router states properly.
4102
+ if (!nextState.url.startsWith(placeDefinitionPath)) {
4103
+ /** @type {?} */
4104
+ const self = this;
4105
+ /** @type {?} */
4106
+ let canLeave = yield component.canDeactivate();
4107
+ // component is happy to leave but we need to check if it's left an interaction
4108
+ // open. If so we close and stay where we are.
4109
+ if (canLeave && this.interactionContext.isActive()) {
4110
+ canLeave = false;
4111
+ console.log("cancelling", { activity: this.interactionContext.currentActivity });
4112
+ this.interactionContext.currentActivity.cancel(null);
4113
+ }
4114
+ // If we're still leaving then remember it since angular will call this method multiple
4115
+ // times if any route parameters are changed along the way.
4116
+ if (canLeave) {
4117
+ self.placeRouter.navigationSession.rememberAcceptanceOf(component);
3971
4118
  }
3972
4119
  else {
3973
- self._alreadyAccepted.push(component);
4120
+ // Angular doesn't preserve the url when a guard cancels the back button.
4121
+ // See https://github.com/angular/angular/issues/13586#issuecomment-432795720
4122
+ if (this.placeRouter.navigationSession.isPopState) {
4123
+ console.log('cancelled during popstate');
4124
+ this.angularLocation.go(this.placeRouter.navigationSession.initialUrl);
4125
+ }
3974
4126
  }
3975
4127
  return canLeave;
3976
- }));
4128
+ }
4129
+ else {
4130
+ return true;
4131
+ }
3977
4132
  }
3978
- return true;
3979
- }
3980
- }
3981
- /**
3982
- * @param {?} placeComponent
3983
- * @return {?}
3984
- */
3985
- alreadyAccepted(placeComponent) {
3986
- return this._alreadyAccepted.includes(placeComponent);
4133
+ });
3987
4134
  }
3988
4135
  }
3989
4136
  LeavePlaceGuard.decorators = [
@@ -3995,36 +4142,31 @@ LeavePlaceGuard.decorators = [
3995
4142
  LeavePlaceGuard.ctorParameters = () => [
3996
4143
  { type: Router },
3997
4144
  { type: Injector },
4145
+ { type: PlaceRouter },
3998
4146
  { type: InteractionContext },
3999
4147
  { type: Location }
4000
4148
  ];
4001
- /** @nocollapse */ LeavePlaceGuard.ngInjectableDef = ɵɵdefineInjectable({ factory: function LeavePlaceGuard_Factory() { return new LeavePlaceGuard(ɵɵinject(Router), ɵɵinject(INJECTOR), ɵɵinject(InteractionContext), ɵɵinject(Location)); }, token: LeavePlaceGuard, providedIn: "root" });
4002
- __decorate([
4003
- Trace(),
4004
- __metadata("design:type", Function),
4005
- __metadata("design:paramtypes", [PlaceComponent]),
4006
- __metadata("design:returntype", Boolean)
4007
- ], LeavePlaceGuard.prototype, "alreadyAccepted", null);
4149
+ /** @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" });
4008
4150
  if (false) {
4009
4151
  /**
4010
4152
  * @type {?}
4011
4153
  * @private
4012
4154
  */
4013
- LeavePlaceGuard.prototype._alreadyAccepted;
4155
+ LeavePlaceGuard.prototype.router;
4014
4156
  /**
4015
4157
  * @type {?}
4016
4158
  * @private
4017
4159
  */
4018
- LeavePlaceGuard.prototype.router;
4160
+ LeavePlaceGuard.prototype.injector;
4019
4161
  /**
4020
4162
  * @type {?}
4021
4163
  * @private
4022
4164
  */
4023
- LeavePlaceGuard.prototype.injector;
4165
+ LeavePlaceGuard.prototype.placeRouter;
4024
4166
  /** @type {?} */
4025
4167
  LeavePlaceGuard.prototype.interactionContext;
4026
4168
  /** @type {?} */
4027
- LeavePlaceGuard.prototype.location;
4169
+ LeavePlaceGuard.prototype.angularLocation;
4028
4170
  }
4029
4171
 
4030
4172
  /**
@@ -4297,5 +4439,5 @@ var ParameterType;
4297
4439
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
4298
4440
  */
4299
4441
 
4300
- export { ACTIVITY_DATA, AbstractActivity, AbstractInputComponent, AbstractPlaceNavigationComponent, ActivityContainerComponent, ActivityOutletComponent, AlertDialogComponent, AngularUiPowerupsModule, Bounds, BusyOverlayComponent, CloseInteractionGuard, CommandDirective, ConfirmThenDialogComponent, ConfirmationDialogComponent, DEFINITION_META_DATA_KEY, DIALOG_INTERACTION_SERVICE_DEFAULTS, DialogInteractionService, Dimension, DisposableComponent, EmptyStateComponent, FocusBindingDirective, InteractionContext, InteractionModule, LEFT_RIGHT_PLACE_ANIMATION, LeavePlaceGuard, ListPlaceNavComponent, NumberInputComponent, ParameterDefinition, ParameterSnapshot, ParameterType, PasswordInputComponent, Place, PlaceComponent, PlaceDefinition, PlaceHistory, PlaceModule, PlaceOutletComponent, PlaceRouteGuard, PlaceRouter, Point, ROUTE_PARAMETER_LIST_KEY, ResizeAwareComponent, RouteId, RouteParameter, RouteParameterList, RouteParameterValue, SelectInputComponent, StringInputComponent, TabbedPlaceNavigationComponent, leftRightPlaceAnimation, slideDownAndUpAnimation, CommandDirective as ɵa, FocusBindingDirective as ɵb, ConfirmThenDialogComponent as ɵba, InteractionContext as ɵbb, AlertDialogComponent as ɵbc, DIALOG_INTERACTION_SERVICE_DEFAULTS as ɵbe, DialogInteractionService as ɵbf, DisposableComponent as ɵc, NumberInputComponent as ɵd, AbstractInputComponent as ɵe, StringInputComponent as ɵf, PasswordInputComponent as ɵg, SelectInputComponent as ɵh, PlaceModule as ɵi, EmptyStateComponent as ɵj, BusyOverlayComponent as ɵk, PlaceOutletComponent as ɵl, leftRightPlaceAnimation as ɵm, LEFT_RIGHT_PLACE_ANIMATION as ɵn, PlaceRouter as ɵo, PlaceHistory as ɵp, TabbedPlaceNavigationComponent as ɵq, AbstractPlaceNavigationComponent as ɵr, ListPlaceNavComponent as ɵs, InteractionModule as ɵt, ActivityContainerComponent as ɵu, ActivityOutletComponent as ɵv, ConfirmationDialogComponent as ɵw, AbstractActivity as ɵx, ACTIVITY_DATA as ɵy };
4442
+ export { ACTIVITY_DATA, AbstractActivity, AbstractInputComponent, AbstractPlaceNavigationComponent, Activity, ActivityContainerComponent, ActivityOutletComponent, AlertDialogComponent, AngularUiPowerupsModule, Bounds, BusyOverlayComponent, CloseInteractionGuard, CommandDirective, ConfirmThenDialogComponent, ConfirmationDialogComponent, DEFINITION_META_DATA_KEY, DIALOG_INTERACTION_SERVICE_DEFAULTS, DialogInteractionService, Dimension, DisposableComponent, EmptyStateComponent, FocusBindingDirective, InteractionContext, InteractionModule, LEFT_RIGHT_PLACE_ANIMATION, LeavePlaceGuard, ListPlaceNavComponent, NumberInputComponent, ParameterDefinition, ParameterSnapshot, ParameterType, PasswordInputComponent, Place, PlaceComponent, PlaceDefinition, PlaceHistory, PlaceModule, PlaceOutletComponent, PlaceRouteGuard, PlaceRouter, Point, ROUTE_PARAMETER_LIST_KEY, ResizeAwareComponent, RouteId, RouteParameter, RouteParameterList, RouteParameterValue, SelectInputComponent, StringInputComponent, TabbedPlaceNavigationComponent, leftRightPlaceAnimation, slideDownAndUpAnimation, CommandDirective as ɵa, FocusBindingDirective as ɵb, Activity as ɵba, ConfirmThenDialogComponent as ɵbc, AlertDialogComponent as ɵbd, DIALOG_INTERACTION_SERVICE_DEFAULTS as ɵbf, DialogInteractionService as ɵbg, DisposableComponent as ɵc, NumberInputComponent as ɵd, AbstractInputComponent as ɵe, StringInputComponent as ɵf, PasswordInputComponent as ɵg, SelectInputComponent as ɵh, PlaceModule as ɵi, EmptyStateComponent as ɵj, BusyOverlayComponent as ɵk, PlaceOutletComponent as ɵl, leftRightPlaceAnimation as ɵm, LEFT_RIGHT_PLACE_ANIMATION as ɵn, PlaceRouter as ɵo, PlaceHistory as ɵp, TabbedPlaceNavigationComponent as ɵq, AbstractPlaceNavigationComponent as ɵr, ListPlaceNavComponent as ɵs, InteractionModule as ɵt, ActivityContainerComponent as ɵu, InteractionContext as ɵv, ActivityOutletComponent as ɵw, ConfirmationDialogComponent as ɵx, AbstractActivity as ɵy, ACTIVITY_DATA as ɵz };
4301
4443
  //# sourceMappingURL=coolon-angular-ui-powerups.js.map