@theseam/ui-common 0.2.9 → 0.2.13

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 (365) hide show
  1. package/assets/vendor/intl-tel-input/js/utils.js +255 -254
  2. package/bundles/theseam-ui-common-asset-reader.umd.js +7 -9
  3. package/bundles/theseam-ui-common-asset-reader.umd.js.map +1 -1
  4. package/bundles/theseam-ui-common-breadcrumbs.umd.js +6 -8
  5. package/bundles/theseam-ui-common-breadcrumbs.umd.js.map +1 -1
  6. package/bundles/theseam-ui-common-buttons.umd.js +5 -5
  7. package/bundles/theseam-ui-common-buttons.umd.js.map +1 -1
  8. package/bundles/theseam-ui-common-card.umd.js +6 -6
  9. package/bundles/theseam-ui-common-card.umd.js.map +1 -1
  10. package/bundles/theseam-ui-common-checkbox.umd.js +4 -4
  11. package/bundles/theseam-ui-common-checkbox.umd.js.map +1 -1
  12. package/bundles/theseam-ui-common-confirm-dialog.umd.js +4 -4
  13. package/bundles/theseam-ui-common-confirm-dialog.umd.js.map +1 -1
  14. package/bundles/theseam-ui-common-core.umd.js +4 -4
  15. package/bundles/theseam-ui-common-core.umd.js.map +1 -1
  16. package/bundles/theseam-ui-common-data-exporter.umd.js +5 -5
  17. package/bundles/theseam-ui-common-data-filters.umd.js +9 -6
  18. package/bundles/theseam-ui-common-data-filters.umd.js.map +1 -1
  19. package/bundles/theseam-ui-common-datatable-dynamic.umd.js +7 -7
  20. package/bundles/theseam-ui-common-datatable-dynamic.umd.js.map +1 -1
  21. package/bundles/theseam-ui-common-datatable.umd.js +1353 -375
  22. package/bundles/theseam-ui-common-datatable.umd.js.map +1 -1
  23. package/bundles/theseam-ui-common-dynamic-component-loader.umd.js +5 -7
  24. package/bundles/theseam-ui-common-dynamic-component-loader.umd.js.map +1 -1
  25. package/bundles/theseam-ui-common-dynamic.umd.js +7 -9
  26. package/bundles/theseam-ui-common-dynamic.umd.js.map +1 -1
  27. package/bundles/theseam-ui-common-footer-bar.umd.js +3 -3
  28. package/bundles/theseam-ui-common-form-field-error.umd.js +5 -5
  29. package/bundles/theseam-ui-common-form-field-error.umd.js.map +1 -1
  30. package/bundles/theseam-ui-common-form-field.umd.js +5 -5
  31. package/bundles/theseam-ui-common-form-field.umd.js.map +1 -1
  32. package/bundles/theseam-ui-common-framework.umd.js +28 -30
  33. package/bundles/theseam-ui-common-framework.umd.js.map +1 -1
  34. package/bundles/theseam-ui-common-graphql.umd.js +958 -8
  35. package/bundles/theseam-ui-common-graphql.umd.js.map +1 -1
  36. package/bundles/theseam-ui-common-icon.umd.js +5 -5
  37. package/bundles/theseam-ui-common-icon.umd.js.map +1 -1
  38. package/bundles/theseam-ui-common-layout.umd.js +5 -7
  39. package/bundles/theseam-ui-common-layout.umd.js.map +1 -1
  40. package/bundles/theseam-ui-common-loading.umd.js +4 -4
  41. package/bundles/theseam-ui-common-menu.umd.js +5 -5
  42. package/bundles/theseam-ui-common-menu.umd.js.map +1 -1
  43. package/bundles/theseam-ui-common-modal.umd.js +6 -6
  44. package/bundles/theseam-ui-common-modal.umd.js.map +1 -1
  45. package/bundles/theseam-ui-common-models.umd.js +3 -3
  46. package/bundles/theseam-ui-common-popover.umd.js +4 -4
  47. package/bundles/theseam-ui-common-progress.umd.js +5 -5
  48. package/bundles/theseam-ui-common-progress.umd.js.map +1 -1
  49. package/bundles/theseam-ui-common-scrollbar.umd.js +7 -9
  50. package/bundles/theseam-ui-common-scrollbar.umd.js.map +1 -1
  51. package/bundles/theseam-ui-common-services.umd.js +6 -8
  52. package/bundles/theseam-ui-common-services.umd.js.map +1 -1
  53. package/bundles/theseam-ui-common-shared.umd.js +4 -4
  54. package/bundles/theseam-ui-common-shared.umd.js.map +1 -1
  55. package/bundles/theseam-ui-common-storage.umd.js +5 -7
  56. package/bundles/theseam-ui-common-storage.umd.js.map +1 -1
  57. package/bundles/theseam-ui-common-story-helpers.umd.js +4 -4
  58. package/bundles/theseam-ui-common-story-helpers.umd.js.map +1 -1
  59. package/bundles/theseam-ui-common-tabbed.umd.js +5 -5
  60. package/bundles/theseam-ui-common-tabbed.umd.js.map +1 -1
  61. package/bundles/theseam-ui-common-table-cell-type.umd.js +5 -7
  62. package/bundles/theseam-ui-common-table-cell-type.umd.js.map +1 -1
  63. package/bundles/theseam-ui-common-table-cell-types.umd.js +258 -32
  64. package/bundles/theseam-ui-common-table-cell-types.umd.js.map +1 -1
  65. package/bundles/theseam-ui-common-table.umd.js +5 -5
  66. package/bundles/theseam-ui-common-table.umd.js.map +1 -1
  67. package/bundles/theseam-ui-common-tel-input.umd.js +6 -6
  68. package/bundles/theseam-ui-common-tel-input.umd.js.map +1 -1
  69. package/bundles/theseam-ui-common-testing.umd.js +568 -0
  70. package/bundles/theseam-ui-common-testing.umd.js.map +1 -0
  71. package/bundles/theseam-ui-common-tiled-select.umd.js +56 -39
  72. package/bundles/theseam-ui-common-tiled-select.umd.js.map +1 -1
  73. package/bundles/theseam-ui-common-toggle-edit.umd.js +8 -10
  74. package/bundles/theseam-ui-common-toggle-edit.umd.js.map +1 -1
  75. package/bundles/theseam-ui-common-toggle-group.umd.js +4 -4
  76. package/bundles/theseam-ui-common-toggle-group.umd.js.map +1 -1
  77. package/bundles/theseam-ui-common-unsaved-changes-dialog.umd.js +5 -7
  78. package/bundles/theseam-ui-common-unsaved-changes-dialog.umd.js.map +1 -1
  79. package/bundles/theseam-ui-common-utils.umd.js +174 -81
  80. package/bundles/theseam-ui-common-utils.umd.js.map +1 -1
  81. package/bundles/theseam-ui-common-validators.umd.js +3 -3
  82. package/bundles/theseam-ui-common-viewers.umd.js +6 -8
  83. package/bundles/theseam-ui-common-viewers.umd.js.map +1 -1
  84. package/bundles/theseam-ui-common-widget.umd.js +18 -20
  85. package/bundles/theseam-ui-common-widget.umd.js.map +1 -1
  86. package/bundles/theseam-ui-common.umd.js +2 -2
  87. package/buttons/theseam-ui-common-buttons.metadata.json +1 -1
  88. package/card/theseam-ui-common-card.metadata.json +1 -1
  89. package/data-filters/data-filter.d.ts +10 -6
  90. package/data-filters/theseam-ui-common-data-filters.metadata.json +1 -1
  91. package/datatable/datatable/datatable.component.d.ts +48 -32
  92. package/datatable/datatable-column/datatable-column.component.d.ts +26 -25
  93. package/datatable/datatable-column-preferences/datatable-column-preferences.component.d.ts +7 -5
  94. package/datatable/datatable-column-preferences-button/datatable-column-preferences-button.component.d.ts +7 -1
  95. package/datatable/datatable-footer/datatable-footer-tpl.directive.d.ts +5 -0
  96. package/datatable/datatable-footer/datatable-footer.directive.d.ts +6 -0
  97. package/datatable/datatable-menu-bar/datatable-menu-bar.component.d.ts +1 -1
  98. package/datatable/directives/datatable-filter.directive.d.ts +1 -1
  99. package/datatable/models/columns-alteration.d.ts +61 -0
  100. package/datatable/models/columns-alterations/hide-column.columns-alteration.d.ts +15 -0
  101. package/datatable/models/columns-alterations/order.columns-alteration.d.ts +20 -0
  102. package/datatable/models/columns-alterations/sort.columns-alteration.d.ts +14 -0
  103. package/datatable/models/columns-alterations/width.columns-alteration.d.ts +16 -0
  104. package/datatable/models/datatable-accessor.d.ts +5 -3
  105. package/datatable/models/internal-column-props.d.ts +7 -0
  106. package/datatable/models/page-info.d.ts +12 -0
  107. package/datatable/models/preferences-accessor.d.ts +1 -1
  108. package/datatable/models/preferences.d.ts +11 -3
  109. package/datatable/models/sort-item.d.ts +2 -1
  110. package/datatable/public-api.d.ts +2 -0
  111. package/datatable/services/columns-alterations-manager.service.d.ts +39 -0
  112. package/datatable/services/columns-manager.service.d.ts +55 -0
  113. package/datatable/services/datatable-preferences.service.d.ts +10 -7
  114. package/datatable/theseam-ui-common-datatable.d.ts +2 -0
  115. package/datatable/theseam-ui-common-datatable.metadata.json +1 -1
  116. package/datatable/tokens/datatable-preferences-accessor.d.ts +2 -2
  117. package/datatable/utils/create-action-menu-column.d.ts +3 -0
  118. package/datatable/utils/create-checkbox-column.d.ts +3 -0
  119. package/datatable/utils/get-column-prop.d.ts +5 -0
  120. package/datatable/utils/map-columns-alterations-states.d.ts +2 -0
  121. package/datatable/utils/remove-unused-diffs.d.ts +7 -0
  122. package/datatable/utils/set-column-defaults.d.ts +2 -0
  123. package/datatable/utils/translate-templates.d.ts +2 -0
  124. package/datatable/utils/with-stored-column-info.d.ts +2 -2
  125. package/datatable-dynamic/theseam-ui-common-datatable-dynamic.metadata.json +1 -1
  126. package/esm2015/buttons/progress-circle-button/progress-circle-button.component.js +1 -1
  127. package/esm2015/card/card-action/card-action.component.js +1 -1
  128. package/esm2015/card/card-body/card-body.component.js +1 -1
  129. package/esm2015/data-filters/data-filter.js +5 -2
  130. package/esm2015/data-filters/filters/data-filter-search/data-filter-search.component.js +1 -1
  131. package/esm2015/data-filters/filters/data-filter-text/data-filter-text.component.js +1 -1
  132. package/esm2015/datatable/datatable/datatable.component.js +197 -211
  133. package/esm2015/datatable/datatable-action-menu/datatable-action-menu.component.js +1 -1
  134. package/esm2015/datatable/datatable-column/datatable-column.component.js +1 -1
  135. package/esm2015/datatable/datatable-column-preferences/datatable-column-preferences.component.js +42 -19
  136. package/esm2015/datatable/datatable-column-preferences-button/datatable-column-preferences-button.component.js +38 -4
  137. package/esm2015/datatable/datatable-export-button/datatable-export-button.component.js +1 -1
  138. package/esm2015/datatable/datatable-footer/datatable-footer-tpl.directive.js +15 -0
  139. package/esm2015/datatable/datatable-footer/datatable-footer.directive.js +18 -0
  140. package/esm2015/datatable/datatable-menu-bar/datatable-menu-bar.component.js +1 -1
  141. package/esm2015/datatable/datatable-menu-bar-column-center/datatable-menu-bar-column-center.component.js +1 -1
  142. package/esm2015/datatable/datatable-menu-bar-column-left/datatable-menu-bar-column-left.component.js +1 -1
  143. package/esm2015/datatable/datatable-menu-bar-column-right/datatable-menu-bar-column-right.component.js +1 -1
  144. package/esm2015/datatable/datatable-menu-bar-row/datatable-menu-bar-row.component.js +1 -1
  145. package/esm2015/datatable/datatable.module.js +7 -1
  146. package/esm2015/datatable/models/columns-alteration.js +38 -0
  147. package/esm2015/datatable/models/columns-alterations/hide-column.columns-alteration.js +38 -0
  148. package/esm2015/datatable/models/columns-alterations/order.columns-alteration.js +81 -0
  149. package/esm2015/datatable/models/columns-alterations/sort.columns-alteration.js +33 -0
  150. package/esm2015/datatable/models/columns-alterations/width.columns-alteration.js +41 -0
  151. package/esm2015/datatable/models/datatable-accessor.js +1 -1
  152. package/esm2015/datatable/models/internal-column-props.js +15 -0
  153. package/esm2015/datatable/models/page-info.js +1 -1
  154. package/esm2015/datatable/models/preferences-accessor.js +1 -1
  155. package/esm2015/datatable/models/preferences.js +6 -2
  156. package/esm2015/datatable/models/sort-item.js +1 -1
  157. package/esm2015/datatable/public-api.js +3 -1
  158. package/esm2015/datatable/services/columns-alterations-manager.service.js +134 -0
  159. package/esm2015/datatable/services/columns-manager.service.js +257 -0
  160. package/esm2015/datatable/services/datatable-preferences.service.js +78 -32
  161. package/esm2015/datatable/theseam-ui-common-datatable.js +3 -1
  162. package/esm2015/datatable/tokens/datatable-preferences-accessor.js +2 -2
  163. package/esm2015/datatable/utils/create-action-menu-column.js +18 -0
  164. package/esm2015/datatable/utils/create-checkbox-column.js +15 -0
  165. package/esm2015/datatable/utils/get-column-prop.js +9 -0
  166. package/esm2015/datatable/utils/map-columns-alterations-states.js +39 -0
  167. package/esm2015/datatable/utils/remove-unused-diffs.js +9 -0
  168. package/esm2015/datatable/utils/set-column-defaults.js +10 -0
  169. package/esm2015/datatable/utils/translate-templates.js +12 -0
  170. package/esm2015/datatable/utils/with-stored-column-info.js +1 -1
  171. package/esm2015/datatable-dynamic/datatable-dynamic-action-menu/datatable-dynamic-action-menu.component.js +1 -1
  172. package/esm2015/datatable-dynamic/datatable-dynamic-filter-container/datatable-dynamic-filter-container.component.js +1 -1
  173. package/esm2015/datatable-dynamic/datatable-dynamic.component.js +1 -1
  174. package/esm2015/form-field/form-field.component.js +1 -1
  175. package/esm2015/form-field-error/form-field-error/form-field-error.component.js +1 -1
  176. package/esm2015/framework/base-layout/base-layout.component.js +1 -1
  177. package/esm2015/framework/dashboard/dashboard-widgets/dashboard-widgets.component.js +1 -1
  178. package/esm2015/framework/dynamic-router/hierarchy-router-outlet/hierarchy-router-outlet.component.js +1 -1
  179. package/esm2015/framework/schema-form-controls/schema-form-input/schema-form-input.component.js +1 -1
  180. package/esm2015/framework/schema-form-controls/schema-form-number/schema-form-number.component.js +1 -1
  181. package/esm2015/framework/schema-form-controls/schema-form-select/schema-form-select.component.js +1 -1
  182. package/esm2015/framework/schema-form-controls/schema-form-submit-split/schema-form-submit-split.component.js +1 -1
  183. package/esm2015/framework/side-nav/side-nav-item/side-nav-item.component.js +3 -3
  184. package/esm2015/framework/side-nav/side-nav-toggle/side-nav-toggle.component.js +1 -1
  185. package/esm2015/framework/side-nav/side-nav.component.js +1 -1
  186. package/esm2015/framework/top-bar/top-bar-menu-button/top-bar-menu-button.component.js +1 -1
  187. package/esm2015/framework/top-bar/top-bar-title/top-bar-title.component.js +1 -1
  188. package/esm2015/framework/top-bar/top-bar.component.js +1 -1
  189. package/esm2015/graphql/datatable/create-page-info-observable.js +38 -0
  190. package/esm2015/graphql/datatable/datatable-graphql-query-ref.js +236 -0
  191. package/esm2015/graphql/datatable/datatable-graphql.service.js +35 -0
  192. package/esm2015/graphql/datatable/datatable-helpers.js +170 -0
  193. package/esm2015/graphql/datatable/get-page-info.js +11 -0
  194. package/esm2015/graphql/datatable/index.js +7 -0
  195. package/esm2015/graphql/datatable/map-filter-states.js +64 -0
  196. package/esm2015/graphql/datatable/map-page-info.js +14 -0
  197. package/esm2015/graphql/datatable/mapper-context.js +2 -0
  198. package/esm2015/graphql/models/gql-datatable-accessor.js +2 -0
  199. package/esm2015/graphql/models/index.js +2 -1
  200. package/esm2015/graphql/models/query-processing-config.js +1 -1
  201. package/esm2015/graphql/public-api.js +2 -1
  202. package/esm2015/graphql/utils/parse-hints.js +3 -3
  203. package/esm2015/icon/icon/icon.component.js +1 -1
  204. package/esm2015/loading/loading/loading.component.js +1 -1
  205. package/esm2015/menu/menu.component.js +1 -1
  206. package/esm2015/modal/modal-body/modal-body.component.js +1 -1
  207. package/esm2015/modal/modal-container/modal-container.component.js +1 -1
  208. package/esm2015/popover/popover/popover.component.js +1 -1
  209. package/esm2015/progress/progress-circle/progress-circle.component.js +1 -1
  210. package/esm2015/tabbed/tabbed.component.js +1 -1
  211. package/esm2015/table/table/table.component.js +1 -1
  212. package/esm2015/table-cell-types/public-api.js +8 -1
  213. package/esm2015/table-cell-types/table-cell-type-currency/table-cell-type-currency-config.js +2 -0
  214. package/esm2015/table-cell-types/table-cell-type-currency/table-cell-type-currency.component.js +74 -0
  215. package/esm2015/table-cell-types/table-cell-type-currency/table-cell-type-currency.js +2 -0
  216. package/esm2015/table-cell-types/table-cell-type-decimal/table-cell-type-decimal-config.js +1 -1
  217. package/esm2015/table-cell-types/table-cell-type-decimal/table-cell-type-decimal.component.js +73 -0
  218. package/esm2015/table-cell-types/table-cell-type-decimal/table-cell-type-decimal.js +2 -0
  219. package/esm2015/table-cell-types/table-cell-type-icon/table-cell-type-icon.component.js +1 -1
  220. package/esm2015/table-cell-types/table-cell-type-integer/table-cell-type-integer-config.js +1 -1
  221. package/esm2015/table-cell-types/table-cell-type-integer/table-cell-type-integer.component.js +71 -0
  222. package/esm2015/table-cell-types/table-cell-type-integer/table-cell-type-integer.js +2 -0
  223. package/esm2015/table-cell-types/table-cell-type-manifests.js +29 -17
  224. package/esm2015/table-cell-types/table-cell-type-progress-circle/table-cell-type-progress-circle.component.js +1 -1
  225. package/esm2015/table-cell-types/table-cell-types.module.js +9 -2
  226. package/esm2015/tel-input/tel-input/tel-input.component.js +1 -1
  227. package/esm2015/testing/current-tick-time.js +16 -0
  228. package/esm2015/testing/fake-toastr.js +29 -0
  229. package/esm2015/testing/get-harness.js +16 -0
  230. package/esm2015/testing/public-api.js +7 -0
  231. package/esm2015/testing/render-story.js +12 -0
  232. package/esm2015/testing/story-expect.js +39 -0
  233. package/esm2015/testing/theseam-ui-common-testing.js +5 -0
  234. package/esm2015/testing/tick-helper.js +74 -0
  235. package/esm2015/tiled-select/components/tiled-select/tiled-select.component.js +25 -17
  236. package/esm2015/tiled-select/components/tiled-select-tile/tiled-select-tile.component.js +5 -2
  237. package/esm2015/tiled-select/components/tiled-select-tile-icon/tiled-select-tile-icon.component.js +1 -1
  238. package/esm2015/tiled-select/public-api.js +2 -1
  239. package/esm2015/tiled-select/tiled-select.models.js +1 -1
  240. package/esm2015/tiled-select/tiled-select.module.js +4 -4
  241. package/esm2015/toggle-edit/toggle-edit-actions-container/toggle-edit-actions-container.component.js +1 -1
  242. package/esm2015/toggle-edit/toggle-edit.component.js +1 -1
  243. package/esm2015/utils/array-move.js +62 -0
  244. package/esm2015/utils/public-api.js +2 -1
  245. package/esm2015/utils/subscriber-count.js +31 -4
  246. package/esm2015/widget/widget/widget.component.js +1 -1
  247. package/esm2015/widget/widget-content-components/widget-button-group/widget-button-group.component.js +1 -1
  248. package/esm2015/widget/widget-content-components/widget-content-header/widget-content-header.component.js +1 -1
  249. package/esm2015/widget/widget-content-components/widget-empty-label/widget-empty-label.component.js +1 -1
  250. package/esm2015/widget/widget-content-components/widget-footer-link/widget-footer-link.component.js +1 -1
  251. package/esm2015/widget/widget-content-components/widget-footer-text/widget-footer-text.component.js +1 -1
  252. package/esm2015/widget/widget-content-components/widget-header-badge/widget-header-badge.component.js +1 -1
  253. package/esm2015/widget/widget-content-components/widget-tile/widget-tile-footer-item/widget-tile-footer-item.component.js +1 -1
  254. package/esm2015/widget/widget-content-components/widget-tile/widget-tile-group/widget-tile-group.component.js +1 -1
  255. package/esm2015/widget/widget-content-components/widget-tile/widget-tile.component.js +1 -1
  256. package/esm2015/widget/widget-content-components/widget-tile-list/widget-tile-list.component.js +1 -1
  257. package/esm2015/widget/widget-footer/widget-footer.component.js +1 -1
  258. package/fesm2015/theseam-ui-common-buttons.js +1 -1
  259. package/fesm2015/theseam-ui-common-card.js +2 -2
  260. package/fesm2015/theseam-ui-common-data-filters.js +6 -3
  261. package/fesm2015/theseam-ui-common-data-filters.js.map +1 -1
  262. package/fesm2015/theseam-ui-common-datatable-dynamic.js +3 -3
  263. package/fesm2015/theseam-ui-common-datatable.js +1136 -316
  264. package/fesm2015/theseam-ui-common-datatable.js.map +1 -1
  265. package/fesm2015/theseam-ui-common-form-field-error.js +1 -1
  266. package/fesm2015/theseam-ui-common-form-field.js +1 -1
  267. package/fesm2015/theseam-ui-common-framework.js +14 -14
  268. package/fesm2015/theseam-ui-common-framework.js.map +1 -1
  269. package/fesm2015/theseam-ui-common-graphql.js +555 -5
  270. package/fesm2015/theseam-ui-common-graphql.js.map +1 -1
  271. package/fesm2015/theseam-ui-common-icon.js +1 -1
  272. package/fesm2015/theseam-ui-common-loading.js +1 -1
  273. package/fesm2015/theseam-ui-common-menu.js +1 -1
  274. package/fesm2015/theseam-ui-common-modal.js +2 -2
  275. package/fesm2015/theseam-ui-common-popover.js +1 -1
  276. package/fesm2015/theseam-ui-common-progress.js +1 -1
  277. package/fesm2015/theseam-ui-common-tabbed.js +1 -1
  278. package/fesm2015/theseam-ui-common-table-cell-types.js +234 -22
  279. package/fesm2015/theseam-ui-common-table-cell-types.js.map +1 -1
  280. package/fesm2015/theseam-ui-common-table.js +1 -1
  281. package/fesm2015/theseam-ui-common-tel-input.js +1 -1
  282. package/fesm2015/theseam-ui-common-testing.js +191 -0
  283. package/fesm2015/theseam-ui-common-testing.js.map +1 -0
  284. package/fesm2015/theseam-ui-common-tiled-select.js +34 -21
  285. package/fesm2015/theseam-ui-common-tiled-select.js.map +1 -1
  286. package/fesm2015/theseam-ui-common-toggle-edit.js +2 -2
  287. package/fesm2015/theseam-ui-common-utils.js +92 -4
  288. package/fesm2015/theseam-ui-common-utils.js.map +1 -1
  289. package/fesm2015/theseam-ui-common-widget.js +12 -12
  290. package/form-field/theseam-ui-common-form-field.metadata.json +1 -1
  291. package/form-field-error/theseam-ui-common-form-field-error.metadata.json +1 -1
  292. package/framework/side-nav/side-nav-item/side-nav-item.component.scss +36 -9
  293. package/framework/theseam-ui-common-framework.metadata.json +1 -1
  294. package/graphql/datatable/create-page-info-observable.d.ts +4 -0
  295. package/graphql/datatable/datatable-graphql-query-ref.d.ts +65 -0
  296. package/graphql/datatable/datatable-graphql.service.d.ts +26 -0
  297. package/graphql/datatable/datatable-helpers.d.ts +12 -0
  298. package/graphql/datatable/get-page-info.d.ts +4 -0
  299. package/graphql/datatable/index.d.ts +6 -0
  300. package/graphql/datatable/map-filter-states.d.ts +18 -0
  301. package/graphql/datatable/map-page-info.d.ts +11 -0
  302. package/graphql/datatable/mapper-context.d.ts +6 -0
  303. package/graphql/models/gql-datatable-accessor.d.ts +9 -0
  304. package/graphql/models/index.d.ts +1 -0
  305. package/graphql/models/query-processing-config.d.ts +4 -0
  306. package/graphql/public-api.d.ts +1 -0
  307. package/graphql/theseam-ui-common-graphql.metadata.json +1 -1
  308. package/icon/theseam-ui-common-icon.metadata.json +1 -1
  309. package/loading/theseam-ui-common-loading.metadata.json +1 -1
  310. package/menu/theseam-ui-common-menu.metadata.json +1 -1
  311. package/modal/theseam-ui-common-modal.metadata.json +1 -1
  312. package/package.json +1 -1
  313. package/popover/theseam-ui-common-popover.metadata.json +1 -1
  314. package/progress/theseam-ui-common-progress.metadata.json +1 -1
  315. package/styles/common/_table.scss +0 -5
  316. package/styles/vendor/ngx-datatable/_ngx-datatable.scss +478 -87
  317. package/styles/vendor/ngx-datatable/_themes/bootstrap/_variables.scss +174 -0
  318. package/styles/vendor/ngx-datatable/_themes/dark/_variables.scss +166 -0
  319. package/styles/vendor/ngx-datatable/_themes/material/_variables.scss +165 -0
  320. package/styles/vendor/ngx-datatable/_variables.scss +3 -0
  321. package/tabbed/theseam-ui-common-tabbed.metadata.json +1 -1
  322. package/table/theseam-ui-common-table.metadata.json +1 -1
  323. package/table-cell-types/public-api.d.ts +7 -0
  324. package/table-cell-types/table-cell-type-currency/table-cell-type-currency-config.d.ts +39 -0
  325. package/table-cell-types/table-cell-type-currency/table-cell-type-currency.component.d.ts +19 -0
  326. package/table-cell-types/table-cell-type-currency/table-cell-type-currency.d.ts +3 -0
  327. package/table-cell-types/table-cell-type-decimal/table-cell-type-decimal-config.d.ts +31 -1
  328. package/table-cell-types/table-cell-type-decimal/table-cell-type-decimal.component.d.ts +19 -0
  329. package/table-cell-types/table-cell-type-decimal/table-cell-type-decimal.d.ts +3 -0
  330. package/table-cell-types/table-cell-type-integer/table-cell-type-integer-config.d.ts +23 -1
  331. package/table-cell-types/table-cell-type-integer/table-cell-type-integer.component.d.ts +19 -0
  332. package/table-cell-types/table-cell-type-integer/table-cell-type-integer.d.ts +3 -0
  333. package/table-cell-types/table-cell-type-manifests.d.ts +2 -1
  334. package/table-cell-types/theseam-ui-common-table-cell-types.metadata.json +1 -1
  335. package/tel-input/theseam-ui-common-tel-input.metadata.json +1 -1
  336. package/testing/current-tick-time.d.ts +13 -0
  337. package/testing/fake-toastr.d.ts +30 -0
  338. package/testing/get-harness.d.ts +7 -0
  339. package/testing/package.json +11 -0
  340. package/testing/public-api.d.ts +6 -0
  341. package/testing/render-story.d.ts +2 -0
  342. package/testing/story-expect.d.ts +5 -0
  343. package/{test-helpers/theseam-ui-common-test-helpers.d.ts → testing/theseam-ui-common-testing.d.ts} +0 -0
  344. package/testing/theseam-ui-common-testing.metadata.json +1 -0
  345. package/{test-helpers → testing}/tick-helper.d.ts +0 -0
  346. package/tiled-select/components/tiled-select/tiled-select.component.d.ts +7 -3
  347. package/tiled-select/components/tiled-select-tile/tiled-select-tile.component.d.ts +1 -0
  348. package/tiled-select/theseam-ui-common-tiled-select.metadata.json +1 -1
  349. package/tiled-select/tiled-select.models.d.ts +3 -1
  350. package/toggle-edit/theseam-ui-common-toggle-edit.metadata.json +1 -1
  351. package/utils/array-move.d.ts +49 -0
  352. package/utils/public-api.d.ts +1 -0
  353. package/utils/subscriber-count.d.ts +13 -1
  354. package/utils/theseam-ui-common-utils.metadata.json +1 -1
  355. package/widget/theseam-ui-common-widget.metadata.json +1 -1
  356. package/bundles/theseam-ui-common-test-helpers.umd.js +0 -94
  357. package/bundles/theseam-ui-common-test-helpers.umd.js.map +0 -1
  358. package/esm2015/test-helpers/public-api.js +0 -2
  359. package/esm2015/test-helpers/theseam-ui-common-test-helpers.js +0 -5
  360. package/esm2015/test-helpers/tick-helper.js +0 -74
  361. package/fesm2015/theseam-ui-common-test-helpers.js +0 -81
  362. package/fesm2015/theseam-ui-common-test-helpers.js.map +0 -1
  363. package/test-helpers/package.json +0 -11
  364. package/test-helpers/public-api.d.ts +0 -1
  365. package/test-helpers/theseam-ui-common-test-helpers.metadata.json +0 -1
@@ -1,16 +1,16 @@
1
- import { __decorate } from 'tslib';
1
+ import { __awaiter, __decorate } from 'tslib';
2
2
  import { trigger, transition, style, animate } from '@angular/animations';
3
3
  import { coerceArray } from '@angular/cdk/coercion';
4
- import * as i0 from '@angular/core';
5
- import { EventEmitter, Component, ChangeDetectionStrategy, Input, Output, ContentChildren, Directive, TemplateRef, Injectable, ContentChild, Self, Inject, forwardRef, InjectionToken, isDevMode, Optional, KeyValueDiffers, ViewChild, ElementRef, HostBinding, ViewContainerRef, HostListener, NgZone, NgModule } from '@angular/core';
6
- import { BehaviorSubject, of, Subject, Subscription, isObservable, combineLatest } from 'rxjs';
7
- import { switchMap, map, startWith, shareReplay, take, tap, concatMap, takeUntil, catchError } from 'rxjs/operators';
8
4
  import { DataSource, isDataSource } from '@angular/cdk/collections';
5
+ import * as i0 from '@angular/core';
6
+ import { EventEmitter, Component, ChangeDetectionStrategy, Input, Output, ContentChildren, Directive, TemplateRef, Injectable, ContentChild, Self, Inject, forwardRef, KeyValueDiffers, InjectionToken, isDevMode, Optional, ViewChild, ElementRef, HostListener, HostBinding, ViewContainerRef, NgZone, NgModule } from '@angular/core';
7
+ import { Subject, BehaviorSubject, of, defer, combineLatest, EMPTY, Subscription, from, isObservable } from 'rxjs';
8
+ import { switchMap, map, startWith, auditTime, shareReplay, tap, take, distinctUntilChanged, takeUntil, concatMap, catchError } from 'rxjs/operators';
9
9
  import { faEllipsisH, faChevronDown, faChevronRight, faSpinner, faColumns, faFileDownload } from '@fortawesome/free-solid-svg-icons';
10
- import { setColumnDefaults, ColumnMode, SortType, translateTemplates, DatatableComponent as DatatableComponent$1, DatatableRowDetailDirective, NgxDatatableModule, ScrollbarHelper } from '@marklb/ngx-datatable';
10
+ import { camelCase, setColumnDefaults as setColumnDefaults$1, translateTemplates, SelectionType, SortType, ColumnMode, DatatableComponent as DatatableComponent$1, DatatableRowDetailDirective, NgxDatatableModule, ScrollbarHelper } from '@marklb/ngx-datatable';
11
11
  import { InputBoolean, InputNumber } from '@theseam/ui-common/core';
12
12
  import { THESEAM_DATA_FILTER, THESEAM_DATA_FILTER_CONTAINER, composeDataFilterStates, composeDataFilters } from '@theseam/ui-common/data-filters';
13
- import { notNullOrUndefined, hasProperty, observeControlValue } from '@theseam/ui-common/utils';
13
+ import { notNullOrUndefined, hasProperty, arrayMoveMutable, waitOnConditionAsync, observeControlValue } from '@theseam/ui-common/utils';
14
14
  import { Router, RouterModule } from '@angular/router';
15
15
  import { SeamConfirmDialogService, TheSeamConfirmDialogModule } from '@theseam/ui-common/confirm-dialog';
16
16
  import { FormControl, ReactiveFormsModule } from '@angular/forms';
@@ -36,45 +36,6 @@ import { TheSeamPopoverModule } from '@theseam/ui-common/popover';
36
36
  import { TheSeamSharedModule } from '@theseam/ui-common/shared';
37
37
  import { TheSeamTableCellTypeModule } from '@theseam/ui-common/table-cell-type';
38
38
 
39
- class DatatableDataSource extends DataSource {
40
- constructor() {
41
- super();
42
- this._datatableSubject = new BehaviorSubject(undefined);
43
- this.sorts$ = this._datatableSubject.pipe(switchMap(_datatable => {
44
- if (!_datatable) {
45
- return of([]);
46
- }
47
- return _datatable.sort.pipe(map(v => v.sorts), startWith(_datatable.sorts));
48
- }));
49
- this.filterStates$ = this._datatableSubject.pipe(switchMap(_datatable => {
50
- if (!_datatable) {
51
- return of([]);
52
- }
53
- return _datatable.filterStates;
54
- }));
55
- this.page$ = this._datatableSubject.pipe(switchMap(_datatable => {
56
- if (!_datatable) {
57
- return of({
58
- offset: 0,
59
- pageSize: 0,
60
- limit: undefined,
61
- count: 0
62
- });
63
- }
64
- return _datatable.page.pipe(startWith(_datatable.pageInfo));
65
- }));
66
- }
67
- // connect(): Observable<readonly TRow[]> {
68
- // return this.
69
- // }
70
- // disconnect(): void {
71
- // throw new Error('Method not implemented.')
72
- // }
73
- setDatatableAccessor(accessor) {
74
- this._datatableSubject.next(accessor);
75
- }
76
- }
77
-
78
39
  class DatatableActionMenuItemComponent {
79
40
  constructor() {
80
41
  this.click = new EventEmitter();
@@ -189,7 +150,7 @@ DatatableActionMenuComponent.decorators = [
189
150
  { type: Component, args: [{
190
151
  selector: 'seam-datatable-action-menu',
191
152
  template: "<seam-menu #menu\n menuClass=\"list-group py-0 border-0 seam-datatable-action-menu\"\n animationType=\"fade\">\n\n <ng-container *ngFor=\"let item of items\">\n <ng-container *ngIf=\"(item.routerLink || item.href) && !item.confirmDialog; else noRouterLink\">\n <a *ngIf=\"item.href; else noHref\"\n seamMenuItem\n class=\"list-group-item list-group-item-action py-1\"\n [disabled]=\"item.disabled\"\n [attr.href]=\"item.href\"\n [target]=\"item.target\"\n (click)=\"activateItem($event, item)\">\n {{ item.label }}\n </a>\n <ng-template #noHref>\n <a seamMenuItem\n class=\"list-group-item list-group-item-action py-1\"\n [disabled]=\"item.disabled\"\n [queryParams]=\"item.queryParams\"\n [fragment]=\"$any(item.fragment)\"\n [queryParamsHandling]=\"item.queryParamsHandling\"\n [preserveFragment]=\"$any(item.preserveFragment)\"\n [skipLocationChange]=\"$any(item.skipLocationChange)\"\n [replaceUrl]=\"$any(item.replaceUrl)\"\n [state]=\"$any(item.state)\"\n [routerLink]=\"item.routerLink\"\n [target]=\"$any(item.target)\"\n (click)=\"activateItem($event, item)\">\n {{ item.label }}\n </a>\n </ng-template>\n </ng-container>\n <ng-template #noRouterLink>\n <button seamMenuItem\n type=\"button\"\n class=\"list-group-item list-group-item-action py-1\"\n [disabled]=\"item.disabled\"\n (click)=\"activateItem($event, item)\">\n {{ item.label }}\n </button>\n </ng-template>\n </ng-container>\n</seam-menu>\n\n<button type=\"button\" class=\"datatable-action-button btn\"\n [seamMenuToggle]=\"menu\"\n [positions]=\"_actionMenuPositions || []\"\n title=\"Row Actions\">\n <seam-icon [icon]=\"faEllipsisH\"></seam-icon>\n</button>\n",
192
- styles: [":host{display:block;position:relative}.datatable-action-button{font-size:20px;line-height:20px;width:30px;height:30px;padding:0;border-radius:15px;text-align:center}.datatable-action-button::ng-deep .svg-inline--fa{vertical-align:middle}"]
153
+ styles: [":host{display:block;position:relative}.datatable-action-button{font-size:20px;line-height:20px;width:30px;height:30px;padding:0;border-radius:15px;text-align:center}.datatable-action-button::ng-deep .svg-inline--fa{vertical-align:middle}\n"]
193
154
  },] }
194
155
  ];
195
156
  DatatableActionMenuComponent.ctorParameters = () => [
@@ -309,6 +270,36 @@ DatatableColumnComponent.propDecorators = {
309
270
  _cellTemplateQuery: [{ type: ContentChild, args: [DatatableCellTplDirective, { read: TemplateRef, static: true },] }]
310
271
  };
311
272
 
273
+ class DatatableFooterTplDirective {
274
+ constructor(template) {
275
+ this.template = template;
276
+ }
277
+ }
278
+ DatatableFooterTplDirective.decorators = [
279
+ { type: Directive, args: [{
280
+ selector: '[seamDatatableFooterTpl]'
281
+ },] }
282
+ ];
283
+ DatatableFooterTplDirective.ctorParameters = () => [
284
+ { type: TemplateRef }
285
+ ];
286
+
287
+ class TheSeamDatatableFooterDirective {
288
+ get template() {
289
+ return this._templateInput || this._templateQuery;
290
+ }
291
+ }
292
+ TheSeamDatatableFooterDirective.decorators = [
293
+ { type: Directive, args: [{
294
+ // tslint:disable-next-line: directive-selector
295
+ selector: 'seam-datatable-footer'
296
+ },] }
297
+ ];
298
+ TheSeamDatatableFooterDirective.propDecorators = {
299
+ _templateInput: [{ type: Input, args: ['template',] }],
300
+ _templateQuery: [{ type: ContentChild, args: [DatatableFooterTplDirective, { read: TemplateRef, static: true },] }]
301
+ };
302
+
312
303
  class DatatableFilterDirective {
313
304
  constructor(dataFilters) {
314
305
  if (dataFilters && dataFilters.length > 0) {
@@ -371,7 +362,7 @@ DatatableMenuBarComponent.decorators = [
371
362
  selector: 'seam-datatable-menu-bar',
372
363
  template: "<div class=\"bg-light border rounded p-2\">\n <ng-content></ng-content>\n</div>\n",
373
364
  providers: [_THESEAM_DATA_FILTER_CONTAINER],
374
- styles: [":host{display:block}"]
365
+ styles: [":host{display:block}\n"]
375
366
  },] }
376
367
  ];
377
368
  DatatableMenuBarComponent.ctorParameters = () => [];
@@ -474,34 +465,368 @@ DatatableRowActionItemDirective.ctorParameters = () => [
474
465
  { type: TemplateRef }
475
466
  ];
476
467
 
477
- const THESEAM_DATATABLE_PREFERENCES_ACCESSOR = new InjectionToken('ITheSeamDatatablePreferencesAccessor');
468
+ class DatatableDataSource extends DataSource {
469
+ constructor() {
470
+ super();
471
+ this._datatableSubject = new BehaviorSubject(undefined);
472
+ this.sorts$ = this._datatableSubject.pipe(switchMap(_datatable => {
473
+ if (!_datatable) {
474
+ return of([]);
475
+ }
476
+ return _datatable.sort.pipe(map(v => v.sorts), startWith(_datatable.sorts));
477
+ }));
478
+ this.filterStates$ = this._datatableSubject.pipe(switchMap(_datatable => {
479
+ if (!_datatable) {
480
+ return of([]);
481
+ }
482
+ return _datatable.filterStates;
483
+ }));
484
+ this.page$ = this._datatableSubject.pipe(switchMap(_datatable => {
485
+ if (!_datatable) {
486
+ return of({
487
+ offset: 0,
488
+ pageSize: 0,
489
+ limit: undefined,
490
+ count: 0
491
+ });
492
+ }
493
+ return _datatable.page.pipe(startWith(_datatable.pageInfo));
494
+ }));
495
+ }
496
+ // connect(): Observable<readonly TRow[]> {
497
+ // return this.
498
+ // }
499
+ // disconnect(): void {
500
+ // throw new Error('Method not implemented.')
501
+ // }
502
+ setDatatableAccessor(accessor) {
503
+ this._datatableSubject.next(accessor);
504
+ }
505
+ }
478
506
 
479
- function withStoredColumnInfo(columns, preferenceColumns) {
480
- const _columns = [];
481
- for (const col of columns) {
482
- const storedCol = preferenceColumns.find(v => v.prop === col.prop);
483
- if (storedCol) {
484
- const _col = Object.assign({}, col);
485
- if (hasProperty(storedCol, 'width')) {
486
- _col.width = Math.max(storedCol.width, 0);
507
+ const ACTION_MENU_COLUMN_PROP = '$$__actionMenu__';
508
+ function createActionMenuColumn(cellTemplate, headerTemplate) {
509
+ return {
510
+ prop: ACTION_MENU_COLUMN_PROP,
511
+ name: '',
512
+ width: 50,
513
+ minWidth: 50,
514
+ maxWidth: 50,
515
+ resizeable: false,
516
+ sortable: false,
517
+ draggable: false,
518
+ // TODO: Fix column auto sizing with fixed column and cell overlay before enabling.
519
+ // frozenRight: true,
520
+ cellTemplate,
521
+ headerTemplate,
522
+ };
523
+ }
524
+
525
+ const CHECKBOX_COLUMN_PROP = '$$__checkbox__';
526
+ function createCheckboxColumn() {
527
+ return {
528
+ prop: CHECKBOX_COLUMN_PROP,
529
+ name: '',
530
+ width: 40,
531
+ sortable: false,
532
+ canAutoResize: false,
533
+ draggable: false,
534
+ resizeable: false,
535
+ headerCheckboxable: true,
536
+ checkboxable: true,
537
+ };
538
+ }
539
+
540
+ function getColumnProp(col) {
541
+ if (!notNullOrUndefined(col.prop) && col.name) {
542
+ return camelCase(col.name);
543
+ }
544
+ return col.prop === null ? undefined : col.prop;
545
+ }
546
+
547
+ function setColumnDefaults(columns) {
548
+ for (const column of columns) {
549
+ if (!column.hasOwnProperty('hidden')) {
550
+ column.hidden = false;
551
+ }
552
+ }
553
+ setColumnDefaults$1(columns);
554
+ }
555
+
556
+ // TODO: Replace with a `translateTemplates` function that fits the
557
+ // wrapper component better.
558
+ function translateTemplateColumns(v) {
559
+ const cols = translateTemplates(v);
560
+ for (const col of cols) {
561
+ col.prop = getColumnProp(col);
562
+ }
563
+ return cols;
564
+ }
565
+
566
+ var ColumnsTypes;
567
+ (function (ColumnsTypes) {
568
+ ColumnsTypes[ColumnsTypes["Input"] = 0] = "Input";
569
+ ColumnsTypes[ColumnsTypes["Template"] = 1] = "Template";
570
+ ColumnsTypes[ColumnsTypes["Result"] = 2] = "Result";
571
+ })(ColumnsTypes || (ColumnsTypes = {}));
572
+ class ColumnsManagerService {
573
+ constructor(_differs, _columnChangesService) {
574
+ this._differs = _differs;
575
+ this._columnChangesService = _columnChangesService;
576
+ this._updateColumns = new Subject();
577
+ this._inputColumns = new BehaviorSubject([]);
578
+ this._templateColumns = new BehaviorSubject([]);
579
+ this._inpColDiffersMap = new Map();
580
+ this._tplColDiffersMap = new Map();
581
+ this._resultColDiffersMap = new Map();
582
+ const templateColumns$ = this._columnChangesService.columnInputChanges$.pipe(startWith(undefined), switchMap(() => {
583
+ return this._templateColumns.asObservable().pipe(map(translateTemplateColumns));
584
+ }));
585
+ this.columns$ = defer(() => {
586
+ let isFirst = true;
587
+ return combineLatest([
588
+ this._inputColumns.asObservable(),
589
+ templateColumns$,
590
+ this._updateColumns.asObservable().pipe(auditTime(0), startWith(undefined))
591
+ ]).pipe(switchMap(([inputColumns, templateColumns]) => {
592
+ const cols = this._mergeColumns(inputColumns, templateColumns);
593
+ const hasColumnsChanged = this._hasColumnsChanged(cols);
594
+ // TODO: Look for columns added/removed and remove the removed columns
595
+ // differs, not just changes to columns.
596
+ const hasAddedOrRemovedColumns = this._hasAddedOrRemovedColumns(cols);
597
+ // NOTE: Both checks need to be run, even though only one needs to be
598
+ // true, because their differs need to be called.
599
+ if (hasColumnsChanged || hasAddedOrRemovedColumns || isFirst) {
600
+ isFirst = false;
601
+ return of(cols);
602
+ }
603
+ return EMPTY;
604
+ }));
605
+ }).pipe(shareReplay({ refCount: true, bufferSize: 1 }));
606
+ }
607
+ setInputColumns(columns) {
608
+ this._inputColumns.next(columns);
609
+ }
610
+ setTemplateColumns(columns) {
611
+ this._templateColumns.next(columns);
612
+ }
613
+ setInternalColumnsGetter(getter) {
614
+ this._internalColumnsGetter = getter || undefined;
615
+ this._updateColumns.next(undefined);
616
+ }
617
+ setSelectionType(selectionType) {
618
+ const changed = this._selectionType !== selectionType;
619
+ this._selectionType = selectionType;
620
+ if (changed) {
621
+ this._updateColumns.next(undefined);
622
+ }
623
+ }
624
+ getSelectionType() {
625
+ return this._selectionType;
626
+ }
627
+ setRowActionItem(rowActionItem) {
628
+ const changed = this._rowActionItem !== rowActionItem;
629
+ this._rowActionItem = rowActionItem;
630
+ if (changed) {
631
+ this._updateColumns.next(undefined);
632
+ }
633
+ }
634
+ setActionMenuCellTpl(actionMenuCellTpl) {
635
+ const changed = this._actionMenuCellTpl !== actionMenuCellTpl;
636
+ this._actionMenuCellTpl = actionMenuCellTpl;
637
+ if (changed) {
638
+ this._updateColumns.next(undefined);
639
+ }
640
+ }
641
+ setBlankHeaderTpl(blankHeaderTpl) {
642
+ const changed = this._blankHeaderTpl !== blankHeaderTpl;
643
+ this._blankHeaderTpl = blankHeaderTpl;
644
+ if (changed) {
645
+ this._updateColumns.next(undefined);
646
+ }
647
+ }
648
+ setTreeToggleTpl(treeToggleTpl) {
649
+ const changed = this._treeToggleTpl !== treeToggleTpl;
650
+ this._treeToggleTpl = treeToggleTpl;
651
+ if (changed) {
652
+ this._updateColumns.next(undefined);
653
+ }
654
+ }
655
+ setHeaderTpl(headerTpl) {
656
+ const changed = this._headerTpl !== headerTpl;
657
+ this._headerTpl = headerTpl;
658
+ if (changed) {
659
+ this._updateColumns.next(undefined);
660
+ }
661
+ }
662
+ setCellTypeSelectorTpl(cellTypeSelectorTpl) {
663
+ const changed = this._cellTypeSelectorTpl !== cellTypeSelectorTpl;
664
+ this._cellTypeSelectorTpl = cellTypeSelectorTpl;
665
+ if (changed) {
666
+ this._updateColumns.next(undefined);
667
+ }
668
+ }
669
+ _mergeColumns(inputColumns, templateColumns) {
670
+ const cols = [];
671
+ // Add the first column checkbox if 'checkbox' selection is enabled.
672
+ if (this._shouldAddCheckboxColumn()) {
673
+ cols.push(createCheckboxColumn());
674
+ }
675
+ // Column needs to be provided in the inputColumns, so iterate the
676
+ // inputColumns.
677
+ for (const inpCol of inputColumns) {
678
+ const prop = getColumnProp(inpCol);
679
+ if (!notNullOrUndefined(prop)) {
680
+ throw Error(`Column may have 'prop' or 'name' defined.`);
487
681
  }
488
- _col.canAutoResize = storedCol.canAutoResize;
489
- _columns.push(_col);
682
+ const internalCol = this._getInternalColumn(prop);
683
+ const inpColDif = this._getColDif(inpCol, ColumnsTypes.Input);
684
+ if (notNullOrUndefined(inpColDif)) {
685
+ this._updateColDif(inpColDif, internalCol, inpCol);
686
+ }
687
+ const tplCol = this._findColumnByProp(prop, templateColumns);
688
+ if (tplCol !== undefined) {
689
+ const tplColDif = this._getColDif(tplCol, ColumnsTypes.Template);
690
+ if (notNullOrUndefined(tplColDif)) {
691
+ this._updateColDif(tplColDif, internalCol, tplCol);
692
+ }
693
+ }
694
+ const _col = Object.assign(Object.assign(Object.assign({}, (internalCol || {})), inpCol), (tplCol || {}));
695
+ if (this._shouldAddTreeToggleColumn(_col)) {
696
+ _col.treeToggleTemplate = this._treeToggleTpl;
697
+ }
698
+ if (this._shouldAddHeaderTemplate(_col)) {
699
+ _col.headerTemplate = this._headerTpl;
700
+ }
701
+ if (this._shouldAddCellTypeSelectorTpl(_col)) {
702
+ _col.cellTemplate = this._cellTypeSelectorTpl;
703
+ }
704
+ cols.push(_col);
490
705
  }
491
- else {
492
- _columns.push(col);
706
+ if (this._shouldAddRowActionColumn()) {
707
+ cols.push(createActionMenuColumn(this._actionMenuCellTpl, this._blankHeaderTpl));
493
708
  }
709
+ // Make sure the default for any missing props are set.
710
+ // TODO: Determine if this should be done earlier, because I don't like
711
+ // how this is done after dif checks.
712
+ setColumnDefaults(cols);
713
+ return cols;
494
714
  }
495
- return _columns;
496
- }
715
+ _getInternalColumns() {
716
+ if (this._internalColumnsGetter === undefined) {
717
+ return undefined;
718
+ }
719
+ return this._internalColumnsGetter();
720
+ }
721
+ _getInternalColumn(prop) {
722
+ const internalCols = this._getInternalColumns();
723
+ if (internalCols === undefined) {
724
+ return undefined;
725
+ }
726
+ return internalCols.find(c => getColumnProp(c) === prop);
727
+ }
728
+ _findColumnByProp(prop, columns) {
729
+ return columns.find(c => getColumnProp(c) === prop);
730
+ }
731
+ _getDifMapForColumnsType(columnsType) {
732
+ switch (columnsType) {
733
+ case ColumnsTypes.Input: return this._inpColDiffersMap;
734
+ case ColumnsTypes.Template: return this._tplColDiffersMap;
735
+ case ColumnsTypes.Result: return this._resultColDiffersMap;
736
+ }
737
+ }
738
+ _getColumnDiffer(prop, colsType) {
739
+ const difMap = this._getDifMapForColumnsType(colsType);
740
+ if (difMap === null) {
741
+ throw Error(`Invalid columns type.`);
742
+ }
743
+ if (!difMap.has(prop)) {
744
+ difMap.set(prop, this._differs.find({}).create());
745
+ }
746
+ const differ = difMap.get(prop);
747
+ if (differ === undefined) {
748
+ throw Error(`Differ not found. New differ should have been created.`);
749
+ }
750
+ return differ;
751
+ }
752
+ _getColDif(col, colsType) {
753
+ const prop = getColumnProp(col);
754
+ if (prop === undefined) {
755
+ throw Error(`Column prop not found.`);
756
+ }
757
+ return this._getColumnDiffer(prop, colsType).diff(col);
758
+ }
759
+ _updateColDif(colDif, internalColumn, col) {
760
+ colDif.forEachRemovedItem(r => {
761
+ if (internalColumn && internalColumn.hasOwnProperty(r.key)) {
762
+ const k = r.key;
763
+ delete internalColumn[k];
764
+ }
765
+ });
766
+ colDif.forEachAddedItem(r => col[r.key] = r.currentValue);
767
+ colDif.forEachChangedItem(r => col[r.key] = r.currentValue);
768
+ }
769
+ _hasAddedOrRemovedColumns(columns) {
770
+ if (!this._colPropsDiffer) {
771
+ this._colPropsDiffer = this._differs.find([]).create();
772
+ }
773
+ const props = columns.map(c => getColumnProp(c));
774
+ return this._colPropsDiffer.diff(props) !== null;
775
+ }
776
+ _hasColumnsChanged(columns) {
777
+ let colChanged = false;
778
+ for (const col of columns) {
779
+ const resultDif = this._getColDif(col, ColumnsTypes.Result);
780
+ if (resultDif) {
781
+ // NOTE: Can't return early, because the differs need to be updated.
782
+ colChanged = true;
783
+ }
784
+ }
785
+ return colChanged;
786
+ }
787
+ _shouldAddCheckboxColumn() {
788
+ return this._selectionType === SelectionType.checkbox;
789
+ }
790
+ _shouldAddRowActionColumn() {
791
+ return this._rowActionItem !== undefined;
792
+ }
793
+ _shouldAddTreeToggleColumn(column) {
794
+ return column.isTreeColumn !== undefined && column.isTreeColumn &&
795
+ (!hasProperty(column, 'treeToggleTemplate') || !notNullOrUndefined(column.treeToggleTemplate));
796
+ }
797
+ _shouldAddHeaderTemplate(column) {
798
+ return !hasProperty(column, 'headerTemplate');
799
+ }
800
+ _shouldAddCellTypeSelectorTpl(column) {
801
+ return hasProperty(column, 'cellType');
802
+ }
803
+ }
804
+ ColumnsManagerService.decorators = [
805
+ { type: Injectable }
806
+ ];
807
+ ColumnsManagerService.ctorParameters = () => [
808
+ { type: KeyValueDiffers },
809
+ { type: DatatableColumnChangesService }
810
+ ];
497
811
 
812
+ const CURRENT_DATATABLE_PREFERENCES_VERSION = 2;
813
+ const EMPTY_DATATABLE_PREFERENCES = {
814
+ version: 2,
815
+ alterations: []
816
+ };
817
+
818
+ const THESEAM_DATATABLE_PREFERENCES_ACCESSOR = new InjectionToken('TheSeamDatatablePreferencesAccessor');
819
+
820
+ // TODO: Add per key status
498
821
  class DatatablePreferencesService {
499
822
  constructor(_prefsAccessor) {
500
823
  this._prefsAccessor = _prefsAccessor;
501
824
  this._tablePrefsMap = new Map();
502
825
  this._pending = false;
826
+ this._loaded = false;
503
827
  }
504
828
  get pending() { return this._pending; }
829
+ get loaded() { return this._loaded; }
505
830
  preferences(preferenceKey) {
506
831
  let prefs = this._tablePrefsMap.get(preferenceKey);
507
832
  if (!prefs) {
@@ -516,16 +841,17 @@ class DatatablePreferencesService {
516
841
  }
517
842
  _createObservable(refreshSubject, prefKey) {
518
843
  if (!this._prefsAccessor) {
519
- return of({});
844
+ return of(EMPTY_DATATABLE_PREFERENCES);
520
845
  }
521
- const accessor = (key) => this._prefsAccessor ? this._prefsAccessor.get(key) : of('{}');
522
- return refreshSubject.pipe(startWith({}), switchMap(() => accessor(prefKey).pipe(map(v => {
846
+ const accessor = (key) => this._prefsAccessor ? this._prefsAccessor.get(key) : of(JSON.stringify(EMPTY_DATATABLE_PREFERENCES));
847
+ return refreshSubject.pipe(startWith(undefined), switchMap(() => accessor(prefKey).pipe(map(v => {
523
848
  if (!v) {
524
849
  return null;
525
850
  }
526
851
  // TODO: Add a schema validator and migration tool to avoid parsing issues.
527
852
  try {
528
- return JSON.parse(v);
853
+ // return JSON.parse(v) as TheSeamDatatablePreferences
854
+ return this._descerializePreferences(v);
529
855
  }
530
856
  catch (error) {
531
857
  if (isDevMode()) {
@@ -533,7 +859,12 @@ class DatatablePreferencesService {
533
859
  }
534
860
  return null;
535
861
  }
536
- }), map(v => !!v ? v : {}))), shareReplay(1));
862
+ }), map(v => notNullOrUndefined(v) ? v : EMPTY_DATATABLE_PREFERENCES),
863
+ // tap(v => console.log('preferences$', v)),
864
+ tap(() => {
865
+ this._pending = false;
866
+ this._loaded = true;
867
+ }))), shareReplay({ bufferSize: 1, refCount: true }));
537
868
  }
538
869
  refresh(preferenceKey) {
539
870
  const prefs = this._tablePrefsMap.get(preferenceKey);
@@ -549,7 +880,40 @@ class DatatablePreferencesService {
549
880
  // out of order updates. This shouldn't be an issue, with how fast preferences
550
881
  // will most likely be changing, but it could happen in situations, such as
551
882
  // network issues.
552
- setColumnPreference(preferenceKey, column) {
883
+ // public setColumnPreference(preferenceKey: string, column: TheSeamDatatablePreferencesColumn): void {
884
+ // if (!this._prefsAccessor) {
885
+ // return
886
+ // }
887
+ // this._pending = true
888
+ // this.preferences(preferenceKey).pipe(
889
+ // map(prefs => {
890
+ // // Making the preferences immutable may not be necessary, but for now
891
+ // // this obj->str->obj will work as a naive clone.
892
+ // const columns = JSON.parse(JSON.stringify(prefs.columns || []))
893
+ // const _colPref = columns.find((c: any) => c.prop === column.prop)
894
+ // // console.log('has', _colPref)
895
+ // if (_colPref) {
896
+ // // console.log('hasProperty(column, "width"))', hasProperty(column, 'width'))
897
+ // if (hasProperty(column, 'width')) { _colPref.width = column.width }
898
+ // if (hasProperty(column, 'canAutoResize')) { _colPref.canAutoResize = column.canAutoResize }
899
+ // if (hasProperty(column, 'hidden')) { _colPref.hidden = column.hidden }
900
+ // } else {
901
+ // columns.push({ ...column })
902
+ // }
903
+ // const newPrefs: TheSeamDatatablePreferences = { ...prefs, columns }
904
+ // return newPrefs
905
+ // }),
906
+ // // tap(v => console.log('newPrefs', v)),
907
+ // take(1),
908
+ // switchMap(newPrefs => this._prefsAccessor
909
+ // ? this._prefsAccessor.update(preferenceKey, JSON.stringify(newPrefs))
910
+ // : of(newPrefs)
911
+ // ),
912
+ // tap(() => this.refresh(preferenceKey))
913
+ // )
914
+ // .subscribe()
915
+ // }
916
+ setAlterations(preferenceKey, alterations) {
553
917
  if (!this._prefsAccessor) {
554
918
  return;
555
919
  }
@@ -557,25 +921,20 @@ class DatatablePreferencesService {
557
921
  this.preferences(preferenceKey).pipe(map(prefs => {
558
922
  // Making the preferences immutable may not be necessary, but for now
559
923
  // this obj->str->obj will work as a naive clone.
560
- const columns = JSON.parse(JSON.stringify(prefs.columns || []));
561
- const _colPref = columns.find((c) => c.prop === column.prop);
562
- // console.log('has', _colPref)
563
- if (_colPref) {
564
- // console.log('hasProperty(column, "width"))', hasProperty(column, 'width'))
565
- if (hasProperty(column, 'width')) {
566
- _colPref.width = column.width;
567
- }
568
- if (hasProperty(column, 'canAutoResize')) {
569
- _colPref.canAutoResize = column.canAutoResize;
570
- }
571
- if (hasProperty(column, 'hidden')) {
572
- _colPref.hidden = column.hidden;
573
- }
574
- }
575
- else {
576
- columns.push(Object.assign({}, column));
577
- }
578
- const newPrefs = Object.assign(Object.assign({}, prefs), { columns });
924
+ // const columns = JSON.parse(JSON.stringify(prefs.columns || []))
925
+ // const _colPref = columns.find((c: any) => c.prop === column.prop)
926
+ // // console.log('has', _colPref)
927
+ // if (_colPref) {
928
+ // // console.log('hasProperty(column, "width"))', hasProperty(column, 'width'))
929
+ // if (hasProperty(column, 'width')) { _colPref.width = column.width }
930
+ // if (hasProperty(column, 'canAutoResize')) { _colPref.canAutoResize = column.canAutoResize }
931
+ // if (hasProperty(column, 'hidden')) { _colPref.hidden = column.hidden }
932
+ // } else {
933
+ // columns.push({ ...column })
934
+ // }
935
+ // const newPrefs: TheSeamDatatablePreferences = { ...prefs, columns }
936
+ // return newPrefs
937
+ const newPrefs = Object.assign(Object.assign({}, EMPTY_DATATABLE_PREFERENCES), { alterations });
579
938
  return newPrefs;
580
939
  }),
581
940
  // tap(v => console.log('newPrefs', v)),
@@ -584,10 +943,19 @@ class DatatablePreferencesService {
584
943
  : of(newPrefs)), tap(() => this.refresh(preferenceKey)))
585
944
  .subscribe();
586
945
  }
587
- withColumnPreferences(preferenceKey, columns) {
588
- return this.preferences(preferenceKey).pipe(startWith({}), map(preferences => preferences && preferences.columns
589
- ? withStoredColumnInfo(columns, preferences.columns)
590
- : columns));
946
+ // public withColumnPreferences<T>(preferenceKey: string, columns: T[]): Observable<T[]> {
947
+ // return this.preferences(preferenceKey).pipe(
948
+ // startWith(EMPTY_DATATABLE_PREFERENCES),
949
+ // map(preferences => preferences && preferences.columns
950
+ // ? withStoredColumnInfo(columns, preferences.columns) as T[]
951
+ // : columns
952
+ // )
953
+ // )
954
+ // }
955
+ _descerializePreferences(serialized) {
956
+ const prefs = JSON.parse(serialized);
957
+ // TODO: Implement migration
958
+ return prefs;
591
959
  }
592
960
  }
593
961
  DatatablePreferencesService.ɵprov = i0.ɵɵdefineInjectable({ factory: function DatatablePreferencesService_Factory() { return new DatatablePreferencesService(i0.ɵɵinject(THESEAM_DATATABLE_PREFERENCES_ACCESSOR, 8)); }, token: DatatablePreferencesService, providedIn: "root" });
@@ -602,14 +970,406 @@ DatatablePreferencesService.ctorParameters = () => [
602
970
 
603
971
  const THESEAM_DATATABLE_ACCESSOR = new InjectionToken('TheSeamDatatableAccessor');
604
972
 
605
- function _setColumnDefaults(columns) {
606
- for (const column of columns) {
607
- if (!column.hasOwnProperty('hidden')) {
608
- column.hidden = false;
973
+ function removeUnusedDiffs(cols, colDiffersInp, colDiffersTpl) {
974
+ const inpKeys = Object.keys(colDiffersInp);
975
+ inpKeys.filter(k => cols.findIndex(c => c.prop === k) === -1)
976
+ .forEach(k => { delete colDiffersInp[k]; });
977
+ const tplKeys = Object.keys(colDiffersTpl);
978
+ tplKeys.filter(k => cols.findIndex(c => c.prop === k) === -1)
979
+ .forEach(k => { delete colDiffersTpl[k]; });
980
+ }
981
+
982
+ /**
983
+ * Alteration applied to a column or columns that can be persisted.
984
+ *
985
+ * Tracking if a column was altered by user or library code can be confusing.
986
+ * This allows us to store a list of replayable alterations on columns. By
987
+ * having a defined way to implement alterations, the datatable should be easier
988
+ * to support external features that want to provide an alteration.
989
+ *
990
+ * NOTE: Current, to unapply an alteration you can create an alteration with
991
+ * `persistent` set to false and the alteration will be removed after `apply()`
992
+ * is called.
993
+ */
994
+ class ColumnsAlteration {
995
+ constructor(
996
+ /**
997
+ * Persistable state.
998
+ *
999
+ * Returned value should be JSON stringifyable.
1000
+ */
1001
+ state,
1002
+ /**
1003
+ * If false, the state will not be persisted to a persistent storage and
1004
+ * will be removed after applied.
1005
+ */
1006
+ persistent) {
1007
+ this.state = state;
1008
+ this.persistent = persistent;
1009
+ this.state = state;
1010
+ }
1011
+ toJSON() {
1012
+ return {
1013
+ id: this.id,
1014
+ type: this.type,
1015
+ state: this.state
1016
+ };
1017
+ }
1018
+ }
1019
+
1020
+ class HideColumnColumnsAlteration extends ColumnsAlteration {
1021
+ constructor(state, persistent) {
1022
+ super(state, persistent);
1023
+ this.type = 'hide-column';
1024
+ if (!this._isValidState(state)) {
1025
+ throw Error(`Invalid state: ${JSON.stringify(state)}`);
609
1026
  }
1027
+ this.id = `${this.type}--${state.columnProp}`;
1028
+ }
1029
+ apply(columns, datatable) {
1030
+ for (const col of columns) {
1031
+ const prop = getColumnProp(col);
1032
+ if (prop === this.state.columnProp) {
1033
+ col.hidden = this.state.hidden;
1034
+ }
1035
+ }
1036
+ }
1037
+ _isValidState(state) {
1038
+ // NOTE: Checking null or undefined, even though the type doesn't allow,
1039
+ // because the state may have been loaded from an invalid persistant
1040
+ // storage.
1041
+ // TODO: Remove when state validation/migration is implemented to happen
1042
+ // when retrieved from storage.
1043
+ if (!notNullOrUndefined(state.columnProp)) {
1044
+ return false;
1045
+ }
1046
+ // TODO: Remove when state validation/migration is implemented to happen
1047
+ // when retrieved from storage.
1048
+ if (!notNullOrUndefined(state.hidden)) {
1049
+ return false;
1050
+ }
1051
+ return true;
1052
+ }
1053
+ }
1054
+
1055
+ class SortColumnsAlteration extends ColumnsAlteration {
1056
+ constructor(state, persistent) {
1057
+ super(state, persistent);
1058
+ this.type = 'sort';
1059
+ if (!this._isValidState(state)) {
1060
+ throw Error(`Invalid state: ${JSON.stringify(state)}`);
1061
+ }
1062
+ this.id = `${this.type}`;
1063
+ }
1064
+ apply(columns, datatable) {
1065
+ if (datatable.sortType === SortType.single) {
1066
+ datatable.sorts = this.state.sorts.length > 0 ? [this.state.sorts[0]] : [];
1067
+ }
1068
+ else {
1069
+ datatable.sorts = this.state.sorts;
1070
+ }
1071
+ }
1072
+ _isValidState(state) {
1073
+ // NOTE: Checking null or undefined, even though the type doesn't allow,
1074
+ // because the state may have been loaded from an invalid persistant
1075
+ // storage.
1076
+ // TODO: Remove when state validation/migration is implemented to happen
1077
+ // when retrieved from storage.
1078
+ if (!notNullOrUndefined(state.sorts)) {
1079
+ return false;
1080
+ }
1081
+ return true;
1082
+ }
1083
+ }
1084
+
1085
+ class WidthColumnsAlteration extends ColumnsAlteration {
1086
+ constructor(state, persistent) {
1087
+ super(state, persistent);
1088
+ this.type = 'width';
1089
+ if (!this._isValidState(state)) {
1090
+ throw Error(`Invalid state: ${JSON.stringify(state)}`);
1091
+ }
1092
+ this.id = `${this.type}--${state.columnProp}`;
1093
+ }
1094
+ apply(columns, datatable) {
1095
+ for (const col of columns) {
1096
+ const prop = getColumnProp(col);
1097
+ if (prop === this.state.columnProp) {
1098
+ col.canAutoResize = this.state.canAutoResize;
1099
+ if (notNullOrUndefined(this.state.width)) {
1100
+ col.width = this.state.width;
1101
+ }
1102
+ }
1103
+ }
1104
+ }
1105
+ _isValidState(state) {
1106
+ // NOTE: Checking null or undefined, even though the type doesn't allow,
1107
+ // because the state may have been loaded from an invalid persistant
1108
+ // storage.
1109
+ // TODO: Remove when state validation/migration is implemented to happen
1110
+ // when retrieved from storage.
1111
+ if (!notNullOrUndefined(state.columnProp)) {
1112
+ return false;
1113
+ }
1114
+ // TODO: Remove when state validation/migration is implemented to happen
1115
+ // when retrieved from storage.
1116
+ if (!notNullOrUndefined(state.canAutoResize)) {
1117
+ return false;
1118
+ }
1119
+ return true;
1120
+ }
1121
+ }
1122
+
1123
+ class ColumnsAlterationsManagerService {
1124
+ constructor() {
1125
+ this._changesSubject = new Subject();
1126
+ this._alterations = [];
1127
+ this.changes = this._changesSubject.asObservable();
1128
+ }
1129
+ get() {
1130
+ return [...this._alterations];
1131
+ }
1132
+ /**
1133
+ * Adds alterations to be applied to columns.
1134
+ *
1135
+ * If an alteration with the same `id` already exists then the existing
1136
+ * alteration will be removed and the new one added.
1137
+ *
1138
+ * NOTE: When there is a duplicate alteration the old alteration is removed,
1139
+ * instead of updated, to maintain the order alterations are applied.
1140
+ */
1141
+ add(alterations, options) {
1142
+ // console.log('add', alterations)
1143
+ const removed = this.remove(alterations, { emitEvent: false });
1144
+ this._alterations = [...this._alterations, ...alterations];
1145
+ const changes = [
1146
+ ...removed,
1147
+ ...alterations.map(a => {
1148
+ const record = {
1149
+ type: 'added',
1150
+ alteration: a
1151
+ };
1152
+ return record;
1153
+ })
1154
+ ];
1155
+ if (notNullOrUndefined(options === null || options === void 0 ? void 0 : options.emitEvent) && !(options === null || options === void 0 ? void 0 : options.emitEvent)) {
1156
+ return changes;
1157
+ }
1158
+ this._emitChanges(changes);
1159
+ return changes;
1160
+ }
1161
+ remove(alterations, options) {
1162
+ // console.log('remove', alterations)
1163
+ const removed = [];
1164
+ this._alterations = this._alterations.filter(x => {
1165
+ const found = alterations.findIndex(y => y.id === x.id) !== -1;
1166
+ if (found) {
1167
+ const eventRecord = {
1168
+ type: 'removed',
1169
+ alteration: x
1170
+ };
1171
+ removed.push(eventRecord);
1172
+ }
1173
+ return !found;
1174
+ });
1175
+ // console.log('removed', removed, this._alterations)
1176
+ if (notNullOrUndefined(options === null || options === void 0 ? void 0 : options.emitEvent) && !(options === null || options === void 0 ? void 0 : options.emitEvent)) {
1177
+ return removed;
1178
+ }
1179
+ this._emitChanges(removed);
1180
+ return removed;
1181
+ }
1182
+ apply(columns, datatable) {
1183
+ for (const a of this._alterations) {
1184
+ a.apply(columns, datatable);
1185
+ }
1186
+ this._removeNonPersistant();
1187
+ }
1188
+ // TODO: Make aware of original column order and properties. This is tricky,
1189
+ // because the datatable does not deal with immutable column/row records and
1190
+ // it is hard to know where changes happened. Just serializing the columns
1191
+ // input is not enough, because the columns input is called anytime the user
1192
+ // makes a column change. We can probably come up with a mostly accurate
1193
+ // implementation, such as "reset original columns cache when preferencesKey
1194
+ // changes" or "number of columns change". There are issues with those rules,
1195
+ // but with some testing/experimenting I think there should be a "good enough"
1196
+ // solution.
1197
+ //
1198
+ // TODO: Find a generic way to clear alterations. I would like to add an
1199
+ // `unapply` method to `ColumnsAlteration`, but since the alterations
1200
+ // themselves are not too generic it may be tricky.
1201
+ clear(options) {
1202
+ const changes = [];
1203
+ for (const colAlt of this._alterations) {
1204
+ switch (colAlt.type) {
1205
+ case 'hide-column': {
1206
+ const alteration = new HideColumnColumnsAlteration({ columnProp: colAlt.state.columnProp, hidden: false }, false);
1207
+ changes.push(...this.add([alteration]));
1208
+ break;
1209
+ }
1210
+ case 'order': {
1211
+ changes.push(...this.remove([colAlt]));
1212
+ break;
1213
+ }
1214
+ case 'sort': {
1215
+ const alteration = new SortColumnsAlteration({ sorts: [] }, false);
1216
+ changes.push(...this.add([alteration]));
1217
+ break;
1218
+ }
1219
+ case 'width': {
1220
+ const alteration = new WidthColumnsAlteration({ columnProp: colAlt.state.columnProp, canAutoResize: true }, false);
1221
+ changes.push(...this.add([alteration]));
1222
+ break;
1223
+ }
1224
+ }
1225
+ }
1226
+ if (notNullOrUndefined(options === null || options === void 0 ? void 0 : options.emitEvent) && !(options === null || options === void 0 ? void 0 : options.emitEvent)) {
1227
+ return changes;
1228
+ }
1229
+ this._emitChanges(changes);
1230
+ return changes;
1231
+ }
1232
+ _removeNonPersistant() {
1233
+ const nonPersistent = this._alterations.filter(x => !x.persistent);
1234
+ this.remove(nonPersistent, { emitEvent: false });
1235
+ }
1236
+ _emitChanges(changes) {
1237
+ if (changes.length === 0) {
1238
+ return;
1239
+ }
1240
+ const event = {
1241
+ changes
1242
+ };
1243
+ this._changesSubject.next(event);
610
1244
  }
611
- setColumnDefaults(columns);
612
1245
  }
1246
+ ColumnsAlterationsManagerService.decorators = [
1247
+ { type: Injectable }
1248
+ ];
1249
+ ColumnsAlterationsManagerService.ctorParameters = () => [];
1250
+
1251
+ /**
1252
+ * Strings used for columns created and managed
1253
+ * by the datatable.
1254
+ */
1255
+ const INTERNAL_COLUMN_PROPS = [
1256
+ ACTION_MENU_COLUMN_PROP,
1257
+ CHECKBOX_COLUMN_PROP
1258
+ ];
1259
+ function isInternalColumn(column) {
1260
+ return INTERNAL_COLUMN_PROPS.findIndex(p => getColumnProp(column) === p) !== -1;
1261
+ }
1262
+
1263
+ class OrderColumnsAlteration extends ColumnsAlteration {
1264
+ constructor(state, persistent) {
1265
+ super(state, persistent);
1266
+ this.type = 'order';
1267
+ if (!this._isValidState(state)) {
1268
+ throw Error(`Invalid state: ${JSON.stringify(state)}`);
1269
+ }
1270
+ this.id = `${this.type}`;
1271
+ }
1272
+ apply(columns, datatable) {
1273
+ if (this.state.columns.length === 0) {
1274
+ return;
1275
+ }
1276
+ const stateColumns = this._stateColumns();
1277
+ // The internal columns are not intended for a user to be able to move them.
1278
+ // Store the internal columns current index, so it can be moved back ofter
1279
+ // sorting. This may not be the best way to do this, but it is easier than
1280
+ // making a sort that avoids them.
1281
+ //
1282
+ // NOTE: If we add an internal column that can be moved then this will need
1283
+ // to be changed.
1284
+ const internalColumns = columns
1285
+ .filter(c => isInternalColumn(c))
1286
+ .map((column, index) => ({ column, index }));
1287
+ for (const c of stateColumns) {
1288
+ const currentIndex = columns.findIndex(x => getColumnProp(x) === c.columnProp);
1289
+ if (currentIndex === c.index || currentIndex === -1) {
1290
+ // Skip if already at correct index.
1291
+ // Skip columns not found. It may be a column that was removed from the
1292
+ // table, but we still want to handle the other columns.
1293
+ continue;
1294
+ }
1295
+ arrayMoveMutable(columns, currentIndex, c.index);
1296
+ }
1297
+ for (const c of internalColumns) {
1298
+ const currentIndex = columns.findIndex(col => col === c.column);
1299
+ if (currentIndex !== -1) {
1300
+ arrayMoveMutable(columns, currentIndex, c.index);
1301
+ }
1302
+ else {
1303
+ if (isDevMode()) {
1304
+ console.warn(`Internal column could not be found after sorting. Was it lost during the sorting?`);
1305
+ }
1306
+ }
1307
+ }
1308
+ }
1309
+ _isValidState(state) {
1310
+ // NOTE: Checking null or undefined, even though the type doesn't allow,
1311
+ // because the state may have been loaded from an invalid persistant
1312
+ // storage.
1313
+ // TODO: Remove when state validation/migration is implemented to happen
1314
+ // when retrieved from storage.
1315
+ if (!notNullOrUndefined(state.columns)) {
1316
+ return false;
1317
+ }
1318
+ // NOTE: Didn't iterate each column record, because it is probably better to
1319
+ // just skip to invalid column records. It does prevent being able to
1320
+ // validate the whole state though.
1321
+ return true;
1322
+ }
1323
+ _isColumnOrderRecordValid(columnOrder) {
1324
+ return notNullOrUndefined(columnOrder.columnProp) && notNullOrUndefined(columnOrder.index);
1325
+ }
1326
+ _stateColumns() {
1327
+ return this.state.columns.filter(c => {
1328
+ if (!this._isColumnOrderRecordValid(c)) {
1329
+ if (isDevMode()) {
1330
+ console.warn('Invalid column order record', c);
1331
+ }
1332
+ return false;
1333
+ }
1334
+ return true;
1335
+ }).sort((a, b) => a.index === b.index ? 0 : a.index > b.index ? 1 : -1);
1336
+ }
1337
+ }
1338
+
1339
+ function mapColumnsAlterationsStates(states) {
1340
+ const alterations = [];
1341
+ for (const state of states) {
1342
+ try {
1343
+ switch (state.type) {
1344
+ case 'hide-column':
1345
+ alterations.push(new HideColumnColumnsAlteration(state.state, true));
1346
+ break;
1347
+ case 'width':
1348
+ alterations.push(new WidthColumnsAlteration(state.state, true));
1349
+ break;
1350
+ case 'order':
1351
+ alterations.push(new OrderColumnsAlteration(state.state, true));
1352
+ break;
1353
+ case 'sort':
1354
+ alterations.push(new SortColumnsAlteration(state.state, true));
1355
+ break;
1356
+ default: {
1357
+ if (isDevMode()) {
1358
+ console.warn('Unrecognized ColumnsAlteration state', state);
1359
+ }
1360
+ }
1361
+ }
1362
+ }
1363
+ catch (e) {
1364
+ if (isDevMode()) {
1365
+ console.warn('Unable to map ColumnsAlteration state', state);
1366
+ console.warn(e);
1367
+ }
1368
+ }
1369
+ }
1370
+ return alterations;
1371
+ }
1372
+
613
1373
  /**
614
1374
  * Intended for internal classes declared by the `TheSeamDatatableModule`.
615
1375
  */
@@ -624,25 +1384,19 @@ const _THESEAM_DATATABLE_ACCESSOR = {
624
1384
  // tslint:disable-next-line:no-use-before-declare
625
1385
  useExisting: forwardRef(() => DatatableComponent)
626
1386
  };
627
- // TODO: Reduce reliance on BehaviorSubject based observables, because it should
628
- // be easier to avoit over emitting observables.
629
1387
  class DatatableComponent {
630
- constructor(_columnChangesService, _differs, _preferences) {
631
- // this.displayColumns$ = this.hiddenColumns$.pipe(
632
- // switchMap(hiddenColumns => this.columns$.pipe(map(cols => cols.filter(c => hiddenColumns.findIndex(hc => hc === c.prop) === -1))))
633
- // )
634
- this._columnChangesService = _columnChangesService;
635
- this._differs = _differs;
1388
+ constructor(_preferences, _columnsManager, _columnsAlterationsManager) {
636
1389
  this._preferences = _preferences;
637
- this.faChevronDown = faChevronDown;
638
- this.faChevronRight = faChevronRight;
639
- this.faSpinner = faSpinner;
1390
+ this._columnsManager = _columnsManager;
1391
+ this._columnsAlterationsManager = _columnsAlterationsManager;
1392
+ this._faChevronDown = faChevronDown;
1393
+ this._faChevronRight = faChevronRight;
1394
+ this._faSpinner = faSpinner;
640
1395
  this._ngUnsubscribe = new Subject();
641
1396
  this._filtersSubject = new BehaviorSubject([]);
642
- this._columnsObservable = new BehaviorSubject(undefined);
643
1397
  this._dataSourceSubject = new BehaviorSubject(undefined);
1398
+ this._resizing = {};
644
1399
  this._preferencesKey = new BehaviorSubject(undefined);
645
- this._columns = new BehaviorSubject([]);
646
1400
  this._rows = new BehaviorSubject([]);
647
1401
  this.columnMode = ColumnMode.force;
648
1402
  this.selected = [];
@@ -654,7 +1408,7 @@ class DatatableComponent {
654
1408
  this.loadingIndicator = false;
655
1409
  this.reorderable = true;
656
1410
  this.swapColumns = false;
657
- this.sortType = SortType.single;
1411
+ this._sortType = SortType.single;
658
1412
  this._sorts = [];
659
1413
  this.cssClasses = {
660
1414
  sortAscending: 'datatable-icon-up',
@@ -699,27 +1453,43 @@ class DatatableComponent {
699
1453
  this._colDiffersInp = {};
700
1454
  this._colDiffersTpl = {};
701
1455
  this._rowDetailToggleSubscription = Subscription.EMPTY;
702
- const applyPrefs = (cols) => this._preferencesKey.pipe(switchMap(name => !!name
703
- // NOTE: This pending check is temporary to avoid table using previously
704
- // retrieved preference while the new one is being updated on the
705
- // server.
706
- ? !this._preferences.pending
707
- ? this._preferences.withColumnPreferences(name, cols)
708
- : of(cols)
709
- : of(cols)));
710
- this.columns$ = this._columnsObservable.pipe(switchMap(colsObs => colsObs !== null && colsObs !== void 0 ? colsObs : of([])));
711
- this.displayColumns$ = this.columns$.pipe(map(cols => cols.filter(c => !c.hidden)), tap(v => this._removeUnusedDiffs(v)), switchMap(cols => applyPrefs(cols)));
1456
+ this._preferencesKey.pipe(distinctUntilChanged(), switchMap(key => {
1457
+ if (!notNullOrUndefined(key) || key.length === 0) {
1458
+ return of(undefined);
1459
+ }
1460
+ return from(waitOnConditionAsync(() => this._preferences.loaded)).pipe(switchMap(() => this._columnsAlterationsManager.changes.pipe(startWith(undefined), tap(() => {
1461
+ this._preferences.setAlterations(key, this._columnsAlterationsManager.get());
1462
+ }))));
1463
+ }), takeUntil(this._ngUnsubscribe)).subscribe();
1464
+ const applyPrefs = (cols) => this._columnsAlterationsManager.changes.pipe(startWith(undefined), map(() => {
1465
+ this._columnsAlterationsManager.apply(cols, this);
1466
+ return cols;
1467
+ }));
1468
+ this._preferencesKey.pipe(distinctUntilChanged(), switchMap(prefsKey => {
1469
+ if (!notNullOrUndefined(prefsKey)) {
1470
+ return of(undefined);
1471
+ }
1472
+ return this._preferences.preferences(prefsKey).pipe(switchMap((preferences) => __awaiter(this, void 0, void 0, function* () {
1473
+ yield waitOnConditionAsync(() => this._preferences.loaded);
1474
+ return preferences;
1475
+ })), take(1), map(preferences => {
1476
+ let alterations = [];
1477
+ try {
1478
+ alterations = mapColumnsAlterationsStates(preferences.alterations);
1479
+ }
1480
+ catch (e) {
1481
+ if (isDevMode()) {
1482
+ console.warn('Unable to map columns alterations states');
1483
+ console.warn(e);
1484
+ }
1485
+ }
1486
+ this._columnsAlterationsManager.add(alterations);
1487
+ }));
1488
+ }), takeUntil(this._ngUnsubscribe)).subscribe();
1489
+ this.columns$ = this._columnsManager.columns$;
1490
+ this.displayColumns$ = this.columns$.pipe(switchMap(cols => applyPrefs(cols)), map(cols => cols.filter(c => !c.hidden)), tap(v => removeUnusedDiffs(v, this._colDiffersInp, this._colDiffersTpl)));
712
1491
  this.filters$ = this._filtersSubject.asObservable();
713
1492
  this.filterStates = this._filtersSubject.asObservable().pipe(switchMap(filters => composeDataFilterStates(filters)));
714
- // this.rows$ = this._filtersSubject.asObservable()
715
- // .pipe(
716
- // switchMap(filters => {
717
- // if (this.externalFiltering) {
718
- // return this._rows.asObservable()
719
- // }
720
- // return this._rows.asObservable().pipe(composeDataFilters(filters))
721
- // })
722
- // )
723
1493
  this.rows$ = this._dataSourceSubject.pipe(switchMap(dataSource => {
724
1494
  // console.log('dataSource', dataSource)
725
1495
  let dataStream;
@@ -755,34 +1525,35 @@ class DatatableComponent {
755
1525
  // tap(v => console.log('stream', v)),
756
1526
  takeUntil(this._ngUnsubscribe));
757
1527
  }));
758
- // this.hiddenColumns$ = this._hiddenColumns.asObservable()
759
- // this._hiddenColumns.pipe(
760
- // skip(1),
761
- // distinctUntilChanged((a, b) => {
762
- // const _a = Array.isArray(a) ? a : []
763
- // const _b = Array.isArray(b) ? b : []
764
- // if (_a.length !== _b.length) { return false }
765
- // const _as = _a.sort()
766
- // const _bs = _b.sort()
767
- // return !_as.sort().every((value: string, index: number) => _bs[index] === value)
768
- // }),
769
- // tap(v => this.hiddenColumnsChange.emit(v)),
770
- // untilDestroyed(this)
771
- // ).subscribe(v => console.log('hiddenColumnsChange', v))
772
1528
  // TODO: Implement viewChange for CollectionViewer.
773
1529
  this.viewChange = this.page.pipe(map(p => ({ start: 0, end: p.count })));
774
1530
  }
775
1531
  get filters() { return this._filtersSubject.value; }
776
1532
  get preferencesKey() { return this._preferencesKey.value; }
777
1533
  set preferencesKey(value) { this._preferencesKey.next(value || undefined); }
778
- get columns() { return this._columns.value; }
779
1534
  set columns(value) {
780
- // console.log('columns input', value)
781
- this._columns.next(Array.isArray(value) ? value : []);
1535
+ this._columnsManager.setInputColumns(Array.isArray(value) ? value : []);
782
1536
  }
783
1537
  get rows() { return this._rows.value; }
784
- set rows(value) { this._rows.next(value || []); }
785
- get sorts() { return this.ngxDatatable ? this.ngxDatatable.sorts : this._sorts; }
1538
+ set rows(value) {
1539
+ this._rows.next(value || []);
1540
+ }
1541
+ get selectionType() { return this._columnsManager.getSelectionType(); }
1542
+ set selectionType(value) {
1543
+ this._columnsManager.setSelectionType(notNullOrUndefined(value) ? value : undefined);
1544
+ }
1545
+ get sortType() { return this._sortType; }
1546
+ set sortType(value) {
1547
+ if (notNullOrUndefined(value) && (value === SortType.single || value == SortType.multi)) {
1548
+ this._sortType = value;
1549
+ }
1550
+ else {
1551
+ this._sortType = SortType.single;
1552
+ }
1553
+ }
1554
+ get sorts() {
1555
+ return this.ngxDatatable ? this.ngxDatatable.sorts : this._sorts;
1556
+ }
786
1557
  set sorts(value) {
787
1558
  this._sorts = notNullOrUndefined(value) ? coerceArray(value) : [];
788
1559
  }
@@ -792,6 +1563,15 @@ class DatatableComponent {
792
1563
  }
793
1564
  this._dataSourceSubject.next(value || undefined);
794
1565
  }
1566
+ set columnComponents(value) {
1567
+ var _a;
1568
+ this._columnsManager.setTemplateColumns(translateTemplateColumns((_a = value === null || value === void 0 ? void 0 : value.toArray()) !== null && _a !== void 0 ? _a : []));
1569
+ }
1570
+ get rowActionItem() { return this._rowActionItem; }
1571
+ set rowActionItem(value) {
1572
+ this._rowActionItem = value;
1573
+ this._columnsManager.setRowActionItem(notNullOrUndefined(value) ? value : undefined);
1574
+ }
795
1575
  get menuBarComponent() { return this._menuBarComponent; }
796
1576
  set menuBarComponent(value) {
797
1577
  var _a;
@@ -804,6 +1584,54 @@ class DatatableComponent {
804
1584
  this._menuBarSub = (_a = this._menuBarComponent) === null || _a === void 0 ? void 0 : _a.filtersChanged.subscribe(v => { this._setMenuBarFilters(value.filters()); });
805
1585
  }
806
1586
  }
1587
+ get actionMenuCellTpl() { return this._actionMenuCellTpl; }
1588
+ set actionMenuCellTpl(value) {
1589
+ this._actionMenuCellTpl = value;
1590
+ this._columnsManager.setActionMenuCellTpl(notNullOrUndefined(value) ? value : undefined);
1591
+ }
1592
+ get treeToggleTpl() { return this._treeToggleTpl; }
1593
+ set treeToggleTpl(value) {
1594
+ this._treeToggleTpl = value;
1595
+ this._columnsManager.setTreeToggleTpl(notNullOrUndefined(value) ? value : undefined);
1596
+ }
1597
+ get headerTpl() { return this._headerTpl; }
1598
+ set headerTpl(value) {
1599
+ this._headerTpl = value;
1600
+ this._columnsManager.setHeaderTpl(notNullOrUndefined(value) ? value : undefined);
1601
+ }
1602
+ get blankHeaderTpl() { return this._blankHeaderTpl; }
1603
+ set blankHeaderTpl(value) {
1604
+ this._blankHeaderTpl = value;
1605
+ this._columnsManager.setBlankHeaderTpl(notNullOrUndefined(value) ? value : undefined);
1606
+ }
1607
+ get cellTypeSelectorTpl() { return this._cellTypeSelectorTpl; }
1608
+ set cellTypeSelectorTpl(value) {
1609
+ this._cellTypeSelectorTpl = value;
1610
+ this._columnsManager.setCellTypeSelectorTpl(notNullOrUndefined(value) ? value : undefined);
1611
+ }
1612
+ // TODO: Remove this DOM-dependent code when a way to property listen for
1613
+ // dblclick on the header reasize handles.
1614
+ _dblClick(event) {
1615
+ var _a, _b, _c;
1616
+ const isHandle = event.target.classList.contains('resize-handle');
1617
+ if (isHandle) {
1618
+ const isResizeable = (_a = event.target.parentElement) === null || _a === void 0 ? void 0 : _a.classList.contains('resizeable');
1619
+ if (isResizeable) {
1620
+ event.stopPropagation();
1621
+ const id = (_c = (_b = event.target.parentElement) === null || _b === void 0 ? void 0 : _b.querySelector('.datatable-column-header-separator')) === null || _c === void 0 ? void 0 : _c.getAttribute('data-column-id');
1622
+ this._columnsManager.columns$.pipe(take(1)).subscribe(columns => {
1623
+ const column = columns.find(c => c.$$id === id);
1624
+ if (column) {
1625
+ const columnProp = getColumnProp(column);
1626
+ if (columnProp) {
1627
+ const alteration = new WidthColumnsAlteration({ columnProp, canAutoResize: true }, false);
1628
+ this._columnsAlterationsManager.add([alteration]);
1629
+ }
1630
+ }
1631
+ });
1632
+ }
1633
+ }
1634
+ }
807
1635
  ngOnInit() {
808
1636
  if (this.rowDetail) {
809
1637
  this._rowDetailToggleSubscription = this.rowDetail._toggle.subscribe(event => {
@@ -816,131 +1644,7 @@ class DatatableComponent {
816
1644
  ngOnDestroy() {
817
1645
  this._rowDetailToggleSubscription.unsubscribe();
818
1646
  }
819
- ngAfterContentInit() {
820
- var _a, _b;
821
- this.columnComponents$ = this._columnChangesService.columnInputChanges$.pipe(map(() => { var _a, _b; return (_b = (_a = this.columnComponents) === null || _a === void 0 ? void 0 : _a.toArray()) !== null && _b !== void 0 ? _b : []; }), startWith((_b = (_a = this.columnComponents) === null || _a === void 0 ? void 0 : _a.toArray()) !== null && _b !== void 0 ? _b : []), shareReplay({ bufferSize: 1, refCount: true }));
822
- const _columns = combineLatest([
823
- this.columnComponents$,
824
- this._columns
825
- ]).pipe(map(v => { var _a; return this._getMergedTplAndInpColumns(v[0], (_a = v[1]) !== null && _a !== void 0 ? _a : []); }),
826
- // tap(v => console.log('cols', v)),
827
- shareReplay({ bufferSize: 1, refCount: true }));
828
- this._columnsObservable.next(_columns);
829
- }
830
- _getMergedTplAndInpColumns(tplCols, inpCols) {
831
- const cols = [];
832
- if (this.selectionType === 'checkbox') {
833
- const checkBoxCol = {
834
- prop: '$$__checkbox__',
835
- name: '',
836
- width: 40,
837
- sortable: false,
838
- canAutoResize: false,
839
- draggable: false,
840
- resizeable: false,
841
- headerCheckboxable: true,
842
- checkboxable: true
843
- };
844
- cols.push(checkBoxCol);
845
- }
846
- const _tplCols = translateTemplates((tplCols || []));
847
- for (const col of inpCols) {
848
- const tplCol = _tplCols.find(t => t.prop === col.prop);
849
- // console.log({ col: { ...(col || {}) }, tplCol: { ...(tplCol || {}) } })
850
- const dtColumns = (this.ngxDatatable && this.ngxDatatable._internalColumns) || [];
851
- const prev = dtColumns.find(c => c.prop === col.prop);
852
- const inpColDiff = this._getColDiff(col);
853
- const _inpCol = inpColDiff ? {} : this._hasPrevColDiff(col) ? {} : col;
854
- if (inpColDiff) {
855
- inpColDiff.forEachRemovedItem(r => {
856
- if (prev && prev.hasOwnProperty(r.key)) {
857
- const k = r.key;
858
- delete prev[k];
859
- }
860
- });
861
- inpColDiff.forEachAddedItem(r => _inpCol[r.key] = r.currentValue);
862
- inpColDiff.forEachChangedItem(r => _inpCol[r.key] = r.currentValue);
863
- }
864
- let _tplCol = {};
865
- if (tplCol) {
866
- const tplColDiff = tplCol ? this._getColDiff(tplCol, true) : undefined;
867
- _tplCol = tplColDiff ? {} : this._hasPrevColDiff(col, true) ? {} : tplCol;
868
- if (tplColDiff) {
869
- tplColDiff.forEachRemovedItem(r => {
870
- if (prev && prev.hasOwnProperty(r.key)) {
871
- const k = r.key;
872
- delete prev[k];
873
- }
874
- });
875
- tplColDiff.forEachAddedItem(r => _tplCol[r.key] = r.currentValue);
876
- tplColDiff.forEachChangedItem(r => _tplCol[r.key] = r.currentValue);
877
- }
878
- }
879
- const _col = Object.assign(Object.assign(Object.assign({}, (prev || {})), _inpCol), _tplCol);
880
- cols.push(_col);
881
- }
882
- if (this.rowActionItem) {
883
- const actionMenuColumn = {
884
- prop: '$$__actionMenu__',
885
- name: '',
886
- width: 50,
887
- minWidth: 50,
888
- maxWidth: 50,
889
- resizeable: false,
890
- sortable: false,
891
- draggable: false,
892
- // TODO: Fix column auto sizing with fixed column and cell overlay before enabling.
893
- // frozenRight: true,
894
- cellTemplate: this.actionMenuCellTpl,
895
- headerTemplate: this.blankHeaderTpl
896
- };
897
- cols.push(actionMenuColumn);
898
- }
899
- for (const col of cols) {
900
- if (col.isTreeColumn && hasProperty(col, 'treeToggleTemplate')) {
901
- col.treeToggleTemplate = this.treeToggleTpl;
902
- }
903
- if (!hasProperty(col, 'headerTemplate')) {
904
- col.headerTemplate = this.headerTpl;
905
- }
906
- if (hasProperty(col, 'cellType')) {
907
- col.cellTemplate = this.cellTypeSelectorTpl;
908
- }
909
- }
910
- // setColumnDefaults(cols)
911
- _setColumnDefaults(cols);
912
- // console.log(cols.map(c => ({ prop: c.prop, canAutoResize: c.canAutoResize })))
913
- return cols;
914
- }
915
- _hasPrevColDiff(col, isTpl = false) {
916
- if (!col || !col.prop) {
917
- return false;
918
- }
919
- const differsMap = isTpl ? this._colDiffersTpl : this._colDiffersInp;
920
- return !!differsMap;
921
- }
922
- _getColDiff(col, isTpl = false) {
923
- if (!col || !col.prop) {
924
- return;
925
- }
926
- const differsMap = isTpl ? this._colDiffersTpl : this._colDiffersInp;
927
- if (!differsMap[col.prop]) {
928
- differsMap[col.prop] = this._differs.find({}).create();
929
- }
930
- const differ = differsMap[col.prop];
931
- const diff = differ.diff(col);
932
- return diff;
933
- }
934
- _removeUnusedDiffs(cols) {
935
- const inpKeys = Object.keys(this._colDiffersInp);
936
- inpKeys.filter(k => cols.findIndex(c => c.prop === k) === -1)
937
- .forEach(k => { delete this._colDiffersInp[k]; });
938
- const tplKeys = Object.keys(this._colDiffersTpl);
939
- tplKeys.filter(k => cols.findIndex(c => c.prop === k) === -1)
940
- .forEach(k => { delete this._colDiffersTpl[k]; });
941
- }
942
1647
  _setMenuBarFilters(filters) {
943
- // console.log('_setMenuBarFilters', filters)
944
1648
  this._filtersSubject.next(filters || []);
945
1649
  }
946
1650
  getColumnComponent(propName) {
@@ -974,21 +1678,51 @@ class DatatableComponent {
974
1678
  }
975
1679
  }
976
1680
  _onResize(event) {
977
- // console.log('resize', event, event.column.prop)
978
1681
  this.resize.emit(event);
979
- if (event.isDone && this.columns) {
980
- const columns = this.columns;
981
- const col = columns.find(c => c.prop === event.column.prop);
982
- if (col) {
983
- col.canAutoResize = false;
1682
+ if (!notNullOrUndefined(event.column)) {
1683
+ return;
1684
+ }
1685
+ const columnProp = getColumnProp(event.column);
1686
+ if (columnProp) {
1687
+ let addAlteration = false;
1688
+ if (!this._resizing[columnProp]) {
1689
+ this._resizing[columnProp] = true;
1690
+ addAlteration = true;
1691
+ }
1692
+ if (event.isDone) {
1693
+ this._resizing[columnProp] = false;
1694
+ addAlteration = true;
984
1695
  }
985
- if (this.preferencesKey) {
986
- const pref = { prop: event.column.prop, width: event.column.width, canAutoResize: false };
987
- this._preferences.setColumnPreference(this.preferencesKey, pref);
1696
+ if (addAlteration) {
1697
+ const alteration = new WidthColumnsAlteration({
1698
+ columnProp,
1699
+ width: event.column.width,
1700
+ canAutoResize: false
1701
+ }, true);
1702
+ this._columnsAlterationsManager.add([alteration]);
988
1703
  }
989
- this.columns = [...this.columns];
990
1704
  }
991
1705
  }
1706
+ _onReorder(event) {
1707
+ this.reorder.emit(event);
1708
+ const columnProp = getColumnProp(event.column);
1709
+ if (columnProp) {
1710
+ const currentOrderAlteration = this._columnsAlterationsManager.get().find(x => x.type === 'order');
1711
+ const state = {
1712
+ columns: [
1713
+ ...((currentOrderAlteration === null || currentOrderAlteration === void 0 ? void 0 : currentOrderAlteration.state.columns) || []),
1714
+ { columnProp, index: event.newValue }
1715
+ ]
1716
+ };
1717
+ const alteration = new OrderColumnsAlteration(state, true);
1718
+ this._columnsAlterationsManager.add([alteration]);
1719
+ }
1720
+ }
1721
+ _onSort(event) {
1722
+ this.sort.emit(event);
1723
+ const alteration = new SortColumnsAlteration({ sorts: event.sorts }, true);
1724
+ this._columnsAlterationsManager.add([alteration]);
1725
+ }
992
1726
  _onTreeAction(event) {
993
1727
  const index = event.rowIndex;
994
1728
  const row = event.row;
@@ -1003,6 +1737,9 @@ class DatatableComponent {
1003
1737
  triggerActionRefreshRequest() {
1004
1738
  this.actionRefreshRequest.emit(undefined);
1005
1739
  }
1740
+ /**
1741
+ * Returns the page info from the wrapped NgxDatatable instance or defaults.
1742
+ */
1006
1743
  get pageInfo() {
1007
1744
  var _a, _b, _c, _d, _e, _f, _g;
1008
1745
  return {
@@ -1016,7 +1753,7 @@ class DatatableComponent {
1016
1753
  DatatableComponent.decorators = [
1017
1754
  { type: Component, args: [{
1018
1755
  selector: 'seam-datatable',
1019
- template: "<div class=\"datatable-wrapper\">\n <ng-content select=\"seam-datatable-menu-bar\"></ng-content>\n <div class=\"datatable-table-wrapper\">\n <ng-container>\n <ngx-datatable\n class=\"bootstrap\"\n [columnMode]=\"$any(columnMode)\"\n [scrollbarV]=\"scrollbarV\"\n [scrollbarH]=\"scrollbarH\"\n [virtualization]=\"virtualization\"\n [targetMarkerTemplate]=\"targetMarkerTemplate\"\n [groupRowsBy]=\"$any(groupRowsBy)\"\n [groupedRows]=\"$any(groupedRows)\"\n [selected]=\"$any(selected)\"\n [externalPaging]=\"externalPaging\"\n [externalSorting]=\"externalSorting\"\n [limit]=\"$any(limit)\"\n [count]=\"$any(count)\"\n [offset]=\"$any(offset)\"\n [loadingIndicator]=\"loadingIndicator\"\n [selectionType]=\"$any(selectionType)\"\n [reorderable]=\"reorderable\"\n [swapColumns]=\"swapColumns\"\n [sortType]=\"$any(sortType)\"\n [sorts]=\"$any(_sorts)\"\n [cssClasses]=\"cssClasses\"\n [messages]=\"messages\"\n [rowIdentity]=\"$any(rowIdentity)\"\n [rowClass]=\"rowClass\"\n [selectCheck]=\"selectCheck\"\n [displayCheck]=\"$any(displayCheck)\"\n [groupExpansionDefault]=\"groupExpansionDefault\"\n [trackByProp]=\"$any(trackByProp)\"\n [selectAllRowsOnPage]=\"selectAllRowsOnPage\"\n [treeFromRelation]=\"$any(treeFromRelation)\"\n [treeToRelation]=\"$any(treeToRelation)\"\n [summaryRow]=\"summaryRow\"\n [summaryHeight]=\"$any(summaryHeight)\"\n [summaryPosition]=\"$any(summaryPosition)\"\n [rows]=\"rows$ | async\"\n [columns]=\"$any(displayColumns$ | async)\"\n [headerHeight]=\"$any(headerHeight)\"\n [rowHeight]=\"$any(rowHeight)\"\n [footerHeight]=\"$any(footerHeight)\"\n (scroll)=\"scroll.emit($event)\"\n (activate)=\"activate.emit($event)\"\n (select)=\"select.emit($event)\"\n (sort)=\"sort.emit($event)\"\n (page)=\"page.emit($event)\"\n (reorder)=\"reorder.emit($event)\"\n (resize)=\"_onResize($event)\"\n (tableContextmenu)=\"tableContextmenu.emit($event)\"\n (treeAction)=\"treeAction.emit($event)\"\n (seamElemResized)=\"onDatatableResize($event)\"\n (treeAction)=\"_onTreeAction($event)\">\n\n <ngx-datatable-group-header [rowHeight]=\"50\" #myGroupHeader *ngIf=\"groupRowsBy\">\n <ng-template let-group=\"group\" let-expanded=\"expanded\" ngx-datatable-group-header-template>\n <div\n class=\"w-100 bg-light p-1\"\n [class.border-bottom]=\"!expanded\"\n [class.datatable-icon-right]=\"!expanded\"\n [class.datatable-icon-down]=\"expanded\"\n title=\"Expand/Collapse Group\"\n (click)=\"ngxDatatable?.groupHeader?.toggleExpandGroup(group)\">\n <b>Age: {{ group.age }}</b>\n </div>\n </ng-template>\n </ngx-datatable-group-header>\n\n <ngx-datatable-row-detail *ngIf=\"rowDetail && rowDetail.template\"\n [rowHeight]=\"rowDetail.rowHeight || 0\"\n [template]=\"$any(rowDetail.template)\"\n (toggle)=\"rowDetail.toggle.emit($event)\">\n </ngx-datatable-row-detail>\n\n </ngx-datatable>\n </ng-container>\n </div>\n</div>\n\n<ng-template #blankHeaderTpl ngx-datatable-header-template></ng-template>\n\n<ng-template #headerTpl ngx-datatable-header-template\n let-column=\"column\" let-sortFn=\"sortFn\">\n <strong *ngIf=\"!column.sortable\" class=\"draggable\">{{column.name}}</strong>\n <strong *ngIf=\"column.sortable\" class=\"datatable-sort-target draggable\" (click)=\"sortFn()\">{{column.name}}</strong>\n <div class=\"datatable-column-header-separator\"></div>\n</ng-template>\n\n<ng-template #cellTypeSelectorTpl ngx-datatable-cell-template\n let-value=\"value\" let-rowIndex=\"rowIndex\" let-row=\"row\" let-column=\"column\">\n <seam-table-cell-type-selector *ngIf=\"row\"\n [type]=\"column.cellType\"\n [value]=\"value\"\n [rowIndex]=\"rowIndex\"\n [row]=\"row\"\n [colData]=\"column\">\n </seam-table-cell-type-selector>\n</ng-template>\n\n<ng-template #actionMenuCellTpl ngx-datatable-cell-template\n let-value=\"value\" let-rowIndex=\"rowIndex\" let-row=\"row\">\n\n <ng-container *ngIf=\"row && rowActionItem?.template\">\n <ng-template\n [ngTemplateOutlet]=\"$any(rowActionItem?.template)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, row: row, rowIndex: rowIndex }\">\n </ng-template>\n </ng-container>\n\n</ng-template>\n\n<ng-template #treeToggleTpl ngx-datatable-tree-toggle let-tree=\"cellContext\">\n <button\n class=\"p-0 bg-transparent border-0 btn\"\n [disabled]=\"tree.treeStatus==='disabled'\"\n (click)=\"tree.onTreeAction()\">\n <span *ngIf=\"tree.treeStatus==='loading'\">\n <fa-icon [icon]=\"faSpinner\"></fa-icon>\n </span>\n <span *ngIf=\"tree.treeStatus==='collapsed'\">\n <fa-icon [icon]=\"faChevronRight\"></fa-icon>\n </span>\n <span *ngIf=\"tree.treeStatus==='expanded'\">\n <fa-icon [icon]=\"faChevronDown\"></fa-icon>\n </span>\n <span *ngIf=\"tree.treeStatus==='disabled'\">\n <fa-icon [icon]=\"faChevronRight\"></fa-icon>\n </span>\n </button>\n</ng-template>\n",
1756
+ template: "<div class=\"datatable-wrapper\">\n <ng-content select=\"seam-datatable-menu-bar\"></ng-content>\n <div class=\"datatable-table-wrapper\">\n <ng-container>\n <ngx-datatable\n [columnMode]=\"$any(columnMode)\"\n [scrollbarV]=\"scrollbarV\"\n [scrollbarH]=\"scrollbarH\"\n [virtualization]=\"virtualization\"\n [targetMarkerTemplate]=\"targetMarkerTemplate\"\n [groupRowsBy]=\"$any(groupRowsBy)\"\n [groupedRows]=\"$any(groupedRows)\"\n [selected]=\"$any(selected)\"\n [externalPaging]=\"externalPaging\"\n [externalSorting]=\"externalSorting\"\n [limit]=\"$any(limit)\"\n [count]=\"$any(count)\"\n [offset]=\"$any(offset)\"\n [loadingIndicator]=\"loadingIndicator\"\n [selectionType]=\"$any(selectionType)\"\n [reorderable]=\"reorderable\"\n [swapColumns]=\"swapColumns\"\n [sortType]=\"$any(sortType)\"\n [sorts]=\"$any(_sorts)\"\n [cssClasses]=\"cssClasses\"\n [messages]=\"messages\"\n [rowIdentity]=\"$any(rowIdentity)\"\n [rowClass]=\"rowClass\"\n [selectCheck]=\"selectCheck\"\n [displayCheck]=\"$any(displayCheck)\"\n [groupExpansionDefault]=\"groupExpansionDefault\"\n [trackByProp]=\"$any(trackByProp)\"\n [selectAllRowsOnPage]=\"selectAllRowsOnPage\"\n [treeFromRelation]=\"$any(treeFromRelation)\"\n [treeToRelation]=\"$any(treeToRelation)\"\n [summaryRow]=\"summaryRow\"\n [summaryHeight]=\"$any(summaryHeight)\"\n [summaryPosition]=\"$any(summaryPosition)\"\n [rows]=\"rows$ | async\"\n [columns]=\"$any(displayColumns$ | async)\"\n [headerHeight]=\"$any(headerHeight)\"\n [rowHeight]=\"$any(rowHeight)\"\n [footerHeight]=\"$any(footerHeight)\"\n (scroll)=\"scroll.emit($event)\"\n (activate)=\"activate.emit($event)\"\n (select)=\"select.emit($event)\"\n (sort)=\"_onSort($event)\"\n (page)=\"page.emit($event)\"\n (reorder)=\"_onReorder($event)\"\n (resize)=\"_onResize($event)\"\n (tableContextmenu)=\"tableContextmenu.emit($event)\"\n (treeAction)=\"treeAction.emit($event)\"\n (seamElemResized)=\"onDatatableResize($event)\"\n (treeAction)=\"_onTreeAction($event)\">\n\n <ngx-datatable-group-header [rowHeight]=\"50\" #myGroupHeader *ngIf=\"groupRowsBy\">\n <ng-template let-group=\"group\" let-expanded=\"expanded\" ngx-datatable-group-header-template>\n <div\n class=\"w-100 bg-light p-1\"\n [class.border-bottom]=\"!expanded\"\n [class.datatable-icon-right]=\"!expanded\"\n [class.datatable-icon-down]=\"expanded\"\n title=\"Expand/Collapse Group\"\n (click)=\"ngxDatatable?.groupHeader?.toggleExpandGroup(group)\">\n <b>Age: {{ group.age }}</b>\n </div>\n </ng-template>\n </ngx-datatable-group-header>\n\n <ngx-datatable-row-detail *ngIf=\"rowDetail && rowDetail.template\"\n [rowHeight]=\"rowDetail.rowHeight || 0\"\n [template]=\"$any(rowDetail.template)\"\n (toggle)=\"rowDetail.toggle.emit($event)\">\n </ngx-datatable-row-detail>\n\n <ngx-datatable-footer *ngIf=\"footer && footer.template\"\n [template]=\"$any(footer.template)\">\n </ngx-datatable-footer>\n </ngx-datatable>\n </ng-container>\n </div>\n</div>\n\n<ng-template #blankHeaderTpl ngx-datatable-header-template></ng-template>\n\n<ng-template #headerTpl ngx-datatable-header-template\n let-column=\"column\" let-sortFn=\"sortFn\">\n <strong *ngIf=\"!column.sortable\" class=\"draggable\">{{column.name}}</strong>\n <strong *ngIf=\"column.sortable\" class=\"datatable-sort-target draggable\" (click)=\"sortFn()\">{{column.name}}</strong>\n <div class=\"datatable-column-header-separator\" [attr.data-column-id]=\"column.$$id\"></div>\n</ng-template>\n\n<ng-template #cellTypeSelectorTpl ngx-datatable-cell-template\n let-value=\"value\" let-rowIndex=\"rowIndex\" let-row=\"row\" let-column=\"column\">\n <seam-table-cell-type-selector *ngIf=\"row\"\n [type]=\"column.cellType\"\n [value]=\"value\"\n [rowIndex]=\"rowIndex\"\n [row]=\"row\"\n [colData]=\"column\">\n </seam-table-cell-type-selector>\n</ng-template>\n\n<ng-template #actionMenuCellTpl ngx-datatable-cell-template\n let-value=\"value\" let-rowIndex=\"rowIndex\" let-row=\"row\">\n\n <ng-container *ngIf=\"row && rowActionItem?.template\">\n <ng-template\n [ngTemplateOutlet]=\"$any(rowActionItem?.template)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, row: row, rowIndex: rowIndex }\">\n </ng-template>\n </ng-container>\n\n</ng-template>\n\n<ng-template #treeToggleTpl ngx-datatable-tree-toggle let-tree=\"cellContext\">\n <button\n class=\"p-0 bg-transparent border-0 btn\"\n [disabled]=\"tree.treeStatus==='disabled'\"\n (click)=\"tree.onTreeAction()\">\n <span *ngIf=\"tree.treeStatus==='loading'\">\n <fa-icon [icon]=\"_faSpinner\"></fa-icon>\n </span>\n <span *ngIf=\"tree.treeStatus==='collapsed'\">\n <fa-icon [icon]=\"_faChevronRight\"></fa-icon>\n </span>\n <span *ngIf=\"tree.treeStatus==='expanded'\">\n <fa-icon [icon]=\"_faChevronDown\"></fa-icon>\n </span>\n <span *ngIf=\"tree.treeStatus==='disabled'\">\n <fa-icon [icon]=\"_faChevronRight\"></fa-icon>\n </span>\n </button>\n</ng-template>\n",
1020
1757
  changeDetection: ChangeDetectionStrategy.OnPush,
1021
1758
  animations: [
1022
1759
  trigger('slideDown', [
@@ -1030,14 +1767,20 @@ DatatableComponent.decorators = [
1030
1767
  ])
1031
1768
  ])
1032
1769
  ],
1033
- providers: [_THESEAM_DATATABLE, DatatableColumnChangesService, _THESEAM_DATATABLE_ACCESSOR],
1034
- styles: [":host{display:flex;flex-grow:1;flex-direction:column}::ng-deep .seam-datatable-action-menu{min-width:auto!important}ngx-datatable{position:absolute;top:0;left:0;right:0;bottom:0}.datatable-wrapper{display:flex;flex-direction:column;flex-grow:1}.datatable-wrapper .datatable-table-wrapper{position:relative;flex:1 1 100%}.datatable-column-header-separator{position:absolute;top:12px;bottom:12px;right:0;width:2px;background-color:#e1e3e6}.datatable-sort-target{cursor:pointer}"]
1770
+ providers: [
1771
+ _THESEAM_DATATABLE,
1772
+ DatatableColumnChangesService,
1773
+ _THESEAM_DATATABLE_ACCESSOR,
1774
+ ColumnsManagerService,
1775
+ ColumnsAlterationsManagerService,
1776
+ ],
1777
+ styles: [":host{display:flex;flex-grow:1;flex-direction:column}::ng-deep .seam-datatable-action-menu{min-width:auto!important}ngx-datatable{position:absolute!important;top:0;left:0;right:0;bottom:0}.datatable-wrapper{display:flex;flex-direction:column;flex-grow:1}.datatable-wrapper .datatable-table-wrapper{position:relative;flex:1 1 100%}.datatable-column-header-separator{position:absolute}.datatable-sort-target{cursor:pointer}\n"]
1035
1778
  },] }
1036
1779
  ];
1037
1780
  DatatableComponent.ctorParameters = () => [
1038
- { type: DatatableColumnChangesService },
1039
- { type: KeyValueDiffers },
1040
- { type: DatatablePreferencesService }
1781
+ { type: DatatablePreferencesService },
1782
+ { type: ColumnsManagerService },
1783
+ { type: ColumnsAlterationsManagerService }
1041
1784
  ];
1042
1785
  DatatableComponent.propDecorators = {
1043
1786
  preferencesKey: [{ type: Input }],
@@ -1096,6 +1839,7 @@ DatatableComponent.propDecorators = {
1096
1839
  actionMenu: [{ type: ContentChild, args: [DatatableActionMenuComponent, { static: true },] }],
1097
1840
  rowActionItem: [{ type: ContentChild, args: [DatatableRowActionItemDirective, { static: true },] }],
1098
1841
  rowDetail: [{ type: ContentChild, args: [TheSeamDatatableRowDetailDirective, { static: true },] }],
1842
+ footer: [{ type: ContentChild, args: [TheSeamDatatableFooterDirective, { static: true },] }],
1099
1843
  menuBarComponent: [{ type: ContentChild, args: [DatatableMenuBarComponent,] }],
1100
1844
  ngxDatatable: [{ type: ViewChild, args: [DatatableComponent$1,] }],
1101
1845
  ngxDatatableElement: [{ type: ViewChild, args: [DatatableComponent$1, { read: ElementRef },] }],
@@ -1104,7 +1848,8 @@ DatatableComponent.propDecorators = {
1104
1848
  treeToggleTpl: [{ type: ViewChild, args: ['treeToggleTpl', { static: true },] }],
1105
1849
  headerTpl: [{ type: ViewChild, args: ['headerTpl', { static: true },] }],
1106
1850
  blankHeaderTpl: [{ type: ViewChild, args: ['blankHeaderTpl', { static: true },] }],
1107
- cellTypeSelectorTpl: [{ type: ViewChild, args: ['cellTypeSelectorTpl', { static: true },] }]
1851
+ cellTypeSelectorTpl: [{ type: ViewChild, args: ['cellTypeSelectorTpl', { static: true },] }],
1852
+ _dblClick: [{ type: HostListener, args: ['dblclick', ['$event'],] }]
1108
1853
  };
1109
1854
  __decorate([
1110
1855
  InputBoolean()
@@ -1165,60 +1910,112 @@ __decorate([
1165
1910
  ], DatatableComponent.prototype, "scrollbarH", void 0);
1166
1911
 
1167
1912
  class DatatableColumnPreferencesComponent {
1168
- constructor(_datatable) {
1913
+ constructor(_datatable, _columnsAlterationsManager) {
1169
1914
  var _a;
1170
1915
  this._datatable = _datatable;
1916
+ this._columnsAlterationsManager = _columnsAlterationsManager;
1171
1917
  this._filterControl = new FormControl();
1918
+ this._alphabeticalColumnCompareFn = (a, b) => {
1919
+ const aProp = getColumnProp(a);
1920
+ const bProp = getColumnProp(b);
1921
+ return aProp === bProp ? 0 : aProp > bProp ? 1 : -1;
1922
+ };
1172
1923
  this._columns$ = combineLatest([
1173
1924
  (_a = this._datatable.columns$) !== null && _a !== void 0 ? _a : of([]),
1174
1925
  observeControlValue(this._filterControl)
1175
1926
  ]).pipe(map(([columns, filter]) => {
1176
1927
  const _filter = (filter || '').trim().toLowerCase();
1177
- return columns.filter(c => `${(c.name || c.prop || '')}`.toLowerCase().indexOf(_filter) !== -1);
1178
- }), map(cols => cols.sort((a, b) => a.prop === b.prop ? 0 : a.prop > b.prop ? 1 : -1)));
1928
+ return columns
1929
+ .filter(c => this._canToggleColumn(c, _filter))
1930
+ .sort(this._alphabeticalColumnCompareFn);
1931
+ }));
1179
1932
  }
1180
- ngOnInit() { }
1181
- _onChange(event, col) {
1182
- // TODO: Figure out the right way to update this value. If it is set by
1183
- // column component input this may not work right.
1184
- const columns = this._datatable.columns || [];
1185
- const column = columns.find(c => c.prop === col.prop);
1186
- if (column) {
1187
- column.hidden = !event.checked;
1188
- this._datatable.columns = [...columns];
1933
+ _canToggleColumn(column, filter, omitInternalColumns = true) {
1934
+ if (omitInternalColumns && isInternalColumn(column)) {
1935
+ return false;
1189
1936
  }
1937
+ return this._columnMatchesFilter(column, filter);
1190
1938
  }
1191
- _onCloseClick() {
1192
- // TODO: Implement when PopoverRef is implemented.
1939
+ _columnMatchesFilter(column, filter) {
1940
+ if (filter.length === 0) {
1941
+ return true;
1942
+ }
1943
+ return `${(getColumnProp(column) || '')}`.toLowerCase().indexOf(filter) !== -1;
1944
+ }
1945
+ _onChange(event, col) {
1946
+ const columnProp = getColumnProp(col);
1947
+ const hidden = !event.checked;
1948
+ if (!notNullOrUndefined(columnProp)) {
1949
+ throw Error(`Unable to get column prop.`);
1950
+ }
1951
+ const alteration = new HideColumnColumnsAlteration({
1952
+ columnProp,
1953
+ hidden
1954
+ }, hidden);
1955
+ this._columnsAlterationsManager.add([alteration]);
1193
1956
  }
1194
1957
  }
1195
1958
  DatatableColumnPreferencesComponent.decorators = [
1196
1959
  { type: Component, args: [{
1197
1960
  selector: 'seam-datatable-column-preferences',
1198
- template: "<h3>Columns</h3>\n\n<seam-form-field [numPaddingErrors]=\"0\" >\n <input seamInput [formControl]=\"_filterControl\" seamInputSize=\"sm\" placeholder=\"Search\">\n</seam-form-field>\n\n<div seamOverlayScrollbar style=\"min-height: 200px; max-height: 600px; min-width: 250px;\" class=\"flex-grow-1 mb-2\">\n <div class=\"p-2\">\n <ng-container *ngFor=\"let col of _columns$ | async\">\n <seam-checkbox [checked]=\"!col.hidden\" (change)=\"_onChange($event, col)\">{{ col.name || col.prop }}</seam-checkbox>\n </ng-container>\n </div>\n\n</div>\n<div class=\"d-flex flex-row justify-content-end\">\n <!-- <button seamButton size=\"sm\" theme=\"lightgray\" (click)=\"_onCloseClick()\">Close</button> -->\n <!-- <button seamButton size=\"sm\" theme=\"lightgray\" class=\"mr-1\">Cancel</button>\n <button seamButton size=\"sm\" theme=\"success\">Done</button> -->\n</div>\n",
1961
+ template: "<h3>Columns</h3>\n\n<seam-form-field [numPaddingErrors]=\"0\" >\n <input seamInput [formControl]=\"_filterControl\" seamInputSize=\"sm\" placeholder=\"Search\" seamAutoFocus>\n</seam-form-field>\n\n<div seamOverlayScrollbar style=\"min-height: 200px; max-height: 600px; min-width: 250px;\" class=\"flex-grow-1 mb-2\">\n <div class=\"p-2\">\n <ng-container *ngFor=\"let col of _columns$ | async\">\n <seam-checkbox [checked]=\"!col.hidden\" (change)=\"_onChange($event, col)\">{{ col.name || col.prop }}</seam-checkbox>\n </ng-container>\n </div>\n\n</div>\n<div class=\"d-flex flex-row justify-content-end\">\n <!-- <button seamButton size=\"sm\" theme=\"lightgray\" (click)=\"_onCloseClick()\">Close</button> -->\n <!-- <button seamButton size=\"sm\" theme=\"lightgray\" class=\"mr-1\">Cancel</button>\n <button seamButton size=\"sm\" theme=\"success\">Done</button> -->\n</div>\n",
1199
1962
  changeDetection: ChangeDetectionStrategy.OnPush,
1200
- styles: [":host{display:flex;flex-direction:column}"]
1963
+ styles: [":host{display:flex;flex-direction:column}\n"]
1201
1964
  },] }
1202
1965
  ];
1203
1966
  DatatableColumnPreferencesComponent.ctorParameters = () => [
1204
- { type: DatatableComponent, decorators: [{ type: Inject, args: [THESEAM_DATATABLE,] }] }
1967
+ { type: DatatableComponent, decorators: [{ type: Inject, args: [THESEAM_DATATABLE,] }] },
1968
+ { type: ColumnsAlterationsManagerService }
1205
1969
  ];
1206
1970
 
1207
1971
  class DatatableColumnPreferencesButtonComponent {
1208
- constructor() {
1972
+ constructor(_columnsAlterationsManager) {
1973
+ this._columnsAlterationsManager = _columnsAlterationsManager;
1209
1974
  this.icon = faColumns;
1975
+ /** @ignore */
1976
+ this._actionMenuPositions = [
1977
+ {
1978
+ originX: 'start',
1979
+ originY: 'bottom',
1980
+ overlayX: 'end',
1981
+ overlayY: 'top',
1982
+ },
1983
+ {
1984
+ originX: 'start',
1985
+ originY: 'top',
1986
+ overlayX: 'end',
1987
+ overlayY: 'bottom',
1988
+ },
1989
+ {
1990
+ originX: 'end',
1991
+ originY: 'bottom',
1992
+ overlayX: 'start',
1993
+ overlayY: 'top',
1994
+ },
1995
+ {
1996
+ originX: 'end',
1997
+ originY: 'top',
1998
+ overlayX: 'start',
1999
+ overlayY: 'bottom',
2000
+ },
2001
+ ];
1210
2002
  }
1211
2003
  ngOnInit() { }
2004
+ _resetColumns(event) {
2005
+ this._columnsAlterationsManager.clear();
2006
+ }
1212
2007
  }
1213
2008
  DatatableColumnPreferencesButtonComponent.decorators = [
1214
2009
  { type: Component, args: [{
1215
2010
  selector: 'seam-datatable-column-preferences-button',
1216
- template: "<ng-template #colPrefsTpl>\n <seam-datatable-column-preferences></seam-datatable-column-preferences>\n</ng-template>\n\n\n<button\n seamButton\n [seamPopover]=\"colPrefsTpl\"\n theme=\"lightgray\"\n size=\"sm\"\n style=\"padding-left: 10px; padding-right: 10px;\"\n title=\"Column Preferences\"\n >\n <seam-icon [icon]=\"icon\"></seam-icon>\n <span class=\"sr-only\">Column Preferences</span>\n</button>\n",
2011
+ template: "<ng-template #colPrefsTpl>\n <seam-datatable-column-preferences></seam-datatable-column-preferences>\n</ng-template>\n\n<seam-menu #menu\n menuClass=\"list-group py-0 border-0 seam-datatable-action-menu\"\n animationType=\"fade\">\n <button seamMenuItem\n type=\"button\"\n class=\"list-group-item list-group-item-action py-1\"\n [seamPopover]=\"colPrefsTpl\">\n Show/Hide Columns\n </button>\n\n <button seamMenuItem\n type=\"button\"\n class=\"list-group-item list-group-item-action py-1\"\n (click)=\"_resetColumns($event)\">\n Reset Columns\n </button>\n</seam-menu>\n\n<button type=\"button\" class=\"btn btn-lightgray btn-sm\"\n [seamMenuToggle]=\"menu\"\n [positions]=\"_actionMenuPositions || []\"\n style=\"padding-left: 10px; padding-right: 10px;\"\n title=\"Column Preferences\">\n <seam-icon [icon]=\"icon\"></seam-icon>\n <span class=\"sr-only\">Column Preferences</span>\n</button>\n\n",
1217
2012
  changeDetection: ChangeDetectionStrategy.OnPush,
1218
2013
  styles: [""]
1219
2014
  },] }
1220
2015
  ];
1221
- DatatableColumnPreferencesButtonComponent.ctorParameters = () => [];
2016
+ DatatableColumnPreferencesButtonComponent.ctorParameters = () => [
2017
+ { type: ColumnsAlterationsManagerService }
2018
+ ];
1222
2019
 
1223
2020
  class DatatableExportButtonComponent {
1224
2021
  constructor(_datatable, _toastr, _loading, _valueHelper, _data) {
@@ -1295,7 +2092,7 @@ DatatableExportButtonComponent.decorators = [
1295
2092
  selector: 'seam-datatable-export-button',
1296
2093
  template: "<seam-menu #menu>\n <button *ngFor=\"let exp of exporters\"\n seamMenuItem\n [icon]=\"exp?.icon\"\n (click)=\"_onExporterClicked(exp)\">\n {{ exp.label }}\n </button>\n</seam-menu>\n<button\n [seamMenuToggle]=\"menu\"\n seamButton\n theme=\"lightgray\"\n size=\"sm\"\n class=\"dropdown-toggle\"\n style=\"padding-left: 10px; padding-right: 10px;\"\n title=\"Export\"\n [disabled]=\"disabled\"\n >\n <seam-icon [icon]=\"icon\" class=\"mr-2\"></seam-icon>\n</button>\n",
1297
2094
  changeDetection: ChangeDetectionStrategy.OnPush,
1298
- styles: [":host{display:inline-block}"]
2095
+ styles: [":host{display:inline-block}\n"]
1299
2096
  },] }
1300
2097
  ];
1301
2098
  DatatableExportButtonComponent.ctorParameters = () => [
@@ -1319,7 +2116,7 @@ DatatableMenuBarColumnCenterComponent.decorators = [
1319
2116
  selector: 'seam-datatable-menu-bar-column-center',
1320
2117
  template: "<ng-content></ng-content>\n",
1321
2118
  changeDetection: ChangeDetectionStrategy.OnPush,
1322
- styles: [":host{display:flex;flex-direction:row;flex:1 1 auto;justify-content:center}"]
2119
+ styles: [":host{display:flex;flex-direction:row;flex:1 1 auto;justify-content:center}\n"]
1323
2120
  },] }
1324
2121
  ];
1325
2122
  DatatableMenuBarColumnCenterComponent.ctorParameters = () => [];
@@ -1334,7 +2131,7 @@ DatatableMenuBarColumnLeftComponent.decorators = [
1334
2131
  selector: 'seam-datatable-menu-bar-column-left',
1335
2132
  template: "<ng-content></ng-content>\n",
1336
2133
  changeDetection: ChangeDetectionStrategy.OnPush,
1337
- styles: [":host{display:flex;flex-direction:row;flex:1 1 0%;justify-content:flex-start}"]
2134
+ styles: [":host{display:flex;flex-direction:row;flex:1 1 0%;justify-content:flex-start}\n"]
1338
2135
  },] }
1339
2136
  ];
1340
2137
  DatatableMenuBarColumnLeftComponent.ctorParameters = () => [];
@@ -1349,7 +2146,7 @@ DatatableMenuBarColumnRightComponent.decorators = [
1349
2146
  selector: 'seam-datatable-menu-bar-column-right',
1350
2147
  template: "<ng-content></ng-content>\n",
1351
2148
  changeDetection: ChangeDetectionStrategy.OnPush,
1352
- styles: [":host{display:flex;flex-direction:row;flex:1 1 0%;justify-content:flex-end}"]
2149
+ styles: [":host{display:flex;flex-direction:row;flex:1 1 0%;justify-content:flex-end}\n"]
1353
2150
  },] }
1354
2151
  ];
1355
2152
  DatatableMenuBarColumnRightComponent.ctorParameters = () => [];
@@ -1364,7 +2161,7 @@ DatatableMenuBarRowComponent.decorators = [
1364
2161
  selector: 'seam-datatable-menu-bar-row',
1365
2162
  template: "<ng-content></ng-content>\n",
1366
2163
  changeDetection: ChangeDetectionStrategy.OnPush,
1367
- styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap}"]
2164
+ styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap}\n"]
1368
2165
  },] }
1369
2166
  ];
1370
2167
  DatatableMenuBarRowComponent.ctorParameters = () => [];
@@ -1627,6 +2424,25 @@ TheSeamDatatableScrollbarHelperService.ctorParameters = () => [
1627
2424
  { type: OverlayScrollbarsService }
1628
2425
  ];
1629
2426
 
2427
+ function withStoredColumnInfo(columns, preferenceColumns) {
2428
+ const _columns = [];
2429
+ for (const col of columns) {
2430
+ const storedCol = preferenceColumns.find(v => v.prop === col.prop);
2431
+ if (storedCol) {
2432
+ const _col = Object.assign({}, col);
2433
+ if (hasProperty(storedCol, 'width')) {
2434
+ _col.width = Math.max(storedCol.width, 0);
2435
+ }
2436
+ _col.canAutoResize = storedCol.canAutoResize;
2437
+ _columns.push(_col);
2438
+ }
2439
+ else {
2440
+ _columns.push(col);
2441
+ }
2442
+ }
2443
+ return _columns;
2444
+ }
2445
+
1630
2446
  class TheSeamDatatableModule {
1631
2447
  }
1632
2448
  TheSeamDatatableModule.decorators = [
@@ -1644,6 +2460,8 @@ TheSeamDatatableModule.decorators = [
1644
2460
  DatatableExportButtonComponent,
1645
2461
  TheSeamDatatableRowDetailDirective,
1646
2462
  DatatableRowDetailTplDirective,
2463
+ TheSeamDatatableFooterDirective,
2464
+ DatatableFooterTplDirective,
1647
2465
  DatatableColumnPreferencesComponent,
1648
2466
  DatatableColumnPreferencesButtonComponent,
1649
2467
  DatatableActionMenuItemDirective,
@@ -1686,6 +2504,8 @@ TheSeamDatatableModule.decorators = [
1686
2504
  DatatableExportButtonComponent,
1687
2505
  TheSeamDatatableRowDetailDirective,
1688
2506
  DatatableRowDetailTplDirective,
2507
+ TheSeamDatatableFooterDirective,
2508
+ DatatableFooterTplDirective,
1689
2509
  DatatableColumnPreferencesComponent,
1690
2510
  DatatableColumnPreferencesButtonComponent,
1691
2511
  DatatableActionMenuItemDirective,
@@ -1710,5 +2530,5 @@ TheSeamDatatableModule.decorators = [
1710
2530
  * Generated bundle index. Do not edit.
1711
2531
  */
1712
2532
 
1713
- export { DatatableActionMenuComponent, DatatableActionMenuItemComponent, DatatableActionMenuItemDirective, DatatableActionMenuToggleDirective, DatatableCellTplDirective, DatatableColumnChangesService, DatatableColumnComponent, DatatableColumnPreferencesButtonComponent, DatatableColumnPreferencesComponent, DatatableComponent, DatatableDataSource, DatatableExportButtonComponent, DatatableFilterDirective, DatatableGqlDataSource, DatatableMenuBarColumnCenterComponent, DatatableMenuBarColumnLeftComponent, DatatableMenuBarColumnRightComponent, DatatableMenuBarComponent, DatatableMenuBarRowComponent, DatatableMenuBarTextComponent, DatatablePreferencesService, DatatableRowActionItemDirective, DatatableRowDetailTplDirective, THESEAM_DATATABLE, THESEAM_DATATABLE_PREFERENCES_ACCESSOR, THESEAM_MENUBAR_ITEM_DATA, TheSeamDatatableModule, TheSeamDatatableRowDetailDirective, TheSeamDatatableScrollbarHelperService, _THESEAM_DATATABLE, _THESEAM_DATATABLE_ACCESSOR, _THESEAM_DATA_FILTER_CONTAINER, _setColumnDefaults, withStoredColumnInfo, THESEAM_DATATABLE_ACCESSOR as ɵa };
2533
+ export { CURRENT_DATATABLE_PREFERENCES_VERSION, DatatableActionMenuComponent, DatatableActionMenuItemComponent, DatatableActionMenuItemDirective, DatatableActionMenuToggleDirective, DatatableCellTplDirective, DatatableColumnChangesService, DatatableColumnComponent, DatatableColumnPreferencesButtonComponent, DatatableColumnPreferencesComponent, DatatableComponent, DatatableDataSource, DatatableExportButtonComponent, DatatableFilterDirective, DatatableFooterTplDirective, DatatableGqlDataSource, DatatableMenuBarColumnCenterComponent, DatatableMenuBarColumnLeftComponent, DatatableMenuBarColumnRightComponent, DatatableMenuBarComponent, DatatableMenuBarRowComponent, DatatableMenuBarTextComponent, DatatablePreferencesService, DatatableRowActionItemDirective, DatatableRowDetailTplDirective, EMPTY_DATATABLE_PREFERENCES, THESEAM_DATATABLE, THESEAM_DATATABLE_PREFERENCES_ACCESSOR, THESEAM_MENUBAR_ITEM_DATA, TheSeamDatatableFooterDirective, TheSeamDatatableModule, TheSeamDatatableRowDetailDirective, TheSeamDatatableScrollbarHelperService, _THESEAM_DATATABLE, _THESEAM_DATATABLE_ACCESSOR, _THESEAM_DATA_FILTER_CONTAINER, withStoredColumnInfo, THESEAM_DATATABLE_ACCESSOR as ɵa, ColumnsManagerService as ɵb, ColumnsAlterationsManagerService as ɵc };
1714
2534
  //# sourceMappingURL=theseam-ui-common-datatable.js.map