@hermes-ui/angular 0.1.4

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 (539) hide show
  1. package/README.md +52 -0
  2. package/accordion/_accordion.clarity.scss +81 -0
  3. package/accordion/_properties.accordion.scss +45 -0
  4. package/accordion/_variables.accordion.scss +91 -0
  5. package/addons/a11y/README.md +157 -0
  6. package/addons/a11y/forms/required-field-legend.component.scss +17 -0
  7. package/addons/card-container/card/appfx-card.component.scss +137 -0
  8. package/addons/card-container/container/appfx-card-container.component.scss +17 -0
  9. package/addons/card-container/settings/appfx-card-container-settings.component.scss +62 -0
  10. package/addons/certificate-viewer/certificate-viewer/certificate-viewer.component.scss +69 -0
  11. package/addons/certificate-viewer/certificate-viewer-details/certificate-viewer-details.component.scss +49 -0
  12. package/addons/certificate-viewer/certificate-viewer-general/certificate-viewer-general.component.scss +38 -0
  13. package/addons/datagrid/README.md +289 -0
  14. package/addons/datagrid/addons/action-bar/datagrid-action-bar.component.scss +81 -0
  15. package/addons/datagrid/addons/column-toggle/datagrid-column-toggle.component.scss +99 -0
  16. package/addons/datagrid/addons/export/export-datagrid.component.scss +9 -0
  17. package/addons/datagrid/datagrid.component.scss +339 -0
  18. package/addons/datagrid-filters/README.md +223 -0
  19. package/addons/datagrid-filters/advanced-filters/date-time-filter.component.scss +10 -0
  20. package/addons/datagrid-filters/advanced-filters/enum-filter.component.scss +40 -0
  21. package/addons/datagrid-filters/advanced-filters/users-filter.component.scss +11 -0
  22. package/addons/datagrid-filters/common-styles.scss +98 -0
  23. package/addons/datagrid-filters/composite-filters.component.scss +26 -0
  24. package/addons/datagrid-filters/datagrid-filters.component.scss +22 -0
  25. package/addons/datagrid-filters/manage-filters/manage-filter.component.scss +42 -0
  26. package/addons/dialog/README.md +112 -0
  27. package/addons/dialog/multi-page-dialog.a11y.scss +203 -0
  28. package/addons/dialog/multi-page-dialog.component.scss +102 -0
  29. package/addons/dialog/toggle-component/toggle.component.scss +15 -0
  30. package/addons/drag-and-drop/README.md +48 -0
  31. package/addons/menu/menu.component.scss +120 -0
  32. package/addons/property-view/components/property-view-category.component.scss +38 -0
  33. package/addons/property-view/components/property-view-message.component.scss +48 -0
  34. package/addons/property-view/components/property-view-property.component.scss +122 -0
  35. package/addons/property-view/components/property-view-section.component.scss +59 -0
  36. package/addons/property-view/components/property-view.component.scss +23 -0
  37. package/addons/stepper/stepper.component.scss +53 -0
  38. package/addons/tabs/tab-links/tab-links.component.scss +61 -0
  39. package/addons/tabs/tabs.a11y.scss +26 -0
  40. package/addons/tabs/tabs.component.scss +95 -0
  41. package/addons/theme-builder/README.md +70 -0
  42. package/addons/theme-builder/theme-builder.component.scss +194 -0
  43. package/addons/translate/README.md +124 -0
  44. package/addons/var/debug/workflow-model-monitor.component.scss +50 -0
  45. package/addons/var/error/error.component.scss +38 -0
  46. package/addons/var/spinner/spinner.component.scss +33 -0
  47. package/addons/wizard/summary/summary.component.scss +22 -0
  48. package/addons/wizard/wizard.component.scss +251 -0
  49. package/button/_buttons.clarity.scss +388 -0
  50. package/button/_mixins.buttons.scss +241 -0
  51. package/button/_properties.buttons.scss +387 -0
  52. package/button/_properties.toggles.scss +35 -0
  53. package/button/_variables.buttons.scss +905 -0
  54. package/button/_variables.toggles.scss +41 -0
  55. package/button/button-group/_button-group.clarity.scss +202 -0
  56. package/collapsible-panel/_mixins.collapsible-panel.scss +189 -0
  57. package/collapsible-panel/_properties.collapsible-panel.scss +42 -0
  58. package/collapsible-panel/_variables.collapsible-panel.scss +40 -0
  59. package/data/_mixins.tables.scss +114 -0
  60. package/data/_properties.tables.scss +77 -0
  61. package/data/_tables.clarity.scss +120 -0
  62. package/data/_variables.tables.scss +42 -0
  63. package/data/datagrid/_datagrid.clarity.scss +1871 -0
  64. package/data/datagrid/_mixins.datagrid.scss +102 -0
  65. package/data/datagrid/_properties.datagrid.scss +98 -0
  66. package/data/datagrid/_variables.datagrid.scss +98 -0
  67. package/data/stack-view/_properties.stack-view.scss +50 -0
  68. package/data/stack-view/_stack-view.clarity.scss +267 -0
  69. package/data/stack-view/_variables.stack-view.scss +32 -0
  70. package/data/tree-view/_properties.tree-view.scss +41 -0
  71. package/data/tree-view/_tree-view.clarity.scss +281 -0
  72. package/data/tree-view/_variables.tree-view.scss +51 -0
  73. package/emphasis/alert/_alert.clarity.scss +467 -0
  74. package/emphasis/alert/_mixins.alert.scss +96 -0
  75. package/emphasis/alert/_properties.alert.scss +183 -0
  76. package/emphasis/alert/_variables.alert.scss +502 -0
  77. package/emphasis/badge/_badges.clarity.scss +61 -0
  78. package/emphasis/badge/_mixins.bades.scss +34 -0
  79. package/emphasis/badge/_properties.badges.scss +82 -0
  80. package/emphasis/badge/_variables.badges.scss +160 -0
  81. package/emphasis/label/_labels.clarity.scss +179 -0
  82. package/emphasis/label/_mixins.label.scss +77 -0
  83. package/emphasis/label/_properties.label.scss +105 -0
  84. package/emphasis/label/_variables.label.scss +181 -0
  85. package/fesm2022/hermes-ui-angular-accordion.mjs +355 -0
  86. package/fesm2022/hermes-ui-angular-accordion.mjs.map +1 -0
  87. package/fesm2022/hermes-ui-angular-addons-a11y.mjs +544 -0
  88. package/fesm2022/hermes-ui-angular-addons-a11y.mjs.map +1 -0
  89. package/fesm2022/hermes-ui-angular-addons-card-container.mjs +1082 -0
  90. package/fesm2022/hermes-ui-angular-addons-card-container.mjs.map +1 -0
  91. package/fesm2022/hermes-ui-angular-addons-certificate-viewer.mjs +2520 -0
  92. package/fesm2022/hermes-ui-angular-addons-certificate-viewer.mjs.map +1 -0
  93. package/fesm2022/hermes-ui-angular-addons-datagrid-filters.mjs +2818 -0
  94. package/fesm2022/hermes-ui-angular-addons-datagrid-filters.mjs.map +1 -0
  95. package/fesm2022/hermes-ui-angular-addons-datagrid.mjs +3131 -0
  96. package/fesm2022/hermes-ui-angular-addons-datagrid.mjs.map +1 -0
  97. package/fesm2022/hermes-ui-angular-addons-dialog.mjs +386 -0
  98. package/fesm2022/hermes-ui-angular-addons-dialog.mjs.map +1 -0
  99. package/fesm2022/hermes-ui-angular-addons-drag-and-drop.mjs +78 -0
  100. package/fesm2022/hermes-ui-angular-addons-drag-and-drop.mjs.map +1 -0
  101. package/fesm2022/hermes-ui-angular-addons-menu.mjs +559 -0
  102. package/fesm2022/hermes-ui-angular-addons-menu.mjs.map +1 -0
  103. package/fesm2022/hermes-ui-angular-addons-property-view.mjs +1142 -0
  104. package/fesm2022/hermes-ui-angular-addons-property-view.mjs.map +1 -0
  105. package/fesm2022/hermes-ui-angular-addons-stepper.mjs +716 -0
  106. package/fesm2022/hermes-ui-angular-addons-stepper.mjs.map +1 -0
  107. package/fesm2022/hermes-ui-angular-addons-tabs.mjs +539 -0
  108. package/fesm2022/hermes-ui-angular-addons-tabs.mjs.map +1 -0
  109. package/fesm2022/hermes-ui-angular-addons-testing.mjs +2010 -0
  110. package/fesm2022/hermes-ui-angular-addons-testing.mjs.map +1 -0
  111. package/fesm2022/hermes-ui-angular-addons-theme-builder.mjs +922 -0
  112. package/fesm2022/hermes-ui-angular-addons-theme-builder.mjs.map +1 -0
  113. package/fesm2022/hermes-ui-angular-addons-translate.mjs +295 -0
  114. package/fesm2022/hermes-ui-angular-addons-translate.mjs.map +1 -0
  115. package/fesm2022/hermes-ui-angular-addons-var.mjs +2028 -0
  116. package/fesm2022/hermes-ui-angular-addons-var.mjs.map +1 -0
  117. package/fesm2022/hermes-ui-angular-addons-wizard.mjs +610 -0
  118. package/fesm2022/hermes-ui-angular-addons-wizard.mjs.map +1 -0
  119. package/fesm2022/hermes-ui-angular-addons-workflow-strings.mjs +121 -0
  120. package/fesm2022/hermes-ui-angular-addons-workflow-strings.mjs.map +1 -0
  121. package/fesm2022/hermes-ui-angular-addons-workflow.mjs +88 -0
  122. package/fesm2022/hermes-ui-angular-addons-workflow.mjs.map +1 -0
  123. package/fesm2022/hermes-ui-angular-button.mjs +719 -0
  124. package/fesm2022/hermes-ui-angular-button.mjs.map +1 -0
  125. package/fesm2022/hermes-ui-angular-collapsible-panel.mjs +201 -0
  126. package/fesm2022/hermes-ui-angular-collapsible-panel.mjs.map +1 -0
  127. package/fesm2022/hermes-ui-angular-data-datagrid.mjs +8045 -0
  128. package/fesm2022/hermes-ui-angular-data-datagrid.mjs.map +1 -0
  129. package/fesm2022/hermes-ui-angular-data-stack-view.mjs +442 -0
  130. package/fesm2022/hermes-ui-angular-data-stack-view.mjs.map +1 -0
  131. package/fesm2022/hermes-ui-angular-data-tree-view.mjs +1106 -0
  132. package/fesm2022/hermes-ui-angular-data-tree-view.mjs.map +1 -0
  133. package/fesm2022/hermes-ui-angular-data.mjs +40 -0
  134. package/fesm2022/hermes-ui-angular-data.mjs.map +1 -0
  135. package/fesm2022/hermes-ui-angular-emphasis-alert.mjs +624 -0
  136. package/fesm2022/hermes-ui-angular-emphasis-alert.mjs.map +1 -0
  137. package/fesm2022/hermes-ui-angular-emphasis-badge.mjs +69 -0
  138. package/fesm2022/hermes-ui-angular-emphasis-badge.mjs.map +1 -0
  139. package/fesm2022/hermes-ui-angular-emphasis-common.mjs +25 -0
  140. package/fesm2022/hermes-ui-angular-emphasis-common.mjs.map +1 -0
  141. package/fesm2022/hermes-ui-angular-emphasis-label.mjs +105 -0
  142. package/fesm2022/hermes-ui-angular-emphasis-label.mjs.map +1 -0
  143. package/fesm2022/hermes-ui-angular-emphasis.mjs +41 -0
  144. package/fesm2022/hermes-ui-angular-emphasis.mjs.map +1 -0
  145. package/fesm2022/hermes-ui-angular-forms-checkbox.mjs +279 -0
  146. package/fesm2022/hermes-ui-angular-forms-checkbox.mjs.map +1 -0
  147. package/fesm2022/hermes-ui-angular-forms-combobox.mjs +1775 -0
  148. package/fesm2022/hermes-ui-angular-forms-combobox.mjs.map +1 -0
  149. package/fesm2022/hermes-ui-angular-forms-common.mjs +1251 -0
  150. package/fesm2022/hermes-ui-angular-forms-common.mjs.map +1 -0
  151. package/fesm2022/hermes-ui-angular-forms-datalist.mjs +263 -0
  152. package/fesm2022/hermes-ui-angular-forms-datalist.mjs.map +1 -0
  153. package/fesm2022/hermes-ui-angular-forms-datepicker.mjs +3274 -0
  154. package/fesm2022/hermes-ui-angular-forms-datepicker.mjs.map +1 -0
  155. package/fesm2022/hermes-ui-angular-forms-file-input.mjs +826 -0
  156. package/fesm2022/hermes-ui-angular-forms-file-input.mjs.map +1 -0
  157. package/fesm2022/hermes-ui-angular-forms-input.mjs +153 -0
  158. package/fesm2022/hermes-ui-angular-forms-input.mjs.map +1 -0
  159. package/fesm2022/hermes-ui-angular-forms-native-select.mjs +153 -0
  160. package/fesm2022/hermes-ui-angular-forms-native-select.mjs.map +1 -0
  161. package/fesm2022/hermes-ui-angular-forms-number-input.mjs +236 -0
  162. package/fesm2022/hermes-ui-angular-forms-number-input.mjs.map +1 -0
  163. package/fesm2022/hermes-ui-angular-forms-password.mjs +233 -0
  164. package/fesm2022/hermes-ui-angular-forms-password.mjs.map +1 -0
  165. package/fesm2022/hermes-ui-angular-forms-radio.mjs +224 -0
  166. package/fesm2022/hermes-ui-angular-forms-radio.mjs.map +1 -0
  167. package/fesm2022/hermes-ui-angular-forms-range.mjs +186 -0
  168. package/fesm2022/hermes-ui-angular-forms-range.mjs.map +1 -0
  169. package/fesm2022/hermes-ui-angular-forms-select.mjs +606 -0
  170. package/fesm2022/hermes-ui-angular-forms-select.mjs.map +1 -0
  171. package/fesm2022/hermes-ui-angular-forms-textarea.mjs +136 -0
  172. package/fesm2022/hermes-ui-angular-forms-textarea.mjs.map +1 -0
  173. package/fesm2022/hermes-ui-angular-forms.mjs +105 -0
  174. package/fesm2022/hermes-ui-angular-forms.mjs.map +1 -0
  175. package/fesm2022/hermes-ui-angular-icon.mjs +7413 -0
  176. package/fesm2022/hermes-ui-angular-icon.mjs.map +1 -0
  177. package/fesm2022/hermes-ui-angular-layout-breadcrumbs.mjs +120 -0
  178. package/fesm2022/hermes-ui-angular-layout-breadcrumbs.mjs.map +1 -0
  179. package/fesm2022/hermes-ui-angular-layout-main-container.mjs +100 -0
  180. package/fesm2022/hermes-ui-angular-layout-main-container.mjs.map +1 -0
  181. package/fesm2022/hermes-ui-angular-layout-nav.mjs +582 -0
  182. package/fesm2022/hermes-ui-angular-layout-nav.mjs.map +1 -0
  183. package/fesm2022/hermes-ui-angular-layout-tabs.mjs +807 -0
  184. package/fesm2022/hermes-ui-angular-layout-tabs.mjs.map +1 -0
  185. package/fesm2022/hermes-ui-angular-layout-vertical-nav.mjs +507 -0
  186. package/fesm2022/hermes-ui-angular-layout-vertical-nav.mjs.map +1 -0
  187. package/fesm2022/hermes-ui-angular-layout.mjs +44 -0
  188. package/fesm2022/hermes-ui-angular-layout.mjs.map +1 -0
  189. package/fesm2022/hermes-ui-angular-modal.mjs +619 -0
  190. package/fesm2022/hermes-ui-angular-modal.mjs.map +1 -0
  191. package/fesm2022/hermes-ui-angular-popover-common.mjs +1371 -0
  192. package/fesm2022/hermes-ui-angular-popover-common.mjs.map +1 -0
  193. package/fesm2022/hermes-ui-angular-popover-dropdown.mjs +492 -0
  194. package/fesm2022/hermes-ui-angular-popover-dropdown.mjs.map +1 -0
  195. package/fesm2022/hermes-ui-angular-popover-signpost.mjs +494 -0
  196. package/fesm2022/hermes-ui-angular-popover-signpost.mjs.map +1 -0
  197. package/fesm2022/hermes-ui-angular-popover-tooltip.mjs +293 -0
  198. package/fesm2022/hermes-ui-angular-popover-tooltip.mjs.map +1 -0
  199. package/fesm2022/hermes-ui-angular-popover.mjs +41 -0
  200. package/fesm2022/hermes-ui-angular-popover.mjs.map +1 -0
  201. package/fesm2022/hermes-ui-angular-progress-progress-bars.mjs +217 -0
  202. package/fesm2022/hermes-ui-angular-progress-progress-bars.mjs.map +1 -0
  203. package/fesm2022/hermes-ui-angular-progress-spinner.mjs +132 -0
  204. package/fesm2022/hermes-ui-angular-progress-spinner.mjs.map +1 -0
  205. package/fesm2022/hermes-ui-angular-stepper.mjs +694 -0
  206. package/fesm2022/hermes-ui-angular-stepper.mjs.map +1 -0
  207. package/fesm2022/hermes-ui-angular-timeline.mjs +316 -0
  208. package/fesm2022/hermes-ui-angular-timeline.mjs.map +1 -0
  209. package/fesm2022/hermes-ui-angular-toast.mjs +373 -0
  210. package/fesm2022/hermes-ui-angular-toast.mjs.map +1 -0
  211. package/fesm2022/hermes-ui-angular-utils-conditional.mjs +351 -0
  212. package/fesm2022/hermes-ui-angular-utils-conditional.mjs.map +1 -0
  213. package/fesm2022/hermes-ui-angular-utils-loading.mjs +107 -0
  214. package/fesm2022/hermes-ui-angular-utils-loading.mjs.map +1 -0
  215. package/fesm2022/hermes-ui-angular-utils.mjs +2086 -0
  216. package/fesm2022/hermes-ui-angular-utils.mjs.map +1 -0
  217. package/fesm2022/hermes-ui-angular-wizard.mjs +3074 -0
  218. package/fesm2022/hermes-ui-angular-wizard.mjs.map +1 -0
  219. package/fesm2022/hermes-ui-angular.mjs +130 -0
  220. package/fesm2022/hermes-ui-angular.mjs.map +1 -0
  221. package/forms/combobox/_combobox.clarity.scss +330 -0
  222. package/forms/combobox/_properties.combobox.scss +46 -0
  223. package/forms/combobox/_variables.combobox.scss +32 -0
  224. package/forms/datepicker/_datepicker.clarity.scss +259 -0
  225. package/forms/datepicker/_mixins.datepicker.scss +89 -0
  226. package/forms/datepicker/_properties.datepicker.scss +46 -0
  227. package/forms/datepicker/_variables.datepicker.scss +74 -0
  228. package/forms/styles/_checkbox.clarity.scss +193 -0
  229. package/forms/styles/_containers.clarity.scss +230 -0
  230. package/forms/styles/_datalist.clarity.scss +47 -0
  231. package/forms/styles/_file-input.clarity.scss +134 -0
  232. package/forms/styles/_file.clarity.scss +52 -0
  233. package/forms/styles/_form.clarity.scss +87 -0
  234. package/forms/styles/_input-group.clarity.scss +126 -0
  235. package/forms/styles/_input.clarity.scss +83 -0
  236. package/forms/styles/_mixins.forms.scss +193 -0
  237. package/forms/styles/_native-select.clarity.scss +178 -0
  238. package/forms/styles/_number-input.clarity.scss +58 -0
  239. package/forms/styles/_password.clarity.scss +26 -0
  240. package/forms/styles/_properties.forms.scss +180 -0
  241. package/forms/styles/_radio.clarity.scss +120 -0
  242. package/forms/styles/_range.clarity.scss +124 -0
  243. package/forms/styles/_select.clarity.scss +158 -0
  244. package/forms/styles/_textarea.clarity.scss +71 -0
  245. package/forms/styles/_toggles.clarity.scss +209 -0
  246. package/forms/styles/_variables.forms.scss +156 -0
  247. package/hermes-ui.scss +7 -0
  248. package/icon/icon.component.scss +247 -0
  249. package/image/_icons.clarity.scss +101 -0
  250. package/image/_images.clarity.scss +42 -0
  251. package/image/_mixins.images.scss +11 -0
  252. package/layout/_card.clarity.scss +318 -0
  253. package/layout/_login.clarity.scss +240 -0
  254. package/layout/_properties.card.scss +39 -0
  255. package/layout/_properties.login.scss +32 -0
  256. package/layout/_variables.card.scss +24 -0
  257. package/layout/_variables.login.scss +22 -0
  258. package/layout/breadcrumbs/_breadcrumbs.clarity.scss +60 -0
  259. package/layout/breadcrumbs/_properties.breadcrumbs.scss +18 -0
  260. package/layout/breadcrumbs/_variables.breadcrumbs.scss +11 -0
  261. package/layout/grid/_grid.scss +23 -0
  262. package/layout/grid/grid/_grid.scss +39 -0
  263. package/layout/grid/mixins/_breakpoint.scss +83 -0
  264. package/layout/grid/mixins/_clearfix.scss +13 -0
  265. package/layout/grid/mixins/_grid-framework.scss +91 -0
  266. package/layout/grid/mixins/_grid.scss +39 -0
  267. package/layout/grid/utilities/_align.scss +30 -0
  268. package/layout/grid/utilities/_clearfix.scss +12 -0
  269. package/layout/grid/utilities/_display.scss +18 -0
  270. package/layout/grid/utilities/_flex.scss +222 -0
  271. package/layout/grid/utilities/_float.scss +26 -0
  272. package/layout/grid/utilities/_visibility.scss +60 -0
  273. package/layout/main-container/_layout.clarity.scss +87 -0
  274. package/layout/main-container/_properties.header.scss +55 -0
  275. package/layout/main-container/_variables.header.scss +32 -0
  276. package/layout/nav/_header.clarity.scss +40 -0
  277. package/layout/nav/_links.clarity.scss +84 -0
  278. package/layout/nav/_mixins.header.scss +332 -0
  279. package/layout/nav/_mixins.responsive-nav.scss +75 -0
  280. package/layout/nav/_nav.clarity.scss +100 -0
  281. package/layout/nav/_properties.nav.scss +27 -0
  282. package/layout/nav/_properties.responsive-nav.scss +23 -0
  283. package/layout/nav/_properties.subnav.scss +19 -0
  284. package/layout/nav/_responsive-nav.clarity.scss +490 -0
  285. package/layout/nav/_subnav.clarity.scss +48 -0
  286. package/layout/nav/_variables.nav.scss +13 -0
  287. package/layout/nav/_variables.responsive-nav.scss +28 -0
  288. package/layout/nav/_variables.subnav.scss +21 -0
  289. package/layout/tabs/_mixins.tabs.scss +41 -0
  290. package/layout/tabs/_properties.tabs.scss +25 -0
  291. package/layout/tabs/_tabs.clarity.scss +110 -0
  292. package/layout/tabs/_variables.tabs.scss +17 -0
  293. package/layout/vertical-nav/_mixins.vertical-nav.scss +52 -0
  294. package/layout/vertical-nav/_properties.vertical-nav.scss +73 -0
  295. package/layout/vertical-nav/_variables.vertical-nav.scss +52 -0
  296. package/layout/vertical-nav/_vertical-nav.clarity.scss +469 -0
  297. package/main.scss +14 -0
  298. package/modal/_modal.clarity.scss +379 -0
  299. package/modal/_properties.modal.scss +57 -0
  300. package/modal/_variables.modal.scss +41 -0
  301. package/package.json +325 -0
  302. package/popover/common/README.md +112 -0
  303. package/popover/common/_popover.clarity.scss +28 -0
  304. package/popover/dropdown/_dropdown.clarity.scss +326 -0
  305. package/popover/dropdown/_menu-mixins.clarity.scss +132 -0
  306. package/popover/dropdown/_properties.dropdown.scss +50 -0
  307. package/popover/dropdown/_variables.dropdown.scss +36 -0
  308. package/popover/signpost/_properties.signpost.scss +34 -0
  309. package/popover/signpost/_signposts.clarity.scss +414 -0
  310. package/popover/signpost/_variables.signpost.scss +21 -0
  311. package/popover/tooltip/_mixins.tooltip.scss +186 -0
  312. package/popover/tooltip/_properties.tooltip.scss +28 -0
  313. package/popover/tooltip/_tooltips.clarity.scss +122 -0
  314. package/popover/tooltip/_variables.tooltip.scss +20 -0
  315. package/progress/progress-bars/_progress-bars.clarity.scss +616 -0
  316. package/progress/progress-bars/_properties.progress-bars.scss +24 -0
  317. package/progress/progress-bars/_variables.progress-bars.scss +15 -0
  318. package/progress/progress-bars/utils/_mixins.clarity.scss +18 -0
  319. package/progress/spinner/_mixins.spinner.scss +30 -0
  320. package/progress/spinner/_properties.spinner.scss +37 -0
  321. package/progress/spinner/_spinner.clarity.scss +148 -0
  322. package/progress/spinner/_variables.spinner.scss +25 -0
  323. package/schematics/collection.json +14 -0
  324. package/stepper/_properties.stepper.scss +29 -0
  325. package/stepper/_stepper.clarity.scss +184 -0
  326. package/stepper/_variables.stepper.scss +13 -0
  327. package/styles/_a11y.scss +14 -0
  328. package/styles/_close.clarity.scss +60 -0
  329. package/styles/_components.clarity.scss +189 -0
  330. package/styles/_mixins.scss +460 -0
  331. package/styles/_normalize.scss +292 -0
  332. package/styles/_reboot.clarity.scss +374 -0
  333. package/styles/_variables.clarity.scss +139 -0
  334. package/styles/core/base/base.element.scss +97 -0
  335. package/styles/core/global.scss +12 -0
  336. package/styles/core/layout/_alignments.scss +18 -0
  337. package/styles/core/layout/_container.scss +29 -0
  338. package/styles/core/layout/_display.scss +58 -0
  339. package/styles/core/layout/_optimize.scss +60 -0
  340. package/styles/core/layout/_shadow-dom.scss +47 -0
  341. package/styles/core/layout/_spacing.scss +31 -0
  342. package/styles/core/layout/_type-grid.scss +66 -0
  343. package/styles/core/layout/_type-horizontal.scss +33 -0
  344. package/styles/core/layout/_type-vertical.scss +26 -0
  345. package/styles/core/layout/mixins/_mixins.alignment.scss +35 -0
  346. package/styles/core/layout/mixins/_mixins.display.scss +23 -0
  347. package/styles/core/layout/mixins/_mixins.grid.scss +105 -0
  348. package/styles/core/layout/mixins/_mixins.scss +106 -0
  349. package/styles/core/layout/mixins/_mixins.shadow-dom.scss +106 -0
  350. package/styles/core/layout/mixins/_mixins.type-horizontal.scss +113 -0
  351. package/styles/core/layout/mixins/_mixins.type-vertical.scss +108 -0
  352. package/styles/core/module.layout.scss +22 -0
  353. package/styles/core/module.reset.scss +48 -0
  354. package/styles/core/module.typography.scss +9 -0
  355. package/styles/core/theme.dark.scss +298 -0
  356. package/styles/core/theme.high-contrast.scss +42 -0
  357. package/styles/core/theme.low-motion.scss +20 -0
  358. package/styles/core/tokens/_alias-interaction.scss +74 -0
  359. package/styles/core/tokens/_alias-object-background.scss +29 -0
  360. package/styles/core/tokens/_alias-object-border.scss +21 -0
  361. package/styles/core/tokens/_alias-object-container.scss +20 -0
  362. package/styles/core/tokens/_alias-object-opacity.scss +15 -0
  363. package/styles/core/tokens/_alias-object-shadow.scss +17 -0
  364. package/styles/core/tokens/_alias-primary.scss +21 -0
  365. package/styles/core/tokens/_alias-status.scss +40 -0
  366. package/styles/core/tokens/_alias-typography.scss +107 -0
  367. package/styles/core/tokens/_alias-utility.scss +42 -0
  368. package/styles/core/tokens/_alias-viz-colors.scss +170 -0
  369. package/styles/core/tokens/_global-animation.scss +32 -0
  370. package/styles/core/tokens/_global-colors.scss +249 -0
  371. package/styles/core/tokens/_global-space.scss +52 -0
  372. package/styles/core/tokens/_internal-scale.scss +14 -0
  373. package/styles/core/tokens/_properties.tokens.scss +22 -0
  374. package/styles/core/tokens/_variables.tokens.scss +787 -0
  375. package/styles/core/typography/_legacy-typography.scss +328 -0
  376. package/styles/core/typography/_mixins.typography.scss +18 -0
  377. package/styles/core/typography/_typography.scss +328 -0
  378. package/styles/variables/_properties.density.scss +225 -0
  379. package/styles/variables/_properties.global.scss +51 -0
  380. package/styles/variables/_properties.layout.scss +21 -0
  381. package/styles/variables/_properties.scss +11 -0
  382. package/styles/variables/_properties.typography.scss +164 -0
  383. package/styles/variables/_variables.density.scss +116 -0
  384. package/styles/variables/_variables.global.scss +87 -0
  385. package/styles/variables/_variables.layout.scss +37 -0
  386. package/styles/variables/_variables.scss +11 -0
  387. package/styles/variables/_variables.typography.scss +156 -0
  388. package/timeline/_properties.timeline.scss +38 -0
  389. package/timeline/_timeline.clarity.scss +172 -0
  390. package/timeline/_variables.timeline.scss +29 -0
  391. package/toast/README.md +65 -0
  392. package/toast/_properties.toast.scss +56 -0
  393. package/toast/_toast.clarity.scss +190 -0
  394. package/toast/_variables.toast.scss +33 -0
  395. package/types/hermes-ui-angular-accordion.d.ts +101 -0
  396. package/types/hermes-ui-angular-accordion.d.ts.map +1 -0
  397. package/types/hermes-ui-angular-addons-a11y.d.ts +187 -0
  398. package/types/hermes-ui-angular-addons-a11y.d.ts.map +1 -0
  399. package/types/hermes-ui-angular-addons-card-container.d.ts +482 -0
  400. package/types/hermes-ui-angular-addons-card-container.d.ts.map +1 -0
  401. package/types/hermes-ui-angular-addons-certificate-viewer.d.ts +404 -0
  402. package/types/hermes-ui-angular-addons-certificate-viewer.d.ts.map +1 -0
  403. package/types/hermes-ui-angular-addons-datagrid-filters.d.ts +911 -0
  404. package/types/hermes-ui-angular-addons-datagrid-filters.d.ts.map +1 -0
  405. package/types/hermes-ui-angular-addons-datagrid.d.ts +1529 -0
  406. package/types/hermes-ui-angular-addons-datagrid.d.ts.map +1 -0
  407. package/types/hermes-ui-angular-addons-dialog.d.ts +233 -0
  408. package/types/hermes-ui-angular-addons-dialog.d.ts.map +1 -0
  409. package/types/hermes-ui-angular-addons-drag-and-drop.d.ts +35 -0
  410. package/types/hermes-ui-angular-addons-drag-and-drop.d.ts.map +1 -0
  411. package/types/hermes-ui-angular-addons-menu.d.ts +197 -0
  412. package/types/hermes-ui-angular-addons-menu.d.ts.map +1 -0
  413. package/types/hermes-ui-angular-addons-property-view.d.ts +387 -0
  414. package/types/hermes-ui-angular-addons-property-view.d.ts.map +1 -0
  415. package/types/hermes-ui-angular-addons-stepper.d.ts +298 -0
  416. package/types/hermes-ui-angular-addons-stepper.d.ts.map +1 -0
  417. package/types/hermes-ui-angular-addons-tabs.d.ts +173 -0
  418. package/types/hermes-ui-angular-addons-tabs.d.ts.map +1 -0
  419. package/types/hermes-ui-angular-addons-testing.d.ts +592 -0
  420. package/types/hermes-ui-angular-addons-testing.d.ts.map +1 -0
  421. package/types/hermes-ui-angular-addons-theme-builder.d.ts +200 -0
  422. package/types/hermes-ui-angular-addons-theme-builder.d.ts.map +1 -0
  423. package/types/hermes-ui-angular-addons-translate.d.ts +149 -0
  424. package/types/hermes-ui-angular-addons-translate.d.ts.map +1 -0
  425. package/types/hermes-ui-angular-addons-var.d.ts +923 -0
  426. package/types/hermes-ui-angular-addons-var.d.ts.map +1 -0
  427. package/types/hermes-ui-angular-addons-wizard.d.ts +241 -0
  428. package/types/hermes-ui-angular-addons-wizard.d.ts.map +1 -0
  429. package/types/hermes-ui-angular-addons-workflow-strings.d.ts +124 -0
  430. package/types/hermes-ui-angular-addons-workflow-strings.d.ts.map +1 -0
  431. package/types/hermes-ui-angular-addons-workflow.d.ts +15 -0
  432. package/types/hermes-ui-angular-addons-workflow.d.ts.map +1 -0
  433. package/types/hermes-ui-angular-button.d.ts +170 -0
  434. package/types/hermes-ui-angular-button.d.ts.map +1 -0
  435. package/types/hermes-ui-angular-collapsible-panel.d.ts +74 -0
  436. package/types/hermes-ui-angular-collapsible-panel.d.ts.map +1 -0
  437. package/types/hermes-ui-angular-data-datagrid.d.ts +1938 -0
  438. package/types/hermes-ui-angular-data-datagrid.d.ts.map +1 -0
  439. package/types/hermes-ui-angular-data-stack-view.d.ts +88 -0
  440. package/types/hermes-ui-angular-data-stack-view.d.ts.map +1 -0
  441. package/types/hermes-ui-angular-data-tree-view.d.ts +230 -0
  442. package/types/hermes-ui-angular-data-tree-view.d.ts.map +1 -0
  443. package/types/hermes-ui-angular-data.d.ts +16 -0
  444. package/types/hermes-ui-angular-data.d.ts.map +1 -0
  445. package/types/hermes-ui-angular-emphasis-alert.d.ts +176 -0
  446. package/types/hermes-ui-angular-emphasis-alert.d.ts.map +1 -0
  447. package/types/hermes-ui-angular-emphasis-badge.d.ts +26 -0
  448. package/types/hermes-ui-angular-emphasis-badge.d.ts.map +1 -0
  449. package/types/hermes-ui-angular-emphasis-common.d.ts +7 -0
  450. package/types/hermes-ui-angular-emphasis-common.d.ts.map +1 -0
  451. package/types/hermes-ui-angular-emphasis-label.d.ts +30 -0
  452. package/types/hermes-ui-angular-emphasis-label.d.ts.map +1 -0
  453. package/types/hermes-ui-angular-emphasis.d.ts +16 -0
  454. package/types/hermes-ui-angular-emphasis.d.ts.map +1 -0
  455. package/types/hermes-ui-angular-forms-checkbox.d.ts +73 -0
  456. package/types/hermes-ui-angular-forms-checkbox.d.ts.map +1 -0
  457. package/types/hermes-ui-angular-forms-combobox.d.ts +354 -0
  458. package/types/hermes-ui-angular-forms-combobox.d.ts.map +1 -0
  459. package/types/hermes-ui-angular-forms-common.d.ts +340 -0
  460. package/types/hermes-ui-angular-forms-common.d.ts.map +1 -0
  461. package/types/hermes-ui-angular-forms-datalist.d.ts +60 -0
  462. package/types/hermes-ui-angular-forms-datalist.d.ts.map +1 -0
  463. package/types/hermes-ui-angular-forms-datepicker.d.ts +987 -0
  464. package/types/hermes-ui-angular-forms-datepicker.d.ts.map +1 -0
  465. package/types/hermes-ui-angular-forms-file-input.d.ts +194 -0
  466. package/types/hermes-ui-angular-forms-file-input.d.ts.map +1 -0
  467. package/types/hermes-ui-angular-forms-input.d.ts +30 -0
  468. package/types/hermes-ui-angular-forms-input.d.ts.map +1 -0
  469. package/types/hermes-ui-angular-forms-native-select.d.ts +37 -0
  470. package/types/hermes-ui-angular-forms-native-select.d.ts.map +1 -0
  471. package/types/hermes-ui-angular-forms-number-input.d.ts +44 -0
  472. package/types/hermes-ui-angular-forms-number-input.d.ts.map +1 -0
  473. package/types/hermes-ui-angular-forms-password.d.ts +53 -0
  474. package/types/hermes-ui-angular-forms-password.d.ts.map +1 -0
  475. package/types/hermes-ui-angular-forms-radio.d.ts +50 -0
  476. package/types/hermes-ui-angular-forms-radio.d.ts.map +1 -0
  477. package/types/hermes-ui-angular-forms-range.d.ts +38 -0
  478. package/types/hermes-ui-angular-forms-range.d.ts.map +1 -0
  479. package/types/hermes-ui-angular-forms-select.d.ts +211 -0
  480. package/types/hermes-ui-angular-forms-select.d.ts.map +1 -0
  481. package/types/hermes-ui-angular-forms-textarea.d.ts +30 -0
  482. package/types/hermes-ui-angular-forms-textarea.d.ts.map +1 -0
  483. package/types/hermes-ui-angular-forms.d.ts +39 -0
  484. package/types/hermes-ui-angular-forms.d.ts.map +1 -0
  485. package/types/hermes-ui-angular-icon.d.ts +1504 -0
  486. package/types/hermes-ui-angular-icon.d.ts.map +1 -0
  487. package/types/hermes-ui-angular-layout-breadcrumbs.d.ts +46 -0
  488. package/types/hermes-ui-angular-layout-breadcrumbs.d.ts.map +1 -0
  489. package/types/hermes-ui-angular-layout-main-container.d.ts +29 -0
  490. package/types/hermes-ui-angular-layout-main-container.d.ts.map +1 -0
  491. package/types/hermes-ui-angular-layout-nav.d.ts +143 -0
  492. package/types/hermes-ui-angular-layout-nav.d.ts.map +1 -0
  493. package/types/hermes-ui-angular-layout-tabs.d.ts +159 -0
  494. package/types/hermes-ui-angular-layout-tabs.d.ts.map +1 -0
  495. package/types/hermes-ui-angular-layout-vertical-nav.d.ts +129 -0
  496. package/types/hermes-ui-angular-layout-vertical-nav.d.ts.map +1 -0
  497. package/types/hermes-ui-angular-layout.d.ts +20 -0
  498. package/types/hermes-ui-angular-layout.d.ts.map +1 -0
  499. package/types/hermes-ui-angular-modal.d.ts +161 -0
  500. package/types/hermes-ui-angular-modal.d.ts.map +1 -0
  501. package/types/hermes-ui-angular-popover-common.d.ts +317 -0
  502. package/types/hermes-ui-angular-popover-common.d.ts.map +1 -0
  503. package/types/hermes-ui-angular-popover-dropdown.d.ts +124 -0
  504. package/types/hermes-ui-angular-popover-dropdown.d.ts.map +1 -0
  505. package/types/hermes-ui-angular-popover-signpost.d.ts +158 -0
  506. package/types/hermes-ui-angular-popover-signpost.d.ts.map +1 -0
  507. package/types/hermes-ui-angular-popover-tooltip.d.ts +84 -0
  508. package/types/hermes-ui-angular-popover-tooltip.d.ts.map +1 -0
  509. package/types/hermes-ui-angular-popover.d.ts +17 -0
  510. package/types/hermes-ui-angular-popover.d.ts.map +1 -0
  511. package/types/hermes-ui-angular-progress-progress-bars.d.ts +58 -0
  512. package/types/hermes-ui-angular-progress-progress-bars.d.ts.map +1 -0
  513. package/types/hermes-ui-angular-progress-spinner.d.ts +45 -0
  514. package/types/hermes-ui-angular-progress-spinner.d.ts.map +1 -0
  515. package/types/hermes-ui-angular-stepper.d.ts +180 -0
  516. package/types/hermes-ui-angular-stepper.d.ts.map +1 -0
  517. package/types/hermes-ui-angular-timeline.d.ts +87 -0
  518. package/types/hermes-ui-angular-timeline.d.ts.map +1 -0
  519. package/types/hermes-ui-angular-toast.d.ts +131 -0
  520. package/types/hermes-ui-angular-toast.d.ts.map +1 -0
  521. package/types/hermes-ui-angular-utils-conditional.d.ts +133 -0
  522. package/types/hermes-ui-angular-utils-conditional.d.ts.map +1 -0
  523. package/types/hermes-ui-angular-utils-loading.d.ts +39 -0
  524. package/types/hermes-ui-angular-utils-loading.d.ts.map +1 -0
  525. package/types/hermes-ui-angular-utils.d.ts +914 -0
  526. package/types/hermes-ui-angular-utils.d.ts.map +1 -0
  527. package/types/hermes-ui-angular-wizard.d.ts +1509 -0
  528. package/types/hermes-ui-angular-wizard.d.ts.map +1 -0
  529. package/types/hermes-ui-angular.d.ts +44 -0
  530. package/types/hermes-ui-angular.d.ts.map +1 -0
  531. package/typography/_code.scss +36 -0
  532. package/typography/_font-metropolis.scss +45 -0
  533. package/typography/_lists.scss +81 -0
  534. package/typography/_typography.scss +322 -0
  535. package/utils/animations/_animations.clarity.scss +44 -0
  536. package/utils/animations/_mixins.animations.scss +33 -0
  537. package/wizard/_properties.wizard.scss +54 -0
  538. package/wizard/_variables.wizard.scss +59 -0
  539. package/wizard/_wizard.clarity.scss +692 -0
@@ -0,0 +1,2818 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Injectable, EventEmitter, Output, Input, ChangeDetectionStrategy, Component, Directive, Pipe, Optional, SkipSelf, NgModule } from '@angular/core';
3
+ import * as i2$1 from '@angular/cdk/a11y';
4
+ import { A11yModule } from '@angular/cdk/a11y';
5
+ import * as i3 from '@hermes-ui/angular/forms/common';
6
+ import * as i4 from '@hermes-ui/angular/icon';
7
+ import { ClarityIcons, angleIcon, filterGridIcon, plusIcon, searchIcon, windowCloseIcon, HermesIcon } from '@hermes-ui/angular/icon';
8
+ import * as i5 from '@hermes-ui/angular/forms';
9
+ import { HermesCheckboxModule, HermesInputModule, HermesRadioModule, HermesNativeSelectModule } from '@hermes-ui/angular/forms';
10
+ import * as i4$1 from '@hermes-ui/angular/popover/signpost';
11
+ import { HermesSignpostModule } from '@hermes-ui/angular/popover/signpost';
12
+ import * as i5$1 from '@hermes-ui/angular/popover/common';
13
+ import * as i1 from '@angular/forms';
14
+ import { Validators, FormControl, FormArray, FormsModule, ReactiveFormsModule } from '@angular/forms';
15
+ import * as i2 from '@angular/common';
16
+ import { CommonModule, DatePipe } from '@angular/common';
17
+ import { debounceTime, distinctUntilChanged, takeUntil, tap, switchMap, catchError } from 'rxjs/operators';
18
+ import * as i6 from '@hermes-ui/angular/progress/spinner';
19
+ import { HermesSpinnerModule } from '@hermes-ui/angular/progress/spinner';
20
+ import { of, Subject } from 'rxjs';
21
+
22
+ /*
23
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
24
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
25
+ * This software is released under MIT license.
26
+ * The full license information can be found in LICENSE in the root directory of this project.
27
+ */
28
+ var ComparisonOperator;
29
+ (function (ComparisonOperator) {
30
+ ComparisonOperator[ComparisonOperator["Contains"] = 0] = "Contains";
31
+ ComparisonOperator[ComparisonOperator["DoesNotContain"] = 1] = "DoesNotContain";
32
+ ComparisonOperator[ComparisonOperator["Equals"] = 2] = "Equals";
33
+ ComparisonOperator[ComparisonOperator["DoesNotEqual"] = 3] = "DoesNotEqual";
34
+ ComparisonOperator[ComparisonOperator["StartsWith"] = 4] = "StartsWith";
35
+ ComparisonOperator[ComparisonOperator["EndsWith"] = 5] = "EndsWith";
36
+ ComparisonOperator[ComparisonOperator["IsEmpty"] = 6] = "IsEmpty";
37
+ ComparisonOperator[ComparisonOperator["LessThan"] = 7] = "LessThan";
38
+ ComparisonOperator[ComparisonOperator["LessThanOrEqualTo"] = 8] = "LessThanOrEqualTo";
39
+ ComparisonOperator[ComparisonOperator["GreaterThan"] = 9] = "GreaterThan";
40
+ ComparisonOperator[ComparisonOperator["GreaterThanOrEqualTo"] = 10] = "GreaterThanOrEqualTo";
41
+ ComparisonOperator[ComparisonOperator["Before"] = 11] = "Before";
42
+ ComparisonOperator[ComparisonOperator["BeforeOrEqualTo"] = 12] = "BeforeOrEqualTo";
43
+ ComparisonOperator[ComparisonOperator["After"] = 13] = "After";
44
+ ComparisonOperator[ComparisonOperator["AfterOrEqualTo"] = 14] = "AfterOrEqualTo";
45
+ ComparisonOperator[ComparisonOperator["CustomRange"] = 15] = "CustomRange";
46
+ ComparisonOperator[ComparisonOperator["LastDay"] = 16] = "LastDay";
47
+ ComparisonOperator[ComparisonOperator["LastWeek"] = 17] = "LastWeek";
48
+ ComparisonOperator[ComparisonOperator["LastMonth"] = 18] = "LastMonth";
49
+ ComparisonOperator[ComparisonOperator["LastYear"] = 19] = "LastYear";
50
+ ComparisonOperator[ComparisonOperator["TimeSpan"] = 20] = "TimeSpan";
51
+ })(ComparisonOperator || (ComparisonOperator = {}));
52
+ var LogicalOperator;
53
+ (function (LogicalOperator) {
54
+ LogicalOperator[LogicalOperator["And"] = 0] = "And";
55
+ LogicalOperator[LogicalOperator["Or"] = 1] = "Or";
56
+ })(LogicalOperator || (LogicalOperator = {}));
57
+ var FilterMode;
58
+ (function (FilterMode) {
59
+ FilterMode[FilterMode["Quick"] = 0] = "Quick";
60
+ FilterMode[FilterMode["Advanced"] = 1] = "Advanced";
61
+ FilterMode[FilterMode["AdvancedOnly"] = 2] = "AdvancedOnly";
62
+ })(FilterMode || (FilterMode = {}));
63
+ var PropertyType;
64
+ (function (PropertyType) {
65
+ PropertyType[PropertyType["String"] = 0] = "String";
66
+ PropertyType[PropertyType["Enum"] = 1] = "Enum";
67
+ PropertyType[PropertyType["Numeric"] = 2] = "Numeric";
68
+ PropertyType[PropertyType["DateTime"] = 3] = "DateTime";
69
+ PropertyType[PropertyType["User"] = 4] = "User";
70
+ })(PropertyType || (PropertyType = {}));
71
+ var Unit;
72
+ (function (Unit) {
73
+ Unit[Unit["Byte"] = 0] = "Byte";
74
+ Unit[Unit["KB"] = 1] = "KB";
75
+ Unit[Unit["MB"] = 2] = "MB";
76
+ Unit[Unit["GB"] = 3] = "GB";
77
+ Unit[Unit["TB"] = 4] = "TB";
78
+ Unit[Unit["HZ"] = 5] = "HZ";
79
+ Unit[Unit["KHZ"] = 6] = "KHZ";
80
+ Unit[Unit["MHZ"] = 7] = "MHZ";
81
+ Unit[Unit["GHZ"] = 8] = "GHZ";
82
+ Unit[Unit["BytePS"] = 9] = "BytePS";
83
+ Unit[Unit["KBytePS"] = 10] = "KBytePS";
84
+ Unit[Unit["MBytePS"] = 11] = "MBytePS";
85
+ Unit[Unit["GBytePS"] = 12] = "GBytePS";
86
+ Unit[Unit["BitPS"] = 13] = "BitPS";
87
+ Unit[Unit["KBitPS"] = 14] = "KBitPS";
88
+ Unit[Unit["MBitPS"] = 15] = "MBitPS";
89
+ Unit[Unit["GBitPS"] = 16] = "GBitPS";
90
+ })(Unit || (Unit = {}));
91
+ var TimeSpan;
92
+ (function (TimeSpan) {
93
+ TimeSpan[TimeSpan["Minutes"] = 0] = "Minutes";
94
+ TimeSpan[TimeSpan["Hours"] = 1] = "Hours";
95
+ TimeSpan[TimeSpan["Days"] = 2] = "Days";
96
+ TimeSpan[TimeSpan["Weeks"] = 3] = "Weeks";
97
+ TimeSpan[TimeSpan["Months"] = 4] = "Months";
98
+ TimeSpan[TimeSpan["Years"] = 5] = "Years";
99
+ })(TimeSpan || (TimeSpan = {}));
100
+
101
+ /*
102
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
103
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
104
+ * This software is released under MIT license.
105
+ * The full license information can be found in LICENSE in the root directory of this project.
106
+ */
107
+ /* eslint-disable @typescript-eslint/parameter-properties */
108
+ /**
109
+ * Defines a property that can be used to filter data in a datagrid.
110
+ * Filterable properties are usually a subset of the datagrid columns.
111
+ */
112
+ class FilterablePropertyDefinition {
113
+ constructor(displayName, property, operators) {
114
+ this.displayName = displayName;
115
+ this.property = property;
116
+ if (operators) {
117
+ this.supportedOperators = operators;
118
+ }
119
+ }
120
+ }
121
+ class StringPropertyDefinition extends FilterablePropertyDefinition {
122
+ constructor(displayName, property, operators, singleCondition, logicalOperator) {
123
+ super(displayName, property, operators);
124
+ /**
125
+ * Indicates that the property can be used with single condition only.
126
+ */
127
+ this.singleCondition = false;
128
+ this.defaultOperators = [
129
+ ComparisonOperator.Equals,
130
+ ComparisonOperator.DoesNotEqual,
131
+ ComparisonOperator.Contains,
132
+ ComparisonOperator.DoesNotContain,
133
+ ComparisonOperator.StartsWith,
134
+ ComparisonOperator.EndsWith,
135
+ ComparisonOperator.IsEmpty,
136
+ ];
137
+ if (singleCondition) {
138
+ this.singleCondition = singleCondition;
139
+ }
140
+ this.logicalOperator = logicalOperator;
141
+ }
142
+ getOperators() {
143
+ return this.supportedOperators || this.defaultOperators;
144
+ }
145
+ }
146
+ class EnumPropertyDefinition extends FilterablePropertyDefinition {
147
+ /**
148
+ * Creates an instance of EnumPropertyDefinition.
149
+ * @param displayName - The human-readable name of the property shown in the UI.
150
+ * @param property - The technical property name used for filtering logic.
151
+ * @param values - A Map containing the enum keys and their corresponding display values.
152
+ * @param singleSelect - Whether the filter restricts selection to a single item. Defaults to false.
153
+ * @param searchable - Whether to enable a search input for the enum options. Defaults to false.
154
+ * @param enableSelectAll - Whether to display the select all checkbox. Defaults to true.
155
+ * @param allowNotInOperator - Flag indicating whether to allow the use of the "NOT IN" operator
156
+ * for the selected values, enabling users to exclude specific enum items.
157
+ */
158
+ constructor(displayName, property, values, singleSelect = false, searchable = false, enableSelectAll = true, allowNotInOperator = false) {
159
+ super(displayName, property, allowNotInOperator ? [ComparisonOperator.DoesNotEqual, ComparisonOperator.Equals] : undefined);
160
+ /**
161
+ * Indicates that the property should be used for single select filtering
162
+ */
163
+ this.singleSelect = false;
164
+ /**
165
+ * Indicates that the enumeration should be searchable in the filter UI.
166
+ */
167
+ this.searchable = false;
168
+ /**
169
+ * Flag indicating whether to show the select all checkbox.
170
+ */
171
+ this.enableSelectAll = true;
172
+ this.values = values;
173
+ this.singleSelect = singleSelect;
174
+ this.searchable = searchable;
175
+ this.enableSelectAll = enableSelectAll;
176
+ }
177
+ }
178
+ class NumericPropertyDefinition extends FilterablePropertyDefinition {
179
+ constructor(displayName, property, operators, unit, singleCondition, logicalOperator) {
180
+ super(displayName, property, operators);
181
+ /**
182
+ * Indicates that the property can be used with single condition only.
183
+ */
184
+ this.singleCondition = false;
185
+ this.defaultOperators = [
186
+ ComparisonOperator.Equals,
187
+ ComparisonOperator.DoesNotEqual,
188
+ ComparisonOperator.LessThan,
189
+ ComparisonOperator.LessThanOrEqualTo,
190
+ ComparisonOperator.GreaterThan,
191
+ ComparisonOperator.GreaterThanOrEqualTo,
192
+ ComparisonOperator.IsEmpty,
193
+ ];
194
+ // Check for null and undefined
195
+ if (unit !== null && unit !== undefined) {
196
+ this.unit = unit;
197
+ }
198
+ if (singleCondition) {
199
+ this.singleCondition = singleCondition;
200
+ }
201
+ this.logicalOperator = logicalOperator;
202
+ }
203
+ getOperators() {
204
+ return this.supportedOperators || this.defaultOperators;
205
+ }
206
+ }
207
+ class UserPropertyDefinition extends FilterablePropertyDefinition {
208
+ constructor(displayName, property) {
209
+ super(displayName, property, [ComparisonOperator.Equals, ComparisonOperator.DoesNotEqual]);
210
+ }
211
+ }
212
+ class DateTimePropertyDefinition extends FilterablePropertyDefinition {
213
+ constructor(displayName, property, operators, includeSeconds) {
214
+ super(displayName, property, operators);
215
+ this.defaultOperators = [
216
+ ComparisonOperator.Equals,
217
+ ComparisonOperator.Before,
218
+ ComparisonOperator.BeforeOrEqualTo,
219
+ ComparisonOperator.After,
220
+ ComparisonOperator.AfterOrEqualTo,
221
+ ComparisonOperator.CustomRange,
222
+ ComparisonOperator.IsEmpty,
223
+ ComparisonOperator.LastDay,
224
+ ComparisonOperator.LastWeek,
225
+ ComparisonOperator.LastMonth,
226
+ ComparisonOperator.LastYear,
227
+ ComparisonOperator.TimeSpan,
228
+ ];
229
+ this.includeSeconds = includeSeconds ? includeSeconds : false;
230
+ }
231
+ getOperators() {
232
+ return this.supportedOperators || this.defaultOperators;
233
+ }
234
+ }
235
+ class PropertyFilter {
236
+ }
237
+ class PropertyPredicate {
238
+ }
239
+
240
+ /*
241
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
242
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
243
+ * This software is released under MIT license.
244
+ * The full license information can be found in LICENSE in the root directory of this project.
245
+ */
246
+ /**
247
+ * User-visible strings used in the 'appfx-datagrid-filters' library.
248
+ * Fields are read-only to avoid accidentally modifying the values and affecting all
249
+ * filters in the application.
250
+ *
251
+ * Strings are in English only. If you need to provide localized strings:
252
+ * - extend this class
253
+ * - override all fields with localized values
254
+ * - provide instance in the module, where you use AppFx
255
+ *
256
+ * ```
257
+ * @NgModule({
258
+ * ...
259
+ * providers: [
260
+ * { provide: DatagridFiltersStrings, useClass: LocalizedDatagridFiltersStrings },
261
+ * ]
262
+ * })
263
+ * export class AppModule {}
264
+ * ```
265
+ */
266
+ class DatagridFiltersStrings {
267
+ constructor() {
268
+ /**
269
+ * Filter type label.
270
+ */
271
+ this.filterType = 'Filter Type';
272
+ /**
273
+ * Quick filter label.
274
+ */
275
+ this.quickFilter = 'Quick Filter';
276
+ /**
277
+ * Advanced filter label.
278
+ */
279
+ this.advancedFilter = 'Advanced Filter';
280
+ /**
281
+ * Input placeholder.
282
+ */
283
+ this.enterValue = 'Enter value';
284
+ /**
285
+ * Required validator error message
286
+ */
287
+ this.requiredValidatorMessage = 'This field is required';
288
+ /**
289
+ * Numeric input validator error message
290
+ */
291
+ this.integerValidatorMessage = 'Integer value required';
292
+ /**
293
+ * Add new filter button label.
294
+ */
295
+ this.addNew = 'Add new';
296
+ /**
297
+ * Add new filter button aria label.
298
+ */
299
+ this.addNewAriaLabel = 'Add new filter';
300
+ /**
301
+ * Select filter label.
302
+ */
303
+ this.filterLabel = 'Filter';
304
+ /**
305
+ * Select operator label.
306
+ */
307
+ this.operatorLabel = 'Operator';
308
+ /**
309
+ * Comparison operator display names.
310
+ */
311
+ this.operator = {
312
+ after: 'After',
313
+ afterOrEqualTo: 'After or equal to',
314
+ before: 'Before',
315
+ beforeOrEqualTo: 'Before or equal to',
316
+ contains: 'Contains',
317
+ customRange: 'Custom range',
318
+ doesNotContain: 'Does not contain',
319
+ doesNotEqual: 'Does not equal',
320
+ endsWith: 'Ends with',
321
+ equals: 'Equals',
322
+ greaterThan: 'Greater than',
323
+ greaterThanOrEqualTo: 'Greater than or equal to',
324
+ isEmpty: 'Is empty',
325
+ lastDay: 'Last day',
326
+ lastWeek: 'Last week',
327
+ lastMonth: 'Last month',
328
+ lastYear: 'Last year',
329
+ lessThan: 'Less than',
330
+ lessThanOrEqualTo: 'Less than or equal to',
331
+ startsWith: 'Starts with',
332
+ timeSpan: 'Time span',
333
+ };
334
+ /**
335
+ * Select unit aria label.
336
+ */
337
+ this.unitAriaLabel = 'Unit';
338
+ /**
339
+ * Add second condition button label.
340
+ */
341
+ this.addCondition = 'Add condition';
342
+ /**
343
+ * Remove second condition button aria label.
344
+ */
345
+ this.removeConditionAriaLabel = 'Remove second condition';
346
+ /**
347
+ * Conjoiners.
348
+ */
349
+ this.logicalOperator = {
350
+ and: 'And',
351
+ or: 'Or',
352
+ };
353
+ /**
354
+ * Cancel button label.
355
+ */
356
+ this.cancel = 'Cancel';
357
+ /**
358
+ * Apply button label.
359
+ */
360
+ this.apply = 'Apply';
361
+ /**
362
+ * Select values label.
363
+ */
364
+ this.valueLabel = 'Value';
365
+ /**
366
+ * Select all option label.
367
+ */
368
+ this.selectAll = 'Select all';
369
+ /**
370
+ * Applied filters text.
371
+ */
372
+ this.appliedText = 'applied';
373
+ this.editFilterText = 'Edit filter';
374
+ this.removeFilterText = 'Remove filter';
375
+ this.hideButtonLabel = 'Hide';
376
+ this.hideButtonAriaLabel = 'Hide filters';
377
+ this.showButtonLabel = 'Show';
378
+ this.filtersText = 'filters';
379
+ this.filterText = 'filter';
380
+ this.clearAllButtonLabel = 'Clear all';
381
+ this.clearAllButtonAriaLabel = 'Clear all filters';
382
+ this.searchOptions = 'Search options';
383
+ this.searchPlaceholder = 'Search...';
384
+ this.showingFormat = 'Showing {} of {} results';
385
+ this.noValuesFound = 'No matching values found.';
386
+ this.elementsSelectedFormat = '{} elements selected';
387
+ this.loading = 'Loading...';
388
+ this.allSearchResults = 'Select All Search Results';
389
+ this.loadMore = 'Load more ...';
390
+ this.domain = 'Domain';
391
+ this.user = 'User';
392
+ this.errorSearchingUsers = 'Error searching users.';
393
+ this.errorLoadingDomains = 'Error loading domains.';
394
+ this.emptyUsersError = 'Add at least one user.';
395
+ /**
396
+ * Add time condition button label.
397
+ */
398
+ this.addTimeFilter = 'Filter by time';
399
+ /**
400
+ * Date input placeholder.
401
+ */
402
+ this.dateFormat = 'YYYY-MM-DD';
403
+ /**
404
+ * Time input placeholder.
405
+ */
406
+ this.timeFormat = 'HH:mm';
407
+ /**
408
+ * Date input validator error message
409
+ */
410
+ this.dateValidatorMessage = 'Invalid date format';
411
+ /**
412
+ * Time input validator error message
413
+ */
414
+ this.timeValidatorMessage = 'Invalid time format';
415
+ this.fromLabel = 'From';
416
+ this.toLabel = 'To';
417
+ /**
418
+ * Remove time filter button aria label.
419
+ */
420
+ this.removeTimeFilterAriaLabel = 'Remove time filter';
421
+ this.timeSpan = {
422
+ minutes: 'Minutes',
423
+ hours: 'Hours',
424
+ days: 'Days',
425
+ weeks: 'Weeks',
426
+ months: 'Months',
427
+ years: 'Years',
428
+ };
429
+ /**
430
+ * Time span aria label.
431
+ */
432
+ this.timeSpanAriaLabel = 'Time span';
433
+ this.timeSpanInputLabel = 'In the last';
434
+ this.unit = {
435
+ byte: 'B',
436
+ kb: 'KB',
437
+ mb: 'MB',
438
+ gb: 'GB',
439
+ tb: 'TB',
440
+ hz: 'Hz',
441
+ khz: 'KHz',
442
+ mhz: 'MHz',
443
+ ghz: 'GHz',
444
+ byteps: 'B/s',
445
+ kbyteps: 'KB/s',
446
+ mbyteps: 'MB/s',
447
+ gbyteps: 'GB/s',
448
+ bitps: 'Bit/s',
449
+ kbitps: 'Kbit/s',
450
+ mbitps: 'Mbit/s',
451
+ gbitps: 'Gbit/s',
452
+ };
453
+ }
454
+ formatString(stringFormat, args) {
455
+ let result = stringFormat;
456
+ for (const arg of args) {
457
+ result = result.replace('{}', arg);
458
+ }
459
+ return result;
460
+ }
461
+ getOperatorDisplayName(operator) {
462
+ switch (operator) {
463
+ case ComparisonOperator.After:
464
+ return this.operator.after;
465
+ case ComparisonOperator.AfterOrEqualTo:
466
+ return this.operator.afterOrEqualTo;
467
+ case ComparisonOperator.Before:
468
+ return this.operator.before;
469
+ case ComparisonOperator.BeforeOrEqualTo:
470
+ return this.operator.beforeOrEqualTo;
471
+ case ComparisonOperator.Contains:
472
+ return this.operator.contains;
473
+ case ComparisonOperator.CustomRange:
474
+ return this.operator.customRange;
475
+ case ComparisonOperator.DoesNotContain:
476
+ return this.operator.doesNotContain;
477
+ case ComparisonOperator.DoesNotEqual:
478
+ return this.operator.doesNotEqual;
479
+ case ComparisonOperator.Equals:
480
+ return this.operator.equals;
481
+ case ComparisonOperator.EndsWith:
482
+ return this.operator.endsWith;
483
+ case ComparisonOperator.GreaterThan:
484
+ return this.operator.greaterThan;
485
+ case ComparisonOperator.GreaterThanOrEqualTo:
486
+ return this.operator.greaterThanOrEqualTo;
487
+ case ComparisonOperator.IsEmpty:
488
+ return this.operator.isEmpty;
489
+ case ComparisonOperator.LastDay:
490
+ return this.operator.lastDay;
491
+ case ComparisonOperator.LastWeek:
492
+ return this.operator.lastWeek;
493
+ case ComparisonOperator.LastMonth:
494
+ return this.operator.lastMonth;
495
+ case ComparisonOperator.LastYear:
496
+ return this.operator.lastYear;
497
+ case ComparisonOperator.LessThan:
498
+ return this.operator.lessThan;
499
+ case ComparisonOperator.LessThanOrEqualTo:
500
+ return this.operator.lessThanOrEqualTo;
501
+ case ComparisonOperator.StartsWith:
502
+ return this.operator.startsWith;
503
+ case ComparisonOperator.TimeSpan:
504
+ return this.operator.timeSpan;
505
+ default:
506
+ return 'Unknown operator!';
507
+ }
508
+ }
509
+ getConjoinerDisplayName(conjoiner) {
510
+ switch (conjoiner) {
511
+ case LogicalOperator.And:
512
+ return this.logicalOperator.and;
513
+ case LogicalOperator.Or:
514
+ return this.logicalOperator.or;
515
+ default:
516
+ return 'Unknown logical operator!';
517
+ }
518
+ }
519
+ getTimeSpanDisplayName(timeSpan) {
520
+ switch (timeSpan) {
521
+ case TimeSpan.Minutes:
522
+ return this.timeSpan.minutes;
523
+ case TimeSpan.Hours:
524
+ return this.timeSpan.hours;
525
+ case TimeSpan.Days:
526
+ return this.timeSpan.days;
527
+ case TimeSpan.Weeks:
528
+ return this.timeSpan.weeks;
529
+ case TimeSpan.Months:
530
+ return this.timeSpan.months;
531
+ case TimeSpan.Years:
532
+ return this.timeSpan.years;
533
+ default:
534
+ return 'Unknown time span!';
535
+ }
536
+ }
537
+ getUnitDisplayName(unit) {
538
+ switch (unit) {
539
+ case Unit.Byte:
540
+ return this.unit.byte;
541
+ case Unit.KB:
542
+ return this.unit.kb;
543
+ case Unit.MB:
544
+ return this.unit.mb;
545
+ case Unit.GB:
546
+ return this.unit.gb;
547
+ case Unit.TB:
548
+ return this.unit.tb;
549
+ case Unit.HZ:
550
+ return this.unit.hz;
551
+ case Unit.KHZ:
552
+ return this.unit.khz;
553
+ case Unit.MHZ:
554
+ return this.unit.mhz;
555
+ case Unit.GHZ:
556
+ return this.unit.ghz;
557
+ case Unit.BytePS:
558
+ return this.unit.byteps;
559
+ case Unit.KBytePS:
560
+ return this.unit.kbyteps;
561
+ case Unit.MBytePS:
562
+ return this.unit.mbyteps;
563
+ case Unit.GBytePS:
564
+ return this.unit.gbyteps;
565
+ case Unit.BitPS:
566
+ return this.unit.bitps;
567
+ case Unit.KBitPS:
568
+ return this.unit.kbitps;
569
+ case Unit.MBitPS:
570
+ return this.unit.mbitps;
571
+ case Unit.GBitPS:
572
+ return this.unit.gbitps;
573
+ default:
574
+ return 'Unknown unit!';
575
+ }
576
+ }
577
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: DatagridFiltersStrings, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
578
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: DatagridFiltersStrings }); }
579
+ }
580
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: DatagridFiltersStrings, decorators: [{
581
+ type: Injectable
582
+ }] });
583
+
584
+ /*
585
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
586
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
587
+ * This software is released under MIT license.
588
+ * The full license information can be found in LICENSE in the root directory of this project.
589
+ */
590
+ /**
591
+ * Reusable form component.
592
+ *
593
+ */
594
+ class FilterFormComponent {
595
+ constructor(filterStrings) {
596
+ this.filterStrings = filterStrings;
597
+ /**
598
+ * Event emitter to tell hosting view that cancel button was clicked
599
+ */
600
+ this.cancel = new EventEmitter();
601
+ /**
602
+ * Event emitter to tell hosting view that apply button was clicked
603
+ */
604
+ this.apply = new EventEmitter();
605
+ }
606
+ onApplyButtonClick() {
607
+ this.apply.emit();
608
+ }
609
+ onCancelButtonClick() {
610
+ this.cancel.emit();
611
+ }
612
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: FilterFormComponent, deps: [{ token: DatagridFiltersStrings }], target: i0.ɵɵFactoryTarget.Component }); }
613
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.22", type: FilterFormComponent, isStandalone: false, selector: "appfx-filter-form", inputs: { valid: "valid" }, outputs: { cancel: "cancel", apply: "apply" }, ngImport: i0, template: "<!--\r\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\r\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\r\n ~ This software is released under MIT license.\r\n ~ The full license information can be found in LICENSE in the root directory of this project.\r\n -->\r\n<form hermesForm class=\"form-compact\" hermesLayout=\"vertical\">\r\n <div class=\"form-max-height\">\r\n <ng-content></ng-content>\r\n </div>\r\n <div>\r\n <button\r\n type=\"button\"\r\n data-test-id=\"submitBtn\"\r\n class=\"btn btn-sm btn-primary btn-right\"\r\n [disabled]=\"!valid\"\r\n (click)=\"onApplyButtonClick()\"\r\n >\r\n {{ filterStrings.apply }}\r\n </button>\r\n <button\r\n type=\"button\"\r\n data-test-id=\"cancelBtn\"\r\n class=\"btn btn-sm btn-outline btn-right\"\r\n (click)=\"onCancelButtonClick()\"\r\n >\r\n {{ filterStrings.cancel }}\r\n </button>\r\n </div>\r\n</form>\r\n", styles: [".form-compact{padding:0;text-align:left;font-weight:400}.form-control-compact{margin-top:.3rem}.btn-compact{min-width:1.2rem;padding:0;margin:0 .4rem}.btn-right{float:right;margin-right:0;margin-top:.9rem;margin-left:.3rem}.mt-half{margin-top:.6rem}.mt-compact{margin-top:.9rem}.mb-compact{margin-bottom:.9rem}.ml-half{margin-left:.6rem}.mt-0{margin-top:0}.mb-0{margin-bottom:0}:host-context(.zoom2x,.zoom4x) .form-max-height{max-height:8rem;overflow-y:auto}select{max-width:18rem;text-overflow:ellipsis}hermes-signpost-content{max-width:20rem}.flex-end-container{display:flex;align-items:flex-end}.flex-container{display:flex}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:var(--hermes-datagrid-loading-background);display:flex;align-items:center;justify-content:center;z-index:10}.loading-content{display:flex;flex-direction:column;align-items:center;gap:.5rem}\n"], dependencies: [{ kind: "directive", type: i3.HermesForm, selector: "[hermesForm]", inputs: ["hermesLabelSize"] }, { kind: "directive", type: i3.HermesLayout, selector: "[hermesForm][hermesLayout]", inputs: ["hermesLayout"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
614
+ }
615
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: FilterFormComponent, decorators: [{
616
+ type: Component,
617
+ args: [{ selector: 'appfx-filter-form', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!--\r\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\r\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\r\n ~ This software is released under MIT license.\r\n ~ The full license information can be found in LICENSE in the root directory of this project.\r\n -->\r\n<form hermesForm class=\"form-compact\" hermesLayout=\"vertical\">\r\n <div class=\"form-max-height\">\r\n <ng-content></ng-content>\r\n </div>\r\n <div>\r\n <button\r\n type=\"button\"\r\n data-test-id=\"submitBtn\"\r\n class=\"btn btn-sm btn-primary btn-right\"\r\n [disabled]=\"!valid\"\r\n (click)=\"onApplyButtonClick()\"\r\n >\r\n {{ filterStrings.apply }}\r\n </button>\r\n <button\r\n type=\"button\"\r\n data-test-id=\"cancelBtn\"\r\n class=\"btn btn-sm btn-outline btn-right\"\r\n (click)=\"onCancelButtonClick()\"\r\n >\r\n {{ filterStrings.cancel }}\r\n </button>\r\n </div>\r\n</form>\r\n", styles: [".form-compact{padding:0;text-align:left;font-weight:400}.form-control-compact{margin-top:.3rem}.btn-compact{min-width:1.2rem;padding:0;margin:0 .4rem}.btn-right{float:right;margin-right:0;margin-top:.9rem;margin-left:.3rem}.mt-half{margin-top:.6rem}.mt-compact{margin-top:.9rem}.mb-compact{margin-bottom:.9rem}.ml-half{margin-left:.6rem}.mt-0{margin-top:0}.mb-0{margin-bottom:0}:host-context(.zoom2x,.zoom4x) .form-max-height{max-height:8rem;overflow-y:auto}select{max-width:18rem;text-overflow:ellipsis}hermes-signpost-content{max-width:20rem}.flex-end-container{display:flex;align-items:flex-end}.flex-container{display:flex}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:var(--hermes-datagrid-loading-background);display:flex;align-items:center;justify-content:center;z-index:10}.loading-content{display:flex;flex-direction:column;align-items:center;gap:.5rem}\n"] }]
618
+ }], ctorParameters: () => [{ type: DatagridFiltersStrings }], propDecorators: { valid: [{
619
+ type: Input
620
+ }], cancel: [{
621
+ type: Output
622
+ }], apply: [{
623
+ type: Output
624
+ }] } });
625
+
626
+ const enterKey$4 = 'Enter';
627
+ const dateTimeFormat = 'yyyy-MM-ddTHH:mm:ss';
628
+ const requiredValidators = [Validators.required];
629
+ // TODO: zpopov: Existing time utils to convert to/from milliseconds may make the code even easier to read
630
+ const oneSecondMs = 1 * 1000;
631
+ const oneMinuteMs = 60 * oneSecondMs;
632
+ const oneHourMs = 60 * oneMinuteMs;
633
+ const oneDayMs = 24 * oneHourMs;
634
+ const oneWeekMs = 7 * oneDayMs;
635
+ const oneMonthMs = 30 * oneDayMs;
636
+ // We ignore leap years when it comes to time-spans.
637
+ const oneYearMs = 365 * oneDayMs;
638
+ /**
639
+ * Datetime filter component collects filtering criteria for datetime based properties
640
+ *
641
+ */
642
+ class DateTimeFilterComponent {
643
+ /**
644
+ * Property used for filtering
645
+ */
646
+ #filterProperty;
647
+ constructor(formBuilder, datePipe, filterStrings) {
648
+ this.formBuilder = formBuilder;
649
+ this.datePipe = datePipe;
650
+ this.filterStrings = filterStrings;
651
+ this.isEmptyPredicate = false;
652
+ this.isCustomRangePredicate = false;
653
+ this.isRelativePredicate = false;
654
+ this.isTimeSpanPredicate = false;
655
+ this.timePredicate = false;
656
+ this.includeSeconds = false;
657
+ /**
658
+ * Event emitter to tell hosting view that filtering criteria have changed
659
+ */
660
+ this.filterCriteriaChange = new EventEmitter();
661
+ this.relativeOperators = [
662
+ ComparisonOperator.LastDay,
663
+ ComparisonOperator.LastWeek,
664
+ ComparisonOperator.LastMonth,
665
+ ComparisonOperator.LastYear,
666
+ ];
667
+ this.singlePredicateOperators = [
668
+ ComparisonOperator.After,
669
+ ComparisonOperator.AfterOrEqualTo,
670
+ ComparisonOperator.Before,
671
+ ComparisonOperator.BeforeOrEqualTo,
672
+ ];
673
+ this.selectedFilterCriteria = new PropertyFilter();
674
+ this.primaryPredicate = new PropertyPredicate();
675
+ this.secondaryPredicate = new PropertyPredicate();
676
+ this.timeSpans = [TimeSpan.Minutes, TimeSpan.Hours, TimeSpan.Days, TimeSpan.Weeks, TimeSpan.Months, TimeSpan.Years];
677
+ }
678
+ get filterProperty() {
679
+ return this.#filterProperty;
680
+ }
681
+ set filterProperty(filterProperty) {
682
+ this.#filterProperty = filterProperty;
683
+ }
684
+ ngOnInit() {
685
+ this.comparisonOperators = this.filterProperty.getOperators();
686
+ let dateValidators = requiredValidators;
687
+ // To handle edit mode
688
+ const storedOperator = this.propertyFilter?.criteria[0]?.filterableProperty.selectedOperator;
689
+ if (storedOperator) {
690
+ this.processSelectedOperator(storedOperator);
691
+ if (this.noDateTimeInputNeeded()) {
692
+ dateValidators = [];
693
+ }
694
+ }
695
+ this.dateTimeFilterForm = this.formBuilder.group({
696
+ operator: [storedOperator || ComparisonOperator.AfterOrEqualTo],
697
+ dateValue: [this.parseDateValue(this.getStoredDateTimeValue()), dateValidators],
698
+ });
699
+ if (this.parseTimeValue(this.getStoredDateTimeValue()).length > 0) {
700
+ this.enableTimePredicate();
701
+ }
702
+ if (ComparisonOperator.CustomRange === storedOperator) {
703
+ this.isCustomRangePredicate = true;
704
+ this.enableCustomRangePredicate();
705
+ }
706
+ if (this.isTimeSpanPredicate) {
707
+ this.enableTimeSpanPredicate();
708
+ }
709
+ this.onOperatorChange();
710
+ }
711
+ ngOnChanges() {
712
+ this.comparisonOperators = this.filterProperty.getOperators();
713
+ this.includeSeconds = this.filterProperty.includeSeconds;
714
+ }
715
+ onInputKeyPress(event) {
716
+ if (event.key === enterKey$4) {
717
+ event.stopPropagation();
718
+ event.preventDefault();
719
+ if (this.dateTimeFilterForm.valid) {
720
+ this.onApplyButtonClick();
721
+ }
722
+ }
723
+ }
724
+ enableTimePredicate() {
725
+ this.timePredicate = true;
726
+ this.dateTimeFilterForm.addControl('timeValue', new FormControl(this.parseTimeValue(this.getStoredDateTimeValue()), requiredValidators));
727
+ if (this.isCustomRangePredicate) {
728
+ this.dateTimeFilterForm.addControl('timeValueTo', new FormControl(this.parseTimeValue(this.getStoredDateTimeValueTo()), requiredValidators));
729
+ }
730
+ }
731
+ disableTimePredicate() {
732
+ this.timePredicate = false;
733
+ this.dateTimeFilterForm.removeControl('timeValue');
734
+ if (this.isCustomRangePredicate) {
735
+ this.dateTimeFilterForm.removeControl('timeValueTo');
736
+ }
737
+ }
738
+ noDateTimeInputNeeded() {
739
+ return this.isEmptyPredicate || this.isTimeSpanPredicate || this.isRelativePredicate;
740
+ }
741
+ onApplyButtonClick() {
742
+ const selectedOperator = this.dateTimeFilterForm.value.operator;
743
+ if (this.isRelativeDateTimeOperator(selectedOperator)) {
744
+ this.primaryPredicate = this.getRelativeDateTimePredicate(selectedOperator);
745
+ this.secondaryPredicate = this.getcurrentTimePredicate();
746
+ }
747
+ else if (this.isTimeSpanPredicate) {
748
+ this.primaryPredicate = this.getTimeSpanPredicate(this.dateTimeFilterForm.value.timeSpanValue, this.dateTimeFilterForm.value.timeSpan);
749
+ this.secondaryPredicate = this.getcurrentTimePredicate();
750
+ }
751
+ else if (this.isCustomRangePredicate) {
752
+ this.primaryPredicate = this.getFromDateTimePredicate();
753
+ this.secondaryPredicate = this.getToDateTimePredicate();
754
+ }
755
+ else if (ComparisonOperator.Equals === selectedOperator) {
756
+ this.buildEqualsDateTimePredicates();
757
+ }
758
+ else if (this.isSinglePredicateOperator(selectedOperator)) {
759
+ this.primaryPredicate = this.getSinglePredicate(selectedOperator);
760
+ }
761
+ this.primaryPredicate.filterableProperty = this.filterProperty;
762
+ if (!this.isEmptyPredicate) {
763
+ this.primaryPredicate.value = this.adjustTimeZone(this.primaryPredicate.value);
764
+ if (!this.isSinglePredicateOperator(selectedOperator)) {
765
+ this.secondaryPredicate.filterableProperty = this.filterProperty;
766
+ this.secondaryPredicate.value = this.adjustTimeZone(this.secondaryPredicate.value);
767
+ this.selectedFilterCriteria.criteria = [this.primaryPredicate, this.secondaryPredicate];
768
+ this.selectedFilterCriteria.operator = LogicalOperator.And;
769
+ }
770
+ else {
771
+ this.selectedFilterCriteria.criteria = [this.primaryPredicate];
772
+ }
773
+ }
774
+ else {
775
+ this.primaryPredicate.operator = ComparisonOperator.IsEmpty;
776
+ this.selectedFilterCriteria.criteria = [this.primaryPredicate];
777
+ }
778
+ // Selected data is stored, in order to be able to be rendered in edit mode
779
+ this.storeSelectedValues();
780
+ this.filterCriteriaChange.emit(this.selectedFilterCriteria);
781
+ }
782
+ onCancelButtonClick() {
783
+ this.filterCriteriaChange.emit();
784
+ }
785
+ onOperatorChange() {
786
+ this.dateTimeFilterForm.get('operator')?.valueChanges.subscribe((operator) => {
787
+ this.processSelectedOperator(operator);
788
+ if (this.noDateTimeInputNeeded()) {
789
+ this.disableDateTimePredicates();
790
+ }
791
+ else {
792
+ this.isCustomRangePredicate = ComparisonOperator.CustomRange === operator;
793
+ this.enableDateTimePredicates();
794
+ if (!this.isCustomRangePredicate) {
795
+ this.disableCustomRangePredicate();
796
+ }
797
+ }
798
+ if (this.isTimeSpanPredicate) {
799
+ this.enableTimeSpanPredicate();
800
+ }
801
+ else {
802
+ this.disableTimeSpanPredicate();
803
+ }
804
+ });
805
+ }
806
+ addValidators(formControlName, validators) {
807
+ this.dateTimeFilterForm.get(formControlName)?.addValidators(validators);
808
+ this.dateTimeFilterForm.get(formControlName)?.updateValueAndValidity();
809
+ }
810
+ removeValidators(formControlName) {
811
+ this.dateTimeFilterForm.get(formControlName)?.clearValidators();
812
+ this.dateTimeFilterForm.get(formControlName)?.updateValueAndValidity();
813
+ }
814
+ isRelativeDateTimeOperator(operator) {
815
+ return this.relativeOperators.includes(operator);
816
+ }
817
+ isSinglePredicateOperator(operator) {
818
+ return this.singlePredicateOperators.includes(operator);
819
+ }
820
+ enableCustomRangePredicate() {
821
+ this.dateTimeFilterForm.addControl('dateValueTo', new FormControl(this.parseDateValue(this.getStoredDateTimeValueTo()), requiredValidators));
822
+ if (this.timePredicate) {
823
+ this.dateTimeFilterForm.addControl('timeValueTo', new FormControl(this.parseTimeValue(this.getStoredDateTimeValueTo()), requiredValidators));
824
+ }
825
+ }
826
+ disableCustomRangePredicate() {
827
+ this.isCustomRangePredicate = false;
828
+ this.dateTimeFilterForm.removeControl('dateValueTo');
829
+ if (this.timePredicate) {
830
+ this.dateTimeFilterForm.removeControl('timeValueTo');
831
+ }
832
+ }
833
+ enableDateTimePredicates() {
834
+ this.addValidators('dateValue', requiredValidators);
835
+ if (this.timePredicate) {
836
+ this.enableTimePredicate();
837
+ }
838
+ if (this.isCustomRangePredicate) {
839
+ this.enableCustomRangePredicate();
840
+ }
841
+ }
842
+ disableDateTimePredicates() {
843
+ this.removeValidators('dateValue');
844
+ if (this.timePredicate) {
845
+ this.disableTimePredicate();
846
+ }
847
+ if (this.isCustomRangePredicate) {
848
+ this.disableCustomRangePredicate();
849
+ }
850
+ }
851
+ enableTimeSpanPredicate() {
852
+ const timeSpanValue = this.propertyFilter?.criteria[0]?.filterableProperty?.selectedTimeSpanValue;
853
+ this.dateTimeFilterForm.addControl('timeSpanValue', new FormControl(timeSpanValue || '', requiredValidators));
854
+ const timeSpan = this.propertyFilter?.criteria[0]?.filterableProperty?.selectedTimeSpan;
855
+ this.dateTimeFilterForm.addControl('timeSpan', new FormControl(timeSpan || TimeSpan.Minutes));
856
+ }
857
+ disableTimeSpanPredicate() {
858
+ this.dateTimeFilterForm.removeControl('timeSpanValue');
859
+ this.dateTimeFilterForm.removeControl('timeSpan');
860
+ }
861
+ processSelectedOperator(operator) {
862
+ this.isEmptyPredicate = ComparisonOperator.IsEmpty === operator;
863
+ this.isTimeSpanPredicate = ComparisonOperator.TimeSpan === operator;
864
+ this.isRelativePredicate = this.isRelativeDateTimeOperator(operator);
865
+ }
866
+ getRelativeDateTimePredicate(operator) {
867
+ const predicate = new PropertyPredicate();
868
+ predicate.operator = ComparisonOperator.GreaterThanOrEqualTo;
869
+ switch (operator) {
870
+ case ComparisonOperator.LastDay:
871
+ predicate.value = this.getPastDate(oneDayMs);
872
+ return predicate;
873
+ case ComparisonOperator.LastWeek:
874
+ predicate.value = this.getPastDate(oneWeekMs);
875
+ return predicate;
876
+ case ComparisonOperator.LastMonth:
877
+ predicate.value = this.getPastDate(oneMonthMs);
878
+ return predicate;
879
+ case ComparisonOperator.LastYear:
880
+ predicate.value = this.getPastDate(oneYearMs);
881
+ return predicate;
882
+ default:
883
+ return predicate;
884
+ }
885
+ }
886
+ getTimeSpanPredicate(value, timeSpan) {
887
+ const predicate = new PropertyPredicate();
888
+ predicate.operator = ComparisonOperator.GreaterThanOrEqualTo;
889
+ if (value < 0) {
890
+ return predicate;
891
+ }
892
+ switch (timeSpan) {
893
+ case TimeSpan.Minutes:
894
+ predicate.value = this.getPastDate(value * oneMinuteMs);
895
+ return predicate;
896
+ case TimeSpan.Hours:
897
+ predicate.value = this.getPastDate(value * oneHourMs);
898
+ return predicate;
899
+ case TimeSpan.Days:
900
+ predicate.value = this.getPastDate(value * oneDayMs);
901
+ return predicate;
902
+ case TimeSpan.Weeks:
903
+ predicate.value = this.getPastDate(value * oneWeekMs);
904
+ return predicate;
905
+ case TimeSpan.Months:
906
+ predicate.value = this.getPastDate(value * oneMonthMs);
907
+ return predicate;
908
+ case TimeSpan.Years:
909
+ predicate.value = this.getPastDate(value * oneYearMs);
910
+ return predicate;
911
+ default:
912
+ return predicate;
913
+ }
914
+ }
915
+ buildEqualsDateTimePredicates() {
916
+ this.primaryPredicate = this.getFromDateTimePredicate();
917
+ this.secondaryPredicate.operator = ComparisonOperator.LessThan;
918
+ if (this.timePredicate) {
919
+ this.secondaryPredicate.value = this.getCustomDate(this.primaryPredicate.value, oneMinuteMs);
920
+ }
921
+ else {
922
+ this.secondaryPredicate.value = this.getCustomDate(this.primaryPredicate.value, oneDayMs);
923
+ }
924
+ }
925
+ getSinglePredicate(operator) {
926
+ let predicate = new PropertyPredicate();
927
+ switch (operator) {
928
+ case ComparisonOperator.BeforeOrEqualTo:
929
+ predicate = this.getFromDateTimePredicate(true);
930
+ predicate.operator = ComparisonOperator.LessThan;
931
+ return predicate;
932
+ case ComparisonOperator.Before:
933
+ predicate = this.getFromDateTimePredicate();
934
+ predicate.operator = ComparisonOperator.LessThan;
935
+ return predicate;
936
+ case ComparisonOperator.After:
937
+ predicate = this.getFromDateTimePredicate(true);
938
+ predicate.operator = ComparisonOperator.GreaterThanOrEqualTo;
939
+ return predicate;
940
+ case ComparisonOperator.AfterOrEqualTo:
941
+ predicate = this.getFromDateTimePredicate();
942
+ predicate.operator = ComparisonOperator.GreaterThanOrEqualTo;
943
+ return predicate;
944
+ default:
945
+ return predicate;
946
+ }
947
+ }
948
+ getFromDateTimePredicate(adjustTime = false) {
949
+ const fromPredicate = new PropertyPredicate();
950
+ fromPredicate.operator = ComparisonOperator.GreaterThanOrEqualTo;
951
+ let fromValue = this.dateTimeFilterForm.value.dateValue;
952
+ if (this.timePredicate) {
953
+ fromValue += 'T' + this.dateTimeFilterForm.value.timeValue + (this.includeSeconds ? '' : ':00');
954
+ if (adjustTime) {
955
+ fromValue = this.getCustomDate(fromValue, oneMinuteMs);
956
+ }
957
+ }
958
+ else {
959
+ fromValue += 'T00:00:00';
960
+ if (adjustTime) {
961
+ fromValue = this.getCustomDate(fromValue, oneDayMs);
962
+ }
963
+ }
964
+ fromPredicate.value = fromValue;
965
+ return fromPredicate;
966
+ }
967
+ getToDateTimePredicate() {
968
+ const toPredicate = new PropertyPredicate();
969
+ toPredicate.operator = ComparisonOperator.LessThan;
970
+ let toValue = this.dateTimeFilterForm.value.dateValueTo;
971
+ if (this.timePredicate) {
972
+ toValue += 'T' + this.dateTimeFilterForm.value.timeValueTo + (this.includeSeconds ? '' : ':00');
973
+ toValue = this.getCustomDate(toValue, oneMinuteMs);
974
+ }
975
+ else {
976
+ toValue += 'T00:00:00';
977
+ toValue = this.getCustomDate(toValue, oneDayMs);
978
+ }
979
+ toPredicate.value = toValue;
980
+ return toPredicate;
981
+ }
982
+ getcurrentTimePredicate() {
983
+ const predicate = new PropertyPredicate();
984
+ predicate.value = this.datePipe.transform(new Date(), dateTimeFormat);
985
+ predicate.operator = ComparisonOperator.LessThanOrEqualTo;
986
+ return predicate;
987
+ }
988
+ getPastDate(timePeriod) {
989
+ const now = new Date();
990
+ const prevDate = new Date(new Date().setTime(now.getTime() - timePeriod));
991
+ return this.datePipe.transform(prevDate, dateTimeFormat);
992
+ }
993
+ getCustomDate(baseDate, timePeriod) {
994
+ const date = new Date(baseDate);
995
+ const newDate = new Date(new Date().setTime(date.getTime() + timePeriod));
996
+ return this.datePipe.transform(newDate, dateTimeFormat) || baseDate;
997
+ }
998
+ adjustTimeZone(utcDate) {
999
+ if (!utcDate) {
1000
+ return utcDate;
1001
+ }
1002
+ return utcDate + this.getUtcTimeZoneOffset(utcDate);
1003
+ }
1004
+ getUtcTimeZoneOffset(utcDate) {
1005
+ // Difference in minutes between the time on the local computer and Universal Coordinated Time
1006
+ const timeZoneOffset = new Date(utcDate).getTimezoneOffset();
1007
+ const decimalOffset = Math.abs(timeZoneOffset / 60);
1008
+ const offsetHours = Math.trunc(decimalOffset);
1009
+ const offsetMinutes = Math.round((decimalOffset - offsetHours) * 60);
1010
+ // Adding a leading 0 if needed
1011
+ const offsetHoursString = offsetHours.toLocaleString(undefined, {
1012
+ minimumIntegerDigits: 2,
1013
+ });
1014
+ const offsetMinutesString = offsetMinutes.toLocaleString(undefined, {
1015
+ minimumIntegerDigits: 2,
1016
+ });
1017
+ let utcOffset = '';
1018
+ if (timeZoneOffset > 0) {
1019
+ utcOffset = '-' + offsetHoursString + ':' + offsetMinutesString;
1020
+ }
1021
+ else if (timeZoneOffset < 0) {
1022
+ utcOffset = '+' + offsetHoursString + ':' + offsetMinutesString;
1023
+ }
1024
+ return utcOffset;
1025
+ }
1026
+ storeSelectedValues() {
1027
+ this.primaryPredicate.filterableProperty.selectedOperator = this.dateTimeFilterForm.value.operator;
1028
+ this.primaryPredicate.filterableProperty.selectedValue = this.dateTimeFilterForm.value.dateValue;
1029
+ if (this.timePredicate) {
1030
+ this.primaryPredicate.filterableProperty.selectedValue += 'T' + this.dateTimeFilterForm.value.timeValue;
1031
+ }
1032
+ if (this.isCustomRangePredicate) {
1033
+ this.primaryPredicate.filterableProperty.selectedValueTo = this.dateTimeFilterForm.value.dateValueTo;
1034
+ if (this.timePredicate) {
1035
+ this.primaryPredicate.filterableProperty.selectedValueTo += 'T' + this.dateTimeFilterForm.value.timeValueTo;
1036
+ }
1037
+ }
1038
+ if (this.isTimeSpanPredicate) {
1039
+ this.primaryPredicate.filterableProperty.selectedTimeSpanValue = this.dateTimeFilterForm.value.timeSpanValue;
1040
+ this.primaryPredicate.filterableProperty.selectedTimeSpan = this.dateTimeFilterForm.value.timeSpan;
1041
+ }
1042
+ }
1043
+ getStoredDateTimeValue() {
1044
+ return this.propertyFilter?.criteria[0]?.filterableProperty?.selectedValue || '';
1045
+ }
1046
+ getStoredDateTimeValueTo() {
1047
+ return this.propertyFilter?.criteria[0]?.filterableProperty?.selectedValueTo || '';
1048
+ }
1049
+ parseDateValue(dateTime) {
1050
+ if (dateTime) {
1051
+ return dateTime.substring(0, 10);
1052
+ }
1053
+ return '';
1054
+ }
1055
+ parseTimeValue(dateTime) {
1056
+ if (!!dateTime && dateTime.indexOf('T') > 0) {
1057
+ return dateTime.substring(dateTime.indexOf('T') + 1);
1058
+ }
1059
+ return '';
1060
+ }
1061
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: DateTimeFilterComponent, deps: [{ token: i1.FormBuilder }, { token: i2.DatePipe }, { token: DatagridFiltersStrings }], target: i0.ɵɵFactoryTarget.Component }); }
1062
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: DateTimeFilterComponent, isStandalone: false, selector: "appfx-datetime-filter", inputs: { propertyFilter: "propertyFilter", filterProperty: "filterProperty" }, outputs: { filterCriteriaChange: "filterCriteriaChange" }, usesOnChanges: true, ngImport: i0, template: "<!--\r\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\r\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\r\n ~ This software is released under MIT license.\r\n ~ The full license information can be found in LICENSE in the root directory of this project.\r\n -->\r\n<appfx-filter-form\r\n [formGroup]=\"dateTimeFilterForm\"\r\n [valid]=\"dateTimeFilterForm.valid\"\r\n (cancel)=\"onCancelButtonClick()\"\r\n (apply)=\"onApplyButtonClick()\"\r\n>\r\n <hermes-native-select-container class=\"mt-compact\">\r\n <label class=\"hermes-control-label\">\r\n {{ filterStrings.operatorLabel }}\r\n </label>\r\n <select hermesNativeSelect formControlName=\"operator\">\r\n @for (operator of comparisonOperators; track operator) {\r\n <option [ngValue]=\"operator\">\r\n {{ filterStrings.getOperatorDisplayName(operator) }}\r\n </option>\r\n }\r\n </select>\r\n </hermes-native-select-container>\r\n @if (!noDateTimeInputNeeded()) {\r\n <div class=\"flex-container\">\r\n <hermes-input-container>\r\n @if (isCustomRangePredicate) {\r\n <label class=\"hermes-control-label\">\r\n {{ filterStrings.fromLabel }}\r\n </label>\r\n }\r\n <input\r\n type=\"date\"\r\n pattern=\"^[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$\"\r\n formControlName=\"dateValue\"\r\n placeholder=\"{{ filterStrings.dateFormat }}\"\r\n hermesInput\r\n (keydown)=\"onInputKeyPress($event)\"\r\n />\r\n <hermes-control-error *hermesIfError=\"'required'\" role=\"alert\">{{\r\n filterStrings.requiredValidatorMessage\r\n }}</hermes-control-error>\r\n <hermes-control-error *hermesIfError=\"'pattern'\" role=\"alert\">{{\r\n filterStrings.dateValidatorMessage\r\n }}</hermes-control-error>\r\n </hermes-input-container>\r\n </div>\r\n }\r\n @if (timePredicate) {\r\n <div class=\"flex-end-container\">\r\n <hermes-input-container>\r\n <input\r\n type=\"time\"\r\n [step]=\"includeSeconds ? 1 : 60\"\r\n pattern=\"^(0[0-9]|1[0-9]|2[0-4]):([0-5][0-9]):?([0-5][0-9])?$\"\r\n formControlName=\"timeValue\"\r\n placeholder=\"{{ filterStrings.timeFormat }}\"\r\n hermesInput\r\n (keydown)=\"onInputKeyPress($event)\"\r\n />\r\n <hermes-control-error *hermesIfError=\"'required'\" role=\"alert\">{{\r\n filterStrings.requiredValidatorMessage\r\n }}</hermes-control-error>\r\n <hermes-control-error *hermesIfError=\"'pattern'\" role=\"alert\">{{\r\n filterStrings.timeValidatorMessage\r\n }}</hermes-control-error>\r\n </hermes-input-container>\r\n <button\r\n class=\"close ml-half\"\r\n data-test-id=\"close-button\"\r\n [attr.aria-label]=\"filterStrings.removeTimeFilterAriaLabel\"\r\n (click)=\"disableTimePredicate()\"\r\n >\r\n <hermes-icon size=\"20\" shape=\"window-close\"></hermes-icon>\r\n </button>\r\n </div>\r\n }\r\n @if (isCustomRangePredicate) {\r\n <div class=\"flex-container\">\r\n <hermes-input-container>\r\n <label class=\"hermes-control-label\">\r\n {{ filterStrings.toLabel }}\r\n </label>\r\n <input\r\n type=\"date\"\r\n pattern=\"^[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$\"\r\n formControlName=\"dateValueTo\"\r\n placeholder=\"{{ filterStrings.dateFormat }}\"\r\n hermesInput\r\n (keydown)=\"onInputKeyPress($event)\"\r\n />\r\n <hermes-control-error *hermesIfError=\"'required'\" role=\"alert\">{{\r\n filterStrings.requiredValidatorMessage\r\n }}</hermes-control-error>\r\n <hermes-control-error *hermesIfError=\"'pattern'\" role=\"alert\">{{\r\n filterStrings.dateValidatorMessage\r\n }}</hermes-control-error>\r\n </hermes-input-container>\r\n </div>\r\n }\r\n @if (timePredicate && isCustomRangePredicate) {\r\n <div class=\"flex-end-container\">\r\n <hermes-input-container>\r\n <input\r\n type=\"time\"\r\n [step]=\"includeSeconds ? 1 : 60\"\r\n pattern=\"^(0[0-9]|1[0-9]|2[0-4]):([0-5][0-9]):?([0-5][0-9])?$\"\r\n formControlName=\"timeValueTo\"\r\n placeholder=\"{{ filterStrings.timeFormat }}\"\r\n hermesInput\r\n (keydown)=\"onInputKeyPress($event)\"\r\n />\r\n <hermes-control-error *hermesIfError=\"'required'\" role=\"alert\">{{\r\n filterStrings.requiredValidatorMessage\r\n }}</hermes-control-error>\r\n <hermes-control-error *hermesIfError=\"'pattern'\" role=\"alert\">{{\r\n filterStrings.timeValidatorMessage\r\n }}</hermes-control-error>\r\n </hermes-input-container>\r\n <button\r\n class=\"close ml-half\"\r\n data-test-id=\"close-button\"\r\n [attr.aria-label]=\"filterStrings.removeTimeFilterAriaLabel\"\r\n (click)=\"disableTimePredicate()\"\r\n >\r\n <hermes-icon size=\"20\" shape=\"window-close\"></hermes-icon>\r\n </button>\r\n </div>\r\n }\r\n @if (!timePredicate && !noDateTimeInputNeeded()) {\r\n <button\r\n class=\"btn btn-sm btn-link mt-half\"\r\n data-test-id=\"add-button\"\r\n [attr.aria-label]=\"filterStrings.addTimeFilter\"\r\n (click)=\"enableTimePredicate()\"\r\n >\r\n <hermes-icon shape=\"plus\" class=\"is-solid\"></hermes-icon>\r\n {{ filterStrings.addTimeFilter }}\r\n </button>\r\n }\r\n @if (isTimeSpanPredicate) {\r\n <div class=\"flex-end-container\">\r\n <hermes-input-container>\r\n <label class=\"hermes-control-label\">\r\n {{ filterStrings.timeSpanInputLabel }}\r\n </label>\r\n <input\r\n type=\"text\"\r\n pattern=\"^[0-9]+$\"\r\n formControlName=\"timeSpanValue\"\r\n placeholder=\"{{ filterStrings.enterValue }}\"\r\n hermesInput\r\n (keydown)=\"onInputKeyPress($event)\"\r\n />\r\n <hermes-control-error *hermesIfError=\"'required'\" role=\"alert\">{{\r\n filterStrings.requiredValidatorMessage\r\n }}</hermes-control-error>\r\n <hermes-control-error *hermesIfError=\"'pattern'\" role=\"alert\">{{\r\n filterStrings.integerValidatorMessage\r\n }}</hermes-control-error>\r\n </hermes-input-container>\r\n <hermes-native-select-container class=\"ml-half\">\r\n <select hermesNativeSelect formControlName=\"timeSpan\" [attr.aria-label]=\"filterStrings.timeSpanAriaLabel\">\r\n @for (timeSpan of timeSpans; track timeSpan) {\r\n <option [ngValue]=\"timeSpan\">\r\n {{ filterStrings.getTimeSpanDisplayName(timeSpan) }}\r\n </option>\r\n }\r\n </select>\r\n </hermes-native-select-container>\r\n </div>\r\n }\r\n</appfx-filter-form>\r\n", styles: ["hermes-input-container{margin-top:.9rem}\n", ".form-compact{padding:0;text-align:left;font-weight:400}.form-control-compact{margin-top:.3rem}.btn-compact{min-width:1.2rem;padding:0;margin:0 .4rem}.btn-right{float:right;margin-right:0;margin-top:.9rem;margin-left:.3rem}.mt-half{margin-top:.6rem}.mt-compact{margin-top:.9rem}.mb-compact{margin-bottom:.9rem}.ml-half{margin-left:.6rem}.mt-0{margin-top:0}.mb-0{margin-bottom:0}:host-context(.zoom2x,.zoom4x) .form-max-height{max-height:8rem;overflow-y:auto}select{max-width:18rem;text-overflow:ellipsis}hermes-signpost-content{max-width:20rem}.flex-end-container{display:flex;align-items:flex-end}.flex-container{display:flex}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:var(--hermes-datagrid-loading-background);display:flex;align-items:center;justify-content:center;z-index:10}.loading-content{display:flex;flex-direction:column;align-items:center;gap:.5rem}\n"], dependencies: [{ kind: "directive", type: i3.HermesControlLabel, selector: "label", inputs: ["id", "for"] }, { kind: "component", type: i3.HermesControlError, selector: "hermes-control-error" }, { kind: "directive", type: i3.HermesIfError, selector: "[hermesIfError]", inputs: ["hermesIfError"] }, { kind: "component", type: i4.HermesIcon, selector: "hermes-icon, hermes-icon", inputs: ["shape", "size", "direction", "flip", "solid", "status", "inverse", "badge"] }, { kind: "directive", type: i5.HermesInput, selector: "[hermesInput]" }, { kind: "component", type: i5.HermesInputContainer, selector: "hermes-input-container" }, { kind: "directive", type: i5.HermesNativeSelect, selector: "[hermesNativeSelect]" }, { kind: "component", type: i5.HermesNativeSelectContainer, selector: "hermes-native-select-container" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: FilterFormComponent, selector: "appfx-filter-form", inputs: ["valid"], outputs: ["cancel", "apply"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1063
+ }
1064
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: DateTimeFilterComponent, decorators: [{
1065
+ type: Component,
1066
+ args: [{ selector: 'appfx-datetime-filter', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!--\r\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\r\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\r\n ~ This software is released under MIT license.\r\n ~ The full license information can be found in LICENSE in the root directory of this project.\r\n -->\r\n<appfx-filter-form\r\n [formGroup]=\"dateTimeFilterForm\"\r\n [valid]=\"dateTimeFilterForm.valid\"\r\n (cancel)=\"onCancelButtonClick()\"\r\n (apply)=\"onApplyButtonClick()\"\r\n>\r\n <hermes-native-select-container class=\"mt-compact\">\r\n <label class=\"hermes-control-label\">\r\n {{ filterStrings.operatorLabel }}\r\n </label>\r\n <select hermesNativeSelect formControlName=\"operator\">\r\n @for (operator of comparisonOperators; track operator) {\r\n <option [ngValue]=\"operator\">\r\n {{ filterStrings.getOperatorDisplayName(operator) }}\r\n </option>\r\n }\r\n </select>\r\n </hermes-native-select-container>\r\n @if (!noDateTimeInputNeeded()) {\r\n <div class=\"flex-container\">\r\n <hermes-input-container>\r\n @if (isCustomRangePredicate) {\r\n <label class=\"hermes-control-label\">\r\n {{ filterStrings.fromLabel }}\r\n </label>\r\n }\r\n <input\r\n type=\"date\"\r\n pattern=\"^[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$\"\r\n formControlName=\"dateValue\"\r\n placeholder=\"{{ filterStrings.dateFormat }}\"\r\n hermesInput\r\n (keydown)=\"onInputKeyPress($event)\"\r\n />\r\n <hermes-control-error *hermesIfError=\"'required'\" role=\"alert\">{{\r\n filterStrings.requiredValidatorMessage\r\n }}</hermes-control-error>\r\n <hermes-control-error *hermesIfError=\"'pattern'\" role=\"alert\">{{\r\n filterStrings.dateValidatorMessage\r\n }}</hermes-control-error>\r\n </hermes-input-container>\r\n </div>\r\n }\r\n @if (timePredicate) {\r\n <div class=\"flex-end-container\">\r\n <hermes-input-container>\r\n <input\r\n type=\"time\"\r\n [step]=\"includeSeconds ? 1 : 60\"\r\n pattern=\"^(0[0-9]|1[0-9]|2[0-4]):([0-5][0-9]):?([0-5][0-9])?$\"\r\n formControlName=\"timeValue\"\r\n placeholder=\"{{ filterStrings.timeFormat }}\"\r\n hermesInput\r\n (keydown)=\"onInputKeyPress($event)\"\r\n />\r\n <hermes-control-error *hermesIfError=\"'required'\" role=\"alert\">{{\r\n filterStrings.requiredValidatorMessage\r\n }}</hermes-control-error>\r\n <hermes-control-error *hermesIfError=\"'pattern'\" role=\"alert\">{{\r\n filterStrings.timeValidatorMessage\r\n }}</hermes-control-error>\r\n </hermes-input-container>\r\n <button\r\n class=\"close ml-half\"\r\n data-test-id=\"close-button\"\r\n [attr.aria-label]=\"filterStrings.removeTimeFilterAriaLabel\"\r\n (click)=\"disableTimePredicate()\"\r\n >\r\n <hermes-icon size=\"20\" shape=\"window-close\"></hermes-icon>\r\n </button>\r\n </div>\r\n }\r\n @if (isCustomRangePredicate) {\r\n <div class=\"flex-container\">\r\n <hermes-input-container>\r\n <label class=\"hermes-control-label\">\r\n {{ filterStrings.toLabel }}\r\n </label>\r\n <input\r\n type=\"date\"\r\n pattern=\"^[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$\"\r\n formControlName=\"dateValueTo\"\r\n placeholder=\"{{ filterStrings.dateFormat }}\"\r\n hermesInput\r\n (keydown)=\"onInputKeyPress($event)\"\r\n />\r\n <hermes-control-error *hermesIfError=\"'required'\" role=\"alert\">{{\r\n filterStrings.requiredValidatorMessage\r\n }}</hermes-control-error>\r\n <hermes-control-error *hermesIfError=\"'pattern'\" role=\"alert\">{{\r\n filterStrings.dateValidatorMessage\r\n }}</hermes-control-error>\r\n </hermes-input-container>\r\n </div>\r\n }\r\n @if (timePredicate && isCustomRangePredicate) {\r\n <div class=\"flex-end-container\">\r\n <hermes-input-container>\r\n <input\r\n type=\"time\"\r\n [step]=\"includeSeconds ? 1 : 60\"\r\n pattern=\"^(0[0-9]|1[0-9]|2[0-4]):([0-5][0-9]):?([0-5][0-9])?$\"\r\n formControlName=\"timeValueTo\"\r\n placeholder=\"{{ filterStrings.timeFormat }}\"\r\n hermesInput\r\n (keydown)=\"onInputKeyPress($event)\"\r\n />\r\n <hermes-control-error *hermesIfError=\"'required'\" role=\"alert\">{{\r\n filterStrings.requiredValidatorMessage\r\n }}</hermes-control-error>\r\n <hermes-control-error *hermesIfError=\"'pattern'\" role=\"alert\">{{\r\n filterStrings.timeValidatorMessage\r\n }}</hermes-control-error>\r\n </hermes-input-container>\r\n <button\r\n class=\"close ml-half\"\r\n data-test-id=\"close-button\"\r\n [attr.aria-label]=\"filterStrings.removeTimeFilterAriaLabel\"\r\n (click)=\"disableTimePredicate()\"\r\n >\r\n <hermes-icon size=\"20\" shape=\"window-close\"></hermes-icon>\r\n </button>\r\n </div>\r\n }\r\n @if (!timePredicate && !noDateTimeInputNeeded()) {\r\n <button\r\n class=\"btn btn-sm btn-link mt-half\"\r\n data-test-id=\"add-button\"\r\n [attr.aria-label]=\"filterStrings.addTimeFilter\"\r\n (click)=\"enableTimePredicate()\"\r\n >\r\n <hermes-icon shape=\"plus\" class=\"is-solid\"></hermes-icon>\r\n {{ filterStrings.addTimeFilter }}\r\n </button>\r\n }\r\n @if (isTimeSpanPredicate) {\r\n <div class=\"flex-end-container\">\r\n <hermes-input-container>\r\n <label class=\"hermes-control-label\">\r\n {{ filterStrings.timeSpanInputLabel }}\r\n </label>\r\n <input\r\n type=\"text\"\r\n pattern=\"^[0-9]+$\"\r\n formControlName=\"timeSpanValue\"\r\n placeholder=\"{{ filterStrings.enterValue }}\"\r\n hermesInput\r\n (keydown)=\"onInputKeyPress($event)\"\r\n />\r\n <hermes-control-error *hermesIfError=\"'required'\" role=\"alert\">{{\r\n filterStrings.requiredValidatorMessage\r\n }}</hermes-control-error>\r\n <hermes-control-error *hermesIfError=\"'pattern'\" role=\"alert\">{{\r\n filterStrings.integerValidatorMessage\r\n }}</hermes-control-error>\r\n </hermes-input-container>\r\n <hermes-native-select-container class=\"ml-half\">\r\n <select hermesNativeSelect formControlName=\"timeSpan\" [attr.aria-label]=\"filterStrings.timeSpanAriaLabel\">\r\n @for (timeSpan of timeSpans; track timeSpan) {\r\n <option [ngValue]=\"timeSpan\">\r\n {{ filterStrings.getTimeSpanDisplayName(timeSpan) }}\r\n </option>\r\n }\r\n </select>\r\n </hermes-native-select-container>\r\n </div>\r\n }\r\n</appfx-filter-form>\r\n", styles: ["hermes-input-container{margin-top:.9rem}\n", ".form-compact{padding:0;text-align:left;font-weight:400}.form-control-compact{margin-top:.3rem}.btn-compact{min-width:1.2rem;padding:0;margin:0 .4rem}.btn-right{float:right;margin-right:0;margin-top:.9rem;margin-left:.3rem}.mt-half{margin-top:.6rem}.mt-compact{margin-top:.9rem}.mb-compact{margin-bottom:.9rem}.ml-half{margin-left:.6rem}.mt-0{margin-top:0}.mb-0{margin-bottom:0}:host-context(.zoom2x,.zoom4x) .form-max-height{max-height:8rem;overflow-y:auto}select{max-width:18rem;text-overflow:ellipsis}hermes-signpost-content{max-width:20rem}.flex-end-container{display:flex;align-items:flex-end}.flex-container{display:flex}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:var(--hermes-datagrid-loading-background);display:flex;align-items:center;justify-content:center;z-index:10}.loading-content{display:flex;flex-direction:column;align-items:center;gap:.5rem}\n"] }]
1067
+ }], ctorParameters: () => [{ type: i1.FormBuilder }, { type: i2.DatePipe }, { type: DatagridFiltersStrings }], propDecorators: { propertyFilter: [{
1068
+ type: Input
1069
+ }], filterCriteriaChange: [{
1070
+ type: Output
1071
+ }], filterProperty: [{
1072
+ type: Input
1073
+ }] } });
1074
+
1075
+ /*
1076
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
1077
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
1078
+ * This software is released under MIT license.
1079
+ * The full license information can be found in LICENSE in the root directory of this project.
1080
+ */
1081
+ /**
1082
+ * Enum filter component collects filtering criteria for enum based properties
1083
+ *
1084
+ */
1085
+ class EnumFilterComponent {
1086
+ #maxInitiallyShownItems;
1087
+ #loadingTimeoutDelayMs;
1088
+ #maxShownItems;
1089
+ #selectedFilterCriteria;
1090
+ constructor(formBuilder, filterStrings, cdr) {
1091
+ this.formBuilder = formBuilder;
1092
+ this.filterStrings = filterStrings;
1093
+ this.cdr = cdr;
1094
+ /**
1095
+ * Event emitter to tell hosting view that filtering criteria have changed
1096
+ */
1097
+ this.filterCriteriaChange = new EventEmitter();
1098
+ this.optionsData = [];
1099
+ this.filteredOptions = [];
1100
+ this.enumOperators = [ComparisonOperator.DoesNotEqual, ComparisonOperator.Equals];
1101
+ this.isProcessing = false;
1102
+ this.searchResultsLen = 0;
1103
+ this.selectedCount = 0;
1104
+ this.#maxInitiallyShownItems = 50;
1105
+ this.#loadingTimeoutDelayMs = 50;
1106
+ this.#maxShownItems = this.#maxInitiallyShownItems;
1107
+ this.#selectedFilterCriteria = new PropertyFilter();
1108
+ }
1109
+ get additionalOperators() {
1110
+ return this.filterProperty.supportedOperators?.length === 2;
1111
+ }
1112
+ get optionsFormArray() {
1113
+ return this.enumFilterForm?.controls.options;
1114
+ }
1115
+ trackByFilteredOption(_index, item) {
1116
+ return item.index;
1117
+ }
1118
+ trackByOperator(_index, operator) {
1119
+ return operator;
1120
+ }
1121
+ ngOnInit() {
1122
+ this.enumFilterForm = this.formBuilder.group({
1123
+ enumOperator: [this.additionalOperators ? ComparisonOperator.DoesNotEqual : ComparisonOperator.Equals],
1124
+ searchTerm: [''],
1125
+ selectAll: false,
1126
+ options: new FormArray([], this.selectedOptionsValidator()),
1127
+ singleSelectOption: [],
1128
+ });
1129
+ this.enumFilterForm.get('enumOperator')?.valueChanges.subscribe((op) => {
1130
+ this.#selectedFilterCriteria.operator =
1131
+ op === ComparisonOperator.Equals ? LogicalOperator.Or : LogicalOperator.And;
1132
+ });
1133
+ this.enumFilterForm
1134
+ .get('searchTerm')
1135
+ ?.valueChanges.pipe(debounceTime(200), distinctUntilChanged())
1136
+ .subscribe((term) => {
1137
+ this.runAsyncOperation(() => this.performSearch(term));
1138
+ });
1139
+ this.runAsyncOperation(() => this.initializeFilter());
1140
+ }
1141
+ ngOnChanges() {
1142
+ if (this.enumFilterForm) {
1143
+ this.runAsyncOperation(() => {
1144
+ this.initializeFilter();
1145
+ this.enumFilterForm.get('searchTerm')?.setValue('', { emitEvent: false });
1146
+ this.performSearch('');
1147
+ });
1148
+ }
1149
+ }
1150
+ loadMore() {
1151
+ this.runAsyncOperation(() => {
1152
+ this.#maxShownItems += 100;
1153
+ this.performSearch(this.enumFilterForm.get('searchTerm')?.value);
1154
+ });
1155
+ }
1156
+ onSelectAllChange() {
1157
+ this.runAsyncOperation(() => {
1158
+ const selectAllValue = this.enumFilterForm.get('selectAll')?.value;
1159
+ const visibleIndices = new Set(this.filteredOptions.map(opt => opt.index));
1160
+ const searching = this.searchResultsLen === this.optionsData.length;
1161
+ this.optionsFormArray.controls.forEach((control, index) => {
1162
+ if ((searching || visibleIndices.has(index)) && control.value !== selectAllValue) {
1163
+ control.setValue(selectAllValue, { emitEvent: false });
1164
+ }
1165
+ });
1166
+ this.updateSelectedCount();
1167
+ this.enumFilterForm.controls.options.updateValueAndValidity();
1168
+ });
1169
+ }
1170
+ onOptionChange() {
1171
+ this.updateSelectedCount();
1172
+ const allSelected = this.selectedCount === this.optionsFormArray.length;
1173
+ const selectAllControl = this.enumFilterForm.get('selectAll');
1174
+ if (selectAllControl?.value !== allSelected) {
1175
+ selectAllControl?.setValue(allSelected, { emitEvent: false });
1176
+ }
1177
+ this.enumFilterForm.controls.options.updateValueAndValidity();
1178
+ }
1179
+ clearSearch() {
1180
+ this.enumFilterForm.get('searchTerm')?.setValue('');
1181
+ }
1182
+ onApplyButtonClick() {
1183
+ const propertyPredicates = [];
1184
+ if (this.filterProperty.singleSelect) {
1185
+ propertyPredicates.push(this.createEnumPropertyPredicate(this.enumFilterForm.value.singleSelectOption));
1186
+ }
1187
+ else {
1188
+ const selectedOptionsKeys = this.enumFilterForm.value.options
1189
+ .map((checked, i) => (checked ? this.optionsData[i].key : null))
1190
+ .filter((v) => v !== null);
1191
+ selectedOptionsKeys.forEach(value => {
1192
+ propertyPredicates.push(this.createEnumPropertyPredicate(value));
1193
+ });
1194
+ }
1195
+ this.#selectedFilterCriteria.criteria = propertyPredicates;
1196
+ this.filterCriteriaChange.emit(this.#selectedFilterCriteria);
1197
+ }
1198
+ onCancelButtonClick() {
1199
+ this.filterCriteriaChange.emit();
1200
+ }
1201
+ runAsyncOperation(action) {
1202
+ const isHeavyLoad = this.optionsData.length > this.#maxInitiallyShownItems;
1203
+ if (isHeavyLoad) {
1204
+ this.isProcessing = true;
1205
+ this.cdr.markForCheck();
1206
+ setTimeout(() => {
1207
+ action();
1208
+ this.isProcessing = false;
1209
+ this.cdr.markForCheck();
1210
+ }, this.#loadingTimeoutDelayMs);
1211
+ }
1212
+ else {
1213
+ action();
1214
+ }
1215
+ }
1216
+ initializeFilter() {
1217
+ this.updateData();
1218
+ this.updateForm();
1219
+ this.performSearch('');
1220
+ let initialOp = ComparisonOperator.Equals;
1221
+ if (this.additionalOperators) {
1222
+ initialOp =
1223
+ this.propertyFilter?.operator === LogicalOperator.Or
1224
+ ? ComparisonOperator.Equals
1225
+ : ComparisonOperator.DoesNotEqual;
1226
+ }
1227
+ this.enumFilterForm.controls.enumOperator.setValue(initialOp, { emitEvent: false });
1228
+ this.updateSelectedCount();
1229
+ }
1230
+ performSearch(term = '') {
1231
+ const normalizedTerm = term.toLowerCase();
1232
+ const allMatches = this.optionsData
1233
+ .map((data, index) => ({ data, index }))
1234
+ .filter(item => !normalizedTerm ||
1235
+ item.data.value.toLowerCase().includes(normalizedTerm) ||
1236
+ item.data.key.toLowerCase().includes(normalizedTerm));
1237
+ this.searchResultsLen = allMatches.length;
1238
+ this.filteredOptions = allMatches.slice(0, this.#maxShownItems);
1239
+ this.cdr.markForCheck();
1240
+ }
1241
+ updateSelectedCount() {
1242
+ this.selectedCount = this.optionsFormArray.controls.reduce((acc, control) => acc + (control.value ? 1 : 0), 0);
1243
+ }
1244
+ selectedOptionsValidator() {
1245
+ const validator = () => this.filterProperty.singleSelect || this.selectedCount > 0 ? null : { required: true };
1246
+ return validator;
1247
+ }
1248
+ updateData() {
1249
+ this.optionsData = [];
1250
+ let enumValues;
1251
+ if (this.propertyFilter && this.propertyFilter.criteria.length) {
1252
+ enumValues = this.propertyFilter.criteria[0].filterableProperty.values;
1253
+ }
1254
+ else {
1255
+ enumValues = this.filterProperty.values;
1256
+ }
1257
+ enumValues.forEach((v, k) => {
1258
+ this.optionsData.push({ key: k, value: v });
1259
+ });
1260
+ if (this.additionalOperators) {
1261
+ this.enumFilterForm?.controls.enumOperator.setValue(this.propertyFilter?.operator === LogicalOperator.Or
1262
+ ? ComparisonOperator.Equals
1263
+ : ComparisonOperator.DoesNotEqual);
1264
+ }
1265
+ else {
1266
+ this.enumFilterForm?.controls.enumOperator.setValue(ComparisonOperator.Equals);
1267
+ }
1268
+ }
1269
+ updateForm() {
1270
+ if (this.enumFilterForm) {
1271
+ this.optionsFormArray.clear();
1272
+ this.selectAll(false);
1273
+ const selectedOptions = [];
1274
+ if (this.propertyFilter) {
1275
+ this.propertyFilter.criteria.forEach(predicate => {
1276
+ selectedOptions.push(predicate.value);
1277
+ });
1278
+ }
1279
+ this.optionsData.forEach(option => this.optionsFormArray.push(new FormControl(selectedOptions.includes(option.key))));
1280
+ if (selectedOptions.length === this.optionsData.length) {
1281
+ this.selectAll(true);
1282
+ }
1283
+ if (this.filterProperty.singleSelect) {
1284
+ const singleSelectForm = this.enumFilterForm.get('singleSelectOption');
1285
+ if (this.propertyFilter) {
1286
+ singleSelectForm?.setValue(this.propertyFilter.criteria[0].value);
1287
+ }
1288
+ else {
1289
+ singleSelectForm?.setValue(this.filterProperty.values.keys().next().value);
1290
+ }
1291
+ }
1292
+ }
1293
+ }
1294
+ selectAll(value) {
1295
+ this.enumFilterForm.patchValue({
1296
+ selectAll: value,
1297
+ });
1298
+ }
1299
+ createEnumPropertyPredicate(value) {
1300
+ const predicate = new PropertyPredicate();
1301
+ predicate.filterableProperty = this.filterProperty;
1302
+ predicate.operator = this.enumFilterForm.controls.enumOperator.value;
1303
+ predicate.value = value;
1304
+ return predicate;
1305
+ }
1306
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: EnumFilterComponent, deps: [{ token: i1.FormBuilder }, { token: DatagridFiltersStrings }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1307
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.22", type: EnumFilterComponent, isStandalone: false, selector: "appfx-enum-filter", inputs: { filterProperty: "filterProperty", propertyFilter: "propertyFilter" }, outputs: { filterCriteriaChange: "filterCriteriaChange" }, usesOnChanges: true, ngImport: i0, template: "<!--\r\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\r\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\r\n ~ This software is released under MIT license.\r\n ~ The full license information can be found in LICENSE in the root directory of this project.\r\n -->\r\n<appfx-filter-form\r\n [formGroup]=\"enumFilterForm\"\r\n [valid]=\"enumFilterForm.valid\"\r\n (cancel)=\"onCancelButtonClick()\"\r\n (apply)=\"onApplyButtonClick()\"\r\n>\r\n <div class=\"enum-filter-wrapper\">\r\n <hermes-native-select-container *ngIf=\"additionalOperators\" class=\"mt-compact\">\r\n <label class=\"hermes-control-label\">\r\n {{ filterStrings.operatorLabel }}\r\n </label>\r\n <select hermesNativeSelect formControlName=\"enumOperator\">\r\n <option *ngFor=\"let operator of enumOperators; trackBy: trackByOperator\" [ngValue]=\"operator\">\r\n {{ filterStrings.getOperatorDisplayName(operator) }}\r\n </option>\r\n </select>\r\n </hermes-native-select-container>\r\n\r\n <label class=\"hermes-control-label text-left mt-compact\">\r\n {{ filterStrings.valueLabel }}\r\n </label>\r\n\r\n <hermes-input-container *ngIf=\"filterProperty.searchable\" hermes-layout=\"m-t:xs\">\r\n <label class=\"hermes-sr-only\">{{ filterStrings.searchOptions }}</label>\r\n <input hermesInput type=\"text\" [placeholder]=\"filterStrings.searchPlaceholder\" formControlName=\"searchTerm\" />\r\n <hermes-icon shape=\"search\" hermesInputPrefix></hermes-icon>\r\n <hermes-icon\r\n *ngIf=\"enumFilterForm.get('searchTerm')?.value\"\r\n shape=\"window-close\"\r\n hermesInputSuffix\r\n (click)=\"clearSearch()\"\r\n ></hermes-icon>\r\n <hermes-control-helper *ngIf=\"filteredOptions.length\">\r\n {{\r\n filterStrings.formatString(filterStrings.showingFormat, [\r\n filteredOptions.length.toString(),\r\n searchResultsLen.toString(),\r\n ])\r\n }}\r\n </hermes-control-helper>\r\n <hermes-control-helper *ngIf=\"filteredOptions.length === 0 && enumFilterForm.get('searchTerm')?.value\">\r\n {{ filterStrings.noValuesFound }}\r\n </hermes-control-helper>\r\n </hermes-input-container>\r\n\r\n <div *ngIf=\"filteredOptions.length\" hermes-layout=\"m-t:xs m-l:xxs\" class=\"selection-counter\">\r\n <span *ngIf=\"!filterProperty.singleSelect\" class=\"hermes-subtext\" hermes-text=\"body medium\">\r\n {{ filterStrings.formatString(filterStrings.elementsSelectedFormat, [selectedCount.toString()]) }}\r\n </span>\r\n </div>\r\n\r\n <div *ngIf=\"isProcessing\" class=\"loading-overlay\">\r\n <div class=\"loading-content\">\r\n <hermes-spinner hermesMedium>{{ filterStrings.loading }}</hermes-spinner>\r\n </div>\r\n </div>\r\n\r\n <div hermes-layout=\"m-t:xs\">\r\n <hermes-checkbox-container *ngIf=\"!filterProperty.singleSelect\" class=\"enum-options\">\r\n <hermes-checkbox-wrapper *ngIf=\"filterProperty.enableSelectAll\" hermes-layout=\"m-b:xs\">\r\n <input type=\"checkbox\" hermesCheckbox formControlName=\"selectAll\" (change)=\"onSelectAllChange()\" />\r\n <label>\r\n {{ enumFilterForm.get('searchTerm')?.value ? filterStrings.allSearchResults : filterStrings.selectAll }}\r\n </label>\r\n </hermes-checkbox-wrapper>\r\n\r\n <hermes-checkbox-wrapper *ngFor=\"let item of filteredOptions; trackBy: trackByFilteredOption\">\r\n <input\r\n type=\"checkbox\"\r\n hermesCheckbox\r\n [formControl]=\"$any(optionsFormArray.at(item.index))\"\r\n (change)=\"onOptionChange()\"\r\n />\r\n <label>\r\n {{ item.data.value }}\r\n </label>\r\n </hermes-checkbox-wrapper>\r\n </hermes-checkbox-container>\r\n\r\n <hermes-radio-container *ngIf=\"filterProperty.singleSelect\" class=\"enum-options\">\r\n <hermes-radio-wrapper *ngFor=\"let option of filteredOptions; trackBy: trackByFilteredOption\">\r\n <input type=\"radio\" hermesRadio formControlName=\"singleSelectOption\" [value]=\"option.data.key\" />\r\n <label>\r\n {{ option.data.value }}\r\n </label>\r\n </hermes-radio-wrapper>\r\n </hermes-radio-container>\r\n </div>\r\n\r\n <button *ngIf=\"filteredOptions.length < searchResultsLen\" class=\"btn btn-link\" (click)=\"loadMore()\">\r\n {{ filterStrings.loadMore }}\r\n </button>\r\n </div>\r\n</appfx-filter-form>\r\n", styles: [".enum-options{margin-top:.1rem;text-align:left}:host-context(.no-zoom) .enum-options{overflow-y:auto}.enum-filter-wrapper{max-height:18rem;overflow:auto}:host ::ng-deep .hermes-control-container{margin-left:.2rem}hermes-checkbox-container:not(.hermes-default-style){margin-top:0!important;margin-bottom:0!important;min-height:auto!important}.selection-counter .hermes-subtext{color:var(--hermes-info-color, #0072a3)}\n", ".form-compact{padding:0;text-align:left;font-weight:400}.form-control-compact{margin-top:.3rem}.btn-compact{min-width:1.2rem;padding:0;margin:0 .4rem}.btn-right{float:right;margin-right:0;margin-top:.9rem;margin-left:.3rem}.mt-half{margin-top:.6rem}.mt-compact{margin-top:.9rem}.mb-compact{margin-bottom:.9rem}.ml-half{margin-left:.6rem}.mt-0{margin-top:0}.mb-0{margin-bottom:0}:host-context(.zoom2x,.zoom4x) .form-max-height{max-height:8rem;overflow-y:auto}select{max-width:18rem;text-overflow:ellipsis}hermes-signpost-content{max-width:20rem}.flex-end-container{display:flex;align-items:flex-end}.flex-container{display:flex}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:var(--hermes-datagrid-loading-background);display:flex;align-items:center;justify-content:center;z-index:10}.loading-content{display:flex;flex-direction:column;align-items:center;gap:.5rem}\n"], dependencies: [{ kind: "directive", type: i3.HermesControlLabel, selector: "label", inputs: ["id", "for"] }, { kind: "component", type: i3.HermesControlHelper, selector: "hermes-control-helper" }, { kind: "component", type: i4.HermesIcon, selector: "hermes-icon, hermes-icon", inputs: ["shape", "size", "direction", "flip", "solid", "status", "inverse", "badge"] }, { kind: "directive", type: i5.HermesCheckbox, selector: "[hermesCheckbox],[hermesToggle]" }, { kind: "component", type: i5.HermesCheckboxContainer, selector: "hermes-checkbox-container,hermes-toggle-container", inputs: ["hermesInline"] }, { kind: "component", type: i5.HermesCheckboxWrapper, selector: "hermes-checkbox-wrapper,hermes-toggle-wrapper" }, { kind: "directive", type: i5.HermesInput, selector: "[hermesInput]" }, { kind: "component", type: i5.HermesInputContainer, selector: "hermes-input-container" }, { kind: "directive", type: i5.HermesRadio, selector: "[hermesRadio]" }, { kind: "component", type: i5.HermesRadioContainer, selector: "hermes-radio-container", inputs: ["hermesInline"] }, { kind: "component", type: i5.HermesRadioWrapper, selector: "hermes-radio-wrapper" }, { kind: "directive", type: i5.HermesNativeSelect, selector: "[hermesNativeSelect]" }, { kind: "component", type: i5.HermesNativeSelectContainer, selector: "hermes-native-select-container" }, { kind: "component", type: i6.HermesSpinner, selector: "hermes-spinner", inputs: ["hermesInline", "hermesInverse", "hermesSmall", "hermesMedium"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: FilterFormComponent, selector: "appfx-filter-form", inputs: ["valid"], outputs: ["cancel", "apply"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1308
+ }
1309
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: EnumFilterComponent, decorators: [{
1310
+ type: Component,
1311
+ args: [{ selector: 'appfx-enum-filter', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!--\r\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\r\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\r\n ~ This software is released under MIT license.\r\n ~ The full license information can be found in LICENSE in the root directory of this project.\r\n -->\r\n<appfx-filter-form\r\n [formGroup]=\"enumFilterForm\"\r\n [valid]=\"enumFilterForm.valid\"\r\n (cancel)=\"onCancelButtonClick()\"\r\n (apply)=\"onApplyButtonClick()\"\r\n>\r\n <div class=\"enum-filter-wrapper\">\r\n <hermes-native-select-container *ngIf=\"additionalOperators\" class=\"mt-compact\">\r\n <label class=\"hermes-control-label\">\r\n {{ filterStrings.operatorLabel }}\r\n </label>\r\n <select hermesNativeSelect formControlName=\"enumOperator\">\r\n <option *ngFor=\"let operator of enumOperators; trackBy: trackByOperator\" [ngValue]=\"operator\">\r\n {{ filterStrings.getOperatorDisplayName(operator) }}\r\n </option>\r\n </select>\r\n </hermes-native-select-container>\r\n\r\n <label class=\"hermes-control-label text-left mt-compact\">\r\n {{ filterStrings.valueLabel }}\r\n </label>\r\n\r\n <hermes-input-container *ngIf=\"filterProperty.searchable\" hermes-layout=\"m-t:xs\">\r\n <label class=\"hermes-sr-only\">{{ filterStrings.searchOptions }}</label>\r\n <input hermesInput type=\"text\" [placeholder]=\"filterStrings.searchPlaceholder\" formControlName=\"searchTerm\" />\r\n <hermes-icon shape=\"search\" hermesInputPrefix></hermes-icon>\r\n <hermes-icon\r\n *ngIf=\"enumFilterForm.get('searchTerm')?.value\"\r\n shape=\"window-close\"\r\n hermesInputSuffix\r\n (click)=\"clearSearch()\"\r\n ></hermes-icon>\r\n <hermes-control-helper *ngIf=\"filteredOptions.length\">\r\n {{\r\n filterStrings.formatString(filterStrings.showingFormat, [\r\n filteredOptions.length.toString(),\r\n searchResultsLen.toString(),\r\n ])\r\n }}\r\n </hermes-control-helper>\r\n <hermes-control-helper *ngIf=\"filteredOptions.length === 0 && enumFilterForm.get('searchTerm')?.value\">\r\n {{ filterStrings.noValuesFound }}\r\n </hermes-control-helper>\r\n </hermes-input-container>\r\n\r\n <div *ngIf=\"filteredOptions.length\" hermes-layout=\"m-t:xs m-l:xxs\" class=\"selection-counter\">\r\n <span *ngIf=\"!filterProperty.singleSelect\" class=\"hermes-subtext\" hermes-text=\"body medium\">\r\n {{ filterStrings.formatString(filterStrings.elementsSelectedFormat, [selectedCount.toString()]) }}\r\n </span>\r\n </div>\r\n\r\n <div *ngIf=\"isProcessing\" class=\"loading-overlay\">\r\n <div class=\"loading-content\">\r\n <hermes-spinner hermesMedium>{{ filterStrings.loading }}</hermes-spinner>\r\n </div>\r\n </div>\r\n\r\n <div hermes-layout=\"m-t:xs\">\r\n <hermes-checkbox-container *ngIf=\"!filterProperty.singleSelect\" class=\"enum-options\">\r\n <hermes-checkbox-wrapper *ngIf=\"filterProperty.enableSelectAll\" hermes-layout=\"m-b:xs\">\r\n <input type=\"checkbox\" hermesCheckbox formControlName=\"selectAll\" (change)=\"onSelectAllChange()\" />\r\n <label>\r\n {{ enumFilterForm.get('searchTerm')?.value ? filterStrings.allSearchResults : filterStrings.selectAll }}\r\n </label>\r\n </hermes-checkbox-wrapper>\r\n\r\n <hermes-checkbox-wrapper *ngFor=\"let item of filteredOptions; trackBy: trackByFilteredOption\">\r\n <input\r\n type=\"checkbox\"\r\n hermesCheckbox\r\n [formControl]=\"$any(optionsFormArray.at(item.index))\"\r\n (change)=\"onOptionChange()\"\r\n />\r\n <label>\r\n {{ item.data.value }}\r\n </label>\r\n </hermes-checkbox-wrapper>\r\n </hermes-checkbox-container>\r\n\r\n <hermes-radio-container *ngIf=\"filterProperty.singleSelect\" class=\"enum-options\">\r\n <hermes-radio-wrapper *ngFor=\"let option of filteredOptions; trackBy: trackByFilteredOption\">\r\n <input type=\"radio\" hermesRadio formControlName=\"singleSelectOption\" [value]=\"option.data.key\" />\r\n <label>\r\n {{ option.data.value }}\r\n </label>\r\n </hermes-radio-wrapper>\r\n </hermes-radio-container>\r\n </div>\r\n\r\n <button *ngIf=\"filteredOptions.length < searchResultsLen\" class=\"btn btn-link\" (click)=\"loadMore()\">\r\n {{ filterStrings.loadMore }}\r\n </button>\r\n </div>\r\n</appfx-filter-form>\r\n", styles: [".enum-options{margin-top:.1rem;text-align:left}:host-context(.no-zoom) .enum-options{overflow-y:auto}.enum-filter-wrapper{max-height:18rem;overflow:auto}:host ::ng-deep .hermes-control-container{margin-left:.2rem}hermes-checkbox-container:not(.hermes-default-style){margin-top:0!important;margin-bottom:0!important;min-height:auto!important}.selection-counter .hermes-subtext{color:var(--hermes-info-color, #0072a3)}\n", ".form-compact{padding:0;text-align:left;font-weight:400}.form-control-compact{margin-top:.3rem}.btn-compact{min-width:1.2rem;padding:0;margin:0 .4rem}.btn-right{float:right;margin-right:0;margin-top:.9rem;margin-left:.3rem}.mt-half{margin-top:.6rem}.mt-compact{margin-top:.9rem}.mb-compact{margin-bottom:.9rem}.ml-half{margin-left:.6rem}.mt-0{margin-top:0}.mb-0{margin-bottom:0}:host-context(.zoom2x,.zoom4x) .form-max-height{max-height:8rem;overflow-y:auto}select{max-width:18rem;text-overflow:ellipsis}hermes-signpost-content{max-width:20rem}.flex-end-container{display:flex;align-items:flex-end}.flex-container{display:flex}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:var(--hermes-datagrid-loading-background);display:flex;align-items:center;justify-content:center;z-index:10}.loading-content{display:flex;flex-direction:column;align-items:center;gap:.5rem}\n"] }]
1312
+ }], ctorParameters: () => [{ type: i1.FormBuilder }, { type: DatagridFiltersStrings }, { type: i0.ChangeDetectorRef }], propDecorators: { filterProperty: [{
1313
+ type: Input
1314
+ }], propertyFilter: [{
1315
+ type: Input
1316
+ }], filterCriteriaChange: [{
1317
+ type: Output
1318
+ }] } });
1319
+
1320
+ /*
1321
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
1322
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
1323
+ * This software is released under MIT license.
1324
+ * The full license information can be found in LICENSE in the root directory of this project.
1325
+ */
1326
+ /**
1327
+ * A directive that fixes the position of the clarity popover/signpost, which is opened
1328
+ * when adding/editing filters. The popover is positioned bottom middle relative to
1329
+ * the corresponding trigger button. The width of the popover is based on the longest
1330
+ * property name. This means that some parts of the popover may not be visible, because
1331
+ * they will get out of the borders of the parent datagrid component.
1332
+ * To prevent this, the directive modifies the `translateX` property for the `transform` style,
1333
+ * in order to ensure that the popover is positioned within the boundaries of the datagrid.
1334
+ */
1335
+ class FilterPopoverRepositionDirective {
1336
+ constructor(elementRef) {
1337
+ this.elementRef = elementRef;
1338
+ // Minimal `translateX` property of transform style of the popover that
1339
+ // ensures the popover is aligned on the left boundaries of the datagrid.
1340
+ this.menuMinTranslateX = 1;
1341
+ // Selector of the datagrid filter container. It has the same width as the datagrid.
1342
+ this.filterContainerSelector = '.filter-container';
1343
+ }
1344
+ ngAfterViewInit() {
1345
+ const computedStyle = getComputedStyle(this.elementRef.nativeElement);
1346
+ const matrix = new DOMMatrix(computedStyle.transform);
1347
+ const originalTranslateX = matrix.m41;
1348
+ const translateY = matrix.m42;
1349
+ const parentElement = this.elementRef.nativeElement.closest(this.filterContainerSelector);
1350
+ if (!parentElement) {
1351
+ return;
1352
+ }
1353
+ const popoverOriginalEndX = originalTranslateX + this.elementRef.nativeElement.offsetWidth;
1354
+ // If the popover is within the datagrid boundaries, do nothing.
1355
+ if (originalTranslateX > this.menuMinTranslateX && popoverOriginalEndX < parentElement.offsetWidth) {
1356
+ return;
1357
+ }
1358
+ const newTranslateX = Math.max(this.menuMinTranslateX, Math.min(originalTranslateX, originalTranslateX - (popoverOriginalEndX - parentElement.offsetWidth)));
1359
+ // Override default `translateX` property
1360
+ this.elementRef.nativeElement.style.transform = `translateX(${newTranslateX}px) translateY(${translateY}px)`;
1361
+ }
1362
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: FilterPopoverRepositionDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
1363
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: FilterPopoverRepositionDirective, isStandalone: false, selector: "[filterPopoverReposition]", ngImport: i0 }); }
1364
+ }
1365
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: FilterPopoverRepositionDirective, decorators: [{
1366
+ type: Directive,
1367
+ args: [{
1368
+ selector: '[filterPopoverReposition]',
1369
+ standalone: false,
1370
+ }]
1371
+ }], ctorParameters: () => [{ type: i0.ElementRef }] });
1372
+
1373
+ /*
1374
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
1375
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
1376
+ * This software is released under MIT license.
1377
+ * The full license information can be found in LICENSE in the root directory of this project.
1378
+ */
1379
+ const enterKey$3 = 'Enter';
1380
+ const unmericPatternRegex = '^-?[0-9]+$';
1381
+ /**
1382
+ * General filter component collects filtering criteria for string and numeric based properties
1383
+ *
1384
+ */
1385
+ class GeneralFilterComponent {
1386
+ /**
1387
+ * Property used for filtering
1388
+ */
1389
+ #filterProperty;
1390
+ constructor(formBuilder, filterStrings) {
1391
+ this.formBuilder = formBuilder;
1392
+ this.filterStrings = filterStrings;
1393
+ this.isEmptyOperator = ComparisonOperator.IsEmpty;
1394
+ this.units = [];
1395
+ this.isNumericUnitProperty = false;
1396
+ this.additionalPredicate = false;
1397
+ this.isEmptyPrimaryPredicate = false;
1398
+ this.isEmptySecondaryPredicate = false;
1399
+ /**
1400
+ * Event emitter to tell hosting view that filtering criteria have changed
1401
+ */
1402
+ this.filterCriteriaChange = new EventEmitter();
1403
+ this.LogicalOperator = LogicalOperator;
1404
+ this.selectedFilterCriteria = new PropertyFilter();
1405
+ this.primaryPredicate = new PropertyPredicate();
1406
+ this.secondaryPredicate = new PropertyPredicate();
1407
+ this.logicalOperators = [LogicalOperator.And, LogicalOperator.Or];
1408
+ }
1409
+ get filterProperty() {
1410
+ return this.#filterProperty;
1411
+ }
1412
+ set filterProperty(filterProperty) {
1413
+ this.#filterProperty = filterProperty;
1414
+ this.primaryPredicate.filterableProperty = filterProperty;
1415
+ this.secondaryPredicate.filterableProperty = filterProperty;
1416
+ }
1417
+ ngOnInit() {
1418
+ this.isNumericUnitProperty = this.isNumericUnitFilterProperty();
1419
+ this.comparisonOperators = this.filterProperty.getOperators();
1420
+ this.units = this.applicableUnits();
1421
+ // To handle edit mode with operator IsEmpty
1422
+ let validators = [];
1423
+ if (this.propertyFilter?.criteria[0]?.operator === this.isEmptyOperator) {
1424
+ this.isEmptyPrimaryPredicate = true;
1425
+ }
1426
+ else {
1427
+ validators = this.initValidators();
1428
+ }
1429
+ this.generalFilterForm = this.formBuilder.group({
1430
+ primaryOperator: [this.initOperator(0)],
1431
+ primaryValue: [this.initValue(0), validators],
1432
+ primaryUnit: [this.initUnit(0)],
1433
+ logicalOperator: [this.propertyFilter?.operator || LogicalOperator.And],
1434
+ });
1435
+ this.generalFilterForm.get('primaryOperator')?.valueChanges.subscribe((operator) => {
1436
+ if (operator === this.isEmptyOperator) {
1437
+ this.removeValidators('primaryValue');
1438
+ this.isEmptyPrimaryPredicate = true;
1439
+ this.selectLogicalOperator(LogicalOperator.Or);
1440
+ }
1441
+ else {
1442
+ this.addValidators('primaryValue', validators);
1443
+ this.isEmptyPrimaryPredicate = false;
1444
+ }
1445
+ });
1446
+ if (this.propertyFilter?.criteria?.length === 2) {
1447
+ this.enableSecondaryPredicate();
1448
+ }
1449
+ }
1450
+ ngOnChanges() {
1451
+ this.isNumericUnitProperty = this.isNumericUnitFilterProperty();
1452
+ this.comparisonOperators = this.filterProperty.getOperators();
1453
+ // Update property units
1454
+ if (this.isNumericUnitProperty && this.generalFilterForm) {
1455
+ this.units = this.applicableUnits();
1456
+ this.generalFilterForm.patchValue({
1457
+ primaryUnit: this.initUnit(0),
1458
+ });
1459
+ if (this.additionalPredicate) {
1460
+ this.generalFilterForm.patchValue({
1461
+ secondaryUnit: this.initUnit(1),
1462
+ });
1463
+ }
1464
+ }
1465
+ }
1466
+ onInputKeyPress(event) {
1467
+ if (event.key === enterKey$3) {
1468
+ event.stopPropagation();
1469
+ event.preventDefault();
1470
+ if (this.generalFilterForm.valid) {
1471
+ this.onApplyButtonClick();
1472
+ }
1473
+ }
1474
+ }
1475
+ enableSecondaryPredicate() {
1476
+ this.additionalPredicate = true;
1477
+ // To handle edit mode with operator IsEmpty
1478
+ let validators = [];
1479
+ if (this.propertyFilter?.criteria[1]?.operator === this.isEmptyOperator) {
1480
+ this.isEmptySecondaryPredicate = true;
1481
+ }
1482
+ else {
1483
+ validators = this.initValidators();
1484
+ }
1485
+ this.generalFilterForm.addControl('secondaryOperator', new FormControl(this.initOperator(1)));
1486
+ this.generalFilterForm.addControl('secondaryValue', new FormControl(this.initValue(1), validators));
1487
+ this.generalFilterForm.addControl('secondaryUnit', new FormControl(this.initUnit(1)));
1488
+ this.generalFilterForm.get('secondaryOperator')?.valueChanges.subscribe((operator) => {
1489
+ if (operator === this.isEmptyOperator) {
1490
+ this.removeValidators('secondaryValue');
1491
+ this.isEmptySecondaryPredicate = true;
1492
+ this.selectLogicalOperator(LogicalOperator.Or);
1493
+ }
1494
+ else {
1495
+ this.addValidators('secondaryValue', validators);
1496
+ this.isEmptySecondaryPredicate = false;
1497
+ }
1498
+ });
1499
+ }
1500
+ disableSecondaryPredicate() {
1501
+ this.additionalPredicate = false;
1502
+ this.generalFilterForm.removeControl('secondaryOperator');
1503
+ this.generalFilterForm.removeControl('secondaryValue');
1504
+ }
1505
+ onApplyButtonClick() {
1506
+ this.primaryPredicate.operator = this.generalFilterForm.value.primaryOperator;
1507
+ this.primaryPredicate.value = this.generalFilterForm.value.primaryValue;
1508
+ if (this.isNumericUnitProperty) {
1509
+ // Selected value and unit are stored, in order to be able to be rendered in edit mode.
1510
+ // They are stored in an array, because there are up to two conditions for a single property.
1511
+ this.primaryPredicate.filterableProperty.selectedValue = [this.generalFilterForm.value.primaryValue];
1512
+ this.primaryPredicate.filterableProperty.selectedUnit = [this.generalFilterForm.value.primaryUnit];
1513
+ this.primaryPredicate.value = this.convertValue(this.generalFilterForm.value.primaryValue, this.generalFilterForm.value.primaryUnit);
1514
+ }
1515
+ this.selectedFilterCriteria.criteria = [this.primaryPredicate];
1516
+ this.selectedFilterCriteria.operator =
1517
+ this.filterProperty.logicalOperator ?? this.generalFilterForm.value.logicalOperator;
1518
+ if (this.additionalPredicate) {
1519
+ this.secondaryPredicate.operator = this.generalFilterForm.value.secondaryOperator;
1520
+ this.secondaryPredicate.value = this.generalFilterForm.value.secondaryValue;
1521
+ if (this.isNumericUnitProperty) {
1522
+ this.secondaryPredicate.filterableProperty.selectedValue.push(this.generalFilterForm.value.secondaryValue);
1523
+ this.secondaryPredicate.filterableProperty.selectedUnit.push(this.generalFilterForm.value.secondaryUnit);
1524
+ this.secondaryPredicate.value = this.convertValue(this.generalFilterForm.value.secondaryValue, this.generalFilterForm.value.secondaryUnit);
1525
+ }
1526
+ this.selectedFilterCriteria.criteria.push(this.secondaryPredicate);
1527
+ }
1528
+ this.filterCriteriaChange.emit(this.selectedFilterCriteria);
1529
+ }
1530
+ onCancelButtonClick() {
1531
+ this.filterCriteriaChange.emit();
1532
+ }
1533
+ addValidators(formControlName, validators) {
1534
+ this.generalFilterForm.get(formControlName)?.addValidators(validators);
1535
+ this.generalFilterForm.get(formControlName)?.updateValueAndValidity();
1536
+ }
1537
+ removeValidators(formControlName) {
1538
+ this.generalFilterForm.get(formControlName)?.clearValidators();
1539
+ this.generalFilterForm.get(formControlName)?.updateValueAndValidity();
1540
+ }
1541
+ selectLogicalOperator(operator) {
1542
+ this.generalFilterForm.patchValue({
1543
+ logicalOperator: operator,
1544
+ });
1545
+ }
1546
+ initOperator(index) {
1547
+ const selectedOperator = this.propertyFilter?.criteria[index]?.operator;
1548
+ const defaultOperator = this.filterProperty instanceof StringPropertyDefinition ? ComparisonOperator.Contains : ComparisonOperator.Equals;
1549
+ return selectedOperator || defaultOperator;
1550
+ }
1551
+ initValidators() {
1552
+ const validators = [Validators.required];
1553
+ if (this.filterProperty instanceof NumericPropertyDefinition) {
1554
+ validators.push(Validators.pattern(unmericPatternRegex));
1555
+ }
1556
+ return validators;
1557
+ }
1558
+ isNumericUnitFilterProperty() {
1559
+ return this.filterProperty instanceof NumericPropertyDefinition && this.filterProperty.unit !== undefined;
1560
+ }
1561
+ applicableUnits() {
1562
+ if (this.isNumericUnitProperty) {
1563
+ const propertyUnit = this.filterProperty.unit;
1564
+ switch (propertyUnit) {
1565
+ case Unit.Byte:
1566
+ return [Unit.Byte, Unit.KB, Unit.MB, Unit.GB, Unit.TB];
1567
+ case Unit.KB:
1568
+ return [Unit.KB, Unit.MB, Unit.GB, Unit.TB];
1569
+ case Unit.MB:
1570
+ return [Unit.MB, Unit.GB, Unit.TB];
1571
+ case Unit.GB:
1572
+ return [Unit.GB, Unit.TB];
1573
+ case Unit.TB:
1574
+ return [Unit.TB];
1575
+ case Unit.BytePS:
1576
+ return [Unit.BytePS, Unit.KBytePS, Unit.MBytePS, Unit.GBytePS];
1577
+ case Unit.KBytePS:
1578
+ return [Unit.KBytePS, Unit.MBytePS, Unit.GBytePS];
1579
+ case Unit.MBytePS:
1580
+ return [Unit.MBytePS, Unit.GBytePS];
1581
+ case Unit.GBytePS:
1582
+ return [Unit.GBytePS];
1583
+ case Unit.BitPS:
1584
+ return [Unit.BitPS, Unit.KBitPS, Unit.MBitPS, Unit.GBitPS];
1585
+ case Unit.KBitPS:
1586
+ return [Unit.KBitPS, Unit.MBitPS, Unit.GBitPS];
1587
+ case Unit.MBitPS:
1588
+ return [Unit.MBitPS, Unit.GBitPS];
1589
+ case Unit.GBitPS:
1590
+ return [Unit.GBitPS];
1591
+ case Unit.HZ:
1592
+ return [Unit.HZ, Unit.KHZ, Unit.MHZ, Unit.GHZ];
1593
+ case Unit.KHZ:
1594
+ return [Unit.KHZ, Unit.MHZ, Unit.GHZ];
1595
+ case Unit.MHZ:
1596
+ return [Unit.MHZ, Unit.GHZ];
1597
+ case Unit.GHZ:
1598
+ return [Unit.GHZ];
1599
+ default:
1600
+ return [];
1601
+ }
1602
+ }
1603
+ return [];
1604
+ }
1605
+ initUnit(index) {
1606
+ if (this.isNumericUnitProperty) {
1607
+ if (this.propertyFilter?.criteria[index]) {
1608
+ return this.getSelectedUnit(index);
1609
+ }
1610
+ else {
1611
+ return this.units.length > 0 ? this.units[0] : Unit.MB;
1612
+ }
1613
+ }
1614
+ return Unit.MB;
1615
+ }
1616
+ getSelectedUnit(index) {
1617
+ const selectedUnit = this.propertyFilter.criteria[index].filterableProperty.selectedUnit[index];
1618
+ return selectedUnit;
1619
+ }
1620
+ initValue(index) {
1621
+ if (this.isNumericUnitProperty) {
1622
+ return this.propertyFilter?.criteria[index]?.filterableProperty.selectedValue[index] || '';
1623
+ }
1624
+ else {
1625
+ return this.propertyFilter?.criteria[index]?.value || '';
1626
+ }
1627
+ }
1628
+ convertValue(value, sourceUnit) {
1629
+ if (this.isNumericUnitProperty) {
1630
+ const targetUnit = this.filterProperty.unit;
1631
+ if (targetUnit === sourceUnit) {
1632
+ return value;
1633
+ }
1634
+ switch (targetUnit) {
1635
+ case Unit.Byte:
1636
+ switch (sourceUnit) {
1637
+ case Unit.KB:
1638
+ return value * 1024;
1639
+ case Unit.MB:
1640
+ return value * 1024 * 1024;
1641
+ case Unit.GB:
1642
+ return value * 1024 * 1024 * 1024;
1643
+ case Unit.TB:
1644
+ return value * 1024 * 1024 * 1024 * 1024;
1645
+ default:
1646
+ return value;
1647
+ }
1648
+ case Unit.KB:
1649
+ switch (sourceUnit) {
1650
+ case Unit.MB:
1651
+ return value * 1024;
1652
+ case Unit.GB:
1653
+ return value * 1024 * 1024;
1654
+ case Unit.TB:
1655
+ return value * 1024 * 1024 * 1024;
1656
+ default:
1657
+ return value;
1658
+ }
1659
+ case Unit.MB:
1660
+ switch (sourceUnit) {
1661
+ case Unit.GB:
1662
+ return value * 1024;
1663
+ case Unit.TB:
1664
+ return value * 1024 * 1024;
1665
+ default:
1666
+ return value;
1667
+ }
1668
+ case Unit.GB:
1669
+ switch (sourceUnit) {
1670
+ case Unit.TB:
1671
+ return value * 1024;
1672
+ default:
1673
+ return value;
1674
+ }
1675
+ case Unit.HZ:
1676
+ switch (sourceUnit) {
1677
+ case Unit.KHZ:
1678
+ return value * 1000;
1679
+ case Unit.MHZ:
1680
+ return value * 1000 * 1000;
1681
+ case Unit.GHZ:
1682
+ return value * 1000 * 1000 * 1000;
1683
+ default:
1684
+ return value;
1685
+ }
1686
+ case Unit.KHZ:
1687
+ switch (sourceUnit) {
1688
+ case Unit.MHZ:
1689
+ return value * 1000;
1690
+ case Unit.GHZ:
1691
+ return value * 1000 * 1000;
1692
+ default:
1693
+ return value;
1694
+ }
1695
+ case Unit.MHZ:
1696
+ switch (sourceUnit) {
1697
+ case Unit.GHZ:
1698
+ return value * 1000;
1699
+ default:
1700
+ return value;
1701
+ }
1702
+ case Unit.BytePS:
1703
+ switch (sourceUnit) {
1704
+ case Unit.KBytePS:
1705
+ return value * 1000;
1706
+ case Unit.MBytePS:
1707
+ return value * 1000 * 1000;
1708
+ case Unit.GBytePS:
1709
+ return value * 1000 * 1000 * 1000;
1710
+ default:
1711
+ return value;
1712
+ }
1713
+ case Unit.KBytePS:
1714
+ switch (sourceUnit) {
1715
+ case Unit.MBytePS:
1716
+ return value * 1000;
1717
+ case Unit.GBytePS:
1718
+ return value * 1000 * 1000;
1719
+ default:
1720
+ return value;
1721
+ }
1722
+ case Unit.MBytePS:
1723
+ switch (sourceUnit) {
1724
+ case Unit.GBytePS:
1725
+ return value * 1000;
1726
+ default:
1727
+ return value;
1728
+ }
1729
+ case Unit.BitPS:
1730
+ switch (sourceUnit) {
1731
+ case Unit.KBitPS:
1732
+ return value * 1000;
1733
+ case Unit.MBitPS:
1734
+ return value * 1000 * 1000;
1735
+ case Unit.GBitPS:
1736
+ return value * 1000 * 1000 * 1000;
1737
+ default:
1738
+ return value;
1739
+ }
1740
+ case Unit.KBitPS:
1741
+ switch (sourceUnit) {
1742
+ case Unit.MBitPS:
1743
+ return value * 1000;
1744
+ case Unit.GBitPS:
1745
+ return value * 1000 * 1000;
1746
+ default:
1747
+ return value;
1748
+ }
1749
+ case Unit.MBitPS:
1750
+ switch (sourceUnit) {
1751
+ case Unit.GBitPS:
1752
+ return value * 1000;
1753
+ default:
1754
+ return value;
1755
+ }
1756
+ default:
1757
+ return value;
1758
+ }
1759
+ }
1760
+ return value;
1761
+ }
1762
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: GeneralFilterComponent, deps: [{ token: i1.FormBuilder }, { token: DatagridFiltersStrings }], target: i0.ɵɵFactoryTarget.Component }); }
1763
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: GeneralFilterComponent, isStandalone: false, selector: "appfx-general-filter", inputs: { propertyFilter: "propertyFilter", filterProperty: "filterProperty" }, outputs: { filterCriteriaChange: "filterCriteriaChange" }, usesOnChanges: true, ngImport: i0, template: "<!--\r\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\r\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\r\n ~ This software is released under MIT license.\r\n ~ The full license information can be found in LICENSE in the root directory of this project.\r\n -->\r\n<appfx-filter-form\r\n [formGroup]=\"generalFilterForm\"\r\n [valid]=\"generalFilterForm.valid\"\r\n (cancel)=\"onCancelButtonClick()\"\r\n (apply)=\"onApplyButtonClick()\"\r\n>\r\n <hermes-native-select-container class=\"mt-compact\">\r\n <label class=\"hermes-control-label\">\r\n {{ filterStrings.operatorLabel }}\r\n </label>\r\n <select hermesNativeSelect formControlName=\"primaryOperator\">\r\n @for (operator of comparisonOperators; track operator) {\r\n <option [ngValue]=\"operator\">\r\n {{ filterStrings.getOperatorDisplayName(operator) }}\r\n </option>\r\n }\r\n </select>\r\n </hermes-native-select-container>\r\n @if (!isEmptyPrimaryPredicate) {\r\n <div class=\"flex-container\">\r\n <hermes-input-container>\r\n <input\r\n type=\"text\"\r\n formControlName=\"primaryValue\"\r\n placeholder=\"{{ filterStrings.enterValue }}\"\r\n hermesInput\r\n (keydown)=\"onInputKeyPress($event)\"\r\n />\r\n <hermes-control-error *hermesIfError=\"'required'\" role=\"alert\">{{\r\n filterStrings.requiredValidatorMessage\r\n }}</hermes-control-error>\r\n <hermes-control-error *hermesIfError=\"'pattern'\" role=\"alert\">{{\r\n filterStrings.integerValidatorMessage\r\n }}</hermes-control-error>\r\n </hermes-input-container>\r\n @if (isNumericUnitProperty) {\r\n <hermes-native-select-container class=\"ml-half\">\r\n <select hermesNativeSelect formControlName=\"primaryUnit\" [attr.aria-label]=\"filterStrings.unitAriaLabel\">\r\n @for (unit of units; track unit) {\r\n <option [ngValue]=\"unit\">\r\n {{ filterStrings.getUnitDisplayName(unit) }}\r\n </option>\r\n }\r\n </select>\r\n </hermes-native-select-container>\r\n }\r\n </div>\r\n }\r\n @if (!additionalPredicate && !filterProperty.singleCondition) {\r\n <button\r\n class=\"btn btn-sm btn-link mt-half\"\r\n data-test-id=\"add-button\"\r\n [attr.aria-label]=\"filterStrings.addCondition\"\r\n (click)=\"enableSecondaryPredicate()\"\r\n >\r\n <hermes-icon shape=\"plus\" class=\"is-solid\"></hermes-icon>\r\n {{ filterStrings.addCondition }}\r\n </button>\r\n }\r\n @if (additionalPredicate) {\r\n <div>\r\n @if (filterProperty.logicalOperator == undefined) {\r\n <hermes-radio-container hermesInline class=\"mt-compact\">\r\n <hermes-radio-wrapper>\r\n <input\r\n type=\"radio\"\r\n hermesRadio\r\n formControlName=\"logicalOperator\"\r\n [value]=\"logicalOperators[0]\"\r\n [attr.disabled]=\"isEmptyPrimaryPredicate || isEmptySecondaryPredicate ? 'disabled' : null\"\r\n />\r\n <label> {{ filterStrings.getConjoinerDisplayName(logicalOperators[0]) }} </label>\r\n </hermes-radio-wrapper>\r\n <hermes-radio-wrapper>\r\n <input type=\"radio\" hermesRadio formControlName=\"logicalOperator\" [value]=\"logicalOperators[1]\" />\r\n <label> {{ filterStrings.getConjoinerDisplayName(logicalOperators[1]) }} </label>\r\n </hermes-radio-wrapper>\r\n </hermes-radio-container>\r\n }\r\n @if (filterProperty.logicalOperator != undefined) {\r\n <div class=\"hermes-control-container\" hermes-layout=\"m-t:sm\">\r\n <span data-test-id=\"logical-operator\" hermes-text=\"body medium\">{{\r\n filterStrings.getConjoinerDisplayName(filterProperty.logicalOperator)\r\n }}</span>\r\n </div>\r\n }\r\n <div class=\"flex-end-container\">\r\n <hermes-native-select-container class=\"form-control-compact\">\r\n <label class=\"hermes-control-label\">\r\n {{ filterStrings.operatorLabel }}\r\n </label>\r\n <select hermesNativeSelect formControlName=\"secondaryOperator\">\r\n @for (operator of comparisonOperators; track operator) {\r\n <option [ngValue]=\"operator\">\r\n {{ filterStrings.getOperatorDisplayName(operator) }}\r\n </option>\r\n }\r\n </select>\r\n </hermes-native-select-container>\r\n <button\r\n class=\"close ml-half\"\r\n data-test-id=\"close-button\"\r\n [attr.aria-label]=\"filterStrings.removeConditionAriaLabel\"\r\n (click)=\"disableSecondaryPredicate()\"\r\n >\r\n <hermes-icon size=\"20\" shape=\"window-close\"></hermes-icon>\r\n </button>\r\n </div>\r\n @if (!isEmptySecondaryPredicate) {\r\n <div class=\"flex-container\">\r\n <hermes-input-container>\r\n <input\r\n type=\"text\"\r\n formControlName=\"secondaryValue\"\r\n placeholder=\"{{ filterStrings.enterValue }}\"\r\n hermesInput\r\n (keydown)=\"onInputKeyPress($event)\"\r\n />\r\n <hermes-control-error *hermesIfError=\"'required'\" role=\"alert\">{{\r\n filterStrings.requiredValidatorMessage\r\n }}</hermes-control-error>\r\n <hermes-control-error *hermesIfError=\"'pattern'\" role=\"alert\">{{\r\n filterStrings.integerValidatorMessage\r\n }}</hermes-control-error>\r\n </hermes-input-container>\r\n @if (isNumericUnitProperty) {\r\n <hermes-native-select-container class=\"ml-half\">\r\n <select hermesNativeSelect formControlName=\"secondaryUnit\">\r\n @for (unit of units; track unit) {\r\n <option [ngValue]=\"unit\">\r\n {{ filterStrings.getUnitDisplayName(unit) }}\r\n </option>\r\n }\r\n </select>\r\n </hermes-native-select-container>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n</appfx-filter-form>\r\n", styles: [".form-compact{padding:0;text-align:left;font-weight:400}.form-control-compact{margin-top:.3rem}.btn-compact{min-width:1.2rem;padding:0;margin:0 .4rem}.btn-right{float:right;margin-right:0;margin-top:.9rem;margin-left:.3rem}.mt-half{margin-top:.6rem}.mt-compact{margin-top:.9rem}.mb-compact{margin-bottom:.9rem}.ml-half{margin-left:.6rem}.mt-0{margin-top:0}.mb-0{margin-bottom:0}:host-context(.zoom2x,.zoom4x) .form-max-height{max-height:8rem;overflow-y:auto}select{max-width:18rem;text-overflow:ellipsis}hermes-signpost-content{max-width:20rem}.flex-end-container{display:flex;align-items:flex-end}.flex-container{display:flex}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:var(--hermes-datagrid-loading-background);display:flex;align-items:center;justify-content:center;z-index:10}.loading-content{display:flex;flex-direction:column;align-items:center;gap:.5rem}\n"], dependencies: [{ kind: "directive", type: i3.HermesControlLabel, selector: "label", inputs: ["id", "for"] }, { kind: "component", type: i3.HermesControlError, selector: "hermes-control-error" }, { kind: "directive", type: i3.HermesIfError, selector: "[hermesIfError]", inputs: ["hermesIfError"] }, { kind: "component", type: i4.HermesIcon, selector: "hermes-icon, hermes-icon", inputs: ["shape", "size", "direction", "flip", "solid", "status", "inverse", "badge"] }, { kind: "directive", type: i5.HermesInput, selector: "[hermesInput]" }, { kind: "component", type: i5.HermesInputContainer, selector: "hermes-input-container" }, { kind: "directive", type: i5.HermesRadio, selector: "[hermesRadio]" }, { kind: "component", type: i5.HermesRadioContainer, selector: "hermes-radio-container", inputs: ["hermesInline"] }, { kind: "component", type: i5.HermesRadioWrapper, selector: "hermes-radio-wrapper" }, { kind: "directive", type: i5.HermesNativeSelect, selector: "[hermesNativeSelect]" }, { kind: "component", type: i5.HermesNativeSelectContainer, selector: "hermes-native-select-container" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: FilterFormComponent, selector: "appfx-filter-form", inputs: ["valid"], outputs: ["cancel", "apply"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1764
+ }
1765
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: GeneralFilterComponent, decorators: [{
1766
+ type: Component,
1767
+ args: [{ selector: 'appfx-general-filter', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!--\r\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\r\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\r\n ~ This software is released under MIT license.\r\n ~ The full license information can be found in LICENSE in the root directory of this project.\r\n -->\r\n<appfx-filter-form\r\n [formGroup]=\"generalFilterForm\"\r\n [valid]=\"generalFilterForm.valid\"\r\n (cancel)=\"onCancelButtonClick()\"\r\n (apply)=\"onApplyButtonClick()\"\r\n>\r\n <hermes-native-select-container class=\"mt-compact\">\r\n <label class=\"hermes-control-label\">\r\n {{ filterStrings.operatorLabel }}\r\n </label>\r\n <select hermesNativeSelect formControlName=\"primaryOperator\">\r\n @for (operator of comparisonOperators; track operator) {\r\n <option [ngValue]=\"operator\">\r\n {{ filterStrings.getOperatorDisplayName(operator) }}\r\n </option>\r\n }\r\n </select>\r\n </hermes-native-select-container>\r\n @if (!isEmptyPrimaryPredicate) {\r\n <div class=\"flex-container\">\r\n <hermes-input-container>\r\n <input\r\n type=\"text\"\r\n formControlName=\"primaryValue\"\r\n placeholder=\"{{ filterStrings.enterValue }}\"\r\n hermesInput\r\n (keydown)=\"onInputKeyPress($event)\"\r\n />\r\n <hermes-control-error *hermesIfError=\"'required'\" role=\"alert\">{{\r\n filterStrings.requiredValidatorMessage\r\n }}</hermes-control-error>\r\n <hermes-control-error *hermesIfError=\"'pattern'\" role=\"alert\">{{\r\n filterStrings.integerValidatorMessage\r\n }}</hermes-control-error>\r\n </hermes-input-container>\r\n @if (isNumericUnitProperty) {\r\n <hermes-native-select-container class=\"ml-half\">\r\n <select hermesNativeSelect formControlName=\"primaryUnit\" [attr.aria-label]=\"filterStrings.unitAriaLabel\">\r\n @for (unit of units; track unit) {\r\n <option [ngValue]=\"unit\">\r\n {{ filterStrings.getUnitDisplayName(unit) }}\r\n </option>\r\n }\r\n </select>\r\n </hermes-native-select-container>\r\n }\r\n </div>\r\n }\r\n @if (!additionalPredicate && !filterProperty.singleCondition) {\r\n <button\r\n class=\"btn btn-sm btn-link mt-half\"\r\n data-test-id=\"add-button\"\r\n [attr.aria-label]=\"filterStrings.addCondition\"\r\n (click)=\"enableSecondaryPredicate()\"\r\n >\r\n <hermes-icon shape=\"plus\" class=\"is-solid\"></hermes-icon>\r\n {{ filterStrings.addCondition }}\r\n </button>\r\n }\r\n @if (additionalPredicate) {\r\n <div>\r\n @if (filterProperty.logicalOperator == undefined) {\r\n <hermes-radio-container hermesInline class=\"mt-compact\">\r\n <hermes-radio-wrapper>\r\n <input\r\n type=\"radio\"\r\n hermesRadio\r\n formControlName=\"logicalOperator\"\r\n [value]=\"logicalOperators[0]\"\r\n [attr.disabled]=\"isEmptyPrimaryPredicate || isEmptySecondaryPredicate ? 'disabled' : null\"\r\n />\r\n <label> {{ filterStrings.getConjoinerDisplayName(logicalOperators[0]) }} </label>\r\n </hermes-radio-wrapper>\r\n <hermes-radio-wrapper>\r\n <input type=\"radio\" hermesRadio formControlName=\"logicalOperator\" [value]=\"logicalOperators[1]\" />\r\n <label> {{ filterStrings.getConjoinerDisplayName(logicalOperators[1]) }} </label>\r\n </hermes-radio-wrapper>\r\n </hermes-radio-container>\r\n }\r\n @if (filterProperty.logicalOperator != undefined) {\r\n <div class=\"hermes-control-container\" hermes-layout=\"m-t:sm\">\r\n <span data-test-id=\"logical-operator\" hermes-text=\"body medium\">{{\r\n filterStrings.getConjoinerDisplayName(filterProperty.logicalOperator)\r\n }}</span>\r\n </div>\r\n }\r\n <div class=\"flex-end-container\">\r\n <hermes-native-select-container class=\"form-control-compact\">\r\n <label class=\"hermes-control-label\">\r\n {{ filterStrings.operatorLabel }}\r\n </label>\r\n <select hermesNativeSelect formControlName=\"secondaryOperator\">\r\n @for (operator of comparisonOperators; track operator) {\r\n <option [ngValue]=\"operator\">\r\n {{ filterStrings.getOperatorDisplayName(operator) }}\r\n </option>\r\n }\r\n </select>\r\n </hermes-native-select-container>\r\n <button\r\n class=\"close ml-half\"\r\n data-test-id=\"close-button\"\r\n [attr.aria-label]=\"filterStrings.removeConditionAriaLabel\"\r\n (click)=\"disableSecondaryPredicate()\"\r\n >\r\n <hermes-icon size=\"20\" shape=\"window-close\"></hermes-icon>\r\n </button>\r\n </div>\r\n @if (!isEmptySecondaryPredicate) {\r\n <div class=\"flex-container\">\r\n <hermes-input-container>\r\n <input\r\n type=\"text\"\r\n formControlName=\"secondaryValue\"\r\n placeholder=\"{{ filterStrings.enterValue }}\"\r\n hermesInput\r\n (keydown)=\"onInputKeyPress($event)\"\r\n />\r\n <hermes-control-error *hermesIfError=\"'required'\" role=\"alert\">{{\r\n filterStrings.requiredValidatorMessage\r\n }}</hermes-control-error>\r\n <hermes-control-error *hermesIfError=\"'pattern'\" role=\"alert\">{{\r\n filterStrings.integerValidatorMessage\r\n }}</hermes-control-error>\r\n </hermes-input-container>\r\n @if (isNumericUnitProperty) {\r\n <hermes-native-select-container class=\"ml-half\">\r\n <select hermesNativeSelect formControlName=\"secondaryUnit\">\r\n @for (unit of units; track unit) {\r\n <option [ngValue]=\"unit\">\r\n {{ filterStrings.getUnitDisplayName(unit) }}\r\n </option>\r\n }\r\n </select>\r\n </hermes-native-select-container>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n</appfx-filter-form>\r\n", styles: [".form-compact{padding:0;text-align:left;font-weight:400}.form-control-compact{margin-top:.3rem}.btn-compact{min-width:1.2rem;padding:0;margin:0 .4rem}.btn-right{float:right;margin-right:0;margin-top:.9rem;margin-left:.3rem}.mt-half{margin-top:.6rem}.mt-compact{margin-top:.9rem}.mb-compact{margin-bottom:.9rem}.ml-half{margin-left:.6rem}.mt-0{margin-top:0}.mb-0{margin-bottom:0}:host-context(.zoom2x,.zoom4x) .form-max-height{max-height:8rem;overflow-y:auto}select{max-width:18rem;text-overflow:ellipsis}hermes-signpost-content{max-width:20rem}.flex-end-container{display:flex;align-items:flex-end}.flex-container{display:flex}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:var(--hermes-datagrid-loading-background);display:flex;align-items:center;justify-content:center;z-index:10}.loading-content{display:flex;flex-direction:column;align-items:center;gap:.5rem}\n"] }]
1768
+ }], ctorParameters: () => [{ type: i1.FormBuilder }, { type: DatagridFiltersStrings }], propDecorators: { propertyFilter: [{
1769
+ type: Input
1770
+ }], filterCriteriaChange: [{
1771
+ type: Output
1772
+ }], filterProperty: [{
1773
+ type: Input
1774
+ }] } });
1775
+
1776
+ /*
1777
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
1778
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
1779
+ * This software is released under MIT license.
1780
+ * The full license information can be found in LICENSE in the root directory of this project.
1781
+ */
1782
+ const enterKey$2 = 'Enter';
1783
+ const spaceKey$1 = 'Space';
1784
+ /**
1785
+ * Directive which renders a clickable "X" on the right side of a Clarity label badge.
1786
+ * A "close" event is emitted when the "X" is clicked.
1787
+ * The directive is needed in order to be able to remove filtering criteria,
1788
+ * which are displayed in Clarity label badges.
1789
+ */
1790
+ class DismissableDirective {
1791
+ constructor(renderer, elRef) {
1792
+ this.renderer = renderer;
1793
+ this.elRef = elRef;
1794
+ this.dismiss = new EventEmitter();
1795
+ }
1796
+ ngAfterViewInit() {
1797
+ const icon = this.renderer.createElement('hermes-icon');
1798
+ icon.setAttribute('shape', 'window-close');
1799
+ icon.setAttribute('class', 'remove-filter');
1800
+ icon.setAttribute('role', 'button');
1801
+ icon.setAttribute('tabindex', '0');
1802
+ icon.setAttribute('aria-label', this.dismissAriaLabel);
1803
+ icon.style.margin = '1rem';
1804
+ this.renderer.setStyle(icon, 'margin-left', '0.5rem');
1805
+ this.renderer.setStyle(icon, 'margin-right', '0rem');
1806
+ this.renderer.setStyle(icon, 'cursor', 'pointer');
1807
+ this.renderer.appendChild(this.elRef.nativeElement, icon);
1808
+ this.renderer.listen(icon, 'click', () => {
1809
+ this.dismiss.emit();
1810
+ return true;
1811
+ });
1812
+ this.renderer.listen(icon, 'keydown', (event) => {
1813
+ if (event.key === enterKey$2 || event.key === spaceKey$1) {
1814
+ this.dismiss.emit();
1815
+ }
1816
+ return true;
1817
+ });
1818
+ }
1819
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: DismissableDirective, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
1820
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: DismissableDirective, isStandalone: false, selector: "[dismissable]", inputs: { dismissAriaLabel: "dismissAriaLabel" }, outputs: { dismiss: "dismiss" }, ngImport: i0 }); }
1821
+ }
1822
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: DismissableDirective, decorators: [{
1823
+ type: Directive,
1824
+ args: [{
1825
+ selector: '[dismissable]',
1826
+ standalone: false,
1827
+ }]
1828
+ }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }], propDecorators: { dismissAriaLabel: [{
1829
+ type: Input
1830
+ }], dismiss: [{
1831
+ type: Output
1832
+ }] } });
1833
+
1834
+ /*
1835
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
1836
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
1837
+ * This software is released under MIT license.
1838
+ * The full license information can be found in LICENSE in the root directory of this project.
1839
+ */
1840
+ /**
1841
+ * User service that provides users for the datagrid users filter.
1842
+ *
1843
+ * ```
1844
+ * @NgModule({
1845
+ * ...
1846
+ * providers: [
1847
+ * { provide: DatagridFiltersUserService, useClass: CustomUserService },
1848
+ * ]
1849
+ * })
1850
+ * export class AppModule {}
1851
+ * ```
1852
+ */
1853
+ class DatagridFiltersUserService {
1854
+ getDomains() {
1855
+ return of([]);
1856
+ }
1857
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1858
+ searchUsers(searchTerm, domain) {
1859
+ return of([]);
1860
+ }
1861
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: DatagridFiltersUserService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1862
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: DatagridFiltersUserService }); }
1863
+ }
1864
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: DatagridFiltersUserService, decorators: [{
1865
+ type: Injectable
1866
+ }] });
1867
+
1868
+ /*
1869
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
1870
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
1871
+ * This software is released under MIT license.
1872
+ * The full license information can be found in LICENSE in the root directory of this project.
1873
+ */
1874
+ var ErrorType;
1875
+ (function (ErrorType) {
1876
+ ErrorType[ErrorType["DOMAIN"] = 0] = "DOMAIN";
1877
+ ErrorType[ErrorType["USER_SEARCH"] = 1] = "USER_SEARCH";
1878
+ })(ErrorType || (ErrorType = {}));
1879
+ class UsersFilterComponent {
1880
+ #pageSize;
1881
+ #currentMaxShown;
1882
+ #selectedFilterCriteria;
1883
+ #searchTermDebounceTime;
1884
+ #destroy$;
1885
+ constructor(fb, cdr, filterStrings, userService) {
1886
+ this.fb = fb;
1887
+ this.cdr = cdr;
1888
+ this.filterStrings = filterStrings;
1889
+ this.userService = userService;
1890
+ this.filterCriteriaChange = new EventEmitter();
1891
+ this.isLoading = false;
1892
+ this.domains = [''];
1893
+ this.allFetchedUsers = [];
1894
+ this.visibleUsers = [];
1895
+ this.selectedValues = new Set();
1896
+ this.#pageSize = 50;
1897
+ this.#currentMaxShown = this.#pageSize;
1898
+ this.#selectedFilterCriteria = new PropertyFilter();
1899
+ this.#searchTermDebounceTime = 200;
1900
+ this.#destroy$ = new Subject();
1901
+ this.selectionValidator = () => {
1902
+ return this.selectedValues.size > 0 ? null : { required: true };
1903
+ };
1904
+ }
1905
+ get optionsFormArray() {
1906
+ return this.usersSelectionForm?.get('options');
1907
+ }
1908
+ get hasMoreItems() {
1909
+ return this.visibleUsers.length < this.allFetchedUsers.length;
1910
+ }
1911
+ trackByOperator(_index, operator) {
1912
+ return operator;
1913
+ }
1914
+ trackByDomain(_index, domain) {
1915
+ return domain;
1916
+ }
1917
+ ngOnInit() {
1918
+ this.createUsersSelectionForm();
1919
+ this.setupListeners();
1920
+ this.initializeSelectionInEditMode();
1921
+ this.loadDomains();
1922
+ }
1923
+ ngOnChanges(changes) {
1924
+ if (changes['propertyFilter'] && !changes['propertyFilter'].firstChange) {
1925
+ this.initializeSelectionInEditMode();
1926
+ this.rebuildCheckboxList();
1927
+ }
1928
+ }
1929
+ ngOnDestroy() {
1930
+ this.#destroy$.next();
1931
+ this.#destroy$.complete();
1932
+ }
1933
+ onDomainChange() {
1934
+ const term = this.usersSelectionForm.get('searchTerm')?.value || '';
1935
+ this.usersSelectionForm.get('searchTerm')?.setValue(term);
1936
+ }
1937
+ fetchUsers(searchTerm) {
1938
+ return this.userService.searchUsers(searchTerm, this.usersSelectionForm.get('domain')?.value);
1939
+ }
1940
+ loadMore(event) {
1941
+ event.preventDefault();
1942
+ event.stopPropagation();
1943
+ this.#currentMaxShown += this.#pageSize;
1944
+ this.rebuildCheckboxList();
1945
+ }
1946
+ onOptionChange(index) {
1947
+ const user = this.visibleUsers[index];
1948
+ const isChecked = this.optionsFormArray.at(index).value;
1949
+ if (isChecked) {
1950
+ this.selectedValues.add(user);
1951
+ }
1952
+ else {
1953
+ this.selectedValues.delete(user);
1954
+ }
1955
+ this.updateSelectAllState();
1956
+ this.usersSelectionForm.updateValueAndValidity();
1957
+ }
1958
+ onSelectAllChange() {
1959
+ const selectAllValue = this.usersSelectionForm.get('selectAll')?.value;
1960
+ this.optionsFormArray.controls.forEach((ctrl) => {
1961
+ ctrl.setValue(selectAllValue, { emitEvent: false });
1962
+ });
1963
+ this.visibleUsers.forEach(user => {
1964
+ if (selectAllValue) {
1965
+ this.selectedValues.add(user);
1966
+ }
1967
+ else {
1968
+ this.selectedValues.delete(user);
1969
+ }
1970
+ });
1971
+ this.usersSelectionForm.updateValueAndValidity();
1972
+ }
1973
+ clearSearch() {
1974
+ this.usersSelectionForm.get('searchTerm')?.setValue('');
1975
+ }
1976
+ handleError(error, errorType) {
1977
+ if (errorType === ErrorType.USER_SEARCH) {
1978
+ console.error('Error searching users: ', error);
1979
+ this.errorSearchingUsers = this.filterStrings.errorSearchingUsers;
1980
+ }
1981
+ else if (errorType === ErrorType.DOMAIN) {
1982
+ console.error('Error loading domains: ', error);
1983
+ this.errorRetrievingDomains = this.filterStrings.errorLoadingDomains;
1984
+ }
1985
+ this.isLoading = false;
1986
+ this.cdr.markForCheck();
1987
+ if (errorType === ErrorType.DOMAIN) {
1988
+ return of([]);
1989
+ }
1990
+ else {
1991
+ const searchValue = this.usersSelectionForm.get('searchTerm')?.value;
1992
+ return searchValue ? of([searchValue]) : of([]);
1993
+ }
1994
+ }
1995
+ showLoading() {
1996
+ this.isLoading = true;
1997
+ this.cdr.markForCheck();
1998
+ }
1999
+ hideLoading() {
2000
+ this.isLoading = false;
2001
+ this.cdr.markForCheck();
2002
+ }
2003
+ onCancelButtonClick() {
2004
+ this.filterCriteriaChange.emit();
2005
+ }
2006
+ onApplyButtonClick() {
2007
+ const comparisonOperator = this.usersSelectionForm.get('userOperator')?.value || ComparisonOperator.Equals;
2008
+ this.#selectedFilterCriteria.criteria = Array.from(this.selectedValues).map((userValue) => this.createUserPropertyPredicate(userValue, comparisonOperator));
2009
+ this.#selectedFilterCriteria.operator =
2010
+ comparisonOperator === ComparisonOperator.Equals ? LogicalOperator.Or : LogicalOperator.And;
2011
+ this.filterCriteriaChange.emit(this.#selectedFilterCriteria);
2012
+ }
2013
+ setupListeners() {
2014
+ this.usersSelectionForm
2015
+ .get('searchTerm')
2016
+ ?.valueChanges.pipe(takeUntil(this.#destroy$), tap(() => {
2017
+ this.showLoading();
2018
+ this.errorSearchingUsers = undefined;
2019
+ }), debounceTime(this.#searchTermDebounceTime), switchMap((term) => this.fetchUsers(term).pipe(catchError((error) => this.handleError(error, ErrorType.USER_SEARCH)))), tap((results) => {
2020
+ this.allFetchedUsers = results;
2021
+ this.resetPagination();
2022
+ this.rebuildCheckboxList();
2023
+ this.hideLoading();
2024
+ }))
2025
+ .subscribe();
2026
+ this.usersSelectionForm
2027
+ .get('userOperator')
2028
+ ?.valueChanges.pipe(takeUntil(this.#destroy$))
2029
+ .subscribe((op) => {
2030
+ this.#selectedFilterCriteria.operator =
2031
+ op === ComparisonOperator.Equals ? LogicalOperator.Or : LogicalOperator.And;
2032
+ });
2033
+ this.usersSelectionForm.get('userOperator')?.setValue(ComparisonOperator.Equals);
2034
+ this.usersSelectionForm
2035
+ .get('domain')
2036
+ ?.valueChanges.pipe(takeUntil(this.#destroy$))
2037
+ .subscribe(() => {
2038
+ this.usersSelectionForm.get('searchTerm')?.setValue('');
2039
+ });
2040
+ }
2041
+ loadDomains() {
2042
+ this.showLoading();
2043
+ this.userService
2044
+ .getDomains()
2045
+ .pipe(takeUntil(this.#destroy$), catchError((error) => this.handleError(error, ErrorType.DOMAIN)))
2046
+ .subscribe((domains) => {
2047
+ this.domains = domains;
2048
+ const currentDomain = this.usersSelectionForm.get('domain')?.value;
2049
+ if (domains.length > 0 && !currentDomain) {
2050
+ this.usersSelectionForm.get('domain')?.setValue(domains[0]);
2051
+ }
2052
+ });
2053
+ }
2054
+ resetPagination() {
2055
+ this.#currentMaxShown = this.#pageSize;
2056
+ }
2057
+ createUsersSelectionForm() {
2058
+ this.usersSelectionForm = this.fb.group({
2059
+ userOperator: [ComparisonOperator.Equals],
2060
+ domain: [null],
2061
+ searchTerm: [''],
2062
+ selectAll: [false],
2063
+ options: this.fb.array([]),
2064
+ }, { validators: this.selectionValidator });
2065
+ }
2066
+ initializeSelectionInEditMode() {
2067
+ if (!this.propertyFilter) {
2068
+ return;
2069
+ }
2070
+ const initialOp = this.propertyFilter.operator === LogicalOperator.And
2071
+ ? ComparisonOperator.DoesNotEqual
2072
+ : ComparisonOperator.Equals;
2073
+ this.usersSelectionForm.get('userOperator')?.setValue(initialOp, { emitEvent: false });
2074
+ const users = this.propertyFilter.criteria?.map(c => c.value) || [];
2075
+ this.selectedValues = new Set(users);
2076
+ this.usersSelectionForm.updateValueAndValidity();
2077
+ }
2078
+ rebuildCheckboxList() {
2079
+ const slicedUsers = this.allFetchedUsers.slice(0, this.#currentMaxShown);
2080
+ this.visibleUsers = [];
2081
+ const visibleUsersSet = new Set();
2082
+ const searchTerm = this.usersSelectionForm.get('searchTerm')?.value;
2083
+ let searchTermMatchCustomUser = false;
2084
+ if (searchTerm) {
2085
+ this.selectedValues.forEach((user) => {
2086
+ if (user.toLocaleLowerCase().includes(searchTerm.toLocaleLowerCase())) {
2087
+ this.visibleUsers.push(user);
2088
+ visibleUsersSet.add(user);
2089
+ }
2090
+ if (user === searchTerm) {
2091
+ searchTermMatchCustomUser = true;
2092
+ }
2093
+ });
2094
+ if (!searchTermMatchCustomUser) {
2095
+ this.visibleUsers.push(searchTerm);
2096
+ visibleUsersSet.add(searchTerm);
2097
+ }
2098
+ }
2099
+ else {
2100
+ this.selectedValues.forEach(user => {
2101
+ if (!visibleUsersSet.has(user)) {
2102
+ this.visibleUsers.push(user);
2103
+ visibleUsersSet.add(user);
2104
+ }
2105
+ });
2106
+ }
2107
+ slicedUsers
2108
+ .filter(user => !visibleUsersSet.has(user))
2109
+ .forEach(filteredUser => this.visibleUsers.push(filteredUser));
2110
+ const optionsArr = this.optionsFormArray;
2111
+ optionsArr.clear();
2112
+ this.visibleUsers.forEach(user => {
2113
+ const isSelected = this.selectedValues.has(user);
2114
+ optionsArr.push(new FormControl(isSelected));
2115
+ });
2116
+ this.updateSelectAllState();
2117
+ this.cdr.markForCheck();
2118
+ }
2119
+ updateSelectAllState() {
2120
+ if (this.visibleUsers.length === 0) {
2121
+ this.usersSelectionForm.get('selectAll')?.setValue(false, { emitEvent: false });
2122
+ return;
2123
+ }
2124
+ const allVisibleSelected = this.visibleUsers.every(u => this.selectedValues.has(u));
2125
+ this.usersSelectionForm.get('selectAll')?.setValue(allVisibleSelected, { emitEvent: false });
2126
+ }
2127
+ createUserPropertyPredicate(value, comparisonOperator) {
2128
+ const res = new PropertyPredicate();
2129
+ res.filterableProperty = this.filterProperty;
2130
+ res.operator = comparisonOperator;
2131
+ res.value = value;
2132
+ return res;
2133
+ }
2134
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: UsersFilterComponent, deps: [{ token: i1.FormBuilder }, { token: i0.ChangeDetectorRef }, { token: DatagridFiltersStrings }, { token: DatagridFiltersUserService }], target: i0.ɵɵFactoryTarget.Component }); }
2135
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.22", type: UsersFilterComponent, isStandalone: false, selector: "appfx-users-filter", inputs: { filterProperty: "filterProperty", propertyFilter: "propertyFilter" }, outputs: { filterCriteriaChange: "filterCriteriaChange" }, usesOnChanges: true, ngImport: i0, template: "<!--\r\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\r\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\r\n ~ This software is released under MIT license.\r\n ~ The full license information can be found in LICENSE in the root directory of this project.\r\n -->\r\n<appfx-filter-form\r\n [formGroup]=\"usersSelectionForm\"\r\n [valid]=\"usersSelectionForm.valid\"\r\n (cancel)=\"onCancelButtonClick()\"\r\n (apply)=\"onApplyButtonClick()\"\r\n>\r\n <div class=\"user-filter-wrapper\" hermes-layout=\"p-b:xxxs\">\r\n <div *ngIf=\"isLoading\" class=\"loading-overlay\">\r\n <div class=\"loading-content\">\r\n <hermes-spinner hermesMedium>{{ filterStrings.loading }}</hermes-spinner>\r\n </div>\r\n </div>\r\n <!-- Operator -->\r\n <hermes-native-select-container class=\"mt-compact\">\r\n <label class=\"hermes-control-label\">\r\n {{ filterStrings.operatorLabel }}\r\n </label>\r\n <select hermesNativeSelect formControlName=\"userOperator\">\r\n <option\r\n *ngFor=\"let operator of filterProperty.supportedOperators; trackBy: trackByOperator\"\r\n [ngValue]=\"operator\"\r\n >\r\n {{ filterStrings.getOperatorDisplayName(operator) }}\r\n </option>\r\n </select>\r\n </hermes-native-select-container>\r\n\r\n <!-- Domain -->\r\n <hermes-native-select-container *ngIf=\"domains && domains.length > 0\">\r\n <label>{{ filterStrings.domain }}</label>\r\n <select hermesNativeSelect name=\"domain\" formControlName=\"domain\">\r\n <option *ngFor=\"let domain of domains; trackBy: trackByDomain\" [value]=\"domain\">\r\n {{ domain }}\r\n </option>\r\n </select>\r\n </hermes-native-select-container>\r\n\r\n <!-- User -->\r\n <label class=\"hermes-control-label text-left mt-compact\">\r\n {{ filterStrings.user }}\r\n </label>\r\n\r\n <hermes-input-container hermes-layout=\"m-t:xs\">\r\n <label class=\"hermes-sr-only\">{{ filterStrings.searchPlaceholder }}</label>\r\n <input hermesInput type=\"text\" [placeholder]=\"filterStrings.searchPlaceholder\" formControlName=\"searchTerm\" />\r\n <hermes-icon shape=\"search\" hermesInputPrefix></hermes-icon>\r\n <hermes-icon\r\n *ngIf=\"usersSelectionForm.get('searchTerm')?.value\"\r\n shape=\"window-close\"\r\n hermesInputSuffix\r\n (click)=\"clearSearch()\"\r\n ></hermes-icon>\r\n </hermes-input-container>\r\n\r\n <div hermes-layout=\"m-t:xs m-l:xxs\" class=\"selection-counter\">\r\n <span *ngIf=\"selectedValues.size > 0\" class=\"hermes-subtext\" hermes-text=\"body medium\">\r\n {{ filterStrings.formatString(filterStrings.elementsSelectedFormat, [selectedValues.size.toString()]) }}\r\n </span>\r\n </div>\r\n\r\n <div hermes-layout=\"m-t:xs\">\r\n <hermes-checkbox-container class=\"enum-options\">\r\n <hermes-checkbox-wrapper *ngIf=\"visibleUsers.length > 0\" hermes-layout=\"m-b:xs\">\r\n <input type=\"checkbox\" hermesCheckbox formControlName=\"selectAll\" (change)=\"onSelectAllChange()\" />\r\n <label>\r\n {{ usersSelectionForm.get('searchTerm')?.value ? filterStrings.allSearchResults : filterStrings.selectAll }}\r\n </label>\r\n </hermes-checkbox-wrapper>\r\n\r\n <hermes-checkbox-wrapper *ngFor=\"let user of visibleUsers; let i = index\">\r\n <input\r\n type=\"checkbox\"\r\n hermesCheckbox\r\n [formControl]=\"$any(optionsFormArray.at(i))\"\r\n (change)=\"onOptionChange(i)\"\r\n />\r\n <label>\r\n {{ user }}\r\n </label>\r\n </hermes-checkbox-wrapper>\r\n </hermes-checkbox-container>\r\n\r\n <div *ngIf=\"errorSearchingUsers\" class=\"hermes-subtext hermes-error error\">\r\n {{ errorSearchingUsers }}\r\n </div>\r\n\r\n <div *ngIf=\"errorRetrievingDomains\" class=\"hermes-subtext hermes-error error\">\r\n {{ errorRetrievingDomains }}\r\n </div>\r\n </div>\r\n\r\n <button *ngIf=\"hasMoreItems\" class=\"btn btn-link\" (click)=\"loadMore($event)\">\r\n {{ filterStrings.loadMore }}\r\n </button>\r\n </div>\r\n</appfx-filter-form>\r\n", styles: [".user-filter-wrapper{max-height:18rem;overflow:auto}\n", ".form-compact{padding:0;text-align:left;font-weight:400}.form-control-compact{margin-top:.3rem}.btn-compact{min-width:1.2rem;padding:0;margin:0 .4rem}.btn-right{float:right;margin-right:0;margin-top:.9rem;margin-left:.3rem}.mt-half{margin-top:.6rem}.mt-compact{margin-top:.9rem}.mb-compact{margin-bottom:.9rem}.ml-half{margin-left:.6rem}.mt-0{margin-top:0}.mb-0{margin-bottom:0}:host-context(.zoom2x,.zoom4x) .form-max-height{max-height:8rem;overflow-y:auto}select{max-width:18rem;text-overflow:ellipsis}hermes-signpost-content{max-width:20rem}.flex-end-container{display:flex;align-items:flex-end}.flex-container{display:flex}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:var(--hermes-datagrid-loading-background);display:flex;align-items:center;justify-content:center;z-index:10}.loading-content{display:flex;flex-direction:column;align-items:center;gap:.5rem}\n", ".enum-options{margin-top:.1rem;text-align:left}:host-context(.no-zoom) .enum-options{overflow-y:auto}.enum-filter-wrapper{max-height:18rem;overflow:auto}:host ::ng-deep .hermes-control-container{margin-left:.2rem}hermes-checkbox-container:not(.hermes-default-style){margin-top:0!important;margin-bottom:0!important;min-height:auto!important}.selection-counter .hermes-subtext{color:var(--hermes-info-color, #0072a3)}\n"], dependencies: [{ kind: "directive", type: i3.HermesControlLabel, selector: "label", inputs: ["id", "for"] }, { kind: "component", type: i4.HermesIcon, selector: "hermes-icon, hermes-icon", inputs: ["shape", "size", "direction", "flip", "solid", "status", "inverse", "badge"] }, { kind: "directive", type: i5.HermesCheckbox, selector: "[hermesCheckbox],[hermesToggle]" }, { kind: "component", type: i5.HermesCheckboxContainer, selector: "hermes-checkbox-container,hermes-toggle-container", inputs: ["hermesInline"] }, { kind: "component", type: i5.HermesCheckboxWrapper, selector: "hermes-checkbox-wrapper,hermes-toggle-wrapper" }, { kind: "directive", type: i5.HermesInput, selector: "[hermesInput]" }, { kind: "component", type: i5.HermesInputContainer, selector: "hermes-input-container" }, { kind: "directive", type: i5.HermesNativeSelect, selector: "[hermesNativeSelect]" }, { kind: "component", type: i5.HermesNativeSelectContainer, selector: "hermes-native-select-container" }, { kind: "component", type: i6.HermesSpinner, selector: "hermes-spinner", inputs: ["hermesInline", "hermesInverse", "hermesSmall", "hermesMedium"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: FilterFormComponent, selector: "appfx-filter-form", inputs: ["valid"], outputs: ["cancel", "apply"] }] }); }
2136
+ }
2137
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: UsersFilterComponent, decorators: [{
2138
+ type: Component,
2139
+ args: [{ selector: 'appfx-users-filter', standalone: false, template: "<!--\r\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\r\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\r\n ~ This software is released under MIT license.\r\n ~ The full license information can be found in LICENSE in the root directory of this project.\r\n -->\r\n<appfx-filter-form\r\n [formGroup]=\"usersSelectionForm\"\r\n [valid]=\"usersSelectionForm.valid\"\r\n (cancel)=\"onCancelButtonClick()\"\r\n (apply)=\"onApplyButtonClick()\"\r\n>\r\n <div class=\"user-filter-wrapper\" hermes-layout=\"p-b:xxxs\">\r\n <div *ngIf=\"isLoading\" class=\"loading-overlay\">\r\n <div class=\"loading-content\">\r\n <hermes-spinner hermesMedium>{{ filterStrings.loading }}</hermes-spinner>\r\n </div>\r\n </div>\r\n <!-- Operator -->\r\n <hermes-native-select-container class=\"mt-compact\">\r\n <label class=\"hermes-control-label\">\r\n {{ filterStrings.operatorLabel }}\r\n </label>\r\n <select hermesNativeSelect formControlName=\"userOperator\">\r\n <option\r\n *ngFor=\"let operator of filterProperty.supportedOperators; trackBy: trackByOperator\"\r\n [ngValue]=\"operator\"\r\n >\r\n {{ filterStrings.getOperatorDisplayName(operator) }}\r\n </option>\r\n </select>\r\n </hermes-native-select-container>\r\n\r\n <!-- Domain -->\r\n <hermes-native-select-container *ngIf=\"domains && domains.length > 0\">\r\n <label>{{ filterStrings.domain }}</label>\r\n <select hermesNativeSelect name=\"domain\" formControlName=\"domain\">\r\n <option *ngFor=\"let domain of domains; trackBy: trackByDomain\" [value]=\"domain\">\r\n {{ domain }}\r\n </option>\r\n </select>\r\n </hermes-native-select-container>\r\n\r\n <!-- User -->\r\n <label class=\"hermes-control-label text-left mt-compact\">\r\n {{ filterStrings.user }}\r\n </label>\r\n\r\n <hermes-input-container hermes-layout=\"m-t:xs\">\r\n <label class=\"hermes-sr-only\">{{ filterStrings.searchPlaceholder }}</label>\r\n <input hermesInput type=\"text\" [placeholder]=\"filterStrings.searchPlaceholder\" formControlName=\"searchTerm\" />\r\n <hermes-icon shape=\"search\" hermesInputPrefix></hermes-icon>\r\n <hermes-icon\r\n *ngIf=\"usersSelectionForm.get('searchTerm')?.value\"\r\n shape=\"window-close\"\r\n hermesInputSuffix\r\n (click)=\"clearSearch()\"\r\n ></hermes-icon>\r\n </hermes-input-container>\r\n\r\n <div hermes-layout=\"m-t:xs m-l:xxs\" class=\"selection-counter\">\r\n <span *ngIf=\"selectedValues.size > 0\" class=\"hermes-subtext\" hermes-text=\"body medium\">\r\n {{ filterStrings.formatString(filterStrings.elementsSelectedFormat, [selectedValues.size.toString()]) }}\r\n </span>\r\n </div>\r\n\r\n <div hermes-layout=\"m-t:xs\">\r\n <hermes-checkbox-container class=\"enum-options\">\r\n <hermes-checkbox-wrapper *ngIf=\"visibleUsers.length > 0\" hermes-layout=\"m-b:xs\">\r\n <input type=\"checkbox\" hermesCheckbox formControlName=\"selectAll\" (change)=\"onSelectAllChange()\" />\r\n <label>\r\n {{ usersSelectionForm.get('searchTerm')?.value ? filterStrings.allSearchResults : filterStrings.selectAll }}\r\n </label>\r\n </hermes-checkbox-wrapper>\r\n\r\n <hermes-checkbox-wrapper *ngFor=\"let user of visibleUsers; let i = index\">\r\n <input\r\n type=\"checkbox\"\r\n hermesCheckbox\r\n [formControl]=\"$any(optionsFormArray.at(i))\"\r\n (change)=\"onOptionChange(i)\"\r\n />\r\n <label>\r\n {{ user }}\r\n </label>\r\n </hermes-checkbox-wrapper>\r\n </hermes-checkbox-container>\r\n\r\n <div *ngIf=\"errorSearchingUsers\" class=\"hermes-subtext hermes-error error\">\r\n {{ errorSearchingUsers }}\r\n </div>\r\n\r\n <div *ngIf=\"errorRetrievingDomains\" class=\"hermes-subtext hermes-error error\">\r\n {{ errorRetrievingDomains }}\r\n </div>\r\n </div>\r\n\r\n <button *ngIf=\"hasMoreItems\" class=\"btn btn-link\" (click)=\"loadMore($event)\">\r\n {{ filterStrings.loadMore }}\r\n </button>\r\n </div>\r\n</appfx-filter-form>\r\n", styles: [".user-filter-wrapper{max-height:18rem;overflow:auto}\n", ".form-compact{padding:0;text-align:left;font-weight:400}.form-control-compact{margin-top:.3rem}.btn-compact{min-width:1.2rem;padding:0;margin:0 .4rem}.btn-right{float:right;margin-right:0;margin-top:.9rem;margin-left:.3rem}.mt-half{margin-top:.6rem}.mt-compact{margin-top:.9rem}.mb-compact{margin-bottom:.9rem}.ml-half{margin-left:.6rem}.mt-0{margin-top:0}.mb-0{margin-bottom:0}:host-context(.zoom2x,.zoom4x) .form-max-height{max-height:8rem;overflow-y:auto}select{max-width:18rem;text-overflow:ellipsis}hermes-signpost-content{max-width:20rem}.flex-end-container{display:flex;align-items:flex-end}.flex-container{display:flex}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:var(--hermes-datagrid-loading-background);display:flex;align-items:center;justify-content:center;z-index:10}.loading-content{display:flex;flex-direction:column;align-items:center;gap:.5rem}\n", ".enum-options{margin-top:.1rem;text-align:left}:host-context(.no-zoom) .enum-options{overflow-y:auto}.enum-filter-wrapper{max-height:18rem;overflow:auto}:host ::ng-deep .hermes-control-container{margin-left:.2rem}hermes-checkbox-container:not(.hermes-default-style){margin-top:0!important;margin-bottom:0!important;min-height:auto!important}.selection-counter .hermes-subtext{color:var(--hermes-info-color, #0072a3)}\n"] }]
2140
+ }], ctorParameters: () => [{ type: i1.FormBuilder }, { type: i0.ChangeDetectorRef }, { type: DatagridFiltersStrings }, { type: DatagridFiltersUserService }], propDecorators: { filterProperty: [{
2141
+ type: Input
2142
+ }], propertyFilter: [{
2143
+ type: Input
2144
+ }], filterCriteriaChange: [{
2145
+ type: Output
2146
+ }] } });
2147
+
2148
+ /*
2149
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
2150
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
2151
+ * This software is released under MIT license.
2152
+ * The full license information can be found in LICENSE in the root directory of this project.
2153
+ */
2154
+ const enterKey$1 = 'Enter';
2155
+ const spaceKey = 'Space';
2156
+ class ManageFilterComponent {
2157
+ constructor(filterStrings) {
2158
+ this.filterStrings = filterStrings;
2159
+ /**
2160
+ * Event emitter to tell hosting view that filtering criteria have changed
2161
+ */
2162
+ this.filterCriteriaChange = new EventEmitter();
2163
+ this.stringPropertyType = PropertyType.String;
2164
+ this.enumPropertyType = PropertyType.Enum;
2165
+ this.numericPropertyType = PropertyType.Numeric;
2166
+ this.dateTimePropertyType = PropertyType.DateTime;
2167
+ this.userPropertyType = PropertyType.User;
2168
+ this.openPrimaryConditionSignPost = false;
2169
+ this.openSecondaryConditionSignPost = false;
2170
+ this.primaryConditionDisplayText = '';
2171
+ this.secondaryConditionDisplayText = '';
2172
+ this.editFilterAriaLabel = '';
2173
+ this.noDisplayValueOperators = [
2174
+ ComparisonOperator.IsEmpty,
2175
+ ComparisonOperator.LastDay,
2176
+ ComparisonOperator.LastWeek,
2177
+ ComparisonOperator.LastMonth,
2178
+ ComparisonOperator.LastYear,
2179
+ ];
2180
+ }
2181
+ ngOnInit() {
2182
+ this.managedProperty = this.propertyFilter.criteria[0].filterableProperty;
2183
+ if (this.isStringProperty(this.managedProperty)) {
2184
+ this.managedPropertyType = PropertyType.String;
2185
+ this.stringProperty = this.castStringProperty();
2186
+ }
2187
+ else if (this.isEnumProperty(this.managedProperty)) {
2188
+ this.managedPropertyType = PropertyType.Enum;
2189
+ this.enumProperty = this.castEnumProperty();
2190
+ }
2191
+ else if (this.isNumericProperty(this.managedProperty)) {
2192
+ this.managedPropertyType = PropertyType.Numeric;
2193
+ this.numericProperty = this.castNumericProperty();
2194
+ }
2195
+ else if (this.isDateTimeProperty(this.managedProperty)) {
2196
+ this.managedPropertyType = PropertyType.DateTime;
2197
+ this.dateTimeProperty = this.castDateTimeProperty();
2198
+ }
2199
+ else if (this.isUserProperty(this.managedProperty)) {
2200
+ this.managedPropertyType = PropertyType.User;
2201
+ this.userProperty = this.castUserProperty();
2202
+ }
2203
+ this.updateDisplayValues();
2204
+ }
2205
+ onEditFilterKeyPress(event, index) {
2206
+ if (event.target instanceof Element) {
2207
+ const targetElement = event.target;
2208
+ if (targetElement.classList.contains('edit-filter') && (event.key === enterKey$1 || event.key === spaceKey)) {
2209
+ if (index === 0) {
2210
+ this.openPrimaryConditionSignPost = !this.openPrimaryConditionSignPost;
2211
+ }
2212
+ else if (index === 1) {
2213
+ this.openSecondaryConditionSignPost = !this.openSecondaryConditionSignPost;
2214
+ }
2215
+ }
2216
+ }
2217
+ }
2218
+ removeFilter(index) {
2219
+ // 3 or more criteria are displayed as one group
2220
+ // For this reason, they are removed together
2221
+ if (this.propertyFilter.criteria.length > 2 || this.managedPropertyType === PropertyType.DateTime) {
2222
+ this.propertyFilter.criteria = [];
2223
+ }
2224
+ else {
2225
+ this.propertyFilter.criteria.splice(index, 1);
2226
+ if (this.propertyFilter.criteria.length > 0) {
2227
+ const property = this.propertyFilter.criteria[0].filterableProperty;
2228
+ if (this.isNumericUnitFilterProperty(property)) {
2229
+ property.selectedValue.splice(index, 1);
2230
+ property.selectedUnit.splice(index, 1);
2231
+ }
2232
+ this.updateDisplayValues();
2233
+ }
2234
+ }
2235
+ this.filterCriteriaChange.emit(this.propertyFilter);
2236
+ }
2237
+ onFilterCriteriaChange(propertyFilter) {
2238
+ if (propertyFilter) {
2239
+ this.filterCriteriaChange.emit(propertyFilter);
2240
+ }
2241
+ this.openPrimaryConditionSignPost = false;
2242
+ this.openSecondaryConditionSignPost = false;
2243
+ }
2244
+ updateDisplayValues() {
2245
+ this.primaryConditionDisplayText = this.displayFilterValue(0);
2246
+ this.editFilterAriaLabel =
2247
+ this.filterStrings.editFilterText +
2248
+ ' ' +
2249
+ this.managedProperty.displayName +
2250
+ ' ' +
2251
+ this.primaryConditionDisplayText;
2252
+ if (this.propertyFilter.criteria.length === 2) {
2253
+ this.secondaryConditionDisplayText = this.displayFilterValue(1);
2254
+ this.editFilterAriaLabel +=
2255
+ ' ' +
2256
+ this.filterStrings.getConjoinerDisplayName(this.propertyFilter.operator) +
2257
+ ' ' +
2258
+ this.secondaryConditionDisplayText;
2259
+ }
2260
+ }
2261
+ displayFilterValue(index) {
2262
+ if (this.isDateTimeProperty(this.managedProperty)) {
2263
+ return this.displayDateTimeFilter();
2264
+ }
2265
+ const appliedConditions = this.propertyFilter.criteria.length;
2266
+ if (appliedConditions > 2) {
2267
+ return appliedConditions + ' ' + this.filterStrings.appliedText;
2268
+ }
2269
+ if (this.propertyFilter.criteria[index].operator === ComparisonOperator.IsEmpty) {
2270
+ return this.operatorDisplayName(this.propertyFilter.criteria[index].operator);
2271
+ }
2272
+ const property = this.propertyFilter.criteria[index].filterableProperty;
2273
+ let value = this.propertyFilter.criteria[index].value;
2274
+ if (this.isEnumProperty(property)) {
2275
+ const enumProperty = property;
2276
+ value = enumProperty.values.get(this.propertyFilter.criteria[index].value);
2277
+ }
2278
+ else if (this.isNumericUnitFilterProperty(property)) {
2279
+ value = property.selectedValue[index] + ' ' + this.filterStrings.getUnitDisplayName(property.selectedUnit[index]);
2280
+ }
2281
+ return this.operatorDisplayName(this.propertyFilter.criteria[index].operator) + ': ' + value;
2282
+ }
2283
+ displayDateTimeFilter() {
2284
+ const operator = this.propertyFilter.criteria[0].filterableProperty.selectedOperator;
2285
+ if (operator === ComparisonOperator.CustomRange) {
2286
+ const displayValue = this.filterStrings.fromLabel +
2287
+ ': ' +
2288
+ this.formatDateTimeValue(this.propertyFilter.criteria[0].filterableProperty.selectedValue) +
2289
+ ' ' +
2290
+ this.filterStrings.toLabel +
2291
+ ': ' +
2292
+ this.formatDateTimeValue(this.propertyFilter.criteria[0].filterableProperty.selectedValueTo);
2293
+ return displayValue;
2294
+ }
2295
+ else if (this.isNoDisplayValueOperator(operator)) {
2296
+ return this.operatorDisplayName(operator);
2297
+ }
2298
+ else if (operator === ComparisonOperator.TimeSpan) {
2299
+ const timeSpanValue = this.propertyFilter.criteria[0].filterableProperty.selectedTimeSpanValue;
2300
+ const timeSpan = this.propertyFilter.criteria[0].filterableProperty.selectedTimeSpan;
2301
+ return (this.operatorDisplayName(operator) +
2302
+ ': ' +
2303
+ timeSpanValue +
2304
+ ' ' +
2305
+ this.filterStrings.getTimeSpanDisplayName(timeSpan));
2306
+ }
2307
+ else {
2308
+ const filterValue = this.formatDateTimeValue(this.propertyFilter.criteria[0].filterableProperty.selectedValue);
2309
+ return this.operatorDisplayName(operator) + ': ' + filterValue;
2310
+ }
2311
+ }
2312
+ isNoDisplayValueOperator(operator) {
2313
+ return this.noDisplayValueOperators.includes(operator);
2314
+ }
2315
+ formatDateTimeValue(dateTime) {
2316
+ if (!dateTime) {
2317
+ return dateTime;
2318
+ }
2319
+ return dateTime.replace('T', ' ');
2320
+ }
2321
+ isStringProperty(property) {
2322
+ return property instanceof StringPropertyDefinition;
2323
+ }
2324
+ isEnumProperty(property) {
2325
+ return property instanceof EnumPropertyDefinition;
2326
+ }
2327
+ isNumericProperty(property) {
2328
+ return property instanceof NumericPropertyDefinition;
2329
+ }
2330
+ isDateTimeProperty(property) {
2331
+ return property instanceof DateTimePropertyDefinition;
2332
+ }
2333
+ isUserProperty(property) {
2334
+ return property instanceof UserPropertyDefinition;
2335
+ }
2336
+ isNumericUnitFilterProperty(property) {
2337
+ return this.isNumericProperty(property) && property.unit !== undefined;
2338
+ }
2339
+ castStringProperty() {
2340
+ return this.managedProperty;
2341
+ }
2342
+ castEnumProperty() {
2343
+ return this.managedProperty;
2344
+ }
2345
+ castNumericProperty() {
2346
+ return this.managedProperty;
2347
+ }
2348
+ castDateTimeProperty() {
2349
+ return this.managedProperty;
2350
+ }
2351
+ castUserProperty() {
2352
+ return this.managedProperty;
2353
+ }
2354
+ operatorDisplayName(operator) {
2355
+ return this.filterStrings.getOperatorDisplayName(operator);
2356
+ }
2357
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: ManageFilterComponent, deps: [{ token: DatagridFiltersStrings }], target: i0.ɵɵFactoryTarget.Component }); }
2358
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: ManageFilterComponent, isStandalone: false, selector: "appfx-manage-filter", inputs: { propertyFilter: "propertyFilter" }, outputs: { filterCriteriaChange: "filterCriteriaChange" }, ngImport: i0, template: "<!--\r\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\r\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\r\n ~ This software is released under MIT license.\r\n ~ The full license information can be found in LICENSE in the root directory of this project.\r\n -->\r\n<span class=\"label label-blue\">\r\n {{ managedProperty.displayName }}\r\n <span\r\n class=\"badge\"\r\n dismissable\r\n [dismissAriaLabel]=\"\r\n filterStrings.removeFilterText + ' ' + managedProperty.displayName + ' ' + primaryConditionDisplayText\r\n \"\r\n (dismiss)=\"removeFilter(0)\"\r\n >\r\n <hermes-signpost>\r\n <span\r\n hermesSignpostTrigger\r\n class=\"edit-filter\"\r\n tabindex=\"0\"\r\n role=\"button\"\r\n [attr.aria-label]=\"editFilterAriaLabel\"\r\n (keydown)=\"onEditFilterKeyPress($event, 0)\"\r\n >\r\n {{ primaryConditionDisplayText }}\r\n </span>\r\n <ng-template [(hermesIfOpen)]=\"openPrimaryConditionSignPost\">\r\n <hermes-signpost-content [hermesPosition]=\"'bottom-middle'\" filterPopoverReposition>\r\n <hermes-native-select-container class=\"mt-0\">\r\n <label class=\"hermes-control-label\">\r\n {{ this.filterStrings.filterLabel }}\r\n </label>\r\n <select hermesNativeSelect [(ngModel)]=\"managedProperty\" disabled>\r\n <option [ngValue]=\"managedProperty\">\r\n {{ managedProperty.displayName }}\r\n </option>\r\n </select>\r\n </hermes-native-select-container>\r\n @switch (managedPropertyType) {\r\n @case (stringPropertyType) {\r\n <appfx-general-filter\r\n [filterProperty]=\"stringProperty\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-general-filter>\r\n }\r\n @case (numericPropertyType) {\r\n <appfx-general-filter\r\n [filterProperty]=\"numericProperty\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-general-filter>\r\n }\r\n @case (enumPropertyType) {\r\n <appfx-enum-filter\r\n [filterProperty]=\"enumProperty\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-enum-filter>\r\n }\r\n @case (dateTimePropertyType) {\r\n <appfx-datetime-filter\r\n [filterProperty]=\"dateTimeProperty\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-datetime-filter>\r\n }\r\n @case (userPropertyType) {\r\n <appfx-users-filter\r\n [filterProperty]=\"userProperty\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-users-filter>\r\n }\r\n }\r\n </hermes-signpost-content>\r\n </ng-template>\r\n </hermes-signpost>\r\n </span>\r\n @if (propertyFilter.criteria.length === 2 && managedPropertyType !== dateTimePropertyType) {\r\n <span class=\"text-lower\">\r\n {{ this.filterStrings.getConjoinerDisplayName(propertyFilter.operator) }}\r\n </span>\r\n }\r\n @if (propertyFilter.criteria.length === 2 && managedPropertyType !== dateTimePropertyType) {\r\n <span\r\n class=\"badge\"\r\n dismissable\r\n [dismissAriaLabel]=\"\r\n this.filterStrings.removeFilterText + managedProperty.displayName + ' ' + secondaryConditionDisplayText\r\n \"\r\n (dismiss)=\"removeFilter(1)\"\r\n >\r\n <hermes-signpost>\r\n <span\r\n hermesSignpostTrigger\r\n class=\"edit-filter\"\r\n tabindex=\"0\"\r\n role=\"button\"\r\n [attr.aria-label]=\"editFilterAriaLabel\"\r\n (keydown)=\"onEditFilterKeyPress($event, 1)\"\r\n >\r\n {{ secondaryConditionDisplayText }}\r\n </span>\r\n <ng-template [(hermesIfOpen)]=\"openSecondaryConditionSignPost\">\r\n <hermes-signpost-content [hermesPosition]=\"'bottom-middle'\" filterPopoverReposition>\r\n <hermes-native-select-container class=\"mt-0\">\r\n <label class=\"hermes-control-label\">\r\n {{ this.filterStrings.filterLabel }}\r\n </label>\r\n <select hermesNativeSelect [(ngModel)]=\"managedProperty\" disabled>\r\n <option [ngValue]=\"managedProperty\">\r\n {{ managedProperty.displayName }}\r\n </option>\r\n </select>\r\n </hermes-native-select-container>\r\n @switch (managedPropertyType) {\r\n @case (stringPropertyType) {\r\n <appfx-general-filter\r\n [filterProperty]=\"stringProperty\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-general-filter>\r\n }\r\n @case (numericPropertyType) {\r\n <appfx-general-filter\r\n [filterProperty]=\"numericProperty\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-general-filter>\r\n }\r\n @case (enumPropertyType) {\r\n <appfx-enum-filter\r\n [filterProperty]=\"enumProperty\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-enum-filter>\r\n }\r\n @case (userPropertyType) {\r\n <appfx-users-filter\r\n [filterProperty]=\"userProperty\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-users-filter>\r\n }\r\n }\r\n </hermes-signpost-content>\r\n </ng-template>\r\n </hermes-signpost>\r\n </span>\r\n }\r\n</span>\r\n", styles: [".filter-remove-btn{background:transparent;border:none;cursor:pointer}.text-lower{text-transform:lowercase}:host-context(body[data-theme=light]) :host-context(.user-tabbing) .edit-filter:focus,:host-context(body[data-theme=light]) :host-context(.user-tabbing) .remove-filter:focus{outline:2px solid #000}:host-context(body[data-theme=light]) :host-context(.user-tabbing) .edit-filter:focus{outline-offset:1px}:host-context(body[data-theme=dark]) :host-context(.user-tabbing) .edit-filter:focus,:host-context(body[data-theme=dark]) :host-context(.user-tabbing) .remove-filter:focus{outline:2px solid #fafafa}:host-context(body[data-theme=dark]) :host-context(.user-tabbing) .edit-filter:focus{outline-offset:1px}\n", ".form-compact{padding:0;text-align:left;font-weight:400}.form-control-compact{margin-top:.3rem}.btn-compact{min-width:1.2rem;padding:0;margin:0 .4rem}.btn-right{float:right;margin-right:0;margin-top:.9rem;margin-left:.3rem}.mt-half{margin-top:.6rem}.mt-compact{margin-top:.9rem}.mb-compact{margin-bottom:.9rem}.ml-half{margin-left:.6rem}.mt-0{margin-top:0}.mb-0{margin-bottom:0}:host-context(.zoom2x,.zoom4x) .form-max-height{max-height:8rem;overflow-y:auto}select{max-width:18rem;text-overflow:ellipsis}hermes-signpost-content{max-width:20rem}.flex-end-container{display:flex;align-items:flex-end}.flex-container{display:flex}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:var(--hermes-datagrid-loading-background);display:flex;align-items:center;justify-content:center;z-index:10}.loading-content{display:flex;flex-direction:column;align-items:center;gap:.5rem}\n"], dependencies: [{ kind: "directive", type: i3.HermesControlLabel, selector: "label", inputs: ["id", "for"] }, { kind: "directive", type: i5.HermesNativeSelect, selector: "[hermesNativeSelect]" }, { kind: "component", type: i5.HermesNativeSelectContainer, selector: "hermes-native-select-container" }, { kind: "component", type: i4$1.HermesSignpost, selector: "hermes-signpost", inputs: ["hermesSignpostTriggerAriaLabel", "hermesSignpostHideTrigger"] }, { kind: "component", type: i4$1.HermesSignpostContent, selector: "hermes-signpost-content", inputs: ["hermesSignpostCloseAriaLabel", "hermesPosition"] }, { kind: "directive", type: i4$1.HermesSignpostTrigger, selector: "[hermesSignpostTrigger]" }, { kind: "directive", type: i5$1.HermesIfOpen, selector: "[hermesIfOpen]", inputs: ["hermesIfOpen"], outputs: ["hermesIfOpenChange"] }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: DateTimeFilterComponent, selector: "appfx-datetime-filter", inputs: ["propertyFilter", "filterProperty"], outputs: ["filterCriteriaChange"] }, { kind: "directive", type: DismissableDirective, selector: "[dismissable]", inputs: ["dismissAriaLabel"], outputs: ["dismiss"] }, { kind: "component", type: EnumFilterComponent, selector: "appfx-enum-filter", inputs: ["filterProperty", "propertyFilter"], outputs: ["filterCriteriaChange"] }, { kind: "directive", type: FilterPopoverRepositionDirective, selector: "[filterPopoverReposition]" }, { kind: "component", type: GeneralFilterComponent, selector: "appfx-general-filter", inputs: ["propertyFilter", "filterProperty"], outputs: ["filterCriteriaChange"] }, { kind: "component", type: UsersFilterComponent, selector: "appfx-users-filter", inputs: ["filterProperty", "propertyFilter"], outputs: ["filterCriteriaChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2359
+ }
2360
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: ManageFilterComponent, decorators: [{
2361
+ type: Component,
2362
+ args: [{ selector: 'appfx-manage-filter', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!--\r\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\r\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\r\n ~ This software is released under MIT license.\r\n ~ The full license information can be found in LICENSE in the root directory of this project.\r\n -->\r\n<span class=\"label label-blue\">\r\n {{ managedProperty.displayName }}\r\n <span\r\n class=\"badge\"\r\n dismissable\r\n [dismissAriaLabel]=\"\r\n filterStrings.removeFilterText + ' ' + managedProperty.displayName + ' ' + primaryConditionDisplayText\r\n \"\r\n (dismiss)=\"removeFilter(0)\"\r\n >\r\n <hermes-signpost>\r\n <span\r\n hermesSignpostTrigger\r\n class=\"edit-filter\"\r\n tabindex=\"0\"\r\n role=\"button\"\r\n [attr.aria-label]=\"editFilterAriaLabel\"\r\n (keydown)=\"onEditFilterKeyPress($event, 0)\"\r\n >\r\n {{ primaryConditionDisplayText }}\r\n </span>\r\n <ng-template [(hermesIfOpen)]=\"openPrimaryConditionSignPost\">\r\n <hermes-signpost-content [hermesPosition]=\"'bottom-middle'\" filterPopoverReposition>\r\n <hermes-native-select-container class=\"mt-0\">\r\n <label class=\"hermes-control-label\">\r\n {{ this.filterStrings.filterLabel }}\r\n </label>\r\n <select hermesNativeSelect [(ngModel)]=\"managedProperty\" disabled>\r\n <option [ngValue]=\"managedProperty\">\r\n {{ managedProperty.displayName }}\r\n </option>\r\n </select>\r\n </hermes-native-select-container>\r\n @switch (managedPropertyType) {\r\n @case (stringPropertyType) {\r\n <appfx-general-filter\r\n [filterProperty]=\"stringProperty\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-general-filter>\r\n }\r\n @case (numericPropertyType) {\r\n <appfx-general-filter\r\n [filterProperty]=\"numericProperty\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-general-filter>\r\n }\r\n @case (enumPropertyType) {\r\n <appfx-enum-filter\r\n [filterProperty]=\"enumProperty\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-enum-filter>\r\n }\r\n @case (dateTimePropertyType) {\r\n <appfx-datetime-filter\r\n [filterProperty]=\"dateTimeProperty\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-datetime-filter>\r\n }\r\n @case (userPropertyType) {\r\n <appfx-users-filter\r\n [filterProperty]=\"userProperty\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-users-filter>\r\n }\r\n }\r\n </hermes-signpost-content>\r\n </ng-template>\r\n </hermes-signpost>\r\n </span>\r\n @if (propertyFilter.criteria.length === 2 && managedPropertyType !== dateTimePropertyType) {\r\n <span class=\"text-lower\">\r\n {{ this.filterStrings.getConjoinerDisplayName(propertyFilter.operator) }}\r\n </span>\r\n }\r\n @if (propertyFilter.criteria.length === 2 && managedPropertyType !== dateTimePropertyType) {\r\n <span\r\n class=\"badge\"\r\n dismissable\r\n [dismissAriaLabel]=\"\r\n this.filterStrings.removeFilterText + managedProperty.displayName + ' ' + secondaryConditionDisplayText\r\n \"\r\n (dismiss)=\"removeFilter(1)\"\r\n >\r\n <hermes-signpost>\r\n <span\r\n hermesSignpostTrigger\r\n class=\"edit-filter\"\r\n tabindex=\"0\"\r\n role=\"button\"\r\n [attr.aria-label]=\"editFilterAriaLabel\"\r\n (keydown)=\"onEditFilterKeyPress($event, 1)\"\r\n >\r\n {{ secondaryConditionDisplayText }}\r\n </span>\r\n <ng-template [(hermesIfOpen)]=\"openSecondaryConditionSignPost\">\r\n <hermes-signpost-content [hermesPosition]=\"'bottom-middle'\" filterPopoverReposition>\r\n <hermes-native-select-container class=\"mt-0\">\r\n <label class=\"hermes-control-label\">\r\n {{ this.filterStrings.filterLabel }}\r\n </label>\r\n <select hermesNativeSelect [(ngModel)]=\"managedProperty\" disabled>\r\n <option [ngValue]=\"managedProperty\">\r\n {{ managedProperty.displayName }}\r\n </option>\r\n </select>\r\n </hermes-native-select-container>\r\n @switch (managedPropertyType) {\r\n @case (stringPropertyType) {\r\n <appfx-general-filter\r\n [filterProperty]=\"stringProperty\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-general-filter>\r\n }\r\n @case (numericPropertyType) {\r\n <appfx-general-filter\r\n [filterProperty]=\"numericProperty\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-general-filter>\r\n }\r\n @case (enumPropertyType) {\r\n <appfx-enum-filter\r\n [filterProperty]=\"enumProperty\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-enum-filter>\r\n }\r\n @case (userPropertyType) {\r\n <appfx-users-filter\r\n [filterProperty]=\"userProperty\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-users-filter>\r\n }\r\n }\r\n </hermes-signpost-content>\r\n </ng-template>\r\n </hermes-signpost>\r\n </span>\r\n }\r\n</span>\r\n", styles: [".filter-remove-btn{background:transparent;border:none;cursor:pointer}.text-lower{text-transform:lowercase}:host-context(body[data-theme=light]) :host-context(.user-tabbing) .edit-filter:focus,:host-context(body[data-theme=light]) :host-context(.user-tabbing) .remove-filter:focus{outline:2px solid #000}:host-context(body[data-theme=light]) :host-context(.user-tabbing) .edit-filter:focus{outline-offset:1px}:host-context(body[data-theme=dark]) :host-context(.user-tabbing) .edit-filter:focus,:host-context(body[data-theme=dark]) :host-context(.user-tabbing) .remove-filter:focus{outline:2px solid #fafafa}:host-context(body[data-theme=dark]) :host-context(.user-tabbing) .edit-filter:focus{outline-offset:1px}\n", ".form-compact{padding:0;text-align:left;font-weight:400}.form-control-compact{margin-top:.3rem}.btn-compact{min-width:1.2rem;padding:0;margin:0 .4rem}.btn-right{float:right;margin-right:0;margin-top:.9rem;margin-left:.3rem}.mt-half{margin-top:.6rem}.mt-compact{margin-top:.9rem}.mb-compact{margin-bottom:.9rem}.ml-half{margin-left:.6rem}.mt-0{margin-top:0}.mb-0{margin-bottom:0}:host-context(.zoom2x,.zoom4x) .form-max-height{max-height:8rem;overflow-y:auto}select{max-width:18rem;text-overflow:ellipsis}hermes-signpost-content{max-width:20rem}.flex-end-container{display:flex;align-items:flex-end}.flex-container{display:flex}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:var(--hermes-datagrid-loading-background);display:flex;align-items:center;justify-content:center;z-index:10}.loading-content{display:flex;flex-direction:column;align-items:center;gap:.5rem}\n"] }]
2363
+ }], ctorParameters: () => [{ type: DatagridFiltersStrings }], propDecorators: { propertyFilter: [{
2364
+ type: Input
2365
+ }], filterCriteriaChange: [{
2366
+ type: Output
2367
+ }] } });
2368
+
2369
+ /*
2370
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
2371
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
2372
+ * This software is released under MIT license.
2373
+ * The full license information can be found in LICENSE in the root directory of this project.
2374
+ */
2375
+ /**
2376
+ * Pipe used to limit available filter options in a select container.
2377
+ * This is needed in order to prevent applying the same filter more than once
2378
+ */
2379
+ class SkipFiltersPipe {
2380
+ transform(items, propertyDefinitions) {
2381
+ return propertyDefinitions
2382
+ ? items.filter((item) => !propertyDefinitions.includes(item))
2383
+ : items;
2384
+ }
2385
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: SkipFiltersPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
2386
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.22", ngImport: i0, type: SkipFiltersPipe, isStandalone: false, name: "skipFilter" }); }
2387
+ }
2388
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: SkipFiltersPipe, decorators: [{
2389
+ type: Pipe,
2390
+ args: [{
2391
+ name: 'skipFilter',
2392
+ standalone: false,
2393
+ }]
2394
+ }] });
2395
+
2396
+ /*
2397
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
2398
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
2399
+ * This software is released under MIT license.
2400
+ * The full license information can be found in LICENSE in the root directory of this project.
2401
+ */
2402
+ /**
2403
+ * Composite filters component renders different filters based on the type of
2404
+ * the corresponding filterable property, e.g., string, enum, number, etc.
2405
+ */
2406
+ class CompositeFiltersComponent {
2407
+ constructor(filterStrings, cdr) {
2408
+ this.filterStrings = filterStrings;
2409
+ this.cdr = cdr;
2410
+ /**
2411
+ * Event emitter to tell hosting view that the filtering conditions have changed
2412
+ */
2413
+ this.propertyFiltersChange = new EventEmitter();
2414
+ this.stringPropertyType = PropertyType.String;
2415
+ this.enumPropertyType = PropertyType.Enum;
2416
+ this.numericPropertyType = PropertyType.Numeric;
2417
+ this.dateTimePropertyType = PropertyType.DateTime;
2418
+ this.userPropertyType = PropertyType.User;
2419
+ this.signPostOpened = false;
2420
+ // List of active filters to be sent to the hosting view
2421
+ this.propertyFilters = [];
2422
+ this.collapsedFilters = false;
2423
+ this.showHideFiltersArrowDir = 'left';
2424
+ this.showHideFiltersLabel = filterStrings.hideButtonLabel;
2425
+ this.showHideFiltersAriaLabel = filterStrings.hideButtonAriaLabel;
2426
+ }
2427
+ ngOnInit() {
2428
+ if (this.filterableProperties && this.filterableProperties.length > 0) {
2429
+ this.selectedFilterableProperty = this.filterableProperties[0];
2430
+ this.onPropertyChange();
2431
+ }
2432
+ if (this.presetFilters) {
2433
+ this.propertyFilters.push(...this.presetFilters);
2434
+ this.preselectFirstProperty();
2435
+ }
2436
+ }
2437
+ onPropertyChange() {
2438
+ if (this.isStringProperty(this.selectedFilterableProperty)) {
2439
+ this.propertyType = PropertyType.String;
2440
+ this.stringProperty = this.castStringProperty();
2441
+ }
2442
+ else if (this.isEnumProperty(this.selectedFilterableProperty)) {
2443
+ this.propertyType = PropertyType.Enum;
2444
+ this.enumProperty = this.castEnumProperty();
2445
+ }
2446
+ else if (this.isNumericProperty(this.selectedFilterableProperty)) {
2447
+ this.propertyType = PropertyType.Numeric;
2448
+ this.numericProperty = this.castNumericProperty();
2449
+ }
2450
+ else if (this.isDateTimeProperty(this.selectedFilterableProperty)) {
2451
+ this.propertyType = PropertyType.DateTime;
2452
+ this.dateTimeProperty = this.castDateTimeProperty();
2453
+ }
2454
+ else if (this.isUserProperty(this.selectedFilterableProperty)) {
2455
+ this.propertyType = PropertyType.User;
2456
+ this.userProperty = this.castUserProperty();
2457
+ }
2458
+ }
2459
+ onFilterCriteriaChange(propertyFilter) {
2460
+ if (propertyFilter) {
2461
+ if (propertyFilter.criteria.length > 0) {
2462
+ // The property filter contains several filtering criteria.
2463
+ // This is either a new filter, or some of the criteria are modified
2464
+ let i = this.propertyFilters.length;
2465
+ let modified = false;
2466
+ while (i--) {
2467
+ // Check whether there is an existing filter for the same property.
2468
+ // If found, replace it with the new filter
2469
+ if (this.propertyFilters[i].criteria[0].filterableProperty.property ===
2470
+ propertyFilter.criteria[0].filterableProperty.property) {
2471
+ this.propertyFilters[i] = propertyFilter;
2472
+ modified = true;
2473
+ }
2474
+ }
2475
+ // If no existing filter was found, add the new one to the active filters list
2476
+ if (!modified) {
2477
+ this.propertyFilters.push(propertyFilter);
2478
+ }
2479
+ }
2480
+ else {
2481
+ // The property filter does not contain any criteria.
2482
+ // It should be removed from the active filters list
2483
+ let j = this.propertyFilters.length;
2484
+ while (j--) {
2485
+ if (this.propertyFilters[j].criteria.length === 0) {
2486
+ this.propertyFilters.splice(j, 1);
2487
+ }
2488
+ }
2489
+ }
2490
+ this.propertyFiltersChange.emit(this.propertyFilters);
2491
+ }
2492
+ this.signPostOpened = false;
2493
+ this.preselectFirstProperty();
2494
+ this.updateShowHideLabel();
2495
+ // The filter sometimes fails to close, necessitating
2496
+ // a check to detect this state change.
2497
+ this.cdr.markForCheck();
2498
+ }
2499
+ /**
2500
+ * Returns a list properties for which there is an active filter
2501
+ */
2502
+ activeFilters() {
2503
+ const activeProperties = [];
2504
+ this.propertyFilters.forEach(value => {
2505
+ if (value.criteria.length > 0) {
2506
+ activeProperties.push(value.criteria[0].filterableProperty);
2507
+ }
2508
+ });
2509
+ return activeProperties;
2510
+ }
2511
+ clearAllFilters() {
2512
+ this.propertyFilters = [];
2513
+ this.propertyFiltersChange.emit(this.propertyFilters);
2514
+ this.preselectFirstProperty();
2515
+ this.collapsedFilters = false;
2516
+ }
2517
+ showHideAllFilters() {
2518
+ this.collapsedFilters = !this.collapsedFilters;
2519
+ this.updateShowHideLabel();
2520
+ this.showHideFiltersArrowDir = this.collapsedFilters ? 'right' : 'left';
2521
+ }
2522
+ /**
2523
+ * Active filters are not displayed in the new filters list.
2524
+ * We want to preselect the first displayed property
2525
+ */
2526
+ preselectFirstProperty() {
2527
+ const activeProperties = this.activeFilters();
2528
+ const remainingProperties = this.filterableProperties.filter(property => !activeProperties.includes(property));
2529
+ if (remainingProperties.length > 0) {
2530
+ this.selectedFilterableProperty = remainingProperties[0];
2531
+ this.onPropertyChange();
2532
+ }
2533
+ }
2534
+ updateShowHideLabel() {
2535
+ this.showHideFiltersLabel = this.collapsedFilters
2536
+ ? this.filterStrings.showButtonLabel + '(' + this.propertyFilters.length + ')'
2537
+ : this.filterStrings.hideButtonLabel;
2538
+ this.showHideFiltersAriaLabel = this.collapsedFilters
2539
+ ? this.filterStrings.showButtonLabel +
2540
+ ' ' +
2541
+ this.propertyFilters.length +
2542
+ ' ' +
2543
+ (this.propertyFilters.length > 1 ? this.filterStrings.filtersText : this.filterStrings.filterText)
2544
+ : this.filterStrings.hideButtonAriaLabel;
2545
+ }
2546
+ isStringProperty(property) {
2547
+ return property instanceof StringPropertyDefinition;
2548
+ }
2549
+ isEnumProperty(property) {
2550
+ return property instanceof EnumPropertyDefinition;
2551
+ }
2552
+ isNumericProperty(property) {
2553
+ return property instanceof NumericPropertyDefinition;
2554
+ }
2555
+ isDateTimeProperty(property) {
2556
+ return property instanceof DateTimePropertyDefinition;
2557
+ }
2558
+ isUserProperty(property) {
2559
+ return property instanceof UserPropertyDefinition;
2560
+ }
2561
+ castStringProperty() {
2562
+ return this.selectedFilterableProperty;
2563
+ }
2564
+ castEnumProperty() {
2565
+ return this.selectedFilterableProperty;
2566
+ }
2567
+ castNumericProperty() {
2568
+ return this.selectedFilterableProperty;
2569
+ }
2570
+ castDateTimeProperty() {
2571
+ return this.selectedFilterableProperty;
2572
+ }
2573
+ castUserProperty() {
2574
+ return this.selectedFilterableProperty;
2575
+ }
2576
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: CompositeFiltersComponent, deps: [{ token: DatagridFiltersStrings }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
2577
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: CompositeFiltersComponent, isStandalone: false, selector: "appfx-composite-filter", inputs: { filterableProperties: "filterableProperties", presetFilters: "presetFilters" }, outputs: { propertyFiltersChange: "propertyFiltersChange" }, ngImport: i0, template: "<!--\r\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\r\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\r\n ~ This software is released under MIT license.\r\n ~ The full license information can be found in LICENSE in the root directory of this project.\r\n -->\r\n<div class=\"composite-filter-container\">\r\n <hermes-signpost class=\"height-standard\">\r\n <button\r\n hermesSignpostTrigger\r\n class=\"btn btn-sm btn-link btn-compact\"\r\n data-test-id=\"add-button\"\r\n [attr.aria-label]=\"filterStrings.addNewAriaLabel\"\r\n [disabled]=\"filterableProperties.length === propertyFilters.length\"\r\n >\r\n <hermes-icon size=\"20\" shape=\"filter-grid\" class=\"is-solid\"></hermes-icon>\r\n {{ filterStrings.addNew }}\r\n </button>\r\n <ng-template [(hermesIfOpen)]=\"signPostOpened\">\r\n <hermes-signpost-content\r\n cdkTrapFocus\r\n [cdkTrapFocusAutoCapture]=\"true\"\r\n [hermesPosition]=\"'bottom-middle'\"\r\n filterPopoverReposition\r\n >\r\n <hermes-native-select-container class=\"mt-0\">\r\n <label class=\"hermes-control-label\"> {{ filterStrings.filterLabel }} </label>\r\n <select hermesNativeSelect [(ngModel)]=\"selectedFilterableProperty\" (ngModelChange)=\"onPropertyChange()\">\r\n @for (property of filterableProperties | skipFilter: activeFilters(); track property) {\r\n <option [ngValue]=\"property\">\r\n {{ property.displayName }}\r\n </option>\r\n }\r\n </select>\r\n </hermes-native-select-container>\r\n @switch (propertyType) {\r\n @case (stringPropertyType) {\r\n <appfx-general-filter\r\n [filterProperty]=\"stringProperty\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-general-filter>\r\n }\r\n @case (numericPropertyType) {\r\n <appfx-general-filter\r\n [filterProperty]=\"numericProperty\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-general-filter>\r\n }\r\n @case (enumPropertyType) {\r\n <appfx-enum-filter [filterProperty]=\"enumProperty\" (filterCriteriaChange)=\"onFilterCriteriaChange($event)\">\r\n </appfx-enum-filter>\r\n }\r\n @case (dateTimePropertyType) {\r\n <appfx-datetime-filter\r\n [filterProperty]=\"dateTimeProperty\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-datetime-filter>\r\n }\r\n @case (userPropertyType) {\r\n <appfx-users-filter [filterProperty]=\"userProperty\" (filterCriteriaChange)=\"onFilterCriteriaChange($event)\">\r\n </appfx-users-filter>\r\n }\r\n }\r\n </hermes-signpost-content>\r\n </ng-template>\r\n </hermes-signpost>\r\n @if (propertyFilters.length > 0) {\r\n <div class=\"manage-filter-container\">\r\n @for (propertyFilter of propertyFilters; track propertyFilter) {\r\n <appfx-manage-filter\r\n [hidden]=\"collapsedFilters\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-manage-filter>\r\n }\r\n <button\r\n class=\"btn btn-sm btn-link btn-compact\"\r\n data-test-id=\"hide-filters\"\r\n [attr.aria-label]=\"showHideFiltersAriaLabel\"\r\n (click)=\"showHideAllFilters()\"\r\n >\r\n <hermes-icon shape=\"angle\" class=\"is-solid\" [direction]=\"showHideFiltersArrowDir\"></hermes-icon>\r\n {{ showHideFiltersLabel }}\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-link btn-compact\"\r\n data-test-id=\"clear-all-button\"\r\n [attr.aria-label]=\"filterStrings.clearAllButtonAriaLabel\"\r\n (click)=\"clearAllFilters()\"\r\n >\r\n {{ filterStrings.clearAllButtonLabel }}\r\n </button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".composite-filter-container{display:flex}.height-standard{height:1.2rem}.manage-filter-container{display:flex;flex-wrap:wrap}:host-context(.zoom2x,.zoom4x) .composite-filter-container,:host-context(.zoom2x,.zoom4x) .manage-filter-container{display:contents}\n", ".form-compact{padding:0;text-align:left;font-weight:400}.form-control-compact{margin-top:.3rem}.btn-compact{min-width:1.2rem;padding:0;margin:0 .4rem}.btn-right{float:right;margin-right:0;margin-top:.9rem;margin-left:.3rem}.mt-half{margin-top:.6rem}.mt-compact{margin-top:.9rem}.mb-compact{margin-bottom:.9rem}.ml-half{margin-left:.6rem}.mt-0{margin-top:0}.mb-0{margin-bottom:0}:host-context(.zoom2x,.zoom4x) .form-max-height{max-height:8rem;overflow-y:auto}select{max-width:18rem;text-overflow:ellipsis}hermes-signpost-content{max-width:20rem}.flex-end-container{display:flex;align-items:flex-end}.flex-container{display:flex}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:var(--hermes-datagrid-loading-background);display:flex;align-items:center;justify-content:center;z-index:10}.loading-content{display:flex;flex-direction:column;align-items:center;gap:.5rem}\n"], dependencies: [{ kind: "directive", type: i2$1.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "directive", type: i3.HermesControlLabel, selector: "label", inputs: ["id", "for"] }, { kind: "component", type: i4.HermesIcon, selector: "hermes-icon, hermes-icon", inputs: ["shape", "size", "direction", "flip", "solid", "status", "inverse", "badge"] }, { kind: "directive", type: i5.HermesNativeSelect, selector: "[hermesNativeSelect]" }, { kind: "component", type: i5.HermesNativeSelectContainer, selector: "hermes-native-select-container" }, { kind: "component", type: i4$1.HermesSignpost, selector: "hermes-signpost", inputs: ["hermesSignpostTriggerAriaLabel", "hermesSignpostHideTrigger"] }, { kind: "component", type: i4$1.HermesSignpostContent, selector: "hermes-signpost-content", inputs: ["hermesSignpostCloseAriaLabel", "hermesPosition"] }, { kind: "directive", type: i4$1.HermesSignpostTrigger, selector: "[hermesSignpostTrigger]" }, { kind: "directive", type: i5$1.HermesIfOpen, selector: "[hermesIfOpen]", inputs: ["hermesIfOpen"], outputs: ["hermesIfOpenChange"] }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: DateTimeFilterComponent, selector: "appfx-datetime-filter", inputs: ["propertyFilter", "filterProperty"], outputs: ["filterCriteriaChange"] }, { kind: "component", type: EnumFilterComponent, selector: "appfx-enum-filter", inputs: ["filterProperty", "propertyFilter"], outputs: ["filterCriteriaChange"] }, { kind: "directive", type: FilterPopoverRepositionDirective, selector: "[filterPopoverReposition]" }, { kind: "component", type: GeneralFilterComponent, selector: "appfx-general-filter", inputs: ["propertyFilter", "filterProperty"], outputs: ["filterCriteriaChange"] }, { kind: "component", type: ManageFilterComponent, selector: "appfx-manage-filter", inputs: ["propertyFilter"], outputs: ["filterCriteriaChange"] }, { kind: "component", type: UsersFilterComponent, selector: "appfx-users-filter", inputs: ["filterProperty", "propertyFilter"], outputs: ["filterCriteriaChange"] }, { kind: "pipe", type: SkipFiltersPipe, name: "skipFilter" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2578
+ }
2579
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: CompositeFiltersComponent, decorators: [{
2580
+ type: Component,
2581
+ args: [{ selector: 'appfx-composite-filter', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!--\r\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\r\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\r\n ~ This software is released under MIT license.\r\n ~ The full license information can be found in LICENSE in the root directory of this project.\r\n -->\r\n<div class=\"composite-filter-container\">\r\n <hermes-signpost class=\"height-standard\">\r\n <button\r\n hermesSignpostTrigger\r\n class=\"btn btn-sm btn-link btn-compact\"\r\n data-test-id=\"add-button\"\r\n [attr.aria-label]=\"filterStrings.addNewAriaLabel\"\r\n [disabled]=\"filterableProperties.length === propertyFilters.length\"\r\n >\r\n <hermes-icon size=\"20\" shape=\"filter-grid\" class=\"is-solid\"></hermes-icon>\r\n {{ filterStrings.addNew }}\r\n </button>\r\n <ng-template [(hermesIfOpen)]=\"signPostOpened\">\r\n <hermes-signpost-content\r\n cdkTrapFocus\r\n [cdkTrapFocusAutoCapture]=\"true\"\r\n [hermesPosition]=\"'bottom-middle'\"\r\n filterPopoverReposition\r\n >\r\n <hermes-native-select-container class=\"mt-0\">\r\n <label class=\"hermes-control-label\"> {{ filterStrings.filterLabel }} </label>\r\n <select hermesNativeSelect [(ngModel)]=\"selectedFilterableProperty\" (ngModelChange)=\"onPropertyChange()\">\r\n @for (property of filterableProperties | skipFilter: activeFilters(); track property) {\r\n <option [ngValue]=\"property\">\r\n {{ property.displayName }}\r\n </option>\r\n }\r\n </select>\r\n </hermes-native-select-container>\r\n @switch (propertyType) {\r\n @case (stringPropertyType) {\r\n <appfx-general-filter\r\n [filterProperty]=\"stringProperty\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-general-filter>\r\n }\r\n @case (numericPropertyType) {\r\n <appfx-general-filter\r\n [filterProperty]=\"numericProperty\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-general-filter>\r\n }\r\n @case (enumPropertyType) {\r\n <appfx-enum-filter [filterProperty]=\"enumProperty\" (filterCriteriaChange)=\"onFilterCriteriaChange($event)\">\r\n </appfx-enum-filter>\r\n }\r\n @case (dateTimePropertyType) {\r\n <appfx-datetime-filter\r\n [filterProperty]=\"dateTimeProperty\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-datetime-filter>\r\n }\r\n @case (userPropertyType) {\r\n <appfx-users-filter [filterProperty]=\"userProperty\" (filterCriteriaChange)=\"onFilterCriteriaChange($event)\">\r\n </appfx-users-filter>\r\n }\r\n }\r\n </hermes-signpost-content>\r\n </ng-template>\r\n </hermes-signpost>\r\n @if (propertyFilters.length > 0) {\r\n <div class=\"manage-filter-container\">\r\n @for (propertyFilter of propertyFilters; track propertyFilter) {\r\n <appfx-manage-filter\r\n [hidden]=\"collapsedFilters\"\r\n [propertyFilter]=\"propertyFilter\"\r\n (filterCriteriaChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-manage-filter>\r\n }\r\n <button\r\n class=\"btn btn-sm btn-link btn-compact\"\r\n data-test-id=\"hide-filters\"\r\n [attr.aria-label]=\"showHideFiltersAriaLabel\"\r\n (click)=\"showHideAllFilters()\"\r\n >\r\n <hermes-icon shape=\"angle\" class=\"is-solid\" [direction]=\"showHideFiltersArrowDir\"></hermes-icon>\r\n {{ showHideFiltersLabel }}\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-link btn-compact\"\r\n data-test-id=\"clear-all-button\"\r\n [attr.aria-label]=\"filterStrings.clearAllButtonAriaLabel\"\r\n (click)=\"clearAllFilters()\"\r\n >\r\n {{ filterStrings.clearAllButtonLabel }}\r\n </button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".composite-filter-container{display:flex}.height-standard{height:1.2rem}.manage-filter-container{display:flex;flex-wrap:wrap}:host-context(.zoom2x,.zoom4x) .composite-filter-container,:host-context(.zoom2x,.zoom4x) .manage-filter-container{display:contents}\n", ".form-compact{padding:0;text-align:left;font-weight:400}.form-control-compact{margin-top:.3rem}.btn-compact{min-width:1.2rem;padding:0;margin:0 .4rem}.btn-right{float:right;margin-right:0;margin-top:.9rem;margin-left:.3rem}.mt-half{margin-top:.6rem}.mt-compact{margin-top:.9rem}.mb-compact{margin-bottom:.9rem}.ml-half{margin-left:.6rem}.mt-0{margin-top:0}.mb-0{margin-bottom:0}:host-context(.zoom2x,.zoom4x) .form-max-height{max-height:8rem;overflow-y:auto}select{max-width:18rem;text-overflow:ellipsis}hermes-signpost-content{max-width:20rem}.flex-end-container{display:flex;align-items:flex-end}.flex-container{display:flex}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:var(--hermes-datagrid-loading-background);display:flex;align-items:center;justify-content:center;z-index:10}.loading-content{display:flex;flex-direction:column;align-items:center;gap:.5rem}\n"] }]
2582
+ }], ctorParameters: () => [{ type: DatagridFiltersStrings }, { type: i0.ChangeDetectorRef }], propDecorators: { filterableProperties: [{
2583
+ type: Input
2584
+ }], presetFilters: [{
2585
+ type: Input
2586
+ }], propertyFiltersChange: [{
2587
+ type: Output
2588
+ }] } });
2589
+
2590
+ /*
2591
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
2592
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
2593
+ * This software is released under MIT license.
2594
+ * The full license information can be found in LICENSE in the root directory of this project.
2595
+ */
2596
+ const enterKey = 'Enter';
2597
+ const searchTermDebounceTimeMs = 2000;
2598
+ /**
2599
+ * Component provides the ability to choose from quick filter (search)
2600
+ * and advanced filter (composite filters).
2601
+ */
2602
+ class DataGridFiltersComponent {
2603
+ constructor(filterStrings) {
2604
+ this.filterStrings = filterStrings;
2605
+ this.quickMode = FilterMode.Quick;
2606
+ this.advancedMode = FilterMode.Advanced;
2607
+ this.advancedOnlyMode = FilterMode.AdvancedOnly;
2608
+ this.mode = FilterMode.Quick;
2609
+ this.selectedFilterMode = FilterMode.Quick;
2610
+ this.searchTerm = '';
2611
+ /**
2612
+ * Event emitter to tell hosting view that search term, used for filtering
2613
+ * has changed.
2614
+ */
2615
+ this.searchTermChange = new EventEmitter();
2616
+ this.propertyFiltersChange = new EventEmitter();
2617
+ this.lastSearchTerm = '';
2618
+ // When the user is typing in the search input (filter)
2619
+ // the search term change event will be fired
2620
+ // on every 2 sec.
2621
+ this.searchTermDebouncer = new Subject();
2622
+ this.unsubscribeSubject = new Subject();
2623
+ this.appliedFiltersCount = 0;
2624
+ }
2625
+ /**
2626
+ * Quick, Advanced or AdvancedOnly. Default Quick.
2627
+ */
2628
+ set filterMode(filterMode) {
2629
+ if (filterMode !== null && filterMode !== undefined) {
2630
+ this.mode = filterMode;
2631
+ }
2632
+ }
2633
+ ngAfterViewInit() {
2634
+ this.searchTermDebouncer
2635
+ .pipe(debounceTime(searchTermDebounceTimeMs), distinctUntilChanged(), takeUntil(this.unsubscribeSubject))
2636
+ .subscribe((search) => {
2637
+ this.doSearch(search);
2638
+ });
2639
+ }
2640
+ ngOnDestroy() {
2641
+ this.unsubscribeSubject.next();
2642
+ this.unsubscribeSubject.complete();
2643
+ }
2644
+ onFilterModeChange() {
2645
+ // Reset quick search data when switching to advanced mode
2646
+ if (this.selectedFilterMode === FilterMode.Advanced && !!this.searchTerm) {
2647
+ this.searchTerm = '';
2648
+ this.doSearch(this.searchTerm);
2649
+ // Clear debouncer last value
2650
+ this.searchTermDebouncer.next(this.searchTerm);
2651
+ }
2652
+ // Clear applied filters when switching to quick mode
2653
+ if (this.selectedFilterMode === FilterMode.Quick && this.appliedFiltersCount > 0) {
2654
+ this.appliedFiltersCount = 0;
2655
+ this.propertyFiltersChange.emit([]);
2656
+ }
2657
+ }
2658
+ onFilterCriteriaChange(propertyFilters) {
2659
+ this.appliedFiltersCount = propertyFilters.length;
2660
+ this.propertyFiltersChange.emit(propertyFilters);
2661
+ }
2662
+ onSearchInputKeyPress(event) {
2663
+ if (event.key === enterKey) {
2664
+ this.doSearch(this.searchTerm);
2665
+ }
2666
+ }
2667
+ onSearchTermChanged(searchTerm) {
2668
+ this.searchTerm = searchTerm;
2669
+ this.searchTermDebouncer.next(this.searchTerm);
2670
+ }
2671
+ doSearch(search) {
2672
+ search = search.trim();
2673
+ if (this.lastSearchTerm !== search) {
2674
+ this.lastSearchTerm = search;
2675
+ this.searchTermChange.emit(search);
2676
+ }
2677
+ }
2678
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: DataGridFiltersComponent, deps: [{ token: DatagridFiltersStrings }], target: i0.ɵɵFactoryTarget.Component }); }
2679
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: DataGridFiltersComponent, isStandalone: false, selector: "appfx-datagrid-filters", inputs: { filterableProperties: "filterableProperties", presetFilters: "presetFilters", filterMode: "filterMode" }, outputs: { searchTermChange: "searchTermChange", propertyFiltersChange: "propertyFiltersChange" }, ngImport: i0, template: "<!--\r\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\r\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\r\n ~ This software is released under MIT license.\r\n ~ The full license information can be found in LICENSE in the root directory of this project.\r\n -->\r\n<div data-test-id=\"appfx-advanced-datagrid-filter\" class=\"filter-container\">\r\n @switch (mode) {\r\n @case (quickMode) {\r\n <label class=\"hermes-control-label form-control-compact\">\r\n {{ filterStrings.quickFilter }}\r\n </label>\r\n }\r\n @case (advancedOnlyMode) {\r\n <label class=\"hermes-control-label form-control-compact\">\r\n {{ filterStrings.advancedFilter }}\r\n </label>\r\n }\r\n @case (advancedMode) {\r\n <hermes-native-select-container class=\"form-control-compact\">\r\n <select\r\n [attr.aria-label]=\"filterStrings.filterType\"\r\n hermesNativeSelect\r\n [(ngModel)]=\"selectedFilterMode\"\r\n (ngModelChange)=\"onFilterModeChange()\"\r\n >\r\n <option [ngValue]=\"quickMode\">{{ filterStrings.quickFilter }}</option>\r\n <option [ngValue]=\"advancedMode\">{{ filterStrings.advancedFilter }}</option>\r\n </select>\r\n </hermes-native-select-container>\r\n }\r\n }\r\n @if (selectedFilterMode === quickMode && mode !== advancedOnlyMode) {\r\n <hermes-input-container class=\"ml-half form-control-compact\">\r\n <label class=\"hermes-sr-only\"> {{ filterStrings.quickFilter }} </label>\r\n <input\r\n type=\"text\"\r\n (keydown)=\"onSearchInputKeyPress($event)\"\r\n [ngModel]=\"searchTerm\"\r\n (ngModelChange)=\"onSearchTermChanged($event)\"\r\n placeholder=\"{{ filterStrings.enterValue }}\"\r\n hermesInput\r\n />\r\n </hermes-input-container>\r\n }\r\n @if (selectedFilterMode === advancedMode || mode === advancedOnlyMode) {\r\n <appfx-composite-filter\r\n class=\"filter-contents\"\r\n [filterableProperties]=\"filterableProperties\"\r\n [presetFilters]=\"presetFilters\"\r\n (propertyFiltersChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-composite-filter>\r\n }\r\n</div>\r\n", styles: [".filter-container{display:flex;align-items:baseline;margin-left:.2rem}:host-context(.zoom2x,.zoom4x) .filter-container{flex-wrap:wrap}:host-context(.zoom2x,.zoom4x) .filter-contents{display:contents}\n", ".form-compact{padding:0;text-align:left;font-weight:400}.form-control-compact{margin-top:.3rem}.btn-compact{min-width:1.2rem;padding:0;margin:0 .4rem}.btn-right{float:right;margin-right:0;margin-top:.9rem;margin-left:.3rem}.mt-half{margin-top:.6rem}.mt-compact{margin-top:.9rem}.mb-compact{margin-bottom:.9rem}.ml-half{margin-left:.6rem}.mt-0{margin-top:0}.mb-0{margin-bottom:0}:host-context(.zoom2x,.zoom4x) .form-max-height{max-height:8rem;overflow-y:auto}select{max-width:18rem;text-overflow:ellipsis}hermes-signpost-content{max-width:20rem}.flex-end-container{display:flex;align-items:flex-end}.flex-container{display:flex}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:var(--hermes-datagrid-loading-background);display:flex;align-items:center;justify-content:center;z-index:10}.loading-content{display:flex;flex-direction:column;align-items:center;gap:.5rem}\n"], dependencies: [{ kind: "directive", type: i3.HermesControlLabel, selector: "label", inputs: ["id", "for"] }, { kind: "directive", type: i5.HermesInput, selector: "[hermesInput]" }, { kind: "component", type: i5.HermesInputContainer, selector: "hermes-input-container" }, { kind: "directive", type: i5.HermesNativeSelect, selector: "[hermesNativeSelect]" }, { kind: "component", type: i5.HermesNativeSelectContainer, selector: "hermes-native-select-container" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CompositeFiltersComponent, selector: "appfx-composite-filter", inputs: ["filterableProperties", "presetFilters"], outputs: ["propertyFiltersChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2680
+ }
2681
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: DataGridFiltersComponent, decorators: [{
2682
+ type: Component,
2683
+ args: [{ selector: 'appfx-datagrid-filters', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!--\r\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\r\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\r\n ~ This software is released under MIT license.\r\n ~ The full license information can be found in LICENSE in the root directory of this project.\r\n -->\r\n<div data-test-id=\"appfx-advanced-datagrid-filter\" class=\"filter-container\">\r\n @switch (mode) {\r\n @case (quickMode) {\r\n <label class=\"hermes-control-label form-control-compact\">\r\n {{ filterStrings.quickFilter }}\r\n </label>\r\n }\r\n @case (advancedOnlyMode) {\r\n <label class=\"hermes-control-label form-control-compact\">\r\n {{ filterStrings.advancedFilter }}\r\n </label>\r\n }\r\n @case (advancedMode) {\r\n <hermes-native-select-container class=\"form-control-compact\">\r\n <select\r\n [attr.aria-label]=\"filterStrings.filterType\"\r\n hermesNativeSelect\r\n [(ngModel)]=\"selectedFilterMode\"\r\n (ngModelChange)=\"onFilterModeChange()\"\r\n >\r\n <option [ngValue]=\"quickMode\">{{ filterStrings.quickFilter }}</option>\r\n <option [ngValue]=\"advancedMode\">{{ filterStrings.advancedFilter }}</option>\r\n </select>\r\n </hermes-native-select-container>\r\n }\r\n }\r\n @if (selectedFilterMode === quickMode && mode !== advancedOnlyMode) {\r\n <hermes-input-container class=\"ml-half form-control-compact\">\r\n <label class=\"hermes-sr-only\"> {{ filterStrings.quickFilter }} </label>\r\n <input\r\n type=\"text\"\r\n (keydown)=\"onSearchInputKeyPress($event)\"\r\n [ngModel]=\"searchTerm\"\r\n (ngModelChange)=\"onSearchTermChanged($event)\"\r\n placeholder=\"{{ filterStrings.enterValue }}\"\r\n hermesInput\r\n />\r\n </hermes-input-container>\r\n }\r\n @if (selectedFilterMode === advancedMode || mode === advancedOnlyMode) {\r\n <appfx-composite-filter\r\n class=\"filter-contents\"\r\n [filterableProperties]=\"filterableProperties\"\r\n [presetFilters]=\"presetFilters\"\r\n (propertyFiltersChange)=\"onFilterCriteriaChange($event)\"\r\n >\r\n </appfx-composite-filter>\r\n }\r\n</div>\r\n", styles: [".filter-container{display:flex;align-items:baseline;margin-left:.2rem}:host-context(.zoom2x,.zoom4x) .filter-container{flex-wrap:wrap}:host-context(.zoom2x,.zoom4x) .filter-contents{display:contents}\n", ".form-compact{padding:0;text-align:left;font-weight:400}.form-control-compact{margin-top:.3rem}.btn-compact{min-width:1.2rem;padding:0;margin:0 .4rem}.btn-right{float:right;margin-right:0;margin-top:.9rem;margin-left:.3rem}.mt-half{margin-top:.6rem}.mt-compact{margin-top:.9rem}.mb-compact{margin-bottom:.9rem}.ml-half{margin-left:.6rem}.mt-0{margin-top:0}.mb-0{margin-bottom:0}:host-context(.zoom2x,.zoom4x) .form-max-height{max-height:8rem;overflow-y:auto}select{max-width:18rem;text-overflow:ellipsis}hermes-signpost-content{max-width:20rem}.flex-end-container{display:flex;align-items:flex-end}.flex-container{display:flex}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:var(--hermes-datagrid-loading-background);display:flex;align-items:center;justify-content:center;z-index:10}.loading-content{display:flex;flex-direction:column;align-items:center;gap:.5rem}\n"] }]
2684
+ }], ctorParameters: () => [{ type: DatagridFiltersStrings }], propDecorators: { filterableProperties: [{
2685
+ type: Input
2686
+ }], presetFilters: [{
2687
+ type: Input
2688
+ }], searchTermChange: [{
2689
+ type: Output
2690
+ }], propertyFiltersChange: [{
2691
+ type: Output
2692
+ }], filterMode: [{
2693
+ type: Input
2694
+ }] } });
2695
+
2696
+ /*
2697
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
2698
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
2699
+ * This software is released under MIT license.
2700
+ * The full license information can be found in LICENSE in the root directory of this project.
2701
+ */
2702
+ function datagridFiltersStringsServiceFactory(existing) {
2703
+ return existing || new DatagridFiltersStrings();
2704
+ }
2705
+ function datagridFiltersUserServiceFactory(existing) {
2706
+ return existing || new DatagridFiltersUserService();
2707
+ }
2708
+ class AppfxDatagridFiltersModule {
2709
+ constructor() {
2710
+ ClarityIcons.addIcons(angleIcon, filterGridIcon, plusIcon, searchIcon, windowCloseIcon);
2711
+ }
2712
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: AppfxDatagridFiltersModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2713
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.22", ngImport: i0, type: AppfxDatagridFiltersModule, declarations: [CompositeFiltersComponent,
2714
+ DataGridFiltersComponent,
2715
+ DateTimeFilterComponent,
2716
+ DismissableDirective,
2717
+ EnumFilterComponent,
2718
+ FilterFormComponent,
2719
+ FilterPopoverRepositionDirective,
2720
+ GeneralFilterComponent,
2721
+ ManageFilterComponent,
2722
+ SkipFiltersPipe,
2723
+ UsersFilterComponent], imports: [A11yModule,
2724
+ HermesCheckboxModule,
2725
+ HermesIcon,
2726
+ HermesInputModule,
2727
+ HermesRadioModule,
2728
+ HermesNativeSelectModule,
2729
+ HermesSignpostModule,
2730
+ HermesSpinnerModule,
2731
+ CommonModule,
2732
+ FormsModule,
2733
+ ReactiveFormsModule], exports: [CompositeFiltersComponent, DataGridFiltersComponent, FilterFormComponent] }); }
2734
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: AppfxDatagridFiltersModule, providers: [
2735
+ DatePipe,
2736
+ {
2737
+ // This pattern allows the importer of this module to specify its own DatagridFiltersStrings.
2738
+ provide: DatagridFiltersStrings,
2739
+ useFactory: datagridFiltersStringsServiceFactory,
2740
+ deps: [[new Optional(), new SkipSelf(), DatagridFiltersStrings]],
2741
+ },
2742
+ {
2743
+ provide: DatagridFiltersUserService,
2744
+ useFactory: datagridFiltersUserServiceFactory,
2745
+ deps: [[new Optional(), new SkipSelf(), DatagridFiltersUserService]],
2746
+ },
2747
+ ], imports: [A11yModule,
2748
+ HermesCheckboxModule,
2749
+ HermesIcon,
2750
+ HermesInputModule,
2751
+ HermesRadioModule,
2752
+ HermesNativeSelectModule,
2753
+ HermesSignpostModule,
2754
+ HermesSpinnerModule,
2755
+ CommonModule,
2756
+ FormsModule,
2757
+ ReactiveFormsModule] }); }
2758
+ }
2759
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: AppfxDatagridFiltersModule, decorators: [{
2760
+ type: NgModule,
2761
+ args: [{
2762
+ declarations: [
2763
+ CompositeFiltersComponent,
2764
+ DataGridFiltersComponent,
2765
+ DateTimeFilterComponent,
2766
+ DismissableDirective,
2767
+ EnumFilterComponent,
2768
+ FilterFormComponent,
2769
+ FilterPopoverRepositionDirective,
2770
+ GeneralFilterComponent,
2771
+ ManageFilterComponent,
2772
+ SkipFiltersPipe,
2773
+ UsersFilterComponent,
2774
+ ],
2775
+ imports: [
2776
+ A11yModule,
2777
+ HermesCheckboxModule,
2778
+ HermesIcon,
2779
+ HermesInputModule,
2780
+ HermesRadioModule,
2781
+ HermesNativeSelectModule,
2782
+ HermesSignpostModule,
2783
+ HermesSpinnerModule,
2784
+ CommonModule,
2785
+ FormsModule,
2786
+ ReactiveFormsModule,
2787
+ ],
2788
+ exports: [CompositeFiltersComponent, DataGridFiltersComponent, FilterFormComponent],
2789
+ providers: [
2790
+ DatePipe,
2791
+ {
2792
+ // This pattern allows the importer of this module to specify its own DatagridFiltersStrings.
2793
+ provide: DatagridFiltersStrings,
2794
+ useFactory: datagridFiltersStringsServiceFactory,
2795
+ deps: [[new Optional(), new SkipSelf(), DatagridFiltersStrings]],
2796
+ },
2797
+ {
2798
+ provide: DatagridFiltersUserService,
2799
+ useFactory: datagridFiltersUserServiceFactory,
2800
+ deps: [[new Optional(), new SkipSelf(), DatagridFiltersUserService]],
2801
+ },
2802
+ ],
2803
+ }]
2804
+ }], ctorParameters: () => [] });
2805
+
2806
+ /*
2807
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
2808
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
2809
+ * This software is released under MIT license.
2810
+ * The full license information can be found in LICENSE in the root directory of this project.
2811
+ */
2812
+
2813
+ /**
2814
+ * Generated bundle index. Do not edit.
2815
+ */
2816
+
2817
+ export { AppfxDatagridFiltersModule, ComparisonOperator, CompositeFiltersComponent, DataGridFiltersComponent, AppfxDatagridFiltersModule as DatagridFiltersModule, DatagridFiltersStrings, DatagridFiltersUserService, DateTimePropertyDefinition, EnumPropertyDefinition, FilterFormComponent, FilterMode, FilterablePropertyDefinition, LogicalOperator, NumericPropertyDefinition, PropertyFilter, PropertyPredicate, PropertyType, StringPropertyDefinition, Unit, UserPropertyDefinition };
2818
+ //# sourceMappingURL=hermes-ui-angular-addons-datagrid-filters.mjs.map