@coolon/angular-ui-powerups 0.0.24 → 0.0.25

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 (286) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/jest.config.js +9 -0
  3. package/ng-package.json +13 -0
  4. package/package.json +12 -14
  5. package/schematics/ng-add/index.ts +10 -0
  6. package/schematics/place-routes/index.ts +152 -0
  7. package/schematics/place-routes/place-def.ts +93 -0
  8. package/schematics/place-routes/scanner.ts +145 -0
  9. package/schematics/place-routes/schema.ts +7 -0
  10. package/src/lib/angular-ui-powerups.module.spec.ts +14 -0
  11. package/src/lib/angular-ui-powerups.module.ts +49 -0
  12. package/{lib/animations/index.d.ts → src/lib/animations/index.ts} +1 -0
  13. package/src/lib/animations/slideDownAndUpAnimation.ts +39 -0
  14. package/src/lib/components/disposable-component.ts +9 -0
  15. package/src/lib/components/forms/abstract-input.component.ts +108 -0
  16. package/src/lib/components/forms/number-input/number-input.component.html +15 -0
  17. package/src/lib/components/forms/number-input/number-input.component.scss +3 -0
  18. package/src/lib/components/forms/number-input/number-input.component.spec.ts +25 -0
  19. package/src/lib/components/forms/number-input/number-input.component.ts +19 -0
  20. package/src/lib/components/forms/password-input/password-input.component.html +16 -0
  21. package/src/lib/components/forms/password-input/password-input.component.scss +3 -0
  22. package/src/lib/components/forms/password-input/password-input.component.spec.ts +25 -0
  23. package/src/lib/components/forms/password-input/password-input.component.ts +18 -0
  24. package/src/lib/components/forms/scss/mixins.scss +16 -0
  25. package/src/lib/components/forms/select-input/select-input.component.html +16 -0
  26. package/src/lib/components/forms/select-input/select-input.component.scss +7 -0
  27. package/src/lib/components/forms/select-input/select-input.component.spec.ts +25 -0
  28. package/src/lib/components/forms/select-input/select-input.component.ts +31 -0
  29. package/src/lib/components/forms/string-input/string-input.component.html +15 -0
  30. package/src/lib/components/forms/string-input/string-input.component.scss +3 -0
  31. package/src/lib/components/forms/string-input/string-input.component.spec.ts +25 -0
  32. package/src/lib/components/forms/string-input/string-input.component.ts +18 -0
  33. package/{lib/components/index.d.ts → src/lib/components/index.ts} +1 -0
  34. package/src/lib/components/resize-aware.component.ts +52 -0
  35. package/src/lib/components/types/bounds.class.ts +25 -0
  36. package/src/lib/components/types/dimension.class.ts +3 -0
  37. package/src/lib/components/types/point.class.ts +13 -0
  38. package/src/lib/directives/command.directive.spec.ts +73 -0
  39. package/src/lib/directives/command.directive.ts +81 -0
  40. package/src/lib/directives/focus-binding.directive.spec.ts +8 -0
  41. package/src/lib/directives/focus-binding.directive.ts +108 -0
  42. package/{lib/directives/index.d.ts → src/lib/directives/index.ts} +1 -0
  43. package/src/lib/interaction/abstract-activity.ts +57 -0
  44. package/src/lib/interaction/activity.ts +17 -0
  45. package/src/lib/interaction/alert.ts +6 -0
  46. package/src/lib/interaction/components/activity-container/activity-container.component.html +8 -0
  47. package/src/lib/interaction/components/activity-container/activity-container.component.scss +3 -0
  48. package/src/lib/interaction/components/activity-container/activity-container.component.spec.ts +25 -0
  49. package/src/lib/interaction/components/activity-container/activity-container.component.ts +93 -0
  50. package/{lib/interaction/components/activity-outlet/activity-outlet-context.d.ts → src/lib/interaction/components/activity-outlet/activity-outlet-context.ts} +7 -5
  51. package/src/lib/interaction/components/activity-outlet/activity-outlet.component.scss +3 -0
  52. package/src/lib/interaction/components/activity-outlet/activity-outlet.component.spec.ts +25 -0
  53. package/src/lib/interaction/components/activity-outlet/activity-outlet.component.ts +96 -0
  54. package/src/lib/interaction/components/alert-dialog/alert-dialog.component.html +7 -0
  55. package/src/lib/interaction/components/alert-dialog/alert-dialog.component.scss +7 -0
  56. package/src/lib/interaction/components/alert-dialog/alert-dialog.component.spec.ts +25 -0
  57. package/src/lib/interaction/components/alert-dialog/alert-dialog.component.ts +20 -0
  58. package/src/lib/interaction/components/confirmation-dialog/confirmation-dialog.component.html +9 -0
  59. package/src/lib/interaction/components/confirmation-dialog/confirmation-dialog.component.scss +8 -0
  60. package/src/lib/interaction/components/confirmation-dialog/confirmation-dialog.component.spec.ts +25 -0
  61. package/src/lib/interaction/components/confirmation-dialog/confirmation-dialog.component.ts +26 -0
  62. package/{lib/interaction/confirm.d.ts → src/lib/interaction/confirm.ts} +3 -2
  63. package/{lib/interaction/index.d.ts → src/lib/interaction/index.ts} +1 -0
  64. package/src/lib/interaction/interaction-context.ts +16 -0
  65. package/src/lib/interaction/interaction.module.ts +35 -0
  66. package/src/lib/interaction/result.ts +16 -0
  67. package/src/lib/interaction/services/dialog-interaction.service.scss +11 -0
  68. package/src/lib/interaction/services/dialog-interaction.service.spec.ts +12 -0
  69. package/src/lib/interaction/services/dialog-interaction.service.ts +63 -0
  70. package/src/lib/place/abstract-place-component.ts +33 -0
  71. package/src/lib/place/components/busy-overlay/busy-overlay.component.html +4 -0
  72. package/src/lib/place/components/busy-overlay/busy-overlay.component.scss +27 -0
  73. package/src/lib/place/components/busy-overlay/busy-overlay.component.spec.ts +25 -0
  74. package/src/lib/place/components/busy-overlay/busy-overlay.component.ts +23 -0
  75. package/src/lib/place/components/empty-state/empty-state.component.scss +15 -0
  76. package/src/lib/place/components/empty-state/empty-state.component.spec.ts +25 -0
  77. package/src/lib/place/components/empty-state/empty-state.component.ts +19 -0
  78. package/src/lib/place/components/place-outlet/place-outlet.component.html +7 -0
  79. package/src/lib/place/components/place-outlet/place-outlet.component.scss +12 -0
  80. package/src/lib/place/components/place-outlet/place-outlet.component.spec.ts +25 -0
  81. package/src/lib/place/components/place-outlet/place-outlet.component.ts +37 -0
  82. package/src/lib/place/components/place-outlet/route-animations.ts +30 -0
  83. package/src/lib/place/components/tabbed-place-navigation/tabbed-place-navigation.component.html +7 -0
  84. package/src/lib/place/components/tabbed-place-navigation/tabbed-place-navigation.component.scss +100 -0
  85. package/src/lib/place/components/tabbed-place-navigation/tabbed-place-navigation.component.spec.ts +25 -0
  86. package/src/lib/place/components/tabbed-place-navigation/tabbed-place-navigation.component.ts +30 -0
  87. package/src/lib/place/guards/leave-place.guard.spec.ts +15 -0
  88. package/src/lib/place/guards/leave-place.guard.ts +18 -0
  89. package/src/lib/place/guards/place-route.guard.ts +37 -0
  90. package/{lib/place/index.d.ts → src/lib/place/index.ts} +1 -0
  91. package/src/lib/place/place-component.ts +6 -0
  92. package/src/lib/place/place.decorator.ts +40 -0
  93. package/src/lib/place/place.module.ts +44 -0
  94. package/src/lib/place/place.service.spec.ts +12 -0
  95. package/src/lib/place/place.service.ts +29 -0
  96. package/src/lib/place/route/json-types.ts +5 -0
  97. package/src/lib/place/route/parameter-decorators.ts +99 -0
  98. package/src/lib/place/route/parameter-definition.class.ts +12 -0
  99. package/{lib/place/route/parameter-sanitiser.d.ts → src/lib/place/route/parameter-sanitiser.ts} +1 -1
  100. package/src/lib/place/route/parameter-type.ts +31 -0
  101. package/src/lib/place/route/route-parameter-bindings.ts +140 -0
  102. package/src/lib/place/route/route-parameter-sanitiser.ts +135 -0
  103. package/src/test-setup.ts +1 -0
  104. package/tsconfig.json +7 -0
  105. package/tsconfig.lib.json +20 -0
  106. package/tsconfig.schematics.json +35 -0
  107. package/tsconfig.spec.json +10 -0
  108. package/tslint.json +7 -0
  109. package/bundles/coolon-angular-ui-powerups.umd.js +0 -3926
  110. package/bundles/coolon-angular-ui-powerups.umd.js.map +0 -1
  111. package/bundles/coolon-angular-ui-powerups.umd.min.js +0 -2
  112. package/bundles/coolon-angular-ui-powerups.umd.min.js.map +0 -1
  113. package/coolon-angular-ui-powerups.d.ts +0 -30
  114. package/coolon-angular-ui-powerups.metadata.json +0 -1
  115. package/esm2015/coolon-angular-ui-powerups.js +0 -33
  116. package/esm2015/index.js +0 -6
  117. package/esm2015/lib/angular-ui-powerups.module.js +0 -54
  118. package/esm2015/lib/animations/index.js +0 -9
  119. package/esm2015/lib/animations/slideDownAndUpAnimation.js +0 -30
  120. package/esm2015/lib/components/disposable-component.js +0 -14
  121. package/esm2015/lib/components/forms/abstract-input.component.js +0 -183
  122. package/esm2015/lib/components/forms/number-input/number-input.component.js +0 -26
  123. package/esm2015/lib/components/forms/password-input/password-input.component.js +0 -26
  124. package/esm2015/lib/components/forms/select-input/select-input.component.js +0 -60
  125. package/esm2015/lib/components/forms/string-input/string-input.component.js +0 -26
  126. package/esm2015/lib/components/index.js +0 -18
  127. package/esm2015/lib/components/resize-aware.component.js +0 -96
  128. package/esm2015/lib/components/types/bounds.class.js +0 -56
  129. package/esm2015/lib/components/types/dimension.class.js +0 -21
  130. package/esm2015/lib/components/types/point.class.js +0 -36
  131. package/esm2015/lib/directives/command.directive.js +0 -135
  132. package/esm2015/lib/directives/focus-binding.directive.js +0 -179
  133. package/esm2015/lib/directives/index.js +0 -10
  134. package/esm2015/lib/interaction/abstract-activity.js +0 -129
  135. package/esm2015/lib/interaction/activity.js +0 -27
  136. package/esm2015/lib/interaction/alert.js +0 -23
  137. package/esm2015/lib/interaction/components/activity-container/activity-container.component.js +0 -144
  138. package/esm2015/lib/interaction/components/activity-outlet/activity-outlet-context.js +0 -22
  139. package/esm2015/lib/interaction/components/activity-outlet/activity-outlet.component.js +0 -169
  140. package/esm2015/lib/interaction/components/alert-dialog/alert-dialog.component.js +0 -37
  141. package/esm2015/lib/interaction/components/confirmation-dialog/confirmation-dialog.component.js +0 -46
  142. package/esm2015/lib/interaction/confirm.js +0 -17
  143. package/esm2015/lib/interaction/index.js +0 -21
  144. package/esm2015/lib/interaction/interaction-context.js +0 -35
  145. package/esm2015/lib/interaction/interaction.module.js +0 -41
  146. package/esm2015/lib/interaction/result.js +0 -24
  147. package/esm2015/lib/interaction/services/dialog-interaction.service.js +0 -114
  148. package/esm2015/lib/place/abstract-place-component.js +0 -59
  149. package/esm2015/lib/place/components/busy-overlay/busy-overlay.component.js +0 -44
  150. package/esm2015/lib/place/components/empty-state/empty-state.component.js +0 -28
  151. package/esm2015/lib/place/components/place-outlet/place-outlet.component.js +0 -67
  152. package/esm2015/lib/place/components/place-outlet/route-animations.js +0 -35
  153. package/esm2015/lib/place/components/tabbed-place-navigation/tabbed-place-navigation.component.js +0 -50
  154. package/esm2015/lib/place/guards/leave-place.guard.js +0 -52
  155. package/esm2015/lib/place/guards/place-route.guard.js +0 -74
  156. package/esm2015/lib/place/index.js +0 -27
  157. package/esm2015/lib/place/place-component.js +0 -17
  158. package/esm2015/lib/place/place.decorator.js +0 -72
  159. package/esm2015/lib/place/place.module.js +0 -49
  160. package/esm2015/lib/place/place.service.js +0 -61
  161. package/esm2015/lib/place/route/json-types.js +0 -13
  162. package/esm2015/lib/place/route/parameter-decorators.js +0 -178
  163. package/esm2015/lib/place/route/parameter-definition.class.js +0 -24
  164. package/esm2015/lib/place/route/parameter-sanitiser.js +0 -17
  165. package/esm2015/lib/place/route/parameter-type.js +0 -43
  166. package/esm2015/lib/place/route/route-parameter-bindings.js +0 -294
  167. package/esm2015/lib/place/route/route-parameter-sanitiser.js +0 -280
  168. package/esm2015/public_api.js +0 -11
  169. package/esm5/coolon-angular-ui-powerups.js +0 -33
  170. package/esm5/index.js +0 -6
  171. package/esm5/lib/angular-ui-powerups.module.js +0 -58
  172. package/esm5/lib/animations/index.js +0 -9
  173. package/esm5/lib/animations/slideDownAndUpAnimation.js +0 -30
  174. package/esm5/lib/components/disposable-component.js +0 -24
  175. package/esm5/lib/components/forms/abstract-input.component.js +0 -232
  176. package/esm5/lib/components/forms/number-input/number-input.component.js +0 -33
  177. package/esm5/lib/components/forms/password-input/password-input.component.js +0 -33
  178. package/esm5/lib/components/forms/select-input/select-input.component.js +0 -67
  179. package/esm5/lib/components/forms/string-input/string-input.component.js +0 -33
  180. package/esm5/lib/components/index.js +0 -18
  181. package/esm5/lib/components/resize-aware.component.js +0 -124
  182. package/esm5/lib/components/types/bounds.class.js +0 -59
  183. package/esm5/lib/components/types/dimension.class.js +0 -19
  184. package/esm5/lib/components/types/point.class.js +0 -43
  185. package/esm5/lib/directives/command.directive.js +0 -155
  186. package/esm5/lib/directives/focus-binding.directive.js +0 -231
  187. package/esm5/lib/directives/index.js +0 -10
  188. package/esm5/lib/interaction/abstract-activity.js +0 -173
  189. package/esm5/lib/interaction/activity.js +0 -27
  190. package/esm5/lib/interaction/alert.js +0 -23
  191. package/esm5/lib/interaction/components/activity-container/activity-container.component.js +0 -181
  192. package/esm5/lib/interaction/components/activity-outlet/activity-outlet-context.js +0 -22
  193. package/esm5/lib/interaction/components/activity-outlet/activity-outlet.component.js +0 -206
  194. package/esm5/lib/interaction/components/alert-dialog/alert-dialog.component.js +0 -42
  195. package/esm5/lib/interaction/components/confirmation-dialog/confirmation-dialog.component.js +0 -54
  196. package/esm5/lib/interaction/confirm.js +0 -17
  197. package/esm5/lib/interaction/index.js +0 -21
  198. package/esm5/lib/interaction/interaction-context.js +0 -45
  199. package/esm5/lib/interaction/interaction.module.js +0 -45
  200. package/esm5/lib/interaction/result.js +0 -24
  201. package/esm5/lib/interaction/services/dialog-interaction.service.js +0 -140
  202. package/esm5/lib/place/abstract-place-component.js +0 -66
  203. package/esm5/lib/place/components/busy-overlay/busy-overlay.component.js +0 -49
  204. package/esm5/lib/place/components/empty-state/empty-state.component.js +0 -29
  205. package/esm5/lib/place/components/place-outlet/place-outlet.component.js +0 -81
  206. package/esm5/lib/place/components/place-outlet/route-animations.js +0 -35
  207. package/esm5/lib/place/components/tabbed-place-navigation/tabbed-place-navigation.component.js +0 -57
  208. package/esm5/lib/place/guards/leave-place.guard.js +0 -57
  209. package/esm5/lib/place/guards/place-route.guard.js +0 -78
  210. package/esm5/lib/place/index.js +0 -27
  211. package/esm5/lib/place/place-component.js +0 -17
  212. package/esm5/lib/place/place.decorator.js +0 -69
  213. package/esm5/lib/place/place.module.js +0 -53
  214. package/esm5/lib/place/place.service.js +0 -75
  215. package/esm5/lib/place/route/json-types.js +0 -13
  216. package/esm5/lib/place/route/parameter-decorators.js +0 -178
  217. package/esm5/lib/place/route/parameter-definition.class.js +0 -24
  218. package/esm5/lib/place/route/parameter-sanitiser.js +0 -17
  219. package/esm5/lib/place/route/parameter-type.js +0 -65
  220. package/esm5/lib/place/route/route-parameter-bindings.js +0 -339
  221. package/esm5/lib/place/route/route-parameter-sanitiser.js +0 -395
  222. package/esm5/public_api.js +0 -11
  223. package/fesm2015/coolon-angular-ui-powerups.js +0 -3145
  224. package/fesm2015/coolon-angular-ui-powerups.js.map +0 -1
  225. package/fesm5/coolon-angular-ui-powerups.js +0 -3699
  226. package/fesm5/coolon-angular-ui-powerups.js.map +0 -1
  227. package/lib/angular-ui-powerups.module.d.ts +0 -2
  228. package/lib/animations/slideDownAndUpAnimation.d.ts +0 -5
  229. package/lib/components/disposable-component.d.ts +0 -5
  230. package/lib/components/forms/abstract-input.component.d.ts +0 -35
  231. package/lib/components/forms/number-input/number-input.component.d.ts +0 -6
  232. package/lib/components/forms/password-input/password-input.component.d.ts +0 -6
  233. package/lib/components/forms/select-input/select-input.component.d.ts +0 -11
  234. package/lib/components/forms/string-input/string-input.component.d.ts +0 -6
  235. package/lib/components/resize-aware.component.d.ts +0 -22
  236. package/lib/components/types/bounds.class.d.ts +0 -16
  237. package/lib/components/types/dimension.class.d.ts +0 -5
  238. package/lib/components/types/point.class.d.ts +0 -10
  239. package/lib/directives/command.directive.d.ts +0 -14
  240. package/lib/directives/focus-binding.directive.d.ts +0 -22
  241. package/lib/interaction/abstract-activity.d.ts +0 -17
  242. package/lib/interaction/activity.d.ts +0 -11
  243. package/lib/interaction/alert.d.ts +0 -5
  244. package/lib/interaction/components/activity-container/activity-container.component.d.ts +0 -32
  245. package/lib/interaction/components/activity-outlet/activity-outlet.component.d.ts +0 -30
  246. package/lib/interaction/components/alert-dialog/alert-dialog.component.d.ts +0 -8
  247. package/lib/interaction/components/confirmation-dialog/confirmation-dialog.component.d.ts +0 -9
  248. package/lib/interaction/interaction-context.d.ts +0 -11
  249. package/lib/interaction/interaction.module.d.ts +0 -2
  250. package/lib/interaction/result.d.ts +0 -8
  251. package/lib/interaction/services/dialog-interaction.service.d.ts +0 -14
  252. package/lib/place/abstract-place-component.d.ts +0 -13
  253. package/lib/place/components/busy-overlay/busy-overlay.component.d.ts +0 -8
  254. package/lib/place/components/empty-state/empty-state.component.d.ts +0 -5
  255. package/lib/place/components/place-outlet/place-outlet.component.d.ts +0 -13
  256. package/lib/place/components/place-outlet/route-animations.d.ts +0 -1
  257. package/lib/place/components/tabbed-place-navigation/tabbed-place-navigation.component.d.ts +0 -11
  258. package/lib/place/guards/leave-place.guard.d.ts +0 -10
  259. package/lib/place/guards/place-route.guard.d.ts +0 -9
  260. package/lib/place/place-component.d.ts +0 -5
  261. package/lib/place/place.decorator.d.ts +0 -20
  262. package/lib/place/place.module.d.ts +0 -2
  263. package/lib/place/place.service.d.ts +0 -8
  264. package/lib/place/route/json-types.d.ts +0 -7
  265. package/lib/place/route/parameter-decorators.d.ts +0 -26
  266. package/lib/place/route/parameter-definition.class.d.ts +0 -11
  267. package/lib/place/route/parameter-type.d.ts +0 -16
  268. package/lib/place/route/route-parameter-bindings.d.ts +0 -18
  269. package/lib/place/route/route-parameter-sanitiser.d.ts +0 -42
  270. package/schematics/ng-add/index.d.ts +0 -2
  271. package/schematics/ng-add/index.js +0 -12
  272. package/schematics/ng-add/index.js.map +0 -1
  273. package/schematics/place-routes/index.d.ts +0 -3
  274. package/schematics/place-routes/index.js +0 -114
  275. package/schematics/place-routes/index.js.map +0 -1
  276. package/schematics/place-routes/place-def.d.ts +0 -34
  277. package/schematics/place-routes/place-def.js +0 -84
  278. package/schematics/place-routes/place-def.js.map +0 -1
  279. package/schematics/place-routes/scanner.d.ts +0 -26
  280. package/schematics/place-routes/scanner.js +0 -125
  281. package/schematics/place-routes/scanner.js.map +0 -1
  282. package/schematics/place-routes/schema.d.ts +0 -7
  283. package/schematics/place-routes/schema.js +0 -3
  284. package/schematics/place-routes/schema.js.map +0 -1
  285. /package/{index.d.ts → src/index.ts} +0 -0
  286. /package/{public_api.d.ts → src/public_api.ts} +0 -0
@@ -0,0 +1,8 @@
1
+ import { FocusBindingDirective } from './focus-binding.directive';
2
+
3
+ describe('FocusBindingDirective', () => {
4
+ it('should create an instance', () => {
5
+ const directive = new FocusBindingDirective(null, null);
6
+ expect(directive).toBeTruthy();
7
+ });
8
+ });
@@ -0,0 +1,108 @@
1
+ import {DOCUMENT} from '@angular/common';
2
+ import {AfterViewInit, Directive, ElementRef, HostListener, Inject, Input, NgZone, OnInit} from '@angular/core';
3
+ import {Dsl, HasFocusTracking, Logger} from '@coolon/pectin';
4
+ import {DisposableComponent} from '../components/disposable-component';
5
+
6
+
7
+ @Directive({
8
+ // tslint:disable-next-line:directive-selector
9
+ selector: '[pectinFocusBinding]'
10
+ })
11
+ export class FocusBindingDirective extends DisposableComponent implements OnInit, AfterViewInit {
12
+
13
+ private readonly document: Document;
14
+
15
+ @Input() pectinFocusBinding: HasFocusTracking;
16
+ @Input() focusBindingTarget: HTMLElement;
17
+
18
+ @HostListener('focusin')
19
+ onFocusIn() {
20
+ if (this.hasBinding()) {
21
+ this.pectinFocusBinding.focusContext.notifyFocusIn();
22
+ }
23
+ }
24
+
25
+ @HostListener('focusout')
26
+ onFocusOut() {
27
+ if (this.hasBinding()) {
28
+ this.pectinFocusBinding.focusContext.notifyFocusOut();
29
+ }
30
+ }
31
+
32
+ constructor(@Inject(ElementRef) private readonly el: ElementRef,
33
+ @Inject(NgZone) private readonly ngZone: NgZone,
34
+ @Inject(DOCUMENT) document: any) {
35
+ super();
36
+ // @see https://stackoverflow.com/questions/49513359/could-not-resolve-type-document-in-angular5/53715642#53715642
37
+ this.document = document as Document;
38
+ }
39
+
40
+ ngOnInit(): void {
41
+ }
42
+
43
+ ngAfterViewInit(): void {
44
+ // TODO: Make this also track the current enabled/disabled state.
45
+ if (this.hasBinding()) {
46
+ const {chain} = Dsl.disposeWith(this);
47
+ chain(this.pectinFocusBinding.focusContext.focused).subscribe((focused) => {
48
+ if (focused && !this.alreadyHasFocus()) {
49
+ this.tryAndFocus();
50
+ }
51
+ });
52
+ } else {
53
+ Logger.get(this).warn("pectinFocusBinding was nil");
54
+ }
55
+ }
56
+
57
+ private hasBinding() {
58
+ return !!this.pectinFocusBinding && !!this.pectinFocusBinding.focusContext;
59
+ }
60
+
61
+ // Hook method for debugging via tracing.
62
+ alreadyHasFocus() {
63
+ return this.isFocused(this.focusTarget);
64
+ }
65
+
66
+ // Hook method for debugging via tracing.
67
+ isFocused(element: Element): boolean {
68
+ return this.document.activeElement === element;
69
+ }
70
+
71
+ tryAndFocus(retries: number = 5) {
72
+ if (this.modelShouldStillHaveFocus() && this.canFocus()) {
73
+ if (!this.alreadyHasFocus()) {
74
+ this.focusTarget.focus();
75
+ }
76
+ // if we didn't get the focus we try again later.
77
+ if (!this.alreadyHasFocus()) {
78
+ Logger.get(this).log(`focus failed, trying ${retries} more times`);
79
+ if (retries > 0) {
80
+ // try again on the next paint
81
+ // TODO: is there an angular way of doing this without calling a window function.
82
+ requestAnimationFrame(() => {
83
+ this.tryAndFocus(retries - 1);
84
+ });
85
+ } else {
86
+ Logger.get(this).warn(`Tried to focus but gave up as the component wasn't enabled or visible.`);
87
+ }
88
+ }
89
+ }
90
+ }
91
+
92
+ get focusTarget(): HTMLElement {
93
+ return this.focusBindingTarget || this.el.nativeElement;
94
+ }
95
+
96
+ // Hook method for debugging via tracing.
97
+ modelShouldStillHaveFocus() {
98
+ return this.hasBinding() && this.pectinFocusBinding.focusContext.focused.value;
99
+ }
100
+
101
+ // Hook method for debugging via tracing.
102
+ canFocus(): boolean {
103
+ const dimension = this.focusTarget.getBoundingClientRect();
104
+ const hasSize = dimension.height >= 0 && dimension.height >= 0;
105
+ // tslint:disable-next-line:no-string-literal
106
+ return hasSize && !this.focusTarget['disabled'];
107
+ }
108
+ }
@@ -1,5 +1,6 @@
1
1
  /**
2
2
  * @file Automatically generated by barrelsby.
3
3
  */
4
+
4
5
  export * from "./command.directive";
5
6
  export * from "./focus-binding.directive";
@@ -0,0 +1,57 @@
1
+ import { DelegatingValueModel, EventListenerList, ValueModel } from '@coolon/pectin';
2
+ import { DisposableComponent } from '../components/disposable-component';
3
+ import { Activity } from './activity';
4
+
5
+ export class AbstractActivity<D, R, E = any> extends DisposableComponent implements Activity<D, R, E> {
6
+
7
+ private readonly _doneListeners = new EventListenerList<Activity.CallBack<R>>();
8
+ private readonly _cancelListeners = new EventListenerList<Activity.CallBack<E>>();
9
+ private readonly _finishListeners = new EventListenerList<() => void>();
10
+
11
+ private readonly _busyModel = new DelegatingValueModel<boolean>().withDefault(false);
12
+
13
+ onDone(callback: Activity.CallBack<R>) {
14
+ this._doneListeners.add(callback);
15
+ }
16
+
17
+ onCancel(callback: Activity.CallBack<E>) {
18
+ this._cancelListeners.add(callback);
19
+ }
20
+
21
+ done(result?: R): Promise<any> {
22
+ return this._doneListeners
23
+ .fireAndWait(l => l(result))
24
+ .finally(() => this.finalizeAndDispose());
25
+ }
26
+
27
+ cancel(error?: E): Promise<any> {
28
+ return this._cancelListeners
29
+ .fireAndWait(l => l(error))
30
+ .finally(() => this.finalizeAndDispose());
31
+ }
32
+
33
+ private finalizeAndDispose() {
34
+ // this._activeModel.value = false;
35
+ this._finishListeners.fire(l => l());
36
+ // this._interactionContext = null;
37
+ // this._initialized = false;
38
+ [
39
+ this._finishListeners,
40
+ this._doneListeners,
41
+ this._cancelListeners
42
+ ].forEach(l => l.dispose());
43
+ }
44
+
45
+
46
+ get busy(): ValueModel<boolean> {
47
+ return this._busyModel.readonly;
48
+ }
49
+
50
+ busyWhile(busyModel: ValueModel<boolean>) {
51
+ this._busyModel.setDelegate(busyModel);
52
+ }
53
+
54
+ isBusy() {
55
+ return this._busyModel.value;
56
+ }
57
+ }
@@ -0,0 +1,17 @@
1
+ import { InjectionToken } from '@angular/core';
2
+ import { ValueModel } from '@coolon/pectin';
3
+
4
+ export const ACTIVITY_DATA = new InjectionToken<any>('InteractionActivityData');
5
+
6
+ export interface Activity<D, R, E = any> {
7
+ readonly busy: ValueModel<boolean>;
8
+
9
+ onDone(callback: Activity.CallBack<R>);
10
+
11
+ onCancel(callback: Activity.CallBack<E>);
12
+
13
+ }
14
+
15
+ export namespace Activity {
16
+ export type CallBack<T> = (value: T) => void | Promise<any>;
17
+ }
@@ -0,0 +1,6 @@
1
+
2
+ export interface Alert {
3
+ title?():string;
4
+ content():string[];
5
+ ok():string;
6
+ }
@@ -0,0 +1,8 @@
1
+ <mat-tab-group #tabs no-tab-header [dynamicHeight]="true">
2
+ <mat-tab>
3
+ <angular-ui-powerups-activity-outlet [interactionContext]="this" [activityContext]="initialActivity"></angular-ui-powerups-activity-outlet>
4
+ </mat-tab>
5
+ <mat-tab *ngFor="let tab of activityTabs.value">
6
+ <angular-ui-powerups-activity-outlet [interactionContext]="this" [activityContext]="tab"></angular-ui-powerups-activity-outlet>
7
+ </mat-tab>
8
+ </mat-tab-group>
@@ -0,0 +1,25 @@
1
+ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { ActivityContainerComponent } from './activity-container.component';
4
+
5
+ describe('ActivityContainerComponent', () => {
6
+ let component: ActivityContainerComponent;
7
+ let fixture: ComponentFixture<ActivityContainerComponent>;
8
+
9
+ beforeEach(async(() => {
10
+ TestBed.configureTestingModule({
11
+ declarations: [ ActivityContainerComponent ]
12
+ })
13
+ .compileComponents();
14
+ }));
15
+
16
+ beforeEach(() => {
17
+ fixture = TestBed.createComponent(ActivityContainerComponent);
18
+ component = fixture.componentInstance;
19
+ fixture.detectChanges();
20
+ });
21
+
22
+ it('should create', () => {
23
+ expect(component).toBeTruthy();
24
+ });
25
+ });
@@ -0,0 +1,93 @@
1
+ import { AfterViewInit, Component, Input, OnInit, ViewChild } from '@angular/core';
2
+ import { MatTabGroup } from '@angular/material';
3
+ import { Constructable, Dsl, MutableListModel } from '@coolon/pectin';
4
+ import { Deferred } from '@coolon/pectin/lib/promise/deferred.class';
5
+ import { DisposableComponent } from '../../../components/disposable-component';
6
+
7
+ import { Activity } from '../../activity';
8
+ import { Alert } from '../../alert';
9
+ import { Confirm } from '../../confirm';
10
+ import { InteractionContext } from '../../interaction-context';
11
+ import { ActivityOutletContext } from '../activity-outlet/activity-outlet-context';
12
+ import { AlertDialogComponent } from '../alert-dialog/alert-dialog.component';
13
+ import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
14
+
15
+ @Component({
16
+ selector: 'angular-ui-powerups-activity-container',
17
+ templateUrl: './activity-container.component.html',
18
+ styleUrls: ['./activity-container.component.scss']
19
+ })
20
+ export class ActivityContainerComponent extends DisposableComponent implements OnInit, AfterViewInit, InteractionContext {
21
+
22
+ @Input()
23
+ parentInteractionContext: InteractionContext;
24
+
25
+ @Input()
26
+ initialActivity: ActivityOutletContext<any, any, any>;
27
+
28
+ @ViewChild('tabs', { static: true })
29
+ tabs: MatTabGroup;
30
+
31
+ readonly activityTabs = new MutableListModel<ActivityOutletContext<any, any, any>>();
32
+ private obsoleteTabs: ActivityOutletContext<any, any, any>[] = [];
33
+
34
+ constructor() {
35
+ super();
36
+ }
37
+
38
+ ngOnInit() {
39
+ }
40
+
41
+ ngAfterViewInit(): void {
42
+ const { observe } = Dsl.disposeWith(this);
43
+ observe.valuesFrom(this.tabs.animationDone).subscribe(() => this.cleanUpTabs());
44
+ }
45
+
46
+ initialise<D, R, E>(options: ActivityContainerComponent.ActivityContext<D, R, E>) {
47
+ this.initialActivity = {
48
+ ...options,
49
+ interactionContext: this
50
+ };
51
+ }
52
+
53
+ startActivity<D, R, E>(activityType: Constructable<Activity<D, R, E>>, data?: D): Promise<R> {
54
+ const deferred = Deferred.defer<R>();
55
+ const context = {
56
+ interactionContext: this,
57
+ activityClass: activityType,
58
+ activityData: data,
59
+ onDone: deferred.resolve,
60
+ onCancel: deferred.reject
61
+ };
62
+ this.activityTabs.push(context);
63
+ this.tabs.selectedIndex = this.activityTabs.length;
64
+ return deferred.promise.finally(() => {
65
+ this.obsoleteTabs.push(context);
66
+ this.tabs.selectedIndex = this.activityTabs.length - 1;
67
+ });
68
+ }
69
+
70
+ alert(alert: Alert): Promise<void> {
71
+ return this.startActivity(AlertDialogComponent, alert);
72
+ }
73
+
74
+ confirm(confirm: Confirm): Promise<boolean> {
75
+ return this.startActivity(ConfirmationDialogComponent, confirm);
76
+ }
77
+
78
+ private cleanUpTabs() {
79
+ this.activityTabs.value = this.activityTabs.value.filter(tab => {
80
+ return !this.obsoleteTabs.includes(tab);
81
+ });
82
+ }
83
+ }
84
+
85
+ export namespace ActivityContainerComponent {
86
+
87
+ export interface ActivityContext<D, R, E> {
88
+ activityClass: Constructable<Activity<D, R, E>>,
89
+ activityData: D,
90
+ onDone: (result: R) => void,
91
+ onCancel: (error: E) => void,
92
+ }
93
+ }
@@ -1,10 +1,12 @@
1
1
  import { Constructable } from '@coolon/pectin';
2
2
  import { Activity } from '../../activity';
3
3
  import { InteractionContext } from '../../interaction-context';
4
+
5
+
4
6
  export interface ActivityOutletContext<D, R, E> {
5
- interactionContext: InteractionContext;
6
- activityClass: Constructable<Activity<D, R, E>>;
7
- activityData: D;
8
- onDone: (result: R) => void;
9
- onCancel: (error: E) => void;
7
+ interactionContext: InteractionContext,
8
+ activityClass: Constructable<Activity<D, R, E>>,
9
+ activityData: D,
10
+ onDone: (result: R) => void,
11
+ onCancel: (error: E) => void,
10
12
  }
@@ -0,0 +1,25 @@
1
+ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { ActivityOutletComponent } from './activity-outlet.component';
4
+
5
+ describe('PortalOutletComponentComponent', () => {
6
+ let component: ActivityOutletComponent;
7
+ let fixture: ComponentFixture<ActivityOutletComponent>;
8
+
9
+ beforeEach(async(() => {
10
+ TestBed.configureTestingModule({
11
+ declarations: [ ActivityOutletComponent ]
12
+ })
13
+ .compileComponents();
14
+ }));
15
+
16
+ beforeEach(() => {
17
+ fixture = TestBed.createComponent(ActivityOutletComponent);
18
+ component = fixture.componentInstance;
19
+ fixture.detectChanges();
20
+ });
21
+
22
+ it('should create', () => {
23
+ expect(component).toBeTruthy();
24
+ });
25
+ });
@@ -0,0 +1,96 @@
1
+ import {
2
+ AfterViewInit,
3
+ Component,
4
+ ComponentFactoryResolver,
5
+ ComponentRef,
6
+ Injector,
7
+ Input,
8
+ OnInit,
9
+ ViewContainerRef
10
+ } from '@angular/core';
11
+ import { Constructable, lang } from '@coolon/pectin';
12
+ import { Activity, ACTIVITY_DATA } from '../../activity';
13
+ import { Alert } from '../../alert';
14
+ import { Confirm } from '../../confirm';
15
+ import { InteractionContext } from '../../interaction-context';
16
+ import { ActivityOutletContext } from './activity-outlet-context';
17
+
18
+ @Component({
19
+ selector: 'angular-ui-powerups-activity-outlet',
20
+ template: '',
21
+ styleUrls: ['./activity-outlet.component.scss']
22
+ })
23
+ export class ActivityOutletComponent<D, R, E> implements OnInit, InteractionContext {
24
+
25
+ @Input()
26
+ interactionContext: InteractionContext;
27
+
28
+ @Input()
29
+ set activityContext(activityContext: ActivityOutletContext<D, R, E>) {
30
+ this.loadActivity(activityContext);
31
+ };
32
+
33
+ private activityComponent: ComponentRef<Activity<D, R, E>>;
34
+
35
+ constructor(
36
+ private componentFactoryResolver: ComponentFactoryResolver,
37
+ private viewContainerRef: ViewContainerRef,
38
+ private injector: Injector
39
+ ) {
40
+ }
41
+
42
+ ngOnInit() {
43
+ }
44
+
45
+ loadActivity(activityContext: ActivityOutletContext<D, R, E>) {
46
+ const injector = Injector.create({
47
+ providers: [
48
+ {
49
+ provide: InteractionContext,
50
+ useValue: this
51
+ },
52
+ { provide: ACTIVITY_DATA, useValue: activityContext.activityData }
53
+ ],
54
+ parent: this.injector
55
+ });
56
+ const componentFactory = this.componentFactoryResolver.resolveComponentFactory(activityContext.activityClass);
57
+ this.viewContainerRef.clear();
58
+ this.activityComponent = this.viewContainerRef.createComponent(componentFactory, 0, injector);
59
+ this.activityComponent.instance.onDone(activityContext.onDone);
60
+ this.activityComponent.instance.onCancel(activityContext.onCancel);
61
+ }
62
+
63
+ alert(alert: Alert): Promise<void> {
64
+ return this.interactionContext.alert(alert);
65
+ }
66
+
67
+ confirm(confirm: Confirm): Promise<boolean> {
68
+ return this.interactionContext.confirm(confirm);
69
+ }
70
+
71
+ startActivity<D1, R1, E1>(activityType: Constructable<Activity<D1, R1, E1>>, data?: D1): Promise<R1> {
72
+ return this.interactionContext.startActivity(activityType, data);
73
+ }
74
+ }
75
+
76
+ export namespace ActivityOutletComponent {
77
+
78
+ export class OutletInteractionContext<D, R, E> implements InteractionContext {
79
+
80
+ constructor(private readonly context: ActivityOutletContext<D, R, E>) {
81
+ }
82
+
83
+ alert(alert: Alert): Promise<void> {
84
+ return lang.notImplemented();
85
+ }
86
+
87
+ confirm(confirm: Confirm): Promise<boolean> {
88
+ return lang.notImplemented();
89
+ }
90
+
91
+ startActivity<D1, R1, E1>(activityType: Constructable<Activity<D1, R1, E1>>, data?: D1): Promise<R1> {
92
+ return lang.notImplemented();
93
+ }
94
+ }
95
+
96
+ }
@@ -0,0 +1,7 @@
1
+ <h3 matDialogTitle *ngIf="alert.title">{{alert.title()}}</h3>
2
+ <div matDialogContent>
3
+ <p *ngFor="let line of alert.content()">{{line}}</p>
4
+ </div>
5
+ <p matDialogActions>
6
+ <button mat-raised-button color="primary" (click)="done()">{{alert.ok()}}</button>
7
+ </p>
@@ -0,0 +1,7 @@
1
+ :host {
2
+ display: block;
3
+ padding: var(--angular-ui-powerups-default-padding);
4
+ }
5
+ .mat-dialog-actions {
6
+ justify-content: flex-end;
7
+ }
@@ -0,0 +1,25 @@
1
+ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { AlertDialogComponent } from './alert-dialog.component';
4
+
5
+ describe('ConfirmationDialogComponent', () => {
6
+ let component: AlertDialogComponent;
7
+ let fixture: ComponentFixture<AlertDialogComponent>;
8
+
9
+ beforeEach(async(() => {
10
+ TestBed.configureTestingModule({
11
+ declarations: [ AlertDialogComponent ]
12
+ })
13
+ .compileComponents();
14
+ }));
15
+
16
+ beforeEach(() => {
17
+ fixture = TestBed.createComponent(AlertDialogComponent);
18
+ component = fixture.componentInstance;
19
+ fixture.detectChanges();
20
+ });
21
+
22
+ it('should create', () => {
23
+ expect(component).toBeTruthy();
24
+ });
25
+ });
@@ -0,0 +1,20 @@
1
+ import { Component, Inject, OnInit } from '@angular/core';
2
+ import { AbstractActivity } from '../../abstract-activity';
3
+ import { ACTIVITY_DATA } from '../../activity';
4
+ import { Alert } from '../../alert';
5
+
6
+ @Component({
7
+ selector: 'angular-ui-powerups-alert-dialog',
8
+ templateUrl: './alert-dialog.component.html',
9
+ styleUrls: ['./alert-dialog.component.scss']
10
+ })
11
+ export class AlertDialogComponent extends AbstractActivity<Alert, void> implements OnInit {
12
+
13
+ constructor(@Inject(ACTIVITY_DATA) readonly alert: Alert) {
14
+ super();
15
+ }
16
+
17
+ ngOnInit() {
18
+ }
19
+
20
+ }
@@ -0,0 +1,9 @@
1
+ <h3 matDialogTitle *ngIf="confirm.title">{{confirm.title()}}</h3>
2
+ <div matDialogContent>
3
+ <p *ngFor="let line of confirm.content()">{{line}}</p>
4
+ </div>
5
+ <p matDialogActions>
6
+ <button mat-button (click)="cancel()">{{confirm.cancel()}}</button>
7
+ <button mat-raised-button [color]="isDestructive() ? 'warn' : 'primary'" (click)="done(true)">{{confirm.ok()}}</button>
8
+ </p>
9
+
@@ -0,0 +1,8 @@
1
+ :host {
2
+ display: block;
3
+ padding: var(--angular-ui-powerups-default-padding);
4
+ }
5
+
6
+ .mat-dialog-actions {
7
+ justify-content: flex-end;
8
+ }
@@ -0,0 +1,25 @@
1
+ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { ConfirmationDialogComponent } from './confirmation-dialog.component';
4
+
5
+ describe('ConfirmationDialogComponent', () => {
6
+ let component: ConfirmationDialogComponent;
7
+ let fixture: ComponentFixture<ConfirmationDialogComponent>;
8
+
9
+ beforeEach(async(() => {
10
+ TestBed.configureTestingModule({
11
+ declarations: [ ConfirmationDialogComponent ]
12
+ })
13
+ .compileComponents();
14
+ }));
15
+
16
+ beforeEach(() => {
17
+ fixture = TestBed.createComponent(ConfirmationDialogComponent);
18
+ component = fixture.componentInstance;
19
+ fixture.detectChanges();
20
+ });
21
+
22
+ it('should create', () => {
23
+ expect(component).toBeTruthy();
24
+ });
25
+ });
@@ -0,0 +1,26 @@
1
+ import { Component, Inject, OnInit } from '@angular/core';
2
+ import { assert } from '@coolon/pectin';
3
+ import { AbstractActivity } from '../../abstract-activity';
4
+ import { ACTIVITY_DATA } from '../../activity';
5
+ import { Confirm } from '../../confirm';
6
+
7
+ @Component({
8
+ selector: 'angular-ui-powerups-confirmation-dialog',
9
+ templateUrl: './confirmation-dialog.component.html',
10
+ styleUrls: ['./confirmation-dialog.component.scss']
11
+ })
12
+ export class ConfirmationDialogComponent extends AbstractActivity<Confirm, boolean> implements OnInit {
13
+
14
+ constructor(@Inject(ACTIVITY_DATA) readonly confirm: Confirm) {
15
+ super();
16
+ assert.notNil(confirm);
17
+ console.log(confirm);
18
+ }
19
+
20
+ ngOnInit() {
21
+ }
22
+
23
+ isDestructive(): boolean {
24
+ return this.confirm.destructive && this.confirm.destructive();
25
+ }
26
+ }
@@ -1,5 +1,6 @@
1
1
  import { Alert } from './alert';
2
+
2
3
  export interface Confirm extends Alert {
3
- destructive?: () => boolean;
4
- cancel(): string;
4
+ destructive?: () => boolean;
5
+ cancel(): string;
5
6
  }
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @file Automatically generated by barrelsby.
3
3
  */
4
+
4
5
  export * from "./abstract-activity";
5
6
  export * from "./activity";
6
7
  export * from "./alert";
@@ -0,0 +1,16 @@
1
+ import { InjectionToken } from '@angular/core';
2
+ import { Constructable } from '@coolon/pectin';
3
+ import { Activity } from './activity';
4
+ import { Alert } from './alert';
5
+ import { Confirm } from './confirm';
6
+
7
+ export const INTERACTION_CONTEXT = new InjectionToken<any>('InteractionContext');
8
+
9
+ export abstract class InteractionContext {
10
+
11
+ abstract startActivity<D, R, E>(activityType: Constructable<Activity<D, R, E>>, data?: D): Promise<R>;
12
+
13
+ abstract confirm(confirm: Confirm): Promise<boolean>;
14
+
15
+ abstract alert(alert: Alert): Promise<void>;
16
+ }