@theseam/ui-common 0.2.11 → 0.2.15

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 (352) 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 +1314 -378
  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 +27 -29
  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 +46 -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-menu-bar/datatable-menu-bar.component.d.ts +1 -1
  96. package/datatable/directives/datatable-filter.directive.d.ts +1 -1
  97. package/datatable/models/columns-alteration.d.ts +61 -0
  98. package/datatable/models/columns-alterations/hide-column.columns-alteration.d.ts +15 -0
  99. package/datatable/models/columns-alterations/order.columns-alteration.d.ts +20 -0
  100. package/datatable/models/columns-alterations/sort.columns-alteration.d.ts +14 -0
  101. package/datatable/models/columns-alterations/width.columns-alteration.d.ts +16 -0
  102. package/datatable/models/datatable-accessor.d.ts +5 -3
  103. package/datatable/models/internal-column-props.d.ts +7 -0
  104. package/datatable/models/page-info.d.ts +12 -0
  105. package/datatable/models/preferences-accessor.d.ts +1 -1
  106. package/datatable/models/preferences.d.ts +11 -3
  107. package/datatable/models/sort-item.d.ts +2 -1
  108. package/datatable/services/columns-alterations-manager.service.d.ts +39 -0
  109. package/datatable/services/columns-manager.service.d.ts +55 -0
  110. package/datatable/services/datatable-preferences.service.d.ts +10 -7
  111. package/datatable/theseam-ui-common-datatable.d.ts +2 -0
  112. package/datatable/theseam-ui-common-datatable.metadata.json +1 -1
  113. package/datatable/tokens/datatable-preferences-accessor.d.ts +2 -2
  114. package/datatable/utils/create-action-menu-column.d.ts +3 -0
  115. package/datatable/utils/create-checkbox-column.d.ts +3 -0
  116. package/datatable/utils/get-column-prop.d.ts +5 -0
  117. package/datatable/utils/map-columns-alterations-states.d.ts +2 -0
  118. package/datatable/utils/remove-unused-diffs.d.ts +7 -0
  119. package/datatable/utils/set-column-defaults.d.ts +2 -0
  120. package/datatable/utils/translate-templates.d.ts +2 -0
  121. package/datatable/utils/with-stored-column-info.d.ts +2 -2
  122. package/datatable-dynamic/theseam-ui-common-datatable-dynamic.metadata.json +1 -1
  123. package/esm2015/buttons/progress-circle-button/progress-circle-button.component.js +1 -1
  124. package/esm2015/card/card-action/card-action.component.js +1 -1
  125. package/esm2015/card/card-body/card-body.component.js +1 -1
  126. package/esm2015/data-filters/data-filter.js +5 -2
  127. package/esm2015/data-filters/filters/data-filter-search/data-filter-search.component.js +1 -1
  128. package/esm2015/data-filters/filters/data-filter-text/data-filter-text.component.js +1 -1
  129. package/esm2015/datatable/datatable/datatable.component.js +195 -211
  130. package/esm2015/datatable/datatable-action-menu/datatable-action-menu.component.js +1 -1
  131. package/esm2015/datatable/datatable-column/datatable-column.component.js +1 -1
  132. package/esm2015/datatable/datatable-column-preferences/datatable-column-preferences.component.js +42 -19
  133. package/esm2015/datatable/datatable-column-preferences-button/datatable-column-preferences-button.component.js +38 -4
  134. package/esm2015/datatable/datatable-export-button/datatable-export-button.component.js +9 -6
  135. package/esm2015/datatable/datatable-menu-bar/datatable-menu-bar.component.js +1 -1
  136. package/esm2015/datatable/datatable-menu-bar-column-center/datatable-menu-bar-column-center.component.js +1 -1
  137. package/esm2015/datatable/datatable-menu-bar-column-left/datatable-menu-bar-column-left.component.js +1 -1
  138. package/esm2015/datatable/datatable-menu-bar-column-right/datatable-menu-bar-column-right.component.js +1 -1
  139. package/esm2015/datatable/datatable-menu-bar-row/datatable-menu-bar-row.component.js +1 -1
  140. package/esm2015/datatable/models/columns-alteration.js +38 -0
  141. package/esm2015/datatable/models/columns-alterations/hide-column.columns-alteration.js +38 -0
  142. package/esm2015/datatable/models/columns-alterations/order.columns-alteration.js +81 -0
  143. package/esm2015/datatable/models/columns-alterations/sort.columns-alteration.js +33 -0
  144. package/esm2015/datatable/models/columns-alterations/width.columns-alteration.js +41 -0
  145. package/esm2015/datatable/models/datatable-accessor.js +1 -1
  146. package/esm2015/datatable/models/internal-column-props.js +15 -0
  147. package/esm2015/datatable/models/page-info.js +1 -1
  148. package/esm2015/datatable/models/preferences-accessor.js +1 -1
  149. package/esm2015/datatable/models/preferences.js +6 -2
  150. package/esm2015/datatable/models/sort-item.js +1 -1
  151. package/esm2015/datatable/services/columns-alterations-manager.service.js +134 -0
  152. package/esm2015/datatable/services/columns-manager.service.js +257 -0
  153. package/esm2015/datatable/services/datatable-preferences.service.js +78 -32
  154. package/esm2015/datatable/theseam-ui-common-datatable.js +3 -1
  155. package/esm2015/datatable/tokens/datatable-preferences-accessor.js +2 -2
  156. package/esm2015/datatable/utils/create-action-menu-column.js +18 -0
  157. package/esm2015/datatable/utils/create-checkbox-column.js +15 -0
  158. package/esm2015/datatable/utils/get-column-prop.js +9 -0
  159. package/esm2015/datatable/utils/map-columns-alterations-states.js +39 -0
  160. package/esm2015/datatable/utils/remove-unused-diffs.js +9 -0
  161. package/esm2015/datatable/utils/set-column-defaults.js +10 -0
  162. package/esm2015/datatable/utils/translate-templates.js +12 -0
  163. package/esm2015/datatable/utils/with-stored-column-info.js +1 -1
  164. package/esm2015/datatable-dynamic/datatable-dynamic-action-menu/datatable-dynamic-action-menu.component.js +1 -1
  165. package/esm2015/datatable-dynamic/datatable-dynamic-filter-container/datatable-dynamic-filter-container.component.js +1 -1
  166. package/esm2015/datatable-dynamic/datatable-dynamic.component.js +1 -1
  167. package/esm2015/form-field/form-field.component.js +1 -1
  168. package/esm2015/form-field-error/form-field-error/form-field-error.component.js +1 -1
  169. package/esm2015/framework/base-layout/base-layout.component.js +1 -1
  170. package/esm2015/framework/dashboard/dashboard-widgets/dashboard-widgets.component.js +1 -1
  171. package/esm2015/framework/dynamic-router/hierarchy-router-outlet/hierarchy-router-outlet.component.js +1 -1
  172. package/esm2015/framework/schema-form-controls/schema-form-input/schema-form-input.component.js +1 -1
  173. package/esm2015/framework/schema-form-controls/schema-form-number/schema-form-number.component.js +1 -1
  174. package/esm2015/framework/schema-form-controls/schema-form-select/schema-form-select.component.js +1 -1
  175. package/esm2015/framework/schema-form-controls/schema-form-submit-split/schema-form-submit-split.component.js +1 -1
  176. package/esm2015/framework/side-nav/side-nav-item/side-nav-item.component.js +1 -1
  177. package/esm2015/framework/side-nav/side-nav-toggle/side-nav-toggle.component.js +1 -1
  178. package/esm2015/framework/side-nav/side-nav.component.js +1 -1
  179. package/esm2015/framework/top-bar/top-bar-menu-button/top-bar-menu-button.component.js +1 -1
  180. package/esm2015/framework/top-bar/top-bar-title/top-bar-title.component.js +1 -1
  181. package/esm2015/framework/top-bar/top-bar.component.js +1 -1
  182. package/esm2015/graphql/datatable/create-page-info-observable.js +38 -0
  183. package/esm2015/graphql/datatable/datatable-graphql-query-ref.js +236 -0
  184. package/esm2015/graphql/datatable/datatable-graphql.service.js +35 -0
  185. package/esm2015/graphql/datatable/datatable-helpers.js +170 -0
  186. package/esm2015/graphql/datatable/get-page-info.js +11 -0
  187. package/esm2015/graphql/datatable/index.js +7 -0
  188. package/esm2015/graphql/datatable/map-filter-states.js +64 -0
  189. package/esm2015/graphql/datatable/map-page-info.js +14 -0
  190. package/esm2015/graphql/datatable/mapper-context.js +2 -0
  191. package/esm2015/graphql/models/gql-datatable-accessor.js +2 -0
  192. package/esm2015/graphql/models/index.js +2 -1
  193. package/esm2015/graphql/models/query-processing-config.js +1 -1
  194. package/esm2015/graphql/public-api.js +2 -1
  195. package/esm2015/graphql/utils/parse-hints.js +3 -3
  196. package/esm2015/icon/icon/icon.component.js +1 -1
  197. package/esm2015/loading/loading/loading.component.js +1 -1
  198. package/esm2015/menu/menu.component.js +1 -1
  199. package/esm2015/modal/modal-body/modal-body.component.js +1 -1
  200. package/esm2015/modal/modal-container/modal-container.component.js +1 -1
  201. package/esm2015/popover/popover/popover.component.js +1 -1
  202. package/esm2015/progress/progress-circle/progress-circle.component.js +1 -1
  203. package/esm2015/tabbed/tabbed.component.js +1 -1
  204. package/esm2015/table/table/table.component.js +1 -1
  205. package/esm2015/table-cell-types/public-api.js +8 -1
  206. package/esm2015/table-cell-types/table-cell-type-currency/table-cell-type-currency-config.js +2 -0
  207. package/esm2015/table-cell-types/table-cell-type-currency/table-cell-type-currency.component.js +74 -0
  208. package/esm2015/table-cell-types/table-cell-type-currency/table-cell-type-currency.js +2 -0
  209. package/esm2015/table-cell-types/table-cell-type-decimal/table-cell-type-decimal-config.js +1 -1
  210. package/esm2015/table-cell-types/table-cell-type-decimal/table-cell-type-decimal.component.js +73 -0
  211. package/esm2015/table-cell-types/table-cell-type-decimal/table-cell-type-decimal.js +2 -0
  212. package/esm2015/table-cell-types/table-cell-type-icon/table-cell-type-icon.component.js +1 -1
  213. package/esm2015/table-cell-types/table-cell-type-integer/table-cell-type-integer-config.js +1 -1
  214. package/esm2015/table-cell-types/table-cell-type-integer/table-cell-type-integer.component.js +71 -0
  215. package/esm2015/table-cell-types/table-cell-type-integer/table-cell-type-integer.js +2 -0
  216. package/esm2015/table-cell-types/table-cell-type-manifests.js +29 -17
  217. package/esm2015/table-cell-types/table-cell-type-progress-circle/table-cell-type-progress-circle.component.js +1 -1
  218. package/esm2015/table-cell-types/table-cell-types.module.js +9 -2
  219. package/esm2015/tel-input/tel-input/tel-input.component.js +1 -1
  220. package/esm2015/testing/current-tick-time.js +16 -0
  221. package/esm2015/testing/fake-toastr.js +29 -0
  222. package/esm2015/testing/get-harness.js +16 -0
  223. package/esm2015/testing/public-api.js +7 -0
  224. package/esm2015/testing/render-story.js +12 -0
  225. package/esm2015/testing/story-expect.js +39 -0
  226. package/esm2015/testing/theseam-ui-common-testing.js +5 -0
  227. package/esm2015/testing/tick-helper.js +74 -0
  228. package/esm2015/tiled-select/components/tiled-select/tiled-select.component.js +25 -17
  229. package/esm2015/tiled-select/components/tiled-select-tile/tiled-select-tile.component.js +5 -2
  230. package/esm2015/tiled-select/components/tiled-select-tile-icon/tiled-select-tile-icon.component.js +1 -1
  231. package/esm2015/tiled-select/public-api.js +2 -1
  232. package/esm2015/tiled-select/tiled-select.models.js +1 -1
  233. package/esm2015/tiled-select/tiled-select.module.js +4 -4
  234. package/esm2015/toggle-edit/toggle-edit-actions-container/toggle-edit-actions-container.component.js +1 -1
  235. package/esm2015/toggle-edit/toggle-edit.component.js +1 -1
  236. package/esm2015/utils/array-move.js +62 -0
  237. package/esm2015/utils/public-api.js +2 -1
  238. package/esm2015/utils/router/is-empty-url-route.js +1 -1
  239. package/esm2015/utils/subscriber-count.js +31 -4
  240. package/esm2015/widget/widget/widget.component.js +1 -1
  241. package/esm2015/widget/widget-content-components/widget-button-group/widget-button-group.component.js +1 -1
  242. package/esm2015/widget/widget-content-components/widget-content-header/widget-content-header.component.js +1 -1
  243. package/esm2015/widget/widget-content-components/widget-empty-label/widget-empty-label.component.js +1 -1
  244. package/esm2015/widget/widget-content-components/widget-footer-link/widget-footer-link.component.js +1 -1
  245. package/esm2015/widget/widget-content-components/widget-footer-text/widget-footer-text.component.js +1 -1
  246. package/esm2015/widget/widget-content-components/widget-header-badge/widget-header-badge.component.js +1 -1
  247. package/esm2015/widget/widget-content-components/widget-tile/widget-tile-footer-item/widget-tile-footer-item.component.js +1 -1
  248. package/esm2015/widget/widget-content-components/widget-tile/widget-tile-group/widget-tile-group.component.js +1 -1
  249. package/esm2015/widget/widget-content-components/widget-tile/widget-tile.component.js +1 -1
  250. package/esm2015/widget/widget-content-components/widget-tile-list/widget-tile-list.component.js +1 -1
  251. package/esm2015/widget/widget-footer/widget-footer.component.js +1 -1
  252. package/fesm2015/theseam-ui-common-buttons.js +1 -1
  253. package/fesm2015/theseam-ui-common-card.js +2 -2
  254. package/fesm2015/theseam-ui-common-data-filters.js +6 -3
  255. package/fesm2015/theseam-ui-common-data-filters.js.map +1 -1
  256. package/fesm2015/theseam-ui-common-datatable-dynamic.js +3 -3
  257. package/fesm2015/theseam-ui-common-datatable.js +1106 -319
  258. package/fesm2015/theseam-ui-common-datatable.js.map +1 -1
  259. package/fesm2015/theseam-ui-common-form-field-error.js +1 -1
  260. package/fesm2015/theseam-ui-common-form-field.js +1 -1
  261. package/fesm2015/theseam-ui-common-framework.js +13 -13
  262. package/fesm2015/theseam-ui-common-graphql.js +555 -5
  263. package/fesm2015/theseam-ui-common-graphql.js.map +1 -1
  264. package/fesm2015/theseam-ui-common-icon.js +1 -1
  265. package/fesm2015/theseam-ui-common-loading.js +1 -1
  266. package/fesm2015/theseam-ui-common-menu.js +1 -1
  267. package/fesm2015/theseam-ui-common-modal.js +2 -2
  268. package/fesm2015/theseam-ui-common-popover.js +1 -1
  269. package/fesm2015/theseam-ui-common-progress.js +1 -1
  270. package/fesm2015/theseam-ui-common-tabbed.js +1 -1
  271. package/fesm2015/theseam-ui-common-table-cell-types.js +234 -22
  272. package/fesm2015/theseam-ui-common-table-cell-types.js.map +1 -1
  273. package/fesm2015/theseam-ui-common-table.js +1 -1
  274. package/fesm2015/theseam-ui-common-tel-input.js +1 -1
  275. package/fesm2015/theseam-ui-common-testing.js +191 -0
  276. package/fesm2015/theseam-ui-common-testing.js.map +1 -0
  277. package/fesm2015/theseam-ui-common-tiled-select.js +34 -21
  278. package/fesm2015/theseam-ui-common-tiled-select.js.map +1 -1
  279. package/fesm2015/theseam-ui-common-toggle-edit.js +2 -2
  280. package/fesm2015/theseam-ui-common-utils.js +92 -4
  281. package/fesm2015/theseam-ui-common-utils.js.map +1 -1
  282. package/fesm2015/theseam-ui-common-widget.js +12 -12
  283. package/form-field/theseam-ui-common-form-field.metadata.json +1 -1
  284. package/form-field-error/theseam-ui-common-form-field-error.metadata.json +1 -1
  285. package/framework/theseam-ui-common-framework.metadata.json +1 -1
  286. package/graphql/datatable/create-page-info-observable.d.ts +4 -0
  287. package/graphql/datatable/datatable-graphql-query-ref.d.ts +65 -0
  288. package/graphql/datatable/datatable-graphql.service.d.ts +26 -0
  289. package/graphql/datatable/datatable-helpers.d.ts +12 -0
  290. package/graphql/datatable/get-page-info.d.ts +4 -0
  291. package/graphql/datatable/index.d.ts +6 -0
  292. package/graphql/datatable/map-filter-states.d.ts +18 -0
  293. package/graphql/datatable/map-page-info.d.ts +11 -0
  294. package/graphql/datatable/mapper-context.d.ts +6 -0
  295. package/graphql/models/gql-datatable-accessor.d.ts +9 -0
  296. package/graphql/models/index.d.ts +1 -0
  297. package/graphql/models/query-processing-config.d.ts +4 -0
  298. package/graphql/public-api.d.ts +1 -0
  299. package/graphql/theseam-ui-common-graphql.metadata.json +1 -1
  300. package/icon/theseam-ui-common-icon.metadata.json +1 -1
  301. package/loading/theseam-ui-common-loading.metadata.json +1 -1
  302. package/menu/theseam-ui-common-menu.metadata.json +1 -1
  303. package/modal/theseam-ui-common-modal.metadata.json +1 -1
  304. package/package.json +1 -1
  305. package/popover/theseam-ui-common-popover.metadata.json +1 -1
  306. package/progress/theseam-ui-common-progress.metadata.json +1 -1
  307. package/styles/vendor/ngx-datatable/_ngx-datatable.scss +54 -52
  308. package/tabbed/theseam-ui-common-tabbed.metadata.json +1 -1
  309. package/table/theseam-ui-common-table.metadata.json +1 -1
  310. package/table-cell-types/public-api.d.ts +7 -0
  311. package/table-cell-types/table-cell-type-currency/table-cell-type-currency-config.d.ts +39 -0
  312. package/table-cell-types/table-cell-type-currency/table-cell-type-currency.component.d.ts +19 -0
  313. package/table-cell-types/table-cell-type-currency/table-cell-type-currency.d.ts +3 -0
  314. package/table-cell-types/table-cell-type-decimal/table-cell-type-decimal-config.d.ts +31 -1
  315. package/table-cell-types/table-cell-type-decimal/table-cell-type-decimal.component.d.ts +19 -0
  316. package/table-cell-types/table-cell-type-decimal/table-cell-type-decimal.d.ts +3 -0
  317. package/table-cell-types/table-cell-type-integer/table-cell-type-integer-config.d.ts +23 -1
  318. package/table-cell-types/table-cell-type-integer/table-cell-type-integer.component.d.ts +19 -0
  319. package/table-cell-types/table-cell-type-integer/table-cell-type-integer.d.ts +3 -0
  320. package/table-cell-types/table-cell-type-manifests.d.ts +2 -1
  321. package/table-cell-types/theseam-ui-common-table-cell-types.metadata.json +1 -1
  322. package/tel-input/theseam-ui-common-tel-input.metadata.json +1 -1
  323. package/testing/current-tick-time.d.ts +13 -0
  324. package/testing/fake-toastr.d.ts +30 -0
  325. package/testing/get-harness.d.ts +7 -0
  326. package/testing/package.json +11 -0
  327. package/testing/public-api.d.ts +6 -0
  328. package/testing/render-story.d.ts +2 -0
  329. package/testing/story-expect.d.ts +5 -0
  330. package/{test-helpers/theseam-ui-common-test-helpers.d.ts → testing/theseam-ui-common-testing.d.ts} +0 -0
  331. package/testing/theseam-ui-common-testing.metadata.json +1 -0
  332. package/{test-helpers → testing}/tick-helper.d.ts +0 -0
  333. package/tiled-select/components/tiled-select/tiled-select.component.d.ts +7 -3
  334. package/tiled-select/components/tiled-select-tile/tiled-select-tile.component.d.ts +1 -0
  335. package/tiled-select/theseam-ui-common-tiled-select.metadata.json +1 -1
  336. package/tiled-select/tiled-select.models.d.ts +3 -1
  337. package/toggle-edit/theseam-ui-common-toggle-edit.metadata.json +1 -1
  338. package/utils/array-move.d.ts +49 -0
  339. package/utils/public-api.d.ts +1 -0
  340. package/utils/subscriber-count.d.ts +13 -1
  341. package/utils/theseam-ui-common-utils.metadata.json +1 -1
  342. package/widget/theseam-ui-common-widget.metadata.json +1 -1
  343. package/bundles/theseam-ui-common-test-helpers.umd.js +0 -94
  344. package/bundles/theseam-ui-common-test-helpers.umd.js.map +0 -1
  345. package/esm2015/test-helpers/public-api.js +0 -2
  346. package/esm2015/test-helpers/theseam-ui-common-test-helpers.js +0 -5
  347. package/esm2015/test-helpers/tick-helper.js +0 -74
  348. package/fesm2015/theseam-ui-common-test-helpers.js +0 -81
  349. package/fesm2015/theseam-ui-common-test-helpers.js.map +0 -1
  350. package/test-helpers/package.json +0 -11
  351. package/test-helpers/public-api.d.ts +0 -1
  352. 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 = () => [
@@ -401,7 +362,7 @@ DatatableMenuBarComponent.decorators = [
401
362
  selector: 'seam-datatable-menu-bar',
402
363
  template: "<div class=\"bg-light border rounded p-2\">\n <ng-content></ng-content>\n</div>\n",
403
364
  providers: [_THESEAM_DATA_FILTER_CONTAINER],
404
- styles: [":host{display:block}"]
365
+ styles: [":host{display:block}\n"]
405
366
  },] }
406
367
  ];
407
368
  DatatableMenuBarComponent.ctorParameters = () => [];
@@ -504,34 +465,368 @@ DatatableRowActionItemDirective.ctorParameters = () => [
504
465
  { type: TemplateRef }
505
466
  ];
506
467
 
507
- 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
+ }
506
+
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
+ }
508
524
 
509
- function withStoredColumnInfo(columns, preferenceColumns) {
510
- const _columns = [];
511
- for (const col of columns) {
512
- const storedCol = preferenceColumns.find(v => v.prop === col.prop);
513
- if (storedCol) {
514
- const _col = Object.assign({}, col);
515
- if (hasProperty(storedCol, 'width')) {
516
- _col.width = Math.max(storedCol.width, 0);
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.`);
517
681
  }
518
- _col.canAutoResize = storedCol.canAutoResize;
519
- _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);
520
705
  }
521
- else {
522
- _columns.push(col);
706
+ if (this._shouldAddRowActionColumn()) {
707
+ cols.push(createActionMenuColumn(this._actionMenuCellTpl, this._blankHeaderTpl));
523
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;
524
714
  }
525
- return _columns;
526
- }
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
+ ];
527
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
528
821
  class DatatablePreferencesService {
529
822
  constructor(_prefsAccessor) {
530
823
  this._prefsAccessor = _prefsAccessor;
531
824
  this._tablePrefsMap = new Map();
532
825
  this._pending = false;
826
+ this._loaded = false;
533
827
  }
534
828
  get pending() { return this._pending; }
829
+ get loaded() { return this._loaded; }
535
830
  preferences(preferenceKey) {
536
831
  let prefs = this._tablePrefsMap.get(preferenceKey);
537
832
  if (!prefs) {
@@ -546,16 +841,17 @@ class DatatablePreferencesService {
546
841
  }
547
842
  _createObservable(refreshSubject, prefKey) {
548
843
  if (!this._prefsAccessor) {
549
- return of({});
844
+ return of(EMPTY_DATATABLE_PREFERENCES);
550
845
  }
551
- const accessor = (key) => this._prefsAccessor ? this._prefsAccessor.get(key) : of('{}');
552
- 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 => {
553
848
  if (!v) {
554
849
  return null;
555
850
  }
556
851
  // TODO: Add a schema validator and migration tool to avoid parsing issues.
557
852
  try {
558
- return JSON.parse(v);
853
+ // return JSON.parse(v) as TheSeamDatatablePreferences
854
+ return this._descerializePreferences(v);
559
855
  }
560
856
  catch (error) {
561
857
  if (isDevMode()) {
@@ -563,7 +859,12 @@ class DatatablePreferencesService {
563
859
  }
564
860
  return null;
565
861
  }
566
- }), 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 }));
567
868
  }
568
869
  refresh(preferenceKey) {
569
870
  const prefs = this._tablePrefsMap.get(preferenceKey);
@@ -579,7 +880,40 @@ class DatatablePreferencesService {
579
880
  // out of order updates. This shouldn't be an issue, with how fast preferences
580
881
  // will most likely be changing, but it could happen in situations, such as
581
882
  // network issues.
582
- 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) {
583
917
  if (!this._prefsAccessor) {
584
918
  return;
585
919
  }
@@ -587,25 +921,20 @@ class DatatablePreferencesService {
587
921
  this.preferences(preferenceKey).pipe(map(prefs => {
588
922
  // Making the preferences immutable may not be necessary, but for now
589
923
  // this obj->str->obj will work as a naive clone.
590
- const columns = JSON.parse(JSON.stringify(prefs.columns || []));
591
- const _colPref = columns.find((c) => c.prop === column.prop);
592
- // console.log('has', _colPref)
593
- if (_colPref) {
594
- // console.log('hasProperty(column, "width"))', hasProperty(column, 'width'))
595
- if (hasProperty(column, 'width')) {
596
- _colPref.width = column.width;
597
- }
598
- if (hasProperty(column, 'canAutoResize')) {
599
- _colPref.canAutoResize = column.canAutoResize;
600
- }
601
- if (hasProperty(column, 'hidden')) {
602
- _colPref.hidden = column.hidden;
603
- }
604
- }
605
- else {
606
- columns.push(Object.assign({}, column));
607
- }
608
- 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 });
609
938
  return newPrefs;
610
939
  }),
611
940
  // tap(v => console.log('newPrefs', v)),
@@ -614,10 +943,19 @@ class DatatablePreferencesService {
614
943
  : of(newPrefs)), tap(() => this.refresh(preferenceKey)))
615
944
  .subscribe();
616
945
  }
617
- withColumnPreferences(preferenceKey, columns) {
618
- return this.preferences(preferenceKey).pipe(startWith({}), map(preferences => preferences && preferences.columns
619
- ? withStoredColumnInfo(columns, preferences.columns)
620
- : 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;
621
959
  }
622
960
  }
623
961
  DatatablePreferencesService.ɵprov = i0.ɵɵdefineInjectable({ factory: function DatatablePreferencesService_Factory() { return new DatatablePreferencesService(i0.ɵɵinject(THESEAM_DATATABLE_PREFERENCES_ACCESSOR, 8)); }, token: DatatablePreferencesService, providedIn: "root" });
@@ -632,14 +970,406 @@ DatatablePreferencesService.ctorParameters = () => [
632
970
 
633
971
  const THESEAM_DATATABLE_ACCESSOR = new InjectionToken('TheSeamDatatableAccessor');
634
972
 
635
- function _setColumnDefaults(columns) {
636
- for (const column of columns) {
637
- if (!column.hasOwnProperty('hidden')) {
638
- 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)}`);
639
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);
640
1244
  }
641
- setColumnDefaults(columns);
642
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
+ .map((column, index) => ({ column, index }))
1286
+ .filter(x => isInternalColumn(x.column));
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
+
643
1373
  /**
644
1374
  * Intended for internal classes declared by the `TheSeamDatatableModule`.
645
1375
  */
@@ -654,25 +1384,19 @@ const _THESEAM_DATATABLE_ACCESSOR = {
654
1384
  // tslint:disable-next-line:no-use-before-declare
655
1385
  useExisting: forwardRef(() => DatatableComponent)
656
1386
  };
657
- // TODO: Reduce reliance on BehaviorSubject based observables, because it should
658
- // be easier to avoit over emitting observables.
659
1387
  class DatatableComponent {
660
- constructor(_columnChangesService, _differs, _preferences) {
661
- // this.displayColumns$ = this.hiddenColumns$.pipe(
662
- // switchMap(hiddenColumns => this.columns$.pipe(map(cols => cols.filter(c => hiddenColumns.findIndex(hc => hc === c.prop) === -1))))
663
- // )
664
- this._columnChangesService = _columnChangesService;
665
- this._differs = _differs;
1388
+ constructor(_preferences, _columnsManager, _columnsAlterationsManager) {
666
1389
  this._preferences = _preferences;
667
- this.faChevronDown = faChevronDown;
668
- this.faChevronRight = faChevronRight;
669
- this.faSpinner = faSpinner;
1390
+ this._columnsManager = _columnsManager;
1391
+ this._columnsAlterationsManager = _columnsAlterationsManager;
1392
+ this._faChevronDown = faChevronDown;
1393
+ this._faChevronRight = faChevronRight;
1394
+ this._faSpinner = faSpinner;
670
1395
  this._ngUnsubscribe = new Subject();
671
1396
  this._filtersSubject = new BehaviorSubject([]);
672
- this._columnsObservable = new BehaviorSubject(undefined);
673
1397
  this._dataSourceSubject = new BehaviorSubject(undefined);
1398
+ this._resizing = {};
674
1399
  this._preferencesKey = new BehaviorSubject(undefined);
675
- this._columns = new BehaviorSubject([]);
676
1400
  this._rows = new BehaviorSubject([]);
677
1401
  this.columnMode = ColumnMode.force;
678
1402
  this.selected = [];
@@ -684,7 +1408,7 @@ class DatatableComponent {
684
1408
  this.loadingIndicator = false;
685
1409
  this.reorderable = true;
686
1410
  this.swapColumns = false;
687
- this.sortType = SortType.single;
1411
+ this._sortType = SortType.single;
688
1412
  this._sorts = [];
689
1413
  this.cssClasses = {
690
1414
  sortAscending: 'datatable-icon-up',
@@ -729,27 +1453,43 @@ class DatatableComponent {
729
1453
  this._colDiffersInp = {};
730
1454
  this._colDiffersTpl = {};
731
1455
  this._rowDetailToggleSubscription = Subscription.EMPTY;
732
- const applyPrefs = (cols) => this._preferencesKey.pipe(switchMap(name => !!name
733
- // NOTE: This pending check is temporary to avoid table using previously
734
- // retrieved preference while the new one is being updated on the
735
- // server.
736
- ? !this._preferences.pending
737
- ? this._preferences.withColumnPreferences(name, cols)
738
- : of(cols)
739
- : of(cols)));
740
- this.columns$ = this._columnsObservable.pipe(switchMap(colsObs => colsObs !== null && colsObs !== void 0 ? colsObs : of([])));
741
- 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)));
742
1491
  this.filters$ = this._filtersSubject.asObservable();
743
1492
  this.filterStates = this._filtersSubject.asObservable().pipe(switchMap(filters => composeDataFilterStates(filters)));
744
- // this.rows$ = this._filtersSubject.asObservable()
745
- // .pipe(
746
- // switchMap(filters => {
747
- // if (this.externalFiltering) {
748
- // return this._rows.asObservable()
749
- // }
750
- // return this._rows.asObservable().pipe(composeDataFilters(filters))
751
- // })
752
- // )
753
1493
  this.rows$ = this._dataSourceSubject.pipe(switchMap(dataSource => {
754
1494
  // console.log('dataSource', dataSource)
755
1495
  let dataStream;
@@ -785,34 +1525,35 @@ class DatatableComponent {
785
1525
  // tap(v => console.log('stream', v)),
786
1526
  takeUntil(this._ngUnsubscribe));
787
1527
  }));
788
- // this.hiddenColumns$ = this._hiddenColumns.asObservable()
789
- // this._hiddenColumns.pipe(
790
- // skip(1),
791
- // distinctUntilChanged((a, b) => {
792
- // const _a = Array.isArray(a) ? a : []
793
- // const _b = Array.isArray(b) ? b : []
794
- // if (_a.length !== _b.length) { return false }
795
- // const _as = _a.sort()
796
- // const _bs = _b.sort()
797
- // return !_as.sort().every((value: string, index: number) => _bs[index] === value)
798
- // }),
799
- // tap(v => this.hiddenColumnsChange.emit(v)),
800
- // untilDestroyed(this)
801
- // ).subscribe(v => console.log('hiddenColumnsChange', v))
802
1528
  // TODO: Implement viewChange for CollectionViewer.
803
1529
  this.viewChange = this.page.pipe(map(p => ({ start: 0, end: p.count })));
804
1530
  }
805
1531
  get filters() { return this._filtersSubject.value; }
806
1532
  get preferencesKey() { return this._preferencesKey.value; }
807
1533
  set preferencesKey(value) { this._preferencesKey.next(value || undefined); }
808
- get columns() { return this._columns.value; }
809
1534
  set columns(value) {
810
- // console.log('columns input', value)
811
- this._columns.next(Array.isArray(value) ? value : []);
1535
+ this._columnsManager.setInputColumns(Array.isArray(value) ? value : []);
812
1536
  }
813
1537
  get rows() { return this._rows.value; }
814
- set rows(value) { this._rows.next(value || []); }
815
- 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
+ }
816
1557
  set sorts(value) {
817
1558
  this._sorts = notNullOrUndefined(value) ? coerceArray(value) : [];
818
1559
  }
@@ -822,6 +1563,15 @@ class DatatableComponent {
822
1563
  }
823
1564
  this._dataSourceSubject.next(value || undefined);
824
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
+ }
825
1575
  get menuBarComponent() { return this._menuBarComponent; }
826
1576
  set menuBarComponent(value) {
827
1577
  var _a;
@@ -834,6 +1584,54 @@ class DatatableComponent {
834
1584
  this._menuBarSub = (_a = this._menuBarComponent) === null || _a === void 0 ? void 0 : _a.filtersChanged.subscribe(v => { this._setMenuBarFilters(value.filters()); });
835
1585
  }
836
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
+ }
837
1635
  ngOnInit() {
838
1636
  if (this.rowDetail) {
839
1637
  this._rowDetailToggleSubscription = this.rowDetail._toggle.subscribe(event => {
@@ -846,131 +1644,7 @@ class DatatableComponent {
846
1644
  ngOnDestroy() {
847
1645
  this._rowDetailToggleSubscription.unsubscribe();
848
1646
  }
849
- ngAfterContentInit() {
850
- var _a, _b;
851
- 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 }));
852
- const _columns = combineLatest([
853
- this.columnComponents$,
854
- this._columns
855
- ]).pipe(map(v => { var _a; return this._getMergedTplAndInpColumns(v[0], (_a = v[1]) !== null && _a !== void 0 ? _a : []); }),
856
- // tap(v => console.log('cols', v)),
857
- shareReplay({ bufferSize: 1, refCount: true }));
858
- this._columnsObservable.next(_columns);
859
- }
860
- _getMergedTplAndInpColumns(tplCols, inpCols) {
861
- const cols = [];
862
- if (this.selectionType === 'checkbox') {
863
- const checkBoxCol = {
864
- prop: '$$__checkbox__',
865
- name: '',
866
- width: 40,
867
- sortable: false,
868
- canAutoResize: false,
869
- draggable: false,
870
- resizeable: false,
871
- headerCheckboxable: true,
872
- checkboxable: true
873
- };
874
- cols.push(checkBoxCol);
875
- }
876
- const _tplCols = translateTemplates((tplCols || []));
877
- for (const col of inpCols) {
878
- const tplCol = _tplCols.find(t => t.prop === col.prop);
879
- // console.log({ col: { ...(col || {}) }, tplCol: { ...(tplCol || {}) } })
880
- const dtColumns = (this.ngxDatatable && this.ngxDatatable._internalColumns) || [];
881
- const prev = dtColumns.find(c => c.prop === col.prop);
882
- const inpColDiff = this._getColDiff(col);
883
- const _inpCol = inpColDiff ? {} : this._hasPrevColDiff(col) ? {} : col;
884
- if (inpColDiff) {
885
- inpColDiff.forEachRemovedItem(r => {
886
- if (prev && prev.hasOwnProperty(r.key)) {
887
- const k = r.key;
888
- delete prev[k];
889
- }
890
- });
891
- inpColDiff.forEachAddedItem(r => _inpCol[r.key] = r.currentValue);
892
- inpColDiff.forEachChangedItem(r => _inpCol[r.key] = r.currentValue);
893
- }
894
- let _tplCol = {};
895
- if (tplCol) {
896
- const tplColDiff = tplCol ? this._getColDiff(tplCol, true) : undefined;
897
- _tplCol = tplColDiff ? {} : this._hasPrevColDiff(col, true) ? {} : tplCol;
898
- if (tplColDiff) {
899
- tplColDiff.forEachRemovedItem(r => {
900
- if (prev && prev.hasOwnProperty(r.key)) {
901
- const k = r.key;
902
- delete prev[k];
903
- }
904
- });
905
- tplColDiff.forEachAddedItem(r => _tplCol[r.key] = r.currentValue);
906
- tplColDiff.forEachChangedItem(r => _tplCol[r.key] = r.currentValue);
907
- }
908
- }
909
- const _col = Object.assign(Object.assign(Object.assign({}, (prev || {})), _inpCol), _tplCol);
910
- cols.push(_col);
911
- }
912
- if (this.rowActionItem) {
913
- const actionMenuColumn = {
914
- prop: '$$__actionMenu__',
915
- name: '',
916
- width: 50,
917
- minWidth: 50,
918
- maxWidth: 50,
919
- resizeable: false,
920
- sortable: false,
921
- draggable: false,
922
- // TODO: Fix column auto sizing with fixed column and cell overlay before enabling.
923
- // frozenRight: true,
924
- cellTemplate: this.actionMenuCellTpl,
925
- headerTemplate: this.blankHeaderTpl
926
- };
927
- cols.push(actionMenuColumn);
928
- }
929
- for (const col of cols) {
930
- if (col.isTreeColumn && hasProperty(col, 'treeToggleTemplate')) {
931
- col.treeToggleTemplate = this.treeToggleTpl;
932
- }
933
- if (!hasProperty(col, 'headerTemplate')) {
934
- col.headerTemplate = this.headerTpl;
935
- }
936
- if (hasProperty(col, 'cellType')) {
937
- col.cellTemplate = this.cellTypeSelectorTpl;
938
- }
939
- }
940
- // setColumnDefaults(cols)
941
- _setColumnDefaults(cols);
942
- // console.log(cols.map(c => ({ prop: c.prop, canAutoResize: c.canAutoResize })))
943
- return cols;
944
- }
945
- _hasPrevColDiff(col, isTpl = false) {
946
- if (!col || !col.prop) {
947
- return false;
948
- }
949
- const differsMap = isTpl ? this._colDiffersTpl : this._colDiffersInp;
950
- return !!differsMap;
951
- }
952
- _getColDiff(col, isTpl = false) {
953
- if (!col || !col.prop) {
954
- return;
955
- }
956
- const differsMap = isTpl ? this._colDiffersTpl : this._colDiffersInp;
957
- if (!differsMap[col.prop]) {
958
- differsMap[col.prop] = this._differs.find({}).create();
959
- }
960
- const differ = differsMap[col.prop];
961
- const diff = differ.diff(col);
962
- return diff;
963
- }
964
- _removeUnusedDiffs(cols) {
965
- const inpKeys = Object.keys(this._colDiffersInp);
966
- inpKeys.filter(k => cols.findIndex(c => c.prop === k) === -1)
967
- .forEach(k => { delete this._colDiffersInp[k]; });
968
- const tplKeys = Object.keys(this._colDiffersTpl);
969
- tplKeys.filter(k => cols.findIndex(c => c.prop === k) === -1)
970
- .forEach(k => { delete this._colDiffersTpl[k]; });
971
- }
972
1647
  _setMenuBarFilters(filters) {
973
- // console.log('_setMenuBarFilters', filters)
974
1648
  this._filtersSubject.next(filters || []);
975
1649
  }
976
1650
  getColumnComponent(propName) {
@@ -1004,21 +1678,51 @@ class DatatableComponent {
1004
1678
  }
1005
1679
  }
1006
1680
  _onResize(event) {
1007
- // console.log('resize', event, event.column.prop)
1008
1681
  this.resize.emit(event);
1009
- if (event.isDone && this.columns) {
1010
- const columns = this.columns;
1011
- const col = columns.find(c => c.prop === event.column.prop);
1012
- if (col) {
1013
- 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;
1014
1695
  }
1015
- if (this.preferencesKey) {
1016
- const pref = { prop: event.column.prop, width: event.column.width, canAutoResize: false };
1017
- 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]);
1018
1703
  }
1019
- this.columns = [...this.columns];
1020
1704
  }
1021
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
+ }
1022
1726
  _onTreeAction(event) {
1023
1727
  const index = event.rowIndex;
1024
1728
  const row = event.row;
@@ -1033,6 +1737,9 @@ class DatatableComponent {
1033
1737
  triggerActionRefreshRequest() {
1034
1738
  this.actionRefreshRequest.emit(undefined);
1035
1739
  }
1740
+ /**
1741
+ * Returns the page info from the wrapped NgxDatatable instance or defaults.
1742
+ */
1036
1743
  get pageInfo() {
1037
1744
  var _a, _b, _c, _d, _e, _f, _g;
1038
1745
  return {
@@ -1046,7 +1753,7 @@ class DatatableComponent {
1046
1753
  DatatableComponent.decorators = [
1047
1754
  { type: Component, args: [{
1048
1755
  selector: 'seam-datatable',
1049
- 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)=\"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-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\"></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",
1050
1757
  changeDetection: ChangeDetectionStrategy.OnPush,
1051
1758
  animations: [
1052
1759
  trigger('slideDown', [
@@ -1060,14 +1767,20 @@ DatatableComponent.decorators = [
1060
1767
  ])
1061
1768
  ])
1062
1769
  ],
1063
- providers: [_THESEAM_DATATABLE, DatatableColumnChangesService, _THESEAM_DATATABLE_ACCESSOR],
1064
- 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}"]
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"]
1065
1778
  },] }
1066
1779
  ];
1067
1780
  DatatableComponent.ctorParameters = () => [
1068
- { type: DatatableColumnChangesService },
1069
- { type: KeyValueDiffers },
1070
- { type: DatatablePreferencesService }
1781
+ { type: DatatablePreferencesService },
1782
+ { type: ColumnsManagerService },
1783
+ { type: ColumnsAlterationsManagerService }
1071
1784
  ];
1072
1785
  DatatableComponent.propDecorators = {
1073
1786
  preferencesKey: [{ type: Input }],
@@ -1135,7 +1848,8 @@ DatatableComponent.propDecorators = {
1135
1848
  treeToggleTpl: [{ type: ViewChild, args: ['treeToggleTpl', { static: true },] }],
1136
1849
  headerTpl: [{ type: ViewChild, args: ['headerTpl', { static: true },] }],
1137
1850
  blankHeaderTpl: [{ type: ViewChild, args: ['blankHeaderTpl', { static: true },] }],
1138
- cellTypeSelectorTpl: [{ type: ViewChild, args: ['cellTypeSelectorTpl', { static: true },] }]
1851
+ cellTypeSelectorTpl: [{ type: ViewChild, args: ['cellTypeSelectorTpl', { static: true },] }],
1852
+ _dblClick: [{ type: HostListener, args: ['dblclick', ['$event'],] }]
1139
1853
  };
1140
1854
  __decorate([
1141
1855
  InputBoolean()
@@ -1196,60 +1910,112 @@ __decorate([
1196
1910
  ], DatatableComponent.prototype, "scrollbarH", void 0);
1197
1911
 
1198
1912
  class DatatableColumnPreferencesComponent {
1199
- constructor(_datatable) {
1913
+ constructor(_datatable, _columnsAlterationsManager) {
1200
1914
  var _a;
1201
1915
  this._datatable = _datatable;
1916
+ this._columnsAlterationsManager = _columnsAlterationsManager;
1202
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
+ };
1203
1923
  this._columns$ = combineLatest([
1204
1924
  (_a = this._datatable.columns$) !== null && _a !== void 0 ? _a : of([]),
1205
1925
  observeControlValue(this._filterControl)
1206
1926
  ]).pipe(map(([columns, filter]) => {
1207
1927
  const _filter = (filter || '').trim().toLowerCase();
1208
- return columns.filter(c => `${(c.name || c.prop || '')}`.toLowerCase().indexOf(_filter) !== -1);
1209
- }), 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
+ }));
1210
1932
  }
1211
- ngOnInit() { }
1212
- _onChange(event, col) {
1213
- // TODO: Figure out the right way to update this value. If it is set by
1214
- // column component input this may not work right.
1215
- const columns = this._datatable.columns || [];
1216
- const column = columns.find(c => c.prop === col.prop);
1217
- if (column) {
1218
- column.hidden = !event.checked;
1219
- this._datatable.columns = [...columns];
1933
+ _canToggleColumn(column, filter, omitInternalColumns = true) {
1934
+ if (omitInternalColumns && isInternalColumn(column)) {
1935
+ return false;
1220
1936
  }
1937
+ return this._columnMatchesFilter(column, filter);
1221
1938
  }
1222
- _onCloseClick() {
1223
- // 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]);
1224
1956
  }
1225
1957
  }
1226
1958
  DatatableColumnPreferencesComponent.decorators = [
1227
1959
  { type: Component, args: [{
1228
1960
  selector: 'seam-datatable-column-preferences',
1229
- 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",
1230
1962
  changeDetection: ChangeDetectionStrategy.OnPush,
1231
- styles: [":host{display:flex;flex-direction:column}"]
1963
+ styles: [":host{display:flex;flex-direction:column}\n"]
1232
1964
  },] }
1233
1965
  ];
1234
1966
  DatatableColumnPreferencesComponent.ctorParameters = () => [
1235
- { type: DatatableComponent, decorators: [{ type: Inject, args: [THESEAM_DATATABLE,] }] }
1967
+ { type: DatatableComponent, decorators: [{ type: Inject, args: [THESEAM_DATATABLE,] }] },
1968
+ { type: ColumnsAlterationsManagerService }
1236
1969
  ];
1237
1970
 
1238
1971
  class DatatableColumnPreferencesButtonComponent {
1239
- constructor() {
1972
+ constructor(_columnsAlterationsManager) {
1973
+ this._columnsAlterationsManager = _columnsAlterationsManager;
1240
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
+ ];
1241
2002
  }
1242
2003
  ngOnInit() { }
2004
+ _resetColumns(event) {
2005
+ this._columnsAlterationsManager.clear();
2006
+ }
1243
2007
  }
1244
2008
  DatatableColumnPreferencesButtonComponent.decorators = [
1245
2009
  { type: Component, args: [{
1246
2010
  selector: 'seam-datatable-column-preferences-button',
1247
- 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",
1248
2012
  changeDetection: ChangeDetectionStrategy.OnPush,
1249
2013
  styles: [""]
1250
2014
  },] }
1251
2015
  ];
1252
- DatatableColumnPreferencesButtonComponent.ctorParameters = () => [];
2016
+ DatatableColumnPreferencesButtonComponent.ctorParameters = () => [
2017
+ { type: ColumnsAlterationsManagerService }
2018
+ ];
1253
2019
 
1254
2020
  class DatatableExportButtonComponent {
1255
2021
  constructor(_datatable, _toastr, _loading, _valueHelper, _data) {
@@ -1274,12 +2040,14 @@ class DatatableExportButtonComponent {
1274
2040
  : `${exporter.label} export is not available.`;
1275
2041
  this._toastr.error(msg, 'Data Export');
1276
2042
  }
1277
- const export$ = this._datatable.rows$
1278
- .pipe(take(1), map(rows => {
2043
+ const export$ = combineLatest([
2044
+ this._datatable.rows$,
2045
+ this._datatable.columns$.pipe(map(cols => cols.filter(c => !isInternalColumn(c))))
2046
+ ]).pipe(take(1), map(([rows, columns]) => {
1279
2047
  if (exporter.skipDataMapping) {
1280
2048
  return rows;
1281
2049
  }
1282
- return this._mapExportData(this._datatable.columns || [], rows);
2050
+ return this._mapExportData(columns || [], rows);
1283
2051
  }), concatMap(data => exporter.export(data)), catchError(err => {
1284
2052
  console.error(err);
1285
2053
  return of(false);
@@ -1326,7 +2094,7 @@ DatatableExportButtonComponent.decorators = [
1326
2094
  selector: 'seam-datatable-export-button',
1327
2095
  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",
1328
2096
  changeDetection: ChangeDetectionStrategy.OnPush,
1329
- styles: [":host{display:inline-block}"]
2097
+ styles: [":host{display:inline-block}\n"]
1330
2098
  },] }
1331
2099
  ];
1332
2100
  DatatableExportButtonComponent.ctorParameters = () => [
@@ -1350,7 +2118,7 @@ DatatableMenuBarColumnCenterComponent.decorators = [
1350
2118
  selector: 'seam-datatable-menu-bar-column-center',
1351
2119
  template: "<ng-content></ng-content>\n",
1352
2120
  changeDetection: ChangeDetectionStrategy.OnPush,
1353
- styles: [":host{display:flex;flex-direction:row;flex:1 1 auto;justify-content:center}"]
2121
+ styles: [":host{display:flex;flex-direction:row;flex:1 1 auto;justify-content:center}\n"]
1354
2122
  },] }
1355
2123
  ];
1356
2124
  DatatableMenuBarColumnCenterComponent.ctorParameters = () => [];
@@ -1365,7 +2133,7 @@ DatatableMenuBarColumnLeftComponent.decorators = [
1365
2133
  selector: 'seam-datatable-menu-bar-column-left',
1366
2134
  template: "<ng-content></ng-content>\n",
1367
2135
  changeDetection: ChangeDetectionStrategy.OnPush,
1368
- styles: [":host{display:flex;flex-direction:row;flex:1 1 0%;justify-content:flex-start}"]
2136
+ styles: [":host{display:flex;flex-direction:row;flex:1 1 0%;justify-content:flex-start}\n"]
1369
2137
  },] }
1370
2138
  ];
1371
2139
  DatatableMenuBarColumnLeftComponent.ctorParameters = () => [];
@@ -1380,7 +2148,7 @@ DatatableMenuBarColumnRightComponent.decorators = [
1380
2148
  selector: 'seam-datatable-menu-bar-column-right',
1381
2149
  template: "<ng-content></ng-content>\n",
1382
2150
  changeDetection: ChangeDetectionStrategy.OnPush,
1383
- styles: [":host{display:flex;flex-direction:row;flex:1 1 0%;justify-content:flex-end}"]
2151
+ styles: [":host{display:flex;flex-direction:row;flex:1 1 0%;justify-content:flex-end}\n"]
1384
2152
  },] }
1385
2153
  ];
1386
2154
  DatatableMenuBarColumnRightComponent.ctorParameters = () => [];
@@ -1395,7 +2163,7 @@ DatatableMenuBarRowComponent.decorators = [
1395
2163
  selector: 'seam-datatable-menu-bar-row',
1396
2164
  template: "<ng-content></ng-content>\n",
1397
2165
  changeDetection: ChangeDetectionStrategy.OnPush,
1398
- styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap}"]
2166
+ styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap}\n"]
1399
2167
  },] }
1400
2168
  ];
1401
2169
  DatatableMenuBarRowComponent.ctorParameters = () => [];
@@ -1658,6 +2426,25 @@ TheSeamDatatableScrollbarHelperService.ctorParameters = () => [
1658
2426
  { type: OverlayScrollbarsService }
1659
2427
  ];
1660
2428
 
2429
+ function withStoredColumnInfo(columns, preferenceColumns) {
2430
+ const _columns = [];
2431
+ for (const col of columns) {
2432
+ const storedCol = preferenceColumns.find(v => v.prop === col.prop);
2433
+ if (storedCol) {
2434
+ const _col = Object.assign({}, col);
2435
+ if (hasProperty(storedCol, 'width')) {
2436
+ _col.width = Math.max(storedCol.width, 0);
2437
+ }
2438
+ _col.canAutoResize = storedCol.canAutoResize;
2439
+ _columns.push(_col);
2440
+ }
2441
+ else {
2442
+ _columns.push(col);
2443
+ }
2444
+ }
2445
+ return _columns;
2446
+ }
2447
+
1661
2448
  class TheSeamDatatableModule {
1662
2449
  }
1663
2450
  TheSeamDatatableModule.decorators = [
@@ -1745,5 +2532,5 @@ TheSeamDatatableModule.decorators = [
1745
2532
  * Generated bundle index. Do not edit.
1746
2533
  */
1747
2534
 
1748
- export { DatatableActionMenuComponent, DatatableActionMenuItemComponent, DatatableActionMenuItemDirective, DatatableActionMenuToggleDirective, DatatableCellTplDirective, DatatableColumnChangesService, DatatableColumnComponent, DatatableColumnPreferencesButtonComponent, DatatableColumnPreferencesComponent, DatatableComponent, DatatableDataSource, DatatableExportButtonComponent, DatatableFilterDirective, DatatableFooterTplDirective, DatatableGqlDataSource, DatatableMenuBarColumnCenterComponent, DatatableMenuBarColumnLeftComponent, DatatableMenuBarColumnRightComponent, DatatableMenuBarComponent, DatatableMenuBarRowComponent, DatatableMenuBarTextComponent, DatatablePreferencesService, DatatableRowActionItemDirective, DatatableRowDetailTplDirective, THESEAM_DATATABLE, THESEAM_DATATABLE_PREFERENCES_ACCESSOR, THESEAM_MENUBAR_ITEM_DATA, TheSeamDatatableFooterDirective, TheSeamDatatableModule, TheSeamDatatableRowDetailDirective, TheSeamDatatableScrollbarHelperService, _THESEAM_DATATABLE, _THESEAM_DATATABLE_ACCESSOR, _THESEAM_DATA_FILTER_CONTAINER, _setColumnDefaults, withStoredColumnInfo, THESEAM_DATATABLE_ACCESSOR as ɵa };
2535
+ 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 };
1749
2536
  //# sourceMappingURL=theseam-ui-common-datatable.js.map