@tuki-io/tuki-widgets 0.0.219-dev.6 → 0.0.219-dev.60

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 (261) hide show
  1. package/contact-center/cc-import/cc-import.module.d.ts +13 -0
  2. package/contact-center/cc-import/cc-import.service.d.ts +85 -0
  3. package/contact-center/cc-import/components/import-contact-center-panel/import-contact-center-panel.component.d.ts +56 -0
  4. package/contact-center/cc-import/components/import-contact-center-wizard/import-contact-center-wizard.component.d.ts +77 -0
  5. package/contact-center/cc-import/components/import-contact-center-wizard/import-contact-center-wizard.types.d.ts +3 -0
  6. package/contact-center/cc-import/constants/cc-import.constants.d.ts +37 -0
  7. package/contact-center/cc-import/mock/cc-import.mock.d.ts +4 -0
  8. package/contact-center/cc-import/types/cc-import.d.ts +73 -0
  9. package/contact-center/cc-import/types/uccx.d.ts +109 -0
  10. package/contact-center/cc-readiness/cc-readiness.module.d.ts +3 -3
  11. package/contact-center/public-api.d.ts +8 -0
  12. package/contact-center/shared/api.endpoints.d.ts +25 -0
  13. package/contact-center/shared/api.service.d.ts +3 -1
  14. package/contact-center/shared/components/card/card.component.d.ts +13 -0
  15. package/contact-center/shared/dcp-api.service.d.ts +15 -0
  16. package/contact-center/shared/shared.module.d.ts +11 -5
  17. package/di2mt/api/api.endpoints.d.ts +3 -0
  18. package/esm2020/contact-center/cc-import/cc-import.module.mjs +45 -0
  19. package/esm2020/contact-center/cc-import/cc-import.service.mjs +228 -0
  20. package/esm2020/contact-center/cc-import/components/import-contact-center-panel/import-contact-center-panel.component.mjs +144 -0
  21. package/esm2020/contact-center/cc-import/components/import-contact-center-wizard/import-contact-center-wizard.component.mjs +243 -0
  22. package/esm2020/contact-center/cc-import/components/import-contact-center-wizard/import-contact-center-wizard.types.mjs +3 -0
  23. package/esm2020/contact-center/cc-import/constants/cc-import.constants.mjs +62 -0
  24. package/esm2020/contact-center/cc-import/mock/cc-import.mock.mjs +78 -0
  25. package/esm2020/contact-center/cc-import/types/cc-import.mjs +2 -0
  26. package/esm2020/contact-center/cc-import/types/uccx.mjs +24 -0
  27. package/esm2020/contact-center/cc-readiness/cc-readiness.module.mjs +7 -6
  28. package/esm2020/contact-center/cc-readiness/widgets/licences-requirement/licences-requirement.component.mjs +5 -5
  29. package/esm2020/contact-center/cc-readiness/widgets/summary-grid/summary-grid.component.mjs +2 -2
  30. package/esm2020/contact-center/public-api.mjs +9 -1
  31. package/esm2020/contact-center/shared/api.endpoints.mjs +26 -1
  32. package/esm2020/contact-center/shared/api.service.mjs +8 -3
  33. package/esm2020/contact-center/shared/components/card/card.component.mjs +24 -0
  34. package/esm2020/contact-center/shared/dcp-api.service.mjs +26 -0
  35. package/esm2020/contact-center/shared/shared.module.mjs +15 -5
  36. package/esm2020/di2mt/api/api.endpoints.mjs +4 -1
  37. package/esm2020/locations/public-api.mjs +8 -0
  38. package/esm2020/locations/src/app.constants.mjs +18 -0
  39. package/esm2020/locations/src/location-confirm-dialog/location-confirm-dialog.component.mjs +23 -0
  40. package/esm2020/locations/src/locations.component.mjs +398 -0
  41. package/esm2020/locations/src/locations.module.mjs +42 -0
  42. package/esm2020/locations/src/material.module.mjs +55 -0
  43. package/esm2020/locations/src/services/api.service.mjs +67 -0
  44. package/esm2020/locations/src/services/locations.service.mjs +69 -0
  45. package/esm2020/locations/src/types/location.mjs +2 -0
  46. package/esm2020/locations/src/utils/app-loader/app-loader.mjs +14 -0
  47. package/esm2020/locations/tuki-io-tuki-widgets-locations.mjs +5 -0
  48. package/esm2020/meetings/public-api.mjs +8 -0
  49. package/esm2020/meetings/src/app.constants.mjs +9 -0
  50. package/esm2020/meetings/src/components/live-meetings/live-meeting/live-meeting.component.mjs +107 -0
  51. package/esm2020/meetings/src/components/live-meetings/live-meetings.component.mjs +98 -0
  52. package/esm2020/meetings/src/components/meeting-spaces/meeting-space/meeting-space.component.mjs +110 -0
  53. package/esm2020/meetings/src/components/meeting-spaces/meeting-spaces.component.mjs +65 -0
  54. package/esm2020/meetings/src/material.module.mjs +76 -0
  55. package/esm2020/meetings/src/meetings.component.mjs +65 -0
  56. package/esm2020/meetings/src/meetings.module.mjs +51 -0
  57. package/esm2020/meetings/src/services/api.service.mjs +67 -0
  58. package/esm2020/meetings/src/services/live-meetings.service.mjs +178 -0
  59. package/esm2020/meetings/src/services/meeting-spaces.service.mjs +102 -0
  60. package/esm2020/meetings/src/types/live-meeting.mjs +2 -0
  61. package/esm2020/meetings/src/types/meeting-space.mjs +2 -0
  62. package/esm2020/meetings/src/utils/app-loader/app-loader.mjs +14 -0
  63. package/esm2020/meetings/tuki-io-tuki-widgets-meetings.mjs +5 -0
  64. package/esm2020/shared/public-api.mjs +4 -0
  65. package/esm2020/shared/src/ui/material.module.mjs +188 -0
  66. package/esm2020/shared/src/ui/shared.module.mjs +36 -0
  67. package/esm2020/shared/src/ui/tk-page-section/tk-page-section.component.mjs +13 -0
  68. package/esm2020/shared/src/ui/tk-page-section-row/tk-page-section-row.component.mjs +13 -0
  69. package/esm2020/shared/src/ui/ui.module.mjs +37 -0
  70. package/esm2020/shared/tuki-io-tuki-widgets-shared.mjs +5 -0
  71. package/esm2020/user-creation/src/utils/device-default-prefix.mjs +19 -2
  72. package/esm2020/user-creation/src/utils/device-name-dynamic-tokens.mjs +4 -0
  73. package/esm2020/user-creation/src/utils/parse-device-name-rule.mjs +6 -3
  74. package/esm2020/user-creation/src/widgets/user-creation-wizard/components/user-details-step/user-details-step.component.mjs +60 -13
  75. package/esm2020/user-creation/src/widgets/user-creation-wizard/components/user-template-step/user-template-step.component.mjs +2 -1
  76. package/esm2020/user-creation/src/widgets/user-creation-wizard/user-creation-wizard.component.mjs +8 -6
  77. package/esm2020/user-creation/src/widgets/user-creation-wizard/user-creation-wizard.service.mjs +13 -9
  78. package/esm2020/user-device-manage/public-api.mjs +4 -1
  79. package/esm2020/user-device-manage/src/app.constants.mjs +9 -3
  80. package/esm2020/user-device-manage/src/associate-lines/associate-lines.component.mjs +311 -0
  81. package/esm2020/user-device-manage/src/classes/device.mjs +1 -1
  82. package/esm2020/user-device-manage/src/classes/deviceProfile.mjs +1 -1
  83. package/esm2020/user-device-manage/src/classes/simplified-user.mjs +1 -1
  84. package/esm2020/user-device-manage/src/confirm-dialog/info-dialog.component.mjs +2 -2
  85. package/esm2020/user-device-manage/src/device-manage-widget.component.mjs +34 -17
  86. package/esm2020/user-device-manage/src/device-settings/device-settings.component.mjs +207 -0
  87. package/esm2020/user-device-manage/src/line-key-config/line-key-config.component.mjs +401 -0
  88. package/esm2020/user-device-manage/src/services/device.service.mjs +32 -2
  89. package/esm2020/user-device-manage/src/services/user.service.mjs +34 -6
  90. package/esm2020/user-device-manage/src/user-device-manage.module.mjs +19 -7
  91. package/esm2020/user-manage/src/app.constants.mjs +8 -1
  92. package/esm2020/user-manage/src/classes/simplified-user.mjs +19 -4
  93. package/esm2020/user-manage/src/device-list/device-list.component.mjs +7 -4
  94. package/esm2020/user-manage/src/device-list/device-row/device-row.component.mjs +6 -3
  95. package/esm2020/user-manage/src/lazy-loading-select/lazy-loading-select.component.mjs +9 -5
  96. package/esm2020/user-manage/src/material.module.mjs +21 -7
  97. package/esm2020/user-manage/src/services/dcp-api.service.mjs +79 -0
  98. package/esm2020/user-manage/src/services/site-settings.service.mjs +11 -4
  99. package/esm2020/user-manage/src/services/user.service.mjs +94 -19
  100. package/esm2020/user-manage/src/user-calling/user-calling.component.mjs +12 -7
  101. package/esm2020/user-manage/src/user-manage-widget.component.mjs +90 -39
  102. package/esm2020/user-manage/src/user-manage.module.mjs +14 -4
  103. package/esm2020/user-manage/src/user-summary/user-summary.component.mjs +30 -0
  104. package/esm2020/users-list/src/app.constants.mjs +2 -1
  105. package/esm2020/users-list/src/classes/simlified-user.mjs +1 -1
  106. package/esm2020/users-list/src/classes/user-list.mjs +2 -1
  107. package/esm2020/users-list/src/components/table-toolbar/table-toolbar.component.mjs +3 -3
  108. package/esm2020/users-list/src/move-user-wizard/move-user-stepper/move-user-stepper.component.mjs +14 -3
  109. package/esm2020/users-list/src/move-user-wizard/move-user-wizard.component.mjs +5 -3
  110. package/esm2020/users-list/src/users-list.component.mjs +100 -17
  111. package/esm2020/workspaces/public-api.mjs +8 -0
  112. package/esm2020/workspaces/src/app.constants.mjs +27 -0
  113. package/esm2020/workspaces/src/components/workspace-confirm-dialog/workspace-confirm-dialog.component.mjs +32 -0
  114. package/esm2020/workspaces/src/components/workspace-detail/workspace-detail.component.mjs +96 -0
  115. package/esm2020/workspaces/src/components/workspace-device-detail/workspace-device-detail.component.mjs +66 -0
  116. package/esm2020/workspaces/src/components/workspaces-filters/workspaces-filters.component.mjs +56 -0
  117. package/esm2020/workspaces/src/components/workspaces-table/workspaces-table.component.mjs +130 -0
  118. package/esm2020/workspaces/src/material.module.mjs +83 -0
  119. package/esm2020/workspaces/src/services/api-webex.service.mjs +14 -0
  120. package/esm2020/workspaces/src/services/api.service.mjs +67 -0
  121. package/esm2020/workspaces/src/services/workspace-detail.service.mjs +169 -0
  122. package/esm2020/workspaces/src/services/workspaces-migration.service.mjs +59 -0
  123. package/esm2020/workspaces/src/services/workspaces.service.mjs +150 -0
  124. package/esm2020/workspaces/src/types/workspace.mjs +4 -0
  125. package/esm2020/workspaces/src/utils/app-loader/app-loader.mjs +14 -0
  126. package/esm2020/workspaces/src/utils/device-icon.mjs +13 -0
  127. package/esm2020/workspaces/src/utils/workspace-name.mjs +8 -0
  128. package/esm2020/workspaces/src/workspaces.component.mjs +306 -0
  129. package/esm2020/workspaces/src/workspaces.module.mjs +54 -0
  130. package/esm2020/workspaces/tuki-io-tuki-widgets-workspaces.mjs +5 -0
  131. package/fesm2015/tuki-io-tuki-widgets-contact-center.mjs +998 -127
  132. package/fesm2015/tuki-io-tuki-widgets-contact-center.mjs.map +1 -1
  133. package/fesm2015/tuki-io-tuki-widgets-di2mt.mjs +3 -0
  134. package/fesm2015/tuki-io-tuki-widgets-di2mt.mjs.map +1 -1
  135. package/fesm2015/tuki-io-tuki-widgets-locations.mjs +679 -0
  136. package/fesm2015/tuki-io-tuki-widgets-locations.mjs.map +1 -0
  137. package/fesm2015/tuki-io-tuki-widgets-meetings.mjs +894 -0
  138. package/fesm2015/tuki-io-tuki-widgets-meetings.mjs.map +1 -0
  139. package/fesm2015/tuki-io-tuki-widgets-shared.mjs +280 -0
  140. package/fesm2015/tuki-io-tuki-widgets-shared.mjs.map +1 -0
  141. package/fesm2015/tuki-io-tuki-widgets-user-creation.mjs +111 -32
  142. package/fesm2015/tuki-io-tuki-widgets-user-creation.mjs.map +1 -1
  143. package/fesm2015/tuki-io-tuki-widgets-user-device-manage.mjs +1013 -48
  144. package/fesm2015/tuki-io-tuki-widgets-user-device-manage.mjs.map +1 -1
  145. package/fesm2015/tuki-io-tuki-widgets-user-manage.mjs +380 -89
  146. package/fesm2015/tuki-io-tuki-widgets-user-manage.mjs.map +1 -1
  147. package/fesm2015/tuki-io-tuki-widgets-users-list.mjs +121 -22
  148. package/fesm2015/tuki-io-tuki-widgets-users-list.mjs.map +1 -1
  149. package/fesm2015/tuki-io-tuki-widgets-workspaces.mjs +1275 -0
  150. package/fesm2015/tuki-io-tuki-widgets-workspaces.mjs.map +1 -0
  151. package/fesm2020/tuki-io-tuki-widgets-contact-center.mjs +989 -127
  152. package/fesm2020/tuki-io-tuki-widgets-contact-center.mjs.map +1 -1
  153. package/fesm2020/tuki-io-tuki-widgets-di2mt.mjs +3 -0
  154. package/fesm2020/tuki-io-tuki-widgets-di2mt.mjs.map +1 -1
  155. package/fesm2020/tuki-io-tuki-widgets-locations.mjs +672 -0
  156. package/fesm2020/tuki-io-tuki-widgets-locations.mjs.map +1 -0
  157. package/fesm2020/tuki-io-tuki-widgets-meetings.mjs +902 -0
  158. package/fesm2020/tuki-io-tuki-widgets-meetings.mjs.map +1 -0
  159. package/fesm2020/tuki-io-tuki-widgets-shared.mjs +280 -0
  160. package/fesm2020/tuki-io-tuki-widgets-shared.mjs.map +1 -0
  161. package/fesm2020/tuki-io-tuki-widgets-user-creation.mjs +104 -28
  162. package/fesm2020/tuki-io-tuki-widgets-user-creation.mjs.map +1 -1
  163. package/fesm2020/tuki-io-tuki-widgets-user-device-manage.mjs +996 -47
  164. package/fesm2020/tuki-io-tuki-widgets-user-device-manage.mjs.map +1 -1
  165. package/fesm2020/tuki-io-tuki-widgets-user-manage.mjs +366 -82
  166. package/fesm2020/tuki-io-tuki-widgets-user-manage.mjs.map +1 -1
  167. package/fesm2020/tuki-io-tuki-widgets-users-list.mjs +120 -22
  168. package/fesm2020/tuki-io-tuki-widgets-users-list.mjs.map +1 -1
  169. package/fesm2020/tuki-io-tuki-widgets-workspaces.mjs +1276 -0
  170. package/fesm2020/tuki-io-tuki-widgets-workspaces.mjs.map +1 -0
  171. package/locations/index.d.ts +5 -0
  172. package/locations/public-api.d.ts +2 -0
  173. package/locations/src/app.constants.d.ts +10 -0
  174. package/locations/src/location-confirm-dialog/location-confirm-dialog.component.d.ts +15 -0
  175. package/locations/src/locations.component.d.ts +92 -0
  176. package/locations/src/locations.module.d.ts +13 -0
  177. package/locations/src/material.module.d.ts +12 -0
  178. package/locations/src/services/api.service.d.ts +18 -0
  179. package/locations/src/services/locations.service.d.ts +25 -0
  180. package/locations/src/types/location.d.ts +30 -0
  181. package/locations/src/utils/app-loader/app-loader.d.ts +6 -0
  182. package/meetings/index.d.ts +5 -0
  183. package/meetings/public-api.d.ts +2 -0
  184. package/meetings/src/app.constants.d.ts +8 -0
  185. package/meetings/src/components/live-meetings/live-meeting/live-meeting.component.d.ts +34 -0
  186. package/meetings/src/components/live-meetings/live-meetings.component.d.ts +43 -0
  187. package/meetings/src/components/meeting-spaces/meeting-space/meeting-space.component.d.ts +39 -0
  188. package/meetings/src/components/meeting-spaces/meeting-spaces.component.d.ts +27 -0
  189. package/meetings/src/material.module.d.ts +15 -0
  190. package/meetings/src/meetings.component.d.ts +29 -0
  191. package/meetings/src/meetings.module.d.ts +16 -0
  192. package/meetings/src/services/api.service.d.ts +18 -0
  193. package/meetings/src/services/live-meetings.service.d.ts +9 -0
  194. package/meetings/src/services/meeting-spaces.service.d.ts +16 -0
  195. package/meetings/src/types/live-meeting.d.ts +71 -0
  196. package/meetings/src/types/meeting-space.d.ts +52 -0
  197. package/meetings/src/utils/app-loader/app-loader.d.ts +6 -0
  198. package/package.json +33 -1
  199. package/shared/index.d.ts +5 -0
  200. package/shared/public-api.d.ts +3 -0
  201. package/shared/src/ui/material.module.d.ts +28 -0
  202. package/shared/src/ui/shared.module.d.ts +10 -0
  203. package/{user-device-manage/src/shared/tk-page-section/page-section.component.d.ts → shared/src/ui/tk-page-section/tk-page-section.component.d.ts} +1 -1
  204. package/shared/src/ui/tk-page-section-row/tk-page-section-row.component.d.ts +6 -0
  205. package/shared/src/ui/ui.module.d.ts +11 -0
  206. package/user-creation/src/utils/device-default-prefix.d.ts +7 -2
  207. package/user-creation/src/utils/device-name-dynamic-tokens.d.ts +1 -0
  208. package/user-creation/src/utils/parse-device-name-rule.d.ts +1 -0
  209. package/user-creation/src/widgets/user-creation-wizard/components/user-details-step/user-details-step.component.d.ts +2 -0
  210. package/user-device-manage/public-api.d.ts +3 -0
  211. package/user-device-manage/src/app.constants.d.ts +6 -0
  212. package/user-device-manage/src/associate-lines/associate-lines.component.d.ts +95 -0
  213. package/user-device-manage/src/classes/device.d.ts +15 -0
  214. package/user-device-manage/src/classes/deviceProfile.d.ts +5 -0
  215. package/user-device-manage/src/classes/simplified-user.d.ts +1 -1
  216. package/user-device-manage/src/device-associated-line/device-associated-line.component.d.ts +1 -0
  217. package/user-device-manage/src/device-manage-widget.component.d.ts +6 -1
  218. package/user-device-manage/src/device-settings/device-settings.component.d.ts +53 -0
  219. package/user-device-manage/src/line-key-config/line-key-config.component.d.ts +84 -0
  220. package/user-device-manage/src/services/device.service.d.ts +6 -1
  221. package/user-device-manage/src/services/user.service.d.ts +2 -1
  222. package/user-device-manage/src/user-device-manage.module.d.ts +12 -10
  223. package/user-manage/src/app.constants.d.ts +7 -0
  224. package/user-manage/src/classes/simplified-user.d.ts +17 -1
  225. package/user-manage/src/device-list/device-list.component.d.ts +2 -0
  226. package/user-manage/src/material.module.d.ts +3 -1
  227. package/user-manage/src/services/dcp-api.service.d.ts +21 -0
  228. package/user-manage/src/services/user.service.d.ts +19 -1
  229. package/user-manage/src/user-calling/user-calling.component.d.ts +3 -2
  230. package/user-manage/src/user-manage-widget.component.d.ts +14 -2
  231. package/user-manage/src/user-manage.module.d.ts +9 -7
  232. package/user-manage/src/user-summary/user-summary.component.d.ts +10 -0
  233. package/users-list/src/app.constants.d.ts +1 -0
  234. package/users-list/src/classes/simlified-user.d.ts +1 -1
  235. package/users-list/src/classes/user-list.d.ts +4 -0
  236. package/users-list/src/move-user-wizard/move-user-stepper/move-user-stepper.component.d.ts +3 -1
  237. package/users-list/src/move-user-wizard/move-user-wizard.component.d.ts +2 -1
  238. package/users-list/src/users-list.component.d.ts +6 -1
  239. package/workspaces/index.d.ts +5 -0
  240. package/workspaces/public-api.d.ts +2 -0
  241. package/workspaces/src/app.constants.d.ts +25 -0
  242. package/workspaces/src/components/workspace-confirm-dialog/workspace-confirm-dialog.component.d.ts +20 -0
  243. package/workspaces/src/components/workspace-detail/workspace-detail.component.d.ts +34 -0
  244. package/workspaces/src/components/workspace-device-detail/workspace-device-detail.component.d.ts +25 -0
  245. package/workspaces/src/components/workspaces-filters/workspaces-filters.component.d.ts +20 -0
  246. package/workspaces/src/components/workspaces-table/workspaces-table.component.d.ts +43 -0
  247. package/workspaces/src/material.module.d.ts +16 -0
  248. package/workspaces/src/services/api-webex.service.d.ts +6 -0
  249. package/workspaces/src/services/api.service.d.ts +18 -0
  250. package/workspaces/src/services/workspace-detail.service.d.ts +22 -0
  251. package/workspaces/src/services/workspaces-migration.service.d.ts +18 -0
  252. package/workspaces/src/services/workspaces.service.d.ts +11 -0
  253. package/workspaces/src/types/workspace.d.ts +439 -0
  254. package/workspaces/src/utils/app-loader/app-loader.d.ts +6 -0
  255. package/workspaces/src/utils/device-icon.d.ts +1 -0
  256. package/workspaces/src/utils/workspace-name.d.ts +1 -0
  257. package/workspaces/src/workspaces.component.d.ts +74 -0
  258. package/workspaces/src/workspaces.module.d.ts +17 -0
  259. package/contact-center/cc-readiness/components/card/card.component.d.ts +0 -6
  260. package/esm2020/contact-center/cc-readiness/components/card/card.component.mjs +0 -13
  261. package/esm2020/user-device-manage/src/shared/tk-page-section/page-section.component.mjs +0 -13
@@ -1,40 +1,42 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, inject, Component, Input, NgModule, ChangeDetectionStrategy, Inject, EventEmitter, Output, ViewChild } from '@angular/core';
2
+ import { Injectable, inject, Component, Input, NgModule, ChangeDetectionStrategy, Inject, EventEmitter, Output, ViewChild, ViewEncapsulation } from '@angular/core';
3
3
  import * as i1$1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import * as i1 from '@angular/common/http';
6
6
  import { HttpHeaders, HttpClientModule } from '@angular/common/http';
7
- import { map, catchError, of, finalize, Subject, forkJoin, throwError } from 'rxjs';
8
- import * as i2 from 'ng-apexcharts';
9
- import { NgApexchartsModule } from 'ng-apexcharts';
10
- import * as i3 from '@angular/material/select';
7
+ import { map, catchError, of, finalize, Subject, forkJoin, throwError, delay, switchMap, Subscription } from 'rxjs';
8
+ import * as i6 from '@angular/material/select';
11
9
  import { MatSelectModule } from '@angular/material/select';
12
- import * as i4 from '@angular/material/core';
10
+ import * as i3 from '@angular/material/core';
13
11
  import { MatOptionModule } from '@angular/material/core';
12
+ import * as i5 from 'ng-apexcharts';
13
+ import { NgApexchartsModule } from 'ng-apexcharts';
14
+ import { MatProgressBarModule } from '@angular/material/progress-bar';
15
+ import { MatTableModule } from '@angular/material/table';
16
+ import * as i3$1 from '@angular/material/tooltip';
17
+ import { MatTooltipModule } from '@angular/material/tooltip';
18
+ import { MatCheckboxModule } from '@angular/material/checkbox';
14
19
  import * as i1$4 from '@angular/material/button';
15
20
  import { MatButtonModule } from '@angular/material/button';
16
- import { MatCheckboxModule } from '@angular/material/checkbox';
17
- import { MatPaginatorModule } from '@angular/material/paginator';
18
- import * as i4$1 from '@angular/material/progress-spinner';
21
+ import { MatIconModule } from '@angular/material/icon';
22
+ import * as i2$1 from '@angular/material/form-field';
23
+ import { MatFormFieldModule } from '@angular/material/form-field';
24
+ import { MatInputModule } from '@angular/material/input';
25
+ import * as i4 from '@angular/material/progress-spinner';
19
26
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
20
- import { MatTableModule } from '@angular/material/table';
27
+ import { MatPaginatorModule } from '@angular/material/paginator';
21
28
  import cytoscape from 'cytoscape';
22
29
  import dagre from 'cytoscape-dagre';
23
30
  import nodeHtmlLabel from 'cytoscape-node-html-label';
24
31
  import * as i1$2 from '@angular/material/dialog';
25
32
  import { MAT_DIALOG_DATA } from '@angular/material/dialog';
26
33
  import * as uuid from 'uuid';
27
- import * as i3$1 from '@angular/material/tooltip';
28
- import { MatTooltipModule } from '@angular/material/tooltip';
29
34
  import * as i1$3 from '@angular/platform-browser';
30
- import * as i2$1 from '@angular/forms';
35
+ import * as i2 from '@angular/forms';
31
36
  import { FormsModule } from '@angular/forms';
32
- import * as i2$2 from '@angular/material/form-field';
33
- import { MatFormFieldModule } from '@angular/material/form-field';
34
37
  import { mergeMap, takeUntil, finalize as finalize$1, tap } from 'rxjs/operators';
35
- import { MatProgressBarModule } from '@angular/material/progress-bar';
36
- import { MatIconModule } from '@angular/material/icon';
37
- import { MatInputModule } from '@angular/material/input';
38
+ import * as i2$2 from '@angular/material/stepper';
39
+ import { MatStepperModule } from '@angular/material/stepper';
38
40
 
39
41
  class APIService {
40
42
  constructor(httpClient) {
@@ -45,10 +47,15 @@ class APIService {
45
47
  params = params || {};
46
48
  return this.httpClient.get(this.apiUrl + url, { params: this.prepareEncodedParams(params), headers });
47
49
  }
48
- post(url, body, params = {}) {
50
+ post(url, body, params = {}, options = {}) {
49
51
  body = body || null;
50
52
  const headers = this.getHeaders();
51
- return this.httpClient.post(this.apiUrl + url, body, { params: this.prepareEncodedParams(params), headers });
53
+ return this.httpClient.post(this.apiUrl + url, body, {
54
+ params: this.prepareEncodedParams(params),
55
+ headers,
56
+ // Some migration endpoints answer with a file rather than JSON.
57
+ responseType: (options.responseType || 'json')
58
+ });
52
59
  }
53
60
  // use when response extended data is necessary:
54
61
  postExtended(url, body = null, params = {}, headers = {}) {
@@ -117,6 +124,31 @@ const API = {
117
124
  READINESS: {
118
125
  UCCX_SERVER_ENTITY_STATS: (customerId) => `/api/uccx/migration/customer/${customerId}/entity-counts`,
119
126
  LICENSE_USAGE_SUMMARY: (customerId) => `/api/uccx/migration/customer/${customerId}/cc-license-stats`,
127
+ },
128
+ /**
129
+ * The application-centric UCCX migration endpoints, as used by webex-ops-client
130
+ * (`ContactCenterService` / `constants.json`). There is no dedicated
131
+ * "contact center" API - a contact center *is* a UCCX application, and its
132
+ * entities are reached through the e2emigration batches that carry it.
133
+ */
134
+ UCCX: {
135
+ /** Every UCCX application known for the customer. Served by the **dcp** host. */
136
+ APPLICATION_NAMES: (customerId) => `/api/cache/uccx/application/customer/${customerId}/getall`,
137
+ /** All UCCX batches for the customer, one per entity type. */
138
+ BATCHES: (customerId) => `/api/e2emigration/batch/${customerId}/UCCX`,
139
+ /**
140
+ * The entities of one batch.
141
+ *
142
+ * It also takes an `applicationName` param, but on dev2 that filter answers
143
+ * `[]` for every application - including ones whose items *do* carry a
144
+ * matching `applicationName` - so the widget reads the batch unfiltered and
145
+ * narrows on the item field itself.
146
+ */
147
+ BATCH_ITEMS: (customerId, batchId) => `/api/e2emigration/batch/${batchId}/customer/${customerId}/uccx/filter`,
148
+ /** Per-AEF-script migration state (NEW / MIGRATED / MIGRATION_FAILED / ...). */
149
+ CALL_FLOW_MIGRATION_STATUSES: (customerId) => `/api/uccx/migration/customer/${customerId}/callflow/getAll`,
150
+ /** Runs the UCCX -> Webex Contact Center migration. Responds with an XLSX tracker. */
151
+ MIGRATE: (customerId) => `/api/migration/webex/customer/${customerId}/uccx/migrate`,
120
152
  }
121
153
  };
122
154
 
@@ -153,15 +185,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
153
185
  }]
154
186
  }], ctorParameters: function () { return []; } });
155
187
 
188
+ /**
189
+ * Standard contact-center panel chrome. Content goes into the `card-content` slot;
190
+ * `card-title-adornment` takes a small element rendered next to the title (info icon,
191
+ * badge).
192
+ */
156
193
  class CardComponent {
194
+ constructor() {
195
+ /** Tightens the padding and inner spacing for compact panels. */
196
+ this.dense = false;
197
+ }
157
198
  }
158
199
  CardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
159
- CardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: CardComponent, selector: "tk-card", inputs: { title: "title" }, ngImport: i0, template: "<article class=\"card\">\r\n <header class=\"card__header\">\r\n <h2>{{ title }}</h2>\r\n <!--<div class=\"card__menu-button\">\r\n <img width=\"18\" src=\"assets/icons/menu_icon.png\" alt=\"Menu Icon\">\r\n </div>-->\r\n </header>\r\n <div class=\"card__content\">\r\n <ng-content select=\"card-content\"></ng-content>\r\n </div>\r\n</article>\r\n", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";:host{display:block;height:100%;box-sizing:border-box}.card{font-family:Inter,Inter,sans-serif;background-color:#fff;border-radius:1rem;padding:2rem;border:1px solid hsla(0,0%,0%,.2);min-width:300px;max-width:100%;height:100%;display:flex;flex-direction:column;box-sizing:border-box;gap:2.5rem}.card__header{position:relative;display:flex;align-items:center;justify-content:space-between}.card__header h2{font-size:16px;margin:0}.card__header .card__menu-button{position:relative;display:flex;align-items:center}.card__content{display:flex;flex-direction:column;gap:2.5rem;flex-grow:1}\n"] });
200
+ CardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: CardComponent, selector: "tk-card", inputs: { title: "title", dense: "dense" }, ngImport: i0, template: "<article class=\"card\" [class.card--dense]=\"dense\">\r\n <header class=\"card__header\">\r\n <div class=\"card__title-group\">\r\n <h2>{{ title }}</h2>\r\n <ng-content select=\"card-title-adornment\"></ng-content>\r\n </div>\r\n <!--<div class=\"card__menu-button\">\r\n <img width=\"18\" src=\"assets/icons/menu_icon.png\" alt=\"Menu Icon\">\r\n </div>-->\r\n </header>\r\n <div class=\"card__content\">\r\n <ng-content select=\"card-content\"></ng-content>\r\n </div>\r\n</article>\r\n", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";:host{display:block;height:100%;box-sizing:border-box}.card{font-family:Inter,Inter,sans-serif;background-color:#fff;border-radius:1rem;padding:2rem;border:1px solid hsla(0,0%,0%,.2);min-width:300px;max-width:100%;height:100%;display:flex;flex-direction:column;box-sizing:border-box;gap:2.5rem}.card--dense{border-radius:8px;padding:1.5rem;gap:1.25rem}.card--dense .card__content{gap:1.25rem}.card__header{position:relative;display:flex;align-items:center;justify-content:space-between}.card__header h2{font-size:16px;margin:0}.card__header .card__menu-button{position:relative;display:flex;align-items:center}.card__title-group{display:flex;align-items:center;gap:.375rem}.card__content{display:flex;flex-direction:column;gap:2.5rem;flex-grow:1}\n"] });
160
201
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CardComponent, decorators: [{
161
202
  type: Component,
162
- args: [{ selector: 'tk-card', template: "<article class=\"card\">\r\n <header class=\"card__header\">\r\n <h2>{{ title }}</h2>\r\n <!--<div class=\"card__menu-button\">\r\n <img width=\"18\" src=\"assets/icons/menu_icon.png\" alt=\"Menu Icon\">\r\n </div>-->\r\n </header>\r\n <div class=\"card__content\">\r\n <ng-content select=\"card-content\"></ng-content>\r\n </div>\r\n</article>\r\n", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";:host{display:block;height:100%;box-sizing:border-box}.card{font-family:Inter,Inter,sans-serif;background-color:#fff;border-radius:1rem;padding:2rem;border:1px solid hsla(0,0%,0%,.2);min-width:300px;max-width:100%;height:100%;display:flex;flex-direction:column;box-sizing:border-box;gap:2.5rem}.card__header{position:relative;display:flex;align-items:center;justify-content:space-between}.card__header h2{font-size:16px;margin:0}.card__header .card__menu-button{position:relative;display:flex;align-items:center}.card__content{display:flex;flex-direction:column;gap:2.5rem;flex-grow:1}\n"] }]
203
+ args: [{ selector: 'tk-card', template: "<article class=\"card\" [class.card--dense]=\"dense\">\r\n <header class=\"card__header\">\r\n <div class=\"card__title-group\">\r\n <h2>{{ title }}</h2>\r\n <ng-content select=\"card-title-adornment\"></ng-content>\r\n </div>\r\n <!--<div class=\"card__menu-button\">\r\n <img width=\"18\" src=\"assets/icons/menu_icon.png\" alt=\"Menu Icon\">\r\n </div>-->\r\n </header>\r\n <div class=\"card__content\">\r\n <ng-content select=\"card-content\"></ng-content>\r\n </div>\r\n</article>\r\n", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";:host{display:block;height:100%;box-sizing:border-box}.card{font-family:Inter,Inter,sans-serif;background-color:#fff;border-radius:1rem;padding:2rem;border:1px solid hsla(0,0%,0%,.2);min-width:300px;max-width:100%;height:100%;display:flex;flex-direction:column;box-sizing:border-box;gap:2.5rem}.card--dense{border-radius:8px;padding:1.5rem;gap:1.25rem}.card--dense .card__content{gap:1.25rem}.card__header{position:relative;display:flex;align-items:center;justify-content:space-between}.card__header h2{font-size:16px;margin:0}.card__header .card__menu-button{position:relative;display:flex;align-items:center}.card__title-group{display:flex;align-items:center;gap:.375rem}.card__content{display:flex;flex-direction:column;gap:2.5rem;flex-grow:1}\n"] }]
163
204
  }], propDecorators: { title: [{
164
205
  type: Input
206
+ }], dense: [{
207
+ type: Input
165
208
  }] } });
166
209
 
167
210
  const LEGEND_COLORS = {
@@ -337,7 +380,7 @@ class LicencesRequirementComponent {
337
380
  }
338
381
  }
339
382
  LicencesRequirementComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: LicencesRequirementComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
340
- LicencesRequirementComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: LicencesRequirementComponent, selector: "cc-licenses-requirement", inputs: { customerId: "customerId", host: "host", token: "token" }, usesOnChanges: true, ngImport: i0, template: "<tk-card title=\"Licenses requirement\">\r\n <ng-container ngProjectAs=\"card-content\">\r\n <div\r\n class=\"widget-body\"\r\n *ngIf=\"!loading && !error && viewModel; else widgetState\"\r\n >\r\n <div class=\"left-section\">\r\n <mat-select\r\n [(value)]=\"selectedSummaryIndex\"\r\n (selectionChange)=\"onFilterChange($event.value)\"\r\n class=\"filter-select\"\r\n >\r\n <mat-option *ngFor=\"let option of filters; index as i\" [value]=\"i\">\r\n {{ option }}\r\n </mat-option>\r\n </mat-select>\r\n\r\n <div class=\"chart-section\">\r\n <div class=\"chart-wrapper\">\r\n <apx-chart\r\n [series]=\"viewModel.chartOptions.series\"\r\n [chart]=\"viewModel.chartOptions.chart\"\r\n [labels]=\"viewModel.chartOptions.labels\"\r\n [colors]=\"viewModel.chartOptions.colors\"\r\n [legend]=\"viewModel.chartOptions.legend\"\r\n [plotOptions]=\"viewModel.chartOptions.plotOptions\"\r\n [dataLabels]=\"viewModel.chartOptions.dataLabels\"\r\n [tooltip]=\"viewModel.chartOptions.tooltip\"\r\n >\r\n </apx-chart>\r\n </div>\r\n <div class=\"legend\">\r\n <div class=\"legend-item\" *ngFor=\"let item of viewModel.legendItems\">\r\n <span\r\n class=\"legend-marker\"\r\n [style.backgroundColor]=\"item.color\"\r\n ></span>\r\n <span class=\"legend-label\">{{ item.label }}</span>\r\n <span class=\"legend-value\">{{ item.count | number }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"divider\" aria-hidden=\"true\"></div>\r\n\r\n <div class=\"table-section\">\r\n <div class=\"lic-table-header\">\r\n <span>License</span>\r\n <span>Required</span>\r\n </div>\r\n <div class=\"table-row\" *ngFor=\"let row of viewModel.rows\">\r\n <span>{{ row.label }}</span>\r\n <span>{{ row.value | number }}</span>\r\n </div>\r\n <div class=\"table-row total-row\">\r\n <span>Total</span>\r\n <span>{{ viewModel.totalRequired | number }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <ng-template #widgetState>\r\n <div class=\"state-message\" *ngIf=\"loading\">\r\n Loading license requirements\u2026\r\n </div>\r\n <div class=\"state-message error\" *ngIf=\"!loading && error\">\r\n Unable to load license requirements.\r\n </div>\r\n <div class=\"state-message\" *ngIf=\"!loading && !error && !viewModel\">\r\n No license data available.\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n</tk-card>\r\n", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";:host{display:block;width:100%;box-sizing:border-box}.filter-select{font-family:Inter,Inter,sans-serif;font-size:14px;min-width:140px;border:1px solid #e5e7eb;border-radius:.5rem;padding:.5rem .75rem;background-color:#fff}.filter-select:hover{border-color:#d1d5db}:host ::ng-deep .filter-select.mat-mdc-select{border:1px solid #e5e7eb;border-radius:.5rem;background-color:#fff}:host ::ng-deep .filter-select.mat-mdc-select:hover{border-color:#d1d5db}:host ::ng-deep .filter-select.mat-mdc-select.mat-focused{border-color:#16a693}:host ::ng-deep .filter-select .mat-mdc-select-trigger{font-size:14px;padding:.5rem .75rem}:host ::ng-deep .filter-select .mat-mdc-select-value{color:#111827}:host ::ng-deep .filter-select .mat-mdc-select-arrow-wrapper{padding-left:.5rem}.widget-body{display:flex;gap:2.5rem;align-items:flex-start}.left-section{flex:2;display:flex;flex-direction:column;gap:1rem}.chart-section{display:flex;gap:1.5rem;align-items:center}.chart-wrapper{width:220px;min-height:220px;flex-shrink:0}.chart-wrapper apx-chart{width:220px!important;height:220px!important}.legend{display:flex;flex-direction:column;gap:.75rem}.legend-item{display:flex;align-items:center;gap:.5rem;font-family:Inter,Inter,sans-serif;font-size:14px}.legend-marker{width:14px;height:14px;border-radius:50%;display:inline-flex}.legend-label{color:#4b5563}.legend-value{margin-left:auto;font-weight:600;color:#111827}.divider{width:1px;min-height:200px;align-self:stretch;background:#e5e7eb}.table-section{flex:3;display:flex;flex-direction:column;gap:.75rem;font-family:Inter,Inter,sans-serif}.lic-table-header,.table-row{display:flex;justify-content:space-between;font-size:14px}.lic-table-header{font-weight:600;color:#6b7280;padding-bottom:.5rem;border-bottom:1px solid #e5e7eb}.table-row{color:#111827}.total-row{font-weight:700;margin-top:.5rem;padding-top:.5rem;border-top:1px solid #e5e7eb}.state-message{font-family:Inter,Inter,sans-serif;font-size:14px;color:#6b7280}.state-message.error{color:#b91c1c}@media (max-width: 960px){.widget-body{flex-direction:column}.divider{display:none}.chart-section{justify-content:space-between}}:host ::ng-deep .apexcharts-legend{display:none!important}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.ChartComponent, selector: "apx-chart", inputs: ["chart", "annotations", "colors", "dataLabels", "series", "stroke", "labels", "legend", "markers", "noData", "fill", "tooltip", "plotOptions", "responsive", "xaxis", "yaxis", "forecastDataPoints", "grid", "states", "title", "subtitle", "theme", "autoUpdateSeries"] }, { kind: "component", type: i3.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i4.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: CardComponent, selector: "tk-card", inputs: ["title"] }, { kind: "pipe", type: i1$1.DecimalPipe, name: "number" }] });
383
+ LicencesRequirementComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: LicencesRequirementComponent, selector: "cc-licenses-requirement", inputs: { customerId: "customerId", host: "host", token: "token" }, usesOnChanges: true, ngImport: i0, template: "<tk-card title=\"Licenses requirement\">\r\n <ng-container ngProjectAs=\"card-content\">\r\n <div\r\n class=\"widget-body\"\r\n *ngIf=\"!loading && !error && viewModel; else widgetState\"\r\n >\r\n <div class=\"left-section\">\r\n <mat-select\r\n [(value)]=\"selectedSummaryIndex\"\r\n (selectionChange)=\"onFilterChange($event.value)\"\r\n class=\"filter-select\"\r\n >\r\n <mat-option *ngFor=\"let option of filters; index as i\" [value]=\"i\">\r\n {{ option }}\r\n </mat-option>\r\n </mat-select>\r\n\r\n <div class=\"chart-section\">\r\n <div class=\"chart-wrapper\">\r\n <apx-chart\r\n [series]=\"viewModel.chartOptions.series\"\r\n [chart]=\"viewModel.chartOptions.chart\"\r\n [labels]=\"viewModel.chartOptions.labels\"\r\n [colors]=\"viewModel.chartOptions.colors\"\r\n [legend]=\"viewModel.chartOptions.legend\"\r\n [plotOptions]=\"viewModel.chartOptions.plotOptions\"\r\n [dataLabels]=\"viewModel.chartOptions.dataLabels\"\r\n [tooltip]=\"viewModel.chartOptions.tooltip\"\r\n >\r\n </apx-chart>\r\n </div>\r\n <div class=\"legend\">\r\n <div class=\"legend-item\" *ngFor=\"let item of viewModel.legendItems\">\r\n <span\r\n class=\"legend-marker\"\r\n [style.backgroundColor]=\"item.color\"\r\n ></span>\r\n <span class=\"legend-label\">{{ item.label }}</span>\r\n <span class=\"legend-value\">{{ item.count | number }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"divider\" aria-hidden=\"true\"></div>\r\n\r\n <div class=\"table-section\">\r\n <div class=\"lic-table-header\">\r\n <span>License</span>\r\n <span>Required</span>\r\n </div>\r\n <div class=\"table-row\" *ngFor=\"let row of viewModel.rows\">\r\n <span>{{ row.label }}</span>\r\n <span>{{ row.value | number }}</span>\r\n </div>\r\n <div class=\"table-row total-row\">\r\n <span>Total</span>\r\n <span>{{ viewModel.totalRequired | number }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <ng-template #widgetState>\r\n <div class=\"state-message\" *ngIf=\"loading\">\r\n Loading license requirements\u2026\r\n </div>\r\n <div class=\"state-message error\" *ngIf=\"!loading && error\">\r\n Unable to load license requirements.\r\n </div>\r\n <div class=\"state-message\" *ngIf=\"!loading && !error && !viewModel\">\r\n No license data available.\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n</tk-card>\r\n", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";:host{display:block;width:100%;box-sizing:border-box}.filter-select{font-family:Inter,Inter,sans-serif;font-size:14px;min-width:140px;border:1px solid #e5e7eb;border-radius:.5rem;padding:.5rem .75rem;background-color:#fff}.filter-select:hover{border-color:#d1d5db}:host ::ng-deep .filter-select.mat-mdc-select{border:1px solid #e5e7eb;border-radius:.5rem;background-color:#fff}:host ::ng-deep .filter-select.mat-mdc-select:hover{border-color:#d1d5db}:host ::ng-deep .filter-select.mat-mdc-select.mat-focused{border-color:#16a693}:host ::ng-deep .filter-select .mat-mdc-select-trigger{font-size:14px;padding:.5rem .75rem}:host ::ng-deep .filter-select .mat-mdc-select-value{color:#111827}:host ::ng-deep .filter-select .mat-mdc-select-arrow-wrapper{padding-left:.5rem}.widget-body{display:flex;gap:2.5rem;align-items:flex-start}.left-section{flex:2;display:flex;flex-direction:column;gap:1rem}.chart-section{display:flex;gap:1.5rem;align-items:center}.chart-wrapper{width:220px;min-height:220px;flex-shrink:0}.chart-wrapper apx-chart{width:220px!important;height:220px!important}.legend{display:flex;flex-direction:column;gap:.75rem}.legend-item{display:flex;align-items:center;gap:.5rem;font-family:Inter,Inter,sans-serif;font-size:14px}.legend-marker{width:14px;height:14px;border-radius:50%;display:inline-flex}.legend-label{color:#4b5563}.legend-value{margin-left:auto;font-weight:600;color:#111827}.divider{width:1px;min-height:200px;align-self:stretch;background:#e5e7eb}.table-section{flex:3;display:flex;flex-direction:column;gap:.75rem;font-family:Inter,Inter,sans-serif}.lic-table-header,.table-row{display:flex;justify-content:space-between;font-size:14px}.lic-table-header{font-weight:600;color:#6b7280;padding-bottom:.5rem;border-bottom:1px solid #e5e7eb}.table-row{color:#111827}.total-row{font-weight:700;margin-top:.5rem;padding-top:.5rem;border-top:1px solid #e5e7eb}.state-message{font-family:Inter,Inter,sans-serif;font-size:14px;color:#6b7280}.state-message.error{color:#b91c1c}@media (max-width: 960px){.widget-body{flex-direction:column}.divider{display:none}.chart-section{justify-content:space-between}}:host ::ng-deep .apexcharts-legend{display:none!important}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i3.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: CardComponent, selector: "tk-card", inputs: ["title", "dense"] }, { kind: "component", type: i5.ChartComponent, selector: "apx-chart", inputs: ["chart", "annotations", "colors", "dataLabels", "series", "stroke", "labels", "legend", "markers", "noData", "fill", "tooltip", "plotOptions", "responsive", "xaxis", "yaxis", "forecastDataPoints", "grid", "states", "title", "subtitle", "theme", "autoUpdateSeries"] }, { kind: "pipe", type: i1$1.DecimalPipe, name: "number" }] });
341
384
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: LicencesRequirementComponent, decorators: [{
342
385
  type: Component,
343
386
  args: [{ selector: 'cc-licenses-requirement', template: "<tk-card title=\"Licenses requirement\">\r\n <ng-container ngProjectAs=\"card-content\">\r\n <div\r\n class=\"widget-body\"\r\n *ngIf=\"!loading && !error && viewModel; else widgetState\"\r\n >\r\n <div class=\"left-section\">\r\n <mat-select\r\n [(value)]=\"selectedSummaryIndex\"\r\n (selectionChange)=\"onFilterChange($event.value)\"\r\n class=\"filter-select\"\r\n >\r\n <mat-option *ngFor=\"let option of filters; index as i\" [value]=\"i\">\r\n {{ option }}\r\n </mat-option>\r\n </mat-select>\r\n\r\n <div class=\"chart-section\">\r\n <div class=\"chart-wrapper\">\r\n <apx-chart\r\n [series]=\"viewModel.chartOptions.series\"\r\n [chart]=\"viewModel.chartOptions.chart\"\r\n [labels]=\"viewModel.chartOptions.labels\"\r\n [colors]=\"viewModel.chartOptions.colors\"\r\n [legend]=\"viewModel.chartOptions.legend\"\r\n [plotOptions]=\"viewModel.chartOptions.plotOptions\"\r\n [dataLabels]=\"viewModel.chartOptions.dataLabels\"\r\n [tooltip]=\"viewModel.chartOptions.tooltip\"\r\n >\r\n </apx-chart>\r\n </div>\r\n <div class=\"legend\">\r\n <div class=\"legend-item\" *ngFor=\"let item of viewModel.legendItems\">\r\n <span\r\n class=\"legend-marker\"\r\n [style.backgroundColor]=\"item.color\"\r\n ></span>\r\n <span class=\"legend-label\">{{ item.label }}</span>\r\n <span class=\"legend-value\">{{ item.count | number }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"divider\" aria-hidden=\"true\"></div>\r\n\r\n <div class=\"table-section\">\r\n <div class=\"lic-table-header\">\r\n <span>License</span>\r\n <span>Required</span>\r\n </div>\r\n <div class=\"table-row\" *ngFor=\"let row of viewModel.rows\">\r\n <span>{{ row.label }}</span>\r\n <span>{{ row.value | number }}</span>\r\n </div>\r\n <div class=\"table-row total-row\">\r\n <span>Total</span>\r\n <span>{{ viewModel.totalRequired | number }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <ng-template #widgetState>\r\n <div class=\"state-message\" *ngIf=\"loading\">\r\n Loading license requirements\u2026\r\n </div>\r\n <div class=\"state-message error\" *ngIf=\"!loading && error\">\r\n Unable to load license requirements.\r\n </div>\r\n <div class=\"state-message\" *ngIf=\"!loading && !error && !viewModel\">\r\n No license data available.\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n</tk-card>\r\n", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";:host{display:block;width:100%;box-sizing:border-box}.filter-select{font-family:Inter,Inter,sans-serif;font-size:14px;min-width:140px;border:1px solid #e5e7eb;border-radius:.5rem;padding:.5rem .75rem;background-color:#fff}.filter-select:hover{border-color:#d1d5db}:host ::ng-deep .filter-select.mat-mdc-select{border:1px solid #e5e7eb;border-radius:.5rem;background-color:#fff}:host ::ng-deep .filter-select.mat-mdc-select:hover{border-color:#d1d5db}:host ::ng-deep .filter-select.mat-mdc-select.mat-focused{border-color:#16a693}:host ::ng-deep .filter-select .mat-mdc-select-trigger{font-size:14px;padding:.5rem .75rem}:host ::ng-deep .filter-select .mat-mdc-select-value{color:#111827}:host ::ng-deep .filter-select .mat-mdc-select-arrow-wrapper{padding-left:.5rem}.widget-body{display:flex;gap:2.5rem;align-items:flex-start}.left-section{flex:2;display:flex;flex-direction:column;gap:1rem}.chart-section{display:flex;gap:1.5rem;align-items:center}.chart-wrapper{width:220px;min-height:220px;flex-shrink:0}.chart-wrapper apx-chart{width:220px!important;height:220px!important}.legend{display:flex;flex-direction:column;gap:.75rem}.legend-item{display:flex;align-items:center;gap:.5rem;font-family:Inter,Inter,sans-serif;font-size:14px}.legend-marker{width:14px;height:14px;border-radius:50%;display:inline-flex}.legend-label{color:#4b5563}.legend-value{margin-left:auto;font-weight:600;color:#111827}.divider{width:1px;min-height:200px;align-self:stretch;background:#e5e7eb}.table-section{flex:3;display:flex;flex-direction:column;gap:.75rem;font-family:Inter,Inter,sans-serif}.lic-table-header,.table-row{display:flex;justify-content:space-between;font-size:14px}.lic-table-header{font-weight:600;color:#6b7280;padding-bottom:.5rem;border-bottom:1px solid #e5e7eb}.table-row{color:#111827}.total-row{font-weight:700;margin-top:.5rem;padding-top:.5rem;border-top:1px solid #e5e7eb}.state-message{font-family:Inter,Inter,sans-serif;font-size:14px;color:#6b7280}.state-message.error{color:#b91c1c}@media (max-width: 960px){.widget-body{flex-direction:column}.divider{display:none}.chart-section{justify-content:space-between}}:host ::ng-deep .apexcharts-legend{display:none!important}\n"] }]
@@ -381,7 +424,7 @@ class SummaryGridComponent {
381
424
  }
382
425
  }
383
426
  SummaryGridComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SummaryGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
384
- SummaryGridComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: SummaryGridComponent, selector: "cc-summary-grid", inputs: { customerId: "customerId", host: "host", token: "token" }, ngImport: i0, template: "<ng-container *ngIf=\"data$ | async as data\">\r\n <div *ngFor=\"let stats of data\">\r\n <tk-card [title]=\"stats.uccxIp\">\r\n <ng-container ngProjectAs=\"card-content\">\r\n <div class=\"grid-wrapper\">\r\n <div class=\"grid-item\" *ngFor=\"let item of stats.counts\">\r\n <div class=\"item-top\">\r\n <span class=\"item-icon\">\r\n <img width=\"24\" height=\"24\" src=\"assets/icons/{{ item.name }}.svg\" alt=\"{{ item.name }} Icon\">\r\n </span>\r\n <span class=\"item-count\">{{ item.value }}</span>\r\n </div>\r\n <span class=\"item-label\">{{ ENTITY_CONFIG[item.name].label }}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </tk-card>\r\n </div>\r\n</ng-container>", styles: [".grid-wrapper{display:grid;grid-template-columns:repeat(6,1fr);gap:2rem;row-gap:2rem}.grid-item{display:flex;flex-direction:column;gap:.5rem}.item-top{display:flex;align-items:center;gap:inherit}.item-icon{display:flex;align-items:center;background-color:#f2f2f2;padding:.75rem;border-radius:.5rem}.item-count{font-size:30px}.item-label{font-size:14px;margin-left:.15rem}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CardComponent, selector: "tk-card", inputs: ["title"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }] });
427
+ SummaryGridComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: SummaryGridComponent, selector: "cc-summary-grid", inputs: { customerId: "customerId", host: "host", token: "token" }, ngImport: i0, template: "<ng-container *ngIf=\"data$ | async as data\">\r\n <div *ngFor=\"let stats of data\">\r\n <tk-card [title]=\"stats.uccxIp\">\r\n <ng-container ngProjectAs=\"card-content\">\r\n <div class=\"grid-wrapper\">\r\n <div class=\"grid-item\" *ngFor=\"let item of stats.counts\">\r\n <div class=\"item-top\">\r\n <span class=\"item-icon\">\r\n <img width=\"24\" height=\"24\" src=\"assets/icons/{{ item.name }}.svg\" alt=\"{{ item.name }} Icon\">\r\n </span>\r\n <span class=\"item-count\">{{ item.value }}</span>\r\n </div>\r\n <span class=\"item-label\">{{ ENTITY_CONFIG[item.name].label }}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </tk-card>\r\n </div>\r\n</ng-container>", styles: [".grid-wrapper{display:grid;grid-template-columns:repeat(6,1fr);gap:2rem;row-gap:2rem}.grid-item{display:flex;flex-direction:column;gap:.5rem}.item-top{display:flex;align-items:center;gap:inherit}.item-icon{display:flex;align-items:center;background-color:#f2f2f2;padding:.75rem;border-radius:.5rem}.item-count{font-size:30px}.item-label{font-size:14px;margin-left:.15rem}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CardComponent, selector: "tk-card", inputs: ["title", "dense"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }] });
385
428
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SummaryGridComponent, decorators: [{
386
429
  type: Component,
387
430
  args: [{ selector: 'cc-summary-grid', template: "<ng-container *ngIf=\"data$ | async as data\">\r\n <div *ngFor=\"let stats of data\">\r\n <tk-card [title]=\"stats.uccxIp\">\r\n <ng-container ngProjectAs=\"card-content\">\r\n <div class=\"grid-wrapper\">\r\n <div class=\"grid-item\" *ngFor=\"let item of stats.counts\">\r\n <div class=\"item-top\">\r\n <span class=\"item-icon\">\r\n <img width=\"24\" height=\"24\" src=\"assets/icons/{{ item.name }}.svg\" alt=\"{{ item.name }} Icon\">\r\n </span>\r\n <span class=\"item-count\">{{ item.value }}</span>\r\n </div>\r\n <span class=\"item-label\">{{ ENTITY_CONFIG[item.name].label }}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </tk-card>\r\n </div>\r\n</ng-container>", styles: [".grid-wrapper{display:grid;grid-template-columns:repeat(6,1fr);gap:2rem;row-gap:2rem}.grid-item{display:flex;flex-direction:column;gap:.5rem}.item-top{display:flex;align-items:center;gap:inherit}.item-icon{display:flex;align-items:center;background-color:#f2f2f2;padding:.75rem;border-radius:.5rem}.item-count{font-size:30px}.item-label{font-size:14px;margin-left:.15rem}\n"] }]
@@ -393,12 +436,116 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
393
436
  type: Input
394
437
  }] } });
395
438
 
439
+ class MaterialModule {
440
+ }
441
+ MaterialModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MaterialModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
442
+ MaterialModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: MaterialModule, imports: [MatProgressBarModule,
443
+ MatTooltipModule,
444
+ MatTableModule,
445
+ MatCheckboxModule,
446
+ MatButtonModule,
447
+ MatIconModule,
448
+ MatFormFieldModule,
449
+ MatInputModule,
450
+ MatSelectModule], exports: [MatProgressBarModule,
451
+ MatTooltipModule,
452
+ MatTableModule,
453
+ MatCheckboxModule,
454
+ MatButtonModule,
455
+ MatIconModule,
456
+ MatFormFieldModule,
457
+ MatInputModule,
458
+ MatSelectModule,
459
+ MatProgressSpinnerModule] });
460
+ MaterialModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MaterialModule, imports: [MatProgressBarModule,
461
+ MatTooltipModule,
462
+ MatTableModule,
463
+ MatCheckboxModule,
464
+ MatButtonModule,
465
+ MatIconModule,
466
+ MatFormFieldModule,
467
+ MatInputModule,
468
+ MatSelectModule, MatProgressBarModule,
469
+ MatTooltipModule,
470
+ MatTableModule,
471
+ MatCheckboxModule,
472
+ MatButtonModule,
473
+ MatIconModule,
474
+ MatFormFieldModule,
475
+ MatInputModule,
476
+ MatSelectModule,
477
+ MatProgressSpinnerModule] });
478
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MaterialModule, decorators: [{
479
+ type: NgModule,
480
+ args: [{
481
+ imports: [
482
+ MatProgressBarModule,
483
+ MatTooltipModule,
484
+ MatTableModule,
485
+ MatCheckboxModule,
486
+ MatButtonModule,
487
+ MatIconModule,
488
+ MatFormFieldModule,
489
+ MatInputModule,
490
+ MatSelectModule
491
+ ],
492
+ exports: [
493
+ MatProgressBarModule,
494
+ MatTooltipModule,
495
+ MatTableModule,
496
+ MatCheckboxModule,
497
+ MatButtonModule,
498
+ MatIconModule,
499
+ MatFormFieldModule,
500
+ MatInputModule,
501
+ MatSelectModule,
502
+ MatProgressSpinnerModule
503
+ ]
504
+ }]
505
+ }] });
506
+
507
+ /**
508
+ * Presentational building blocks shared by the contact-center widgets.
509
+ * Widget modules import this to pick up the standard card chrome plus the
510
+ * Material/Apex modules they all need.
511
+ */
512
+ class SharedModule {
513
+ }
514
+ SharedModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SharedModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
515
+ SharedModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: SharedModule, declarations: [CardComponent], imports: [CommonModule,
516
+ MaterialModule,
517
+ NgApexchartsModule,
518
+ HttpClientModule], exports: [MaterialModule,
519
+ CardComponent] });
520
+ SharedModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SharedModule, imports: [CommonModule,
521
+ MaterialModule,
522
+ NgApexchartsModule,
523
+ HttpClientModule, MaterialModule] });
524
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SharedModule, decorators: [{
525
+ type: NgModule,
526
+ args: [{
527
+ declarations: [
528
+ CardComponent
529
+ ],
530
+ imports: [
531
+ CommonModule,
532
+ MaterialModule,
533
+ NgApexchartsModule,
534
+ HttpClientModule
535
+ ],
536
+ exports: [
537
+ MaterialModule,
538
+ CardComponent
539
+ ]
540
+ }]
541
+ }] });
542
+
396
543
  class CcReadinessModule {
397
544
  }
398
545
  CcReadinessModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CcReadinessModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
399
546
  CcReadinessModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: CcReadinessModule, declarations: [LicencesRequirementComponent,
400
- SummaryGridComponent,
401
- CardComponent], imports: [CommonModule,
547
+ SummaryGridComponent], imports: [CommonModule,
548
+ SharedModule,
402
549
  HttpClientModule,
403
550
  NgApexchartsModule,
404
551
  MatTableModule,
@@ -411,6 +558,7 @@ CcReadinessModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", versi
411
558
  MatSelectModule], exports: [LicencesRequirementComponent,
412
559
  SummaryGridComponent] });
413
560
  CcReadinessModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CcReadinessModule, imports: [CommonModule,
561
+ SharedModule,
414
562
  HttpClientModule,
415
563
  NgApexchartsModule,
416
564
  MatTableModule,
@@ -426,11 +574,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
426
574
  args: [{
427
575
  declarations: [
428
576
  LicencesRequirementComponent,
429
- SummaryGridComponent,
430
- CardComponent
577
+ SummaryGridComponent
431
578
  ],
432
579
  imports: [
433
580
  CommonModule,
581
+ SharedModule,
434
582
  HttpClientModule,
435
583
  NgApexchartsModule,
436
584
  MatTableModule,
@@ -1454,7 +1602,7 @@ class NodeDetailsSidebarComponent {
1454
1602
  }
1455
1603
  }
1456
1604
  NodeDetailsSidebarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NodeDetailsSidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1457
- NodeDetailsSidebarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: NodeDetailsSidebarComponent, selector: "node-details-sidebar", inputs: { isOpen: "isOpen", nodeData: "nodeData" }, outputs: { close: "close", activityTypeChange: "activityTypeChange", descriptionChange: "descriptionChange" }, usesOnChanges: true, ngImport: i0, template: "<!-- <div class=\"sidebar-overlay\" *ngIf=\"isOpen\" (click)=\"onClose()\"></div> -->\r\n\r\n<div class=\"node-details-sidebar\" [class.open]=\"isOpen\">\r\n <div class=\"sidebar-header\">\r\n <h3>Node Details</h3>\r\n <button class=\"close-btn\" (click)=\"onClose()\">\r\n <span>&times;</span>\r\n </button>\r\n </div>\r\n\r\n <div class=\"sidebar-content\" *ngIf=\"nodeData\">\r\n <!-- Node Preview -->\r\n <div class=\"node-preview\">\r\n <div class=\"node-preview-card\" [ngClass]=\"getNodeColorClass()\">\r\n <div class=\"node-icon\">\r\n <img [src]=\"getNodeIcon()\" alt=\"Node Icon\" />\r\n </div>\r\n <div class=\"node-info\">\r\n <div class=\"node-label\">{{ nodeData.name?.split(\"\\n\")?.[0] }}</div>\r\n <div class=\"node-type\">{{ transformedActivityName }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Activity Type Selector -->\r\n <div class=\"section\">\r\n <label class=\"section-label\">Activity Type</label>\r\n <div class=\"display-type-selector\">\r\n <select\r\n class=\"form-control\"\r\n title=\"Select activity type\"\r\n [value]=\"selectedActivityType?.value\"\r\n (change)=\"onActivityTypeSelectChange($event)\"\r\n >\r\n <option\r\n *ngFor=\"let type of activityDisplayTypes; trackBy: trackByValue\"\r\n [value]=\"type.value\"\r\n >\r\n {{ type.label }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section\">\r\n <label class=\"section-label\">Description</label>\r\n <div class=\"display-type-selector\">\r\n <textarea\r\n class=\"form-control\"\r\n aria-label=\"property-description\"\r\n (input)=\"onDescriptionChange($event)\"\r\n [value]=\"nodeData.suggestedProperties?.uccxDescription\"\r\n rows=\"3\"\r\n ></textarea>\r\n </div>\r\n </div>\r\n\r\n <!-- Node Information -->\r\n <div class=\"section\">\r\n <label class=\"section-label\">Information</label>\r\n <div class=\"info-grid\">\r\n <div class=\"info-item\">\r\n <span class=\"info-label\">UCCX Type:</span>\r\n <span class=\"info-value\" [title]=\"nodeData.uccxTypeName\">{{\r\n nodeData.uccxTypeName\r\n }}</span>\r\n </div>\r\n <div class=\"info-item\">\r\n <span class=\"info-label\">WxCC Activity Name:</span>\r\n <span class=\"info-value\" [title]=\"transformedActivityName\">{{\r\n transformedActivityName\r\n }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Review Status -->\r\n <div class=\"section\" *ngIf=\"nodeData.review\">\r\n <label class=\"section-label\">Review Status</label>\r\n <div class=\"review-status\">\r\n <div class=\"review-badge\" [style.background-color]=\"getReviewColor()\">\r\n {{ getReviewLabel() }}\r\n </div>\r\n <div\r\n class=\"review-reasons\"\r\n *ngIf=\"nodeData.review.reasons && nodeData.review.reasons.length > 0\"\r\n >\r\n <div class=\"reason\" *ngFor=\"let reason of nodeData.review.reasons\">\r\n <span class=\"reason-icon\">\u26A0</span>\r\n <span>{{ reason }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Suggested Properties -->\r\n <div class=\"section\" *ngIf=\"nodeData.suggestedProperties\">\r\n <label class=\"section-label\">Migration Information</label>\r\n <div class=\"migration-info\">\r\n <div\r\n class=\"info-card\"\r\n *ngIf=\"nodeData.suggestedProperties.closestWxccActivity\"\r\n >\r\n <div class=\"card-label\">Closest WXCC Activity</div>\r\n <div class=\"card-value\">\r\n {{ nodeData.suggestedProperties.closestWxccActivity }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"info-card\"\r\n *ngIf=\"nodeData.suggestedProperties.mappingNotes\"\r\n >\r\n <div class=\"card-label\">Mapping Notes</div>\r\n <div class=\"card-value\">\r\n {{ nodeData.suggestedProperties.mappingNotes }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"info-card\"\r\n *ngIf=\"nodeData.suggestedProperties.migrationInstructions\"\r\n >\r\n <div class=\"card-label\">Migration Instructions</div>\r\n <div class=\"card-value instructions\">\r\n {{ nodeData.suggestedProperties.migrationInstructions }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: ["@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.node-details-sidebar{position:fixed;top:0;right:-420px;width:420px;height:100%;background:#ffffff;box-shadow:-2px 0 8px #00000026;z-index:1000;transition:right .4s cubic-bezier(.4,0,.2,1);display:flex;flex-direction:column;overflow:hidden}.node-details-sidebar.open{right:0}.node-details-sidebar .sidebar-header{display:flex;align-items:center;justify-content:space-between;padding:1.5rem;border-bottom:1px solid #e1e4e8;background:#f8f9fa}.node-details-sidebar .sidebar-header h3{margin:0;font-size:1.25rem;font-weight:600;color:#24292e}.node-details-sidebar .sidebar-header .close-btn{background:none;border:none;font-size:2rem;line-height:1;cursor:pointer;color:#586069;padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:all .2s}.node-details-sidebar .sidebar-header .close-btn:hover{background:rgba(0,0,0,.05);color:#24292e}.node-details-sidebar .sidebar-content{flex:1;overflow-y:auto;padding:1.5rem}.node-details-sidebar .sidebar-content .node-preview{margin-bottom:1.5rem}.node-details-sidebar .sidebar-content .node-preview .node-preview-card{display:flex;align-items:center;gap:1rem;padding:1rem;border-radius:8px}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-icon{display:flex;align-items:center;justify-content:center;width:48px;height:48px;border-radius:8px;flex-shrink:0}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-icon img{width:24px;height:24px}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-info{flex:1;min-width:0}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-info .node-label{font-size:1rem;font-weight:600;margin-bottom:.25rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-info .node-type{font-size:.875rem;color:#586069}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-start{background-color:#4caf500d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-start .node-icon{background-color:#4caf501a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-start .node-label{color:#4caf50}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-end{background-color:#f443360d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-end .node-icon{background-color:#f443361a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-end .node-label{color:#f44336}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-gateway{background-color:#ff98000d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-gateway .node-icon{background-color:#ff98001a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-gateway .node-label{color:#ff9800}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-action{background-color:#9c27b00d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-action .node-icon{background-color:#9c27b01a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-action .node-label{color:#9c27b0}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-default{background-color:#607d8b0d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-default .node-icon{background-color:#607d8b1a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-default .node-label{color:#607d8b}.node-details-sidebar .sidebar-content .section{margin-bottom:1.5rem}.node-details-sidebar .sidebar-content .section .section-label{display:block;font-size:.65rem;font-weight:600;color:#24292e;margin-bottom:.75rem;text-transform:uppercase;letter-spacing:.5px}.node-details-sidebar .sidebar-content .section .display-type-selector .form-control{width:100%;padding:.625rem .875rem;font-size:.875rem;border:1px solid #d1d5da;border-radius:6px;background:white;transition:border-color .2s;box-sizing:border-box;resize:vertical}.node-details-sidebar .sidebar-content .section .display-type-selector .form-control:focus{outline:none;border-color:#0366d6;box-shadow:0 0 0 3px #0366d61a}.node-details-sidebar .sidebar-content .section .info-grid{display:flex;flex-direction:column;gap:.75rem}.node-details-sidebar .sidebar-content .section .info-grid .info-item{display:flex;justify-content:space-between;align-items:flex-start;padding:.75rem;background:#f6f8fa;border-radius:6px}.node-details-sidebar .sidebar-content .section .info-grid .info-item .info-label{font-size:.8125rem;color:#586069;font-weight:500}.node-details-sidebar .sidebar-content .section .info-grid .info-item .info-value{font-size:.8125rem;color:#24292e;font-weight:600;text-align:right;max-width:60%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.node-details-sidebar .sidebar-content .section .review-status .review-badge{display:inline-block;padding:.5rem 1rem;border-radius:20px;color:#fff;font-size:.8125rem;font-weight:600;margin-bottom:.75rem}.node-details-sidebar .sidebar-content .section .review-status .review-reasons .reason{display:flex;align-items:flex-start;gap:.5rem;padding:.75rem;background:#fff3cd;border-radius:4px;margin-bottom:.5rem;font-size:.8125rem;color:#856404}.node-details-sidebar .sidebar-content .section .review-status .review-reasons .reason .reason-icon{flex-shrink:0}.node-details-sidebar .sidebar-content .section .migration-info .info-card{padding:1rem;background:#f6f8fa;border-radius:6px;margin-bottom:.75rem}.node-details-sidebar .sidebar-content .section .migration-info .info-card:last-child{margin-bottom:0}.node-details-sidebar .sidebar-content .section .migration-info .info-card .card-label{font-size:.75rem;font-weight:600;color:#586069;text-transform:uppercase;letter-spacing:.5px;margin-bottom:.5rem}.node-details-sidebar .sidebar-content .section .migration-info .info-card .card-value{font-size:.875rem;color:#24292e;line-height:1.5}.node-details-sidebar .sidebar-content .section .migration-info .info-card .card-value.instructions{white-space:pre-wrap}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1605
+ NodeDetailsSidebarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: NodeDetailsSidebarComponent, selector: "node-details-sidebar", inputs: { isOpen: "isOpen", nodeData: "nodeData" }, outputs: { close: "close", activityTypeChange: "activityTypeChange", descriptionChange: "descriptionChange" }, usesOnChanges: true, ngImport: i0, template: "<!-- <div class=\"sidebar-overlay\" *ngIf=\"isOpen\" (click)=\"onClose()\"></div> -->\r\n\r\n<div class=\"node-details-sidebar\" [class.open]=\"isOpen\">\r\n <div class=\"sidebar-header\">\r\n <h3>Node Details</h3>\r\n <button class=\"close-btn\" (click)=\"onClose()\">\r\n <span>&times;</span>\r\n </button>\r\n </div>\r\n\r\n <div class=\"sidebar-content\" *ngIf=\"nodeData\">\r\n <!-- Node Preview -->\r\n <div class=\"node-preview\">\r\n <div class=\"node-preview-card\" [ngClass]=\"getNodeColorClass()\">\r\n <div class=\"node-icon\">\r\n <img [src]=\"getNodeIcon()\" alt=\"Node Icon\" />\r\n </div>\r\n <div class=\"node-info\">\r\n <div class=\"node-label\">{{ nodeData.name?.split(\"\\n\")?.[0] }}</div>\r\n <div class=\"node-type\">{{ transformedActivityName }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Activity Type Selector -->\r\n <div class=\"section\">\r\n <label class=\"section-label\">Activity Type</label>\r\n <div class=\"display-type-selector\">\r\n <select\r\n class=\"form-control\"\r\n title=\"Select activity type\"\r\n [value]=\"selectedActivityType?.value\"\r\n (change)=\"onActivityTypeSelectChange($event)\"\r\n >\r\n <option\r\n *ngFor=\"let type of activityDisplayTypes; trackBy: trackByValue\"\r\n [value]=\"type.value\"\r\n >\r\n {{ type.label }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section\">\r\n <label class=\"section-label\">Description</label>\r\n <div class=\"display-type-selector\">\r\n <textarea\r\n class=\"form-control\"\r\n aria-label=\"property-description\"\r\n (input)=\"onDescriptionChange($event)\"\r\n [value]=\"nodeData.suggestedProperties?.uccxDescription\"\r\n rows=\"3\"\r\n ></textarea>\r\n </div>\r\n </div>\r\n\r\n <!-- Node Information -->\r\n <div class=\"section\">\r\n <label class=\"section-label\">Information</label>\r\n <div class=\"info-grid\">\r\n <div class=\"info-item\">\r\n <span class=\"info-label\">UCCX Type:</span>\r\n <span class=\"info-value\" [title]=\"nodeData.uccxTypeName\">{{\r\n nodeData.uccxTypeName\r\n }}</span>\r\n </div>\r\n <div class=\"info-item\">\r\n <span class=\"info-label\">WxCC Activity Name:</span>\r\n <span class=\"info-value\" [title]=\"transformedActivityName\">{{\r\n transformedActivityName\r\n }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Review Status -->\r\n <div class=\"section\" *ngIf=\"nodeData.review\">\r\n <label class=\"section-label\">Review Status</label>\r\n <div class=\"review-status\">\r\n <div class=\"review-badge\" [style.background-color]=\"getReviewColor()\">\r\n {{ getReviewLabel() }}\r\n </div>\r\n <div\r\n class=\"review-reasons\"\r\n *ngIf=\"nodeData.review.reasons && nodeData.review.reasons.length > 0\"\r\n >\r\n <div class=\"reason\" *ngFor=\"let reason of nodeData.review.reasons\">\r\n <span class=\"reason-icon\">\u26A0</span>\r\n <span>{{ reason }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Suggested Properties -->\r\n <div class=\"section\" *ngIf=\"nodeData.suggestedProperties\">\r\n <label class=\"section-label\">Migration Information</label>\r\n <div class=\"migration-info\">\r\n <div\r\n class=\"info-card\"\r\n *ngIf=\"nodeData.suggestedProperties.closestWxccActivity\"\r\n >\r\n <div class=\"card-label\">Closest WXCC Activity</div>\r\n <div class=\"card-value\">\r\n {{ nodeData.suggestedProperties.closestWxccActivity }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"info-card\"\r\n *ngIf=\"nodeData.suggestedProperties.mappingNotes\"\r\n >\r\n <div class=\"card-label\">Mapping Notes</div>\r\n <div class=\"card-value\">\r\n {{ nodeData.suggestedProperties.mappingNotes }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"info-card\"\r\n *ngIf=\"nodeData.suggestedProperties.migrationInstructions\"\r\n >\r\n <div class=\"card-label\">Migration Instructions</div>\r\n <div class=\"card-value instructions\">\r\n {{ nodeData.suggestedProperties.migrationInstructions }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: ["@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.node-details-sidebar{position:fixed;top:0;right:-420px;width:420px;height:100%;background:#ffffff;box-shadow:-2px 0 8px #00000026;z-index:1000;transition:right .4s cubic-bezier(.4,0,.2,1);display:flex;flex-direction:column;overflow:hidden}.node-details-sidebar.open{right:0}.node-details-sidebar .sidebar-header{display:flex;align-items:center;justify-content:space-between;padding:1.5rem;border-bottom:1px solid #e1e4e8;background:#f8f9fa}.node-details-sidebar .sidebar-header h3{margin:0;font-size:1.25rem;font-weight:600;color:#24292e}.node-details-sidebar .sidebar-header .close-btn{background:none;border:none;font-size:2rem;line-height:1;cursor:pointer;color:#586069;padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:all .2s}.node-details-sidebar .sidebar-header .close-btn:hover{background:rgba(0,0,0,.05);color:#24292e}.node-details-sidebar .sidebar-content{flex:1;overflow-y:auto;padding:1.5rem}.node-details-sidebar .sidebar-content .node-preview{margin-bottom:1.5rem}.node-details-sidebar .sidebar-content .node-preview .node-preview-card{display:flex;align-items:center;gap:1rem;padding:1rem;border-radius:8px}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-icon{display:flex;align-items:center;justify-content:center;width:48px;height:48px;border-radius:8px;flex-shrink:0}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-icon img{width:24px;height:24px}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-info{flex:1;min-width:0}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-info .node-label{font-size:1rem;font-weight:600;margin-bottom:.25rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-info .node-type{font-size:.875rem;color:#586069}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-start{background-color:#4caf500d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-start .node-icon{background-color:#4caf501a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-start .node-label{color:#4caf50}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-end{background-color:#f443360d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-end .node-icon{background-color:#f443361a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-end .node-label{color:#f44336}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-gateway{background-color:#ff98000d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-gateway .node-icon{background-color:#ff98001a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-gateway .node-label{color:#ff9800}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-action{background-color:#9c27b00d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-action .node-icon{background-color:#9c27b01a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-action .node-label{color:#9c27b0}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-default{background-color:#607d8b0d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-default .node-icon{background-color:#607d8b1a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-default .node-label{color:#607d8b}.node-details-sidebar .sidebar-content .section{margin-bottom:1.5rem}.node-details-sidebar .sidebar-content .section .section-label{display:block;font-size:.65rem;font-weight:600;color:#24292e;margin-bottom:.75rem;text-transform:uppercase;letter-spacing:.5px}.node-details-sidebar .sidebar-content .section .display-type-selector .form-control{width:100%;padding:.625rem .875rem;font-size:.875rem;border:1px solid #d1d5da;border-radius:6px;background:white;transition:border-color .2s;box-sizing:border-box;resize:vertical}.node-details-sidebar .sidebar-content .section .display-type-selector .form-control:focus{outline:none;border-color:#0366d6;box-shadow:0 0 0 3px #0366d61a}.node-details-sidebar .sidebar-content .section .info-grid{display:flex;flex-direction:column;gap:.75rem}.node-details-sidebar .sidebar-content .section .info-grid .info-item{display:flex;justify-content:space-between;align-items:flex-start;padding:.75rem;background:#f6f8fa;border-radius:6px}.node-details-sidebar .sidebar-content .section .info-grid .info-item .info-label{font-size:.8125rem;color:#586069;font-weight:500}.node-details-sidebar .sidebar-content .section .info-grid .info-item .info-value{font-size:.8125rem;color:#24292e;font-weight:600;text-align:right;max-width:60%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.node-details-sidebar .sidebar-content .section .review-status .review-badge{display:inline-block;padding:.5rem 1rem;border-radius:20px;color:#fff;font-size:.8125rem;font-weight:600;margin-bottom:.75rem}.node-details-sidebar .sidebar-content .section .review-status .review-reasons .reason{display:flex;align-items:flex-start;gap:.5rem;padding:.75rem;background:#fff3cd;border-radius:4px;margin-bottom:.5rem;font-size:.8125rem;color:#856404}.node-details-sidebar .sidebar-content .section .review-status .review-reasons .reason .reason-icon{flex-shrink:0}.node-details-sidebar .sidebar-content .section .migration-info .info-card{padding:1rem;background:#f6f8fa;border-radius:6px;margin-bottom:.75rem}.node-details-sidebar .sidebar-content .section .migration-info .info-card:last-child{margin-bottom:0}.node-details-sidebar .sidebar-content .section .migration-info .info-card .card-label{font-size:.75rem;font-weight:600;color:#586069;text-transform:uppercase;letter-spacing:.5px;margin-bottom:.5rem}.node-details-sidebar .sidebar-content .section .migration-info .info-card .card-value{font-size:.875rem;color:#24292e;line-height:1.5}.node-details-sidebar .sidebar-content .section .migration-info .info-card .card-value.instructions{white-space:pre-wrap}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1458
1606
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NodeDetailsSidebarComponent, decorators: [{
1459
1607
  type: Component,
1460
1608
  args: [{ selector: 'node-details-sidebar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- <div class=\"sidebar-overlay\" *ngIf=\"isOpen\" (click)=\"onClose()\"></div> -->\r\n\r\n<div class=\"node-details-sidebar\" [class.open]=\"isOpen\">\r\n <div class=\"sidebar-header\">\r\n <h3>Node Details</h3>\r\n <button class=\"close-btn\" (click)=\"onClose()\">\r\n <span>&times;</span>\r\n </button>\r\n </div>\r\n\r\n <div class=\"sidebar-content\" *ngIf=\"nodeData\">\r\n <!-- Node Preview -->\r\n <div class=\"node-preview\">\r\n <div class=\"node-preview-card\" [ngClass]=\"getNodeColorClass()\">\r\n <div class=\"node-icon\">\r\n <img [src]=\"getNodeIcon()\" alt=\"Node Icon\" />\r\n </div>\r\n <div class=\"node-info\">\r\n <div class=\"node-label\">{{ nodeData.name?.split(\"\\n\")?.[0] }}</div>\r\n <div class=\"node-type\">{{ transformedActivityName }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Activity Type Selector -->\r\n <div class=\"section\">\r\n <label class=\"section-label\">Activity Type</label>\r\n <div class=\"display-type-selector\">\r\n <select\r\n class=\"form-control\"\r\n title=\"Select activity type\"\r\n [value]=\"selectedActivityType?.value\"\r\n (change)=\"onActivityTypeSelectChange($event)\"\r\n >\r\n <option\r\n *ngFor=\"let type of activityDisplayTypes; trackBy: trackByValue\"\r\n [value]=\"type.value\"\r\n >\r\n {{ type.label }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section\">\r\n <label class=\"section-label\">Description</label>\r\n <div class=\"display-type-selector\">\r\n <textarea\r\n class=\"form-control\"\r\n aria-label=\"property-description\"\r\n (input)=\"onDescriptionChange($event)\"\r\n [value]=\"nodeData.suggestedProperties?.uccxDescription\"\r\n rows=\"3\"\r\n ></textarea>\r\n </div>\r\n </div>\r\n\r\n <!-- Node Information -->\r\n <div class=\"section\">\r\n <label class=\"section-label\">Information</label>\r\n <div class=\"info-grid\">\r\n <div class=\"info-item\">\r\n <span class=\"info-label\">UCCX Type:</span>\r\n <span class=\"info-value\" [title]=\"nodeData.uccxTypeName\">{{\r\n nodeData.uccxTypeName\r\n }}</span>\r\n </div>\r\n <div class=\"info-item\">\r\n <span class=\"info-label\">WxCC Activity Name:</span>\r\n <span class=\"info-value\" [title]=\"transformedActivityName\">{{\r\n transformedActivityName\r\n }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Review Status -->\r\n <div class=\"section\" *ngIf=\"nodeData.review\">\r\n <label class=\"section-label\">Review Status</label>\r\n <div class=\"review-status\">\r\n <div class=\"review-badge\" [style.background-color]=\"getReviewColor()\">\r\n {{ getReviewLabel() }}\r\n </div>\r\n <div\r\n class=\"review-reasons\"\r\n *ngIf=\"nodeData.review.reasons && nodeData.review.reasons.length > 0\"\r\n >\r\n <div class=\"reason\" *ngFor=\"let reason of nodeData.review.reasons\">\r\n <span class=\"reason-icon\">\u26A0</span>\r\n <span>{{ reason }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Suggested Properties -->\r\n <div class=\"section\" *ngIf=\"nodeData.suggestedProperties\">\r\n <label class=\"section-label\">Migration Information</label>\r\n <div class=\"migration-info\">\r\n <div\r\n class=\"info-card\"\r\n *ngIf=\"nodeData.suggestedProperties.closestWxccActivity\"\r\n >\r\n <div class=\"card-label\">Closest WXCC Activity</div>\r\n <div class=\"card-value\">\r\n {{ nodeData.suggestedProperties.closestWxccActivity }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"info-card\"\r\n *ngIf=\"nodeData.suggestedProperties.mappingNotes\"\r\n >\r\n <div class=\"card-label\">Mapping Notes</div>\r\n <div class=\"card-value\">\r\n {{ nodeData.suggestedProperties.mappingNotes }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"info-card\"\r\n *ngIf=\"nodeData.suggestedProperties.migrationInstructions\"\r\n >\r\n <div class=\"card-label\">Migration Instructions</div>\r\n <div class=\"card-value instructions\">\r\n {{ nodeData.suggestedProperties.migrationInstructions }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: ["@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.node-details-sidebar{position:fixed;top:0;right:-420px;width:420px;height:100%;background:#ffffff;box-shadow:-2px 0 8px #00000026;z-index:1000;transition:right .4s cubic-bezier(.4,0,.2,1);display:flex;flex-direction:column;overflow:hidden}.node-details-sidebar.open{right:0}.node-details-sidebar .sidebar-header{display:flex;align-items:center;justify-content:space-between;padding:1.5rem;border-bottom:1px solid #e1e4e8;background:#f8f9fa}.node-details-sidebar .sidebar-header h3{margin:0;font-size:1.25rem;font-weight:600;color:#24292e}.node-details-sidebar .sidebar-header .close-btn{background:none;border:none;font-size:2rem;line-height:1;cursor:pointer;color:#586069;padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:all .2s}.node-details-sidebar .sidebar-header .close-btn:hover{background:rgba(0,0,0,.05);color:#24292e}.node-details-sidebar .sidebar-content{flex:1;overflow-y:auto;padding:1.5rem}.node-details-sidebar .sidebar-content .node-preview{margin-bottom:1.5rem}.node-details-sidebar .sidebar-content .node-preview .node-preview-card{display:flex;align-items:center;gap:1rem;padding:1rem;border-radius:8px}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-icon{display:flex;align-items:center;justify-content:center;width:48px;height:48px;border-radius:8px;flex-shrink:0}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-icon img{width:24px;height:24px}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-info{flex:1;min-width:0}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-info .node-label{font-size:1rem;font-weight:600;margin-bottom:.25rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-info .node-type{font-size:.875rem;color:#586069}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-start{background-color:#4caf500d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-start .node-icon{background-color:#4caf501a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-start .node-label{color:#4caf50}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-end{background-color:#f443360d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-end .node-icon{background-color:#f443361a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-end .node-label{color:#f44336}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-gateway{background-color:#ff98000d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-gateway .node-icon{background-color:#ff98001a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-gateway .node-label{color:#ff9800}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-action{background-color:#9c27b00d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-action .node-icon{background-color:#9c27b01a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-action .node-label{color:#9c27b0}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-default{background-color:#607d8b0d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-default .node-icon{background-color:#607d8b1a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-default .node-label{color:#607d8b}.node-details-sidebar .sidebar-content .section{margin-bottom:1.5rem}.node-details-sidebar .sidebar-content .section .section-label{display:block;font-size:.65rem;font-weight:600;color:#24292e;margin-bottom:.75rem;text-transform:uppercase;letter-spacing:.5px}.node-details-sidebar .sidebar-content .section .display-type-selector .form-control{width:100%;padding:.625rem .875rem;font-size:.875rem;border:1px solid #d1d5da;border-radius:6px;background:white;transition:border-color .2s;box-sizing:border-box;resize:vertical}.node-details-sidebar .sidebar-content .section .display-type-selector .form-control:focus{outline:none;border-color:#0366d6;box-shadow:0 0 0 3px #0366d61a}.node-details-sidebar .sidebar-content .section .info-grid{display:flex;flex-direction:column;gap:.75rem}.node-details-sidebar .sidebar-content .section .info-grid .info-item{display:flex;justify-content:space-between;align-items:flex-start;padding:.75rem;background:#f6f8fa;border-radius:6px}.node-details-sidebar .sidebar-content .section .info-grid .info-item .info-label{font-size:.8125rem;color:#586069;font-weight:500}.node-details-sidebar .sidebar-content .section .info-grid .info-item .info-value{font-size:.8125rem;color:#24292e;font-weight:600;text-align:right;max-width:60%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.node-details-sidebar .sidebar-content .section .review-status .review-badge{display:inline-block;padding:.5rem 1rem;border-radius:20px;color:#fff;font-size:.8125rem;font-weight:600;margin-bottom:.75rem}.node-details-sidebar .sidebar-content .section .review-status .review-reasons .reason{display:flex;align-items:flex-start;gap:.5rem;padding:.75rem;background:#fff3cd;border-radius:4px;margin-bottom:.5rem;font-size:.8125rem;color:#856404}.node-details-sidebar .sidebar-content .section .review-status .review-reasons .reason .reason-icon{flex-shrink:0}.node-details-sidebar .sidebar-content .section .migration-info .info-card{padding:1rem;background:#f6f8fa;border-radius:6px;margin-bottom:.75rem}.node-details-sidebar .sidebar-content .section .migration-info .info-card:last-child{margin-bottom:0}.node-details-sidebar .sidebar-content .section .migration-info .info-card .card-label{font-size:.75rem;font-weight:600;color:#586069;text-transform:uppercase;letter-spacing:.5px;margin-bottom:.5rem}.node-details-sidebar .sidebar-content .section .migration-info .info-card .card-value{font-size:.875rem;color:#24292e;line-height:1.5}.node-details-sidebar .sidebar-content .section .migration-info .info-card .card-value.instructions{white-space:pre-wrap}\n"] }]
@@ -2115,7 +2263,7 @@ class WxCCFileSelectionBarComponent {
2115
2263
  }
2116
2264
  }
2117
2265
  WxCCFileSelectionBarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCFileSelectionBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2118
- WxCCFileSelectionBarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: WxCCFileSelectionBarComponent, selector: "wxcc-file-selection-bar", inputs: { fileNames: "fileNames", selectedFileName: "selectedFileName", selectedHost: "selectedHost" }, outputs: { fileNameSelectionChange: "fileNameSelectionChange" }, ngImport: i0, template: "<div class=\"file-selection-bar\">\r\n <mat-form-field appearance=\"outline\" class=\"host-selection\" *ngIf=\"hosts?.length\">\r\n <!-- <mat-label>Host</mat-label> -->\r\n <mat-select\r\n [value]=\"selectedHost\"\r\n (selectionChange)=\"onHostSelectionChange($event.value)\">\r\n <mat-option\r\n *ngFor=\"let host of hosts; trackBy: trackByHost\"\r\n title=\"{{ host }}\"\r\n [value]=\"host\">\r\n {{ host }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n\r\n <mat-form-field appearance=\"outline\" class=\"file-selection\">\r\n <!-- <mat-label>Script file</mat-label> -->\r\n <mat-select\r\n [value]=\"selectedFileName\"\r\n (selectionChange)=\"onFileSelectionChange($event.value)\">\r\n <mat-option\r\n *ngFor=\"let name of fileNamesByHost; trackBy: trackByFileName\"\r\n title=\"{{ name }}\"\r\n [value]=\"name\">\r\n {{ name }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n</div>", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";:host ::ng-deep .mat-form-field-appearance-outline .mat-form-field-wrapper{margin:0}:host ::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix{padding:.25rem 0 .5rem}:host ::ng-deep .mat-select-trigger{display:block}:host ::ng-deep .mat-select-trigger .mat-select-arrow-wrapper{transform:none}.file-selection-bar{display:flex;gap:1rem}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "component", type: i3.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i4.MatOption, selector: "mat-option", exportAs: ["matOption"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2266
+ WxCCFileSelectionBarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: WxCCFileSelectionBarComponent, selector: "wxcc-file-selection-bar", inputs: { fileNames: "fileNames", selectedFileName: "selectedFileName", selectedHost: "selectedHost" }, outputs: { fileNameSelectionChange: "fileNameSelectionChange" }, ngImport: i0, template: "<div class=\"file-selection-bar\">\r\n <mat-form-field appearance=\"outline\" class=\"host-selection\" *ngIf=\"hosts?.length\">\r\n <!-- <mat-label>Host</mat-label> -->\r\n <mat-select\r\n [value]=\"selectedHost\"\r\n (selectionChange)=\"onHostSelectionChange($event.value)\">\r\n <mat-option\r\n *ngFor=\"let host of hosts; trackBy: trackByHost\"\r\n title=\"{{ host }}\"\r\n [value]=\"host\">\r\n {{ host }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n\r\n <mat-form-field appearance=\"outline\" class=\"file-selection\">\r\n <!-- <mat-label>Script file</mat-label> -->\r\n <mat-select\r\n [value]=\"selectedFileName\"\r\n (selectionChange)=\"onFileSelectionChange($event.value)\">\r\n <mat-option\r\n *ngFor=\"let name of fileNamesByHost; trackBy: trackByFileName\"\r\n title=\"{{ name }}\"\r\n [value]=\"name\">\r\n {{ name }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n</div>", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";:host ::ng-deep .mat-form-field-appearance-outline .mat-form-field-wrapper{margin:0}:host ::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix{padding:.25rem 0 .5rem}:host ::ng-deep .mat-select-trigger{display:block}:host ::ng-deep .mat-select-trigger .mat-select-arrow-wrapper{transform:none}.file-selection-bar{display:flex;gap:1rem}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i3.MatOption, selector: "mat-option", exportAs: ["matOption"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2119
2267
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCFileSelectionBarComponent, decorators: [{
2120
2268
  type: Component,
2121
2269
  args: [{ selector: 'wxcc-file-selection-bar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"file-selection-bar\">\r\n <mat-form-field appearance=\"outline\" class=\"host-selection\" *ngIf=\"hosts?.length\">\r\n <!-- <mat-label>Host</mat-label> -->\r\n <mat-select\r\n [value]=\"selectedHost\"\r\n (selectionChange)=\"onHostSelectionChange($event.value)\">\r\n <mat-option\r\n *ngFor=\"let host of hosts; trackBy: trackByHost\"\r\n title=\"{{ host }}\"\r\n [value]=\"host\">\r\n {{ host }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n\r\n <mat-form-field appearance=\"outline\" class=\"file-selection\">\r\n <!-- <mat-label>Script file</mat-label> -->\r\n <mat-select\r\n [value]=\"selectedFileName\"\r\n (selectionChange)=\"onFileSelectionChange($event.value)\">\r\n <mat-option\r\n *ngFor=\"let name of fileNamesByHost; trackBy: trackByFileName\"\r\n title=\"{{ name }}\"\r\n [value]=\"name\">\r\n {{ name }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n</div>", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";:host ::ng-deep .mat-form-field-appearance-outline .mat-form-field-wrapper{margin:0}:host ::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix{padding:.25rem 0 .5rem}:host ::ng-deep .mat-select-trigger{display:block}:host ::ng-deep .mat-select-trigger .mat-select-arrow-wrapper{transform:none}.file-selection-bar{display:flex;gap:1rem}\n"] }]
@@ -3270,7 +3418,7 @@ class WxCCFlowchartPageComponent {
3270
3418
  }
3271
3419
  }
3272
3420
  WxCCFlowchartPageComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCFlowchartPageComponent, deps: [{ token: WxCCAPIService }, { token: WxCC2GraphService }], target: i0.ɵɵFactoryTarget.Component });
3273
- WxCCFlowchartPageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: WxCCFlowchartPageComponent, selector: "cc-script-editor", inputs: { customerId: "customerId", host: "host", token: "token" }, ngImport: i0, template: "<div class=\"wxcc-flowchart-wrapper\">\r\n <header class=\"wxcc-flowchart-header\">\r\n <wxcc-file-selection-bar\r\n *ngIf=\"state.fileNames && state.fileNames.length\"\r\n [fileNames]=\"state.fileNames\"\r\n [selectedHost]=\"state.uccxIp\"\r\n [selectedFileName]=\"state.selectedFileName\"\r\n (fileNameSelectionChange)=\"onFileNameSelectionChange($event)\">\r\n </wxcc-file-selection-bar>\r\n <wxcc-actions-bar\r\n *ngIf=\"state.flowchart\"\r\n (save)=\"onSave()\"\r\n (reset)=\"onReset()\"\r\n (exportNonIr)=\"onExportNonIr()\"\r\n (complete)=\"onComplete()\">\r\n </wxcc-actions-bar>\r\n </header>\r\n <ng-container *ngIf=\"!state.loading; else loadingTemplate\">\r\n <wxcc-flowchart\r\n *ngIf=\"state.flowchart; else errorTemplate\"\r\n [flowchart]=\"state.flowchart\">\r\n </wxcc-flowchart>\r\n </ng-container>\r\n</div>\r\n\r\n<ng-template #loadingTemplate>\r\n <div class=\"placeholder-wrapper\">\r\n <mat-spinner diameter=\"40\"></mat-spinner>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #errorTemplate>\r\n <div class=\"placeholder-wrapper\">\r\n Error loading script\r\n </div>\r\n</ng-template>\r\n", styles: [":host{display:block;width:100%;height:100%}.wxcc-flowchart-wrapper{width:100%;height:100%;display:flex;gap:.5rem;flex-direction:column}.wxcc-flowchart-wrapper .wxcc-flowchart-header{display:flex;align-items:center;justify-content:space-between;flex-shrink:0}.wxcc-flowchart-wrapper .placeholder-wrapper{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: WxCCFlowchartComponent, selector: "wxcc-flowchart", inputs: ["flowchart"] }, { kind: "component", type: WxCCFileSelectionBarComponent, selector: "wxcc-file-selection-bar", inputs: ["fileNames", "selectedFileName", "selectedHost"], outputs: ["fileNameSelectionChange"] }, { kind: "component", type: WxCCActionsBarComponent, selector: "wxcc-actions-bar", outputs: ["save", "reset", "complete", "exportNonIr"] }] });
3421
+ WxCCFlowchartPageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: WxCCFlowchartPageComponent, selector: "cc-script-editor", inputs: { customerId: "customerId", host: "host", token: "token" }, ngImport: i0, template: "<div class=\"wxcc-flowchart-wrapper\">\r\n <header class=\"wxcc-flowchart-header\">\r\n <wxcc-file-selection-bar\r\n *ngIf=\"state.fileNames && state.fileNames.length\"\r\n [fileNames]=\"state.fileNames\"\r\n [selectedHost]=\"state.uccxIp\"\r\n [selectedFileName]=\"state.selectedFileName\"\r\n (fileNameSelectionChange)=\"onFileNameSelectionChange($event)\">\r\n </wxcc-file-selection-bar>\r\n <wxcc-actions-bar\r\n *ngIf=\"state.flowchart\"\r\n (save)=\"onSave()\"\r\n (reset)=\"onReset()\"\r\n (exportNonIr)=\"onExportNonIr()\"\r\n (complete)=\"onComplete()\">\r\n </wxcc-actions-bar>\r\n </header>\r\n <ng-container *ngIf=\"!state.loading; else loadingTemplate\">\r\n <wxcc-flowchart\r\n *ngIf=\"state.flowchart; else errorTemplate\"\r\n [flowchart]=\"state.flowchart\">\r\n </wxcc-flowchart>\r\n </ng-container>\r\n</div>\r\n\r\n<ng-template #loadingTemplate>\r\n <div class=\"placeholder-wrapper\">\r\n <mat-spinner diameter=\"40\"></mat-spinner>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #errorTemplate>\r\n <div class=\"placeholder-wrapper\">\r\n Error loading script\r\n </div>\r\n</ng-template>\r\n", styles: [":host{display:block;width:100%;height:100%}.wxcc-flowchart-wrapper{width:100%;height:100%;display:flex;gap:.5rem;flex-direction:column}.wxcc-flowchart-wrapper .wxcc-flowchart-header{display:flex;align-items:center;justify-content:space-between;flex-shrink:0}.wxcc-flowchart-wrapper .placeholder-wrapper{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: WxCCFlowchartComponent, selector: "wxcc-flowchart", inputs: ["flowchart"] }, { kind: "component", type: WxCCFileSelectionBarComponent, selector: "wxcc-file-selection-bar", inputs: ["fileNames", "selectedFileName", "selectedHost"], outputs: ["fileNameSelectionChange"] }, { kind: "component", type: WxCCActionsBarComponent, selector: "wxcc-actions-bar", outputs: ["save", "reset", "complete", "exportNonIr"] }] });
3274
3422
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCFlowchartPageComponent, decorators: [{
3275
3423
  type: Component,
3276
3424
  args: [{ selector: 'cc-script-editor', template: "<div class=\"wxcc-flowchart-wrapper\">\r\n <header class=\"wxcc-flowchart-header\">\r\n <wxcc-file-selection-bar\r\n *ngIf=\"state.fileNames && state.fileNames.length\"\r\n [fileNames]=\"state.fileNames\"\r\n [selectedHost]=\"state.uccxIp\"\r\n [selectedFileName]=\"state.selectedFileName\"\r\n (fileNameSelectionChange)=\"onFileNameSelectionChange($event)\">\r\n </wxcc-file-selection-bar>\r\n <wxcc-actions-bar\r\n *ngIf=\"state.flowchart\"\r\n (save)=\"onSave()\"\r\n (reset)=\"onReset()\"\r\n (exportNonIr)=\"onExportNonIr()\"\r\n (complete)=\"onComplete()\">\r\n </wxcc-actions-bar>\r\n </header>\r\n <ng-container *ngIf=\"!state.loading; else loadingTemplate\">\r\n <wxcc-flowchart\r\n *ngIf=\"state.flowchart; else errorTemplate\"\r\n [flowchart]=\"state.flowchart\">\r\n </wxcc-flowchart>\r\n </ng-container>\r\n</div>\r\n\r\n<ng-template #loadingTemplate>\r\n <div class=\"placeholder-wrapper\">\r\n <mat-spinner diameter=\"40\"></mat-spinner>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #errorTemplate>\r\n <div class=\"placeholder-wrapper\">\r\n Error loading script\r\n </div>\r\n</ng-template>\r\n", styles: [":host{display:block;width:100%;height:100%}.wxcc-flowchart-wrapper{width:100%;height:100%;display:flex;gap:.5rem;flex-direction:column}.wxcc-flowchart-wrapper .wxcc-flowchart-header{display:flex;align-items:center;justify-content:space-between;flex-shrink:0}.wxcc-flowchart-wrapper .placeholder-wrapper{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}\n"] }]
@@ -3282,101 +3430,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
3282
3430
  type: Input
3283
3431
  }] } });
3284
3432
 
3285
- class MaterialModule {
3286
- }
3287
- MaterialModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MaterialModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3288
- MaterialModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: MaterialModule, imports: [MatProgressBarModule,
3289
- MatTooltipModule,
3290
- MatTableModule,
3291
- MatCheckboxModule,
3292
- MatButtonModule,
3293
- MatIconModule,
3294
- MatFormFieldModule,
3295
- MatInputModule,
3296
- MatSelectModule], exports: [MatProgressBarModule,
3297
- MatTooltipModule,
3298
- MatTableModule,
3299
- MatCheckboxModule,
3300
- MatButtonModule,
3301
- MatIconModule,
3302
- MatFormFieldModule,
3303
- MatInputModule,
3304
- MatSelectModule,
3305
- MatProgressSpinnerModule] });
3306
- MaterialModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MaterialModule, imports: [MatProgressBarModule,
3307
- MatTooltipModule,
3308
- MatTableModule,
3309
- MatCheckboxModule,
3310
- MatButtonModule,
3311
- MatIconModule,
3312
- MatFormFieldModule,
3313
- MatInputModule,
3314
- MatSelectModule, MatProgressBarModule,
3315
- MatTooltipModule,
3316
- MatTableModule,
3317
- MatCheckboxModule,
3318
- MatButtonModule,
3319
- MatIconModule,
3320
- MatFormFieldModule,
3321
- MatInputModule,
3322
- MatSelectModule,
3323
- MatProgressSpinnerModule] });
3324
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MaterialModule, decorators: [{
3325
- type: NgModule,
3326
- args: [{
3327
- imports: [
3328
- MatProgressBarModule,
3329
- MatTooltipModule,
3330
- MatTableModule,
3331
- MatCheckboxModule,
3332
- MatButtonModule,
3333
- MatIconModule,
3334
- MatFormFieldModule,
3335
- MatInputModule,
3336
- MatSelectModule
3337
- ],
3338
- exports: [
3339
- MatProgressBarModule,
3340
- MatTooltipModule,
3341
- MatTableModule,
3342
- MatCheckboxModule,
3343
- MatButtonModule,
3344
- MatIconModule,
3345
- MatFormFieldModule,
3346
- MatInputModule,
3347
- MatSelectModule,
3348
- MatProgressSpinnerModule
3349
- ]
3350
- }]
3351
- }] });
3352
-
3353
- class SharedModule {
3354
- }
3355
- SharedModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SharedModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3356
- SharedModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: SharedModule, imports: [CommonModule,
3357
- MaterialModule,
3358
- NgApexchartsModule,
3359
- HttpClientModule], exports: [MaterialModule] });
3360
- SharedModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SharedModule, imports: [CommonModule,
3361
- MaterialModule,
3362
- NgApexchartsModule,
3363
- HttpClientModule, MaterialModule] });
3364
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SharedModule, decorators: [{
3365
- type: NgModule,
3366
- args: [{
3367
- declarations: [],
3368
- imports: [
3369
- CommonModule,
3370
- MaterialModule,
3371
- NgApexchartsModule,
3372
- HttpClientModule
3373
- ],
3374
- exports: [
3375
- MaterialModule
3376
- ]
3377
- }]
3378
- }] });
3379
-
3380
3433
  class FloatingToolbarModule {
3381
3434
  }
3382
3435
  FloatingToolbarModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FloatingToolbarModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
@@ -3463,9 +3516,818 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
3463
3516
  }]
3464
3517
  }] });
3465
3518
 
3519
+ /**
3520
+ * Same contract as {@link APIService}, pointed at the **dcp** host instead of the
3521
+ * main API host. A handful of UCCX endpoints (application names, file downloads,
3522
+ * dependency analysis) are only served there - webex-ops-client does the same thing
3523
+ * with its `ContactCenterService.customUrl`.
3524
+ *
3525
+ * Registered separately from `APIService` so each keeps its own `apiUrl`/`token`.
3526
+ */
3527
+ class DcpApiService extends APIService {
3528
+ constructor() {
3529
+ super(...arguments);
3530
+ this.apiUrl = window.location.protocol + '//' + window.location.hostname + '/dcp';
3531
+ }
3532
+ }
3533
+ DcpApiService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DcpApiService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
3534
+ DcpApiService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DcpApiService, providedIn: 'root' });
3535
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DcpApiService, decorators: [{
3536
+ type: Injectable,
3537
+ args: [{
3538
+ providedIn: 'root'
3539
+ }]
3540
+ }] });
3541
+
3542
+ /**
3543
+ * The UCCX migration payloads as the backend returns them, mirroring
3544
+ * webex-ops-client's `pages/contact-center/interfaces/uccx-batch.interface.ts`.
3545
+ * Only the fields this widget reads are declared.
3546
+ */
3547
+ /** The `type` values a {@link UccxItem} can carry. */
3548
+ const UCCX_ITEM_TYPE = {
3549
+ RESOURCE_GROUP: 'Resource Group',
3550
+ TRIGGER: 'Trigger',
3551
+ SCRIPT: 'Script',
3552
+ APPLICATION: 'Application',
3553
+ CSQ: 'CSQ',
3554
+ DOCUMENT: 'Document',
3555
+ PHONE_BOOK: 'Phone Book',
3556
+ PROMPT: 'Prompt',
3557
+ REASON_CODE: 'Reason Code',
3558
+ RESOURCE: 'Resource',
3559
+ SKILL: 'Skill',
3560
+ TEAM: 'Team',
3561
+ WRAP_UP_CODE: 'Wrap Up Code'
3562
+ };
3563
+ /** The only call-flow state that counts as imported. */
3564
+ const CALL_FLOW_MIGRATED = 'MIGRATED';
3565
+
3566
+ const CHART_COLORS = {
3567
+ customerAssist: '#177A5C',
3568
+ webexContactCenter: '#D0D0D0',
3569
+ requiresReview: '#1268E3'
3570
+ };
3571
+ /** Compatibility score thresholds, per the ticket's scoring table. */
3572
+ const COMPATIBILITY_THRESHOLDS = {
3573
+ /** 80-100 - migrates to Customer Assist with no functional loss. */
3574
+ migratable: 80,
3575
+ /** 60-79 - migrates to Customer Assist, minor unsupported steps dropped. */
3576
+ requiresReview: 60
3577
+ };
3578
+ /**
3579
+ * Slices of the panel's pie chart, in order: the recommended destination for every
3580
+ * contact center detected in the connected UCCX environment.
3581
+ *
3582
+ * The panel is slice-driven, so re-cutting the chart when the design changes means
3583
+ * editing this array - no component change.
3584
+ */
3585
+ const IMPORT_PANEL_SLICES = [
3586
+ {
3587
+ label: 'To Customer Assist',
3588
+ color: CHART_COLORS.customerAssist,
3589
+ tooltip: 'Fully supported by Customer Assist.',
3590
+ match: contactCenter => contactCenter.compatibilityStatus === 'migratable'
3591
+ },
3592
+ {
3593
+ label: 'Requires Review',
3594
+ color: CHART_COLORS.requiresReview,
3595
+ tooltip: 'Supported by Customer Assist, but a few unsupported steps would change. '
3596
+ + 'Can also go to Webex Contact Center for full feature coverage.',
3597
+ match: contactCenter => contactCenter.compatibilityStatus === 'requires-review'
3598
+ },
3599
+ {
3600
+ label: 'To Webex Contact Center',
3601
+ color: CHART_COLORS.webexContactCenter,
3602
+ tooltip: 'Not supported by Customer Assist - migrate to Webex Contact Center.',
3603
+ match: contactCenter => contactCenter.compatibilityStatus === 'unsupported'
3604
+ }
3605
+ ];
3606
+ /**
3607
+ * How UCCX entity types roll up into the groups the Overview step shows, in display
3608
+ * order. Types not listed here get a group of their own under their raw type name,
3609
+ * so nothing the backend returns is silently dropped.
3610
+ */
3611
+ const OVERVIEW_ENTITY_GROUPS = [
3612
+ { label: 'Channel', types: [UCCX_ITEM_TYPE.TRIGGER] },
3613
+ { label: 'Queues', types: [UCCX_ITEM_TYPE.CSQ] },
3614
+ { label: 'Audio files', types: [UCCX_ITEM_TYPE.PROMPT, UCCX_ITEM_TYPE.DOCUMENT] },
3615
+ { label: 'Flows', types: [UCCX_ITEM_TYPE.SCRIPT] },
3616
+ { label: 'Skill', types: [UCCX_ITEM_TYPE.SKILL] },
3617
+ { label: 'Contact center users', types: [UCCX_ITEM_TYPE.RESOURCE] }
3618
+ ];
3619
+ const IMPORT_PANEL_TITLE = 'Import Contact center';
3620
+ const IMPORT_PANEL_TOOLTIP = 'Contact centers detected in the connected UCCX environment, and where each one can migrate to.';
3621
+ const IMPORT_WIZARD_TITLE = 'Contact Center';
3622
+ /** Shown once a "requires review" contact center is picked. Dismissible. */
3623
+ const CUSTOMER_ASSIST_NOTICE = 'This contact center may also be supported by Customer Assist. Check compatibility before continuing.';
3624
+ /** Tooltip on the marker the picker puts next to those same contact centers. */
3625
+ const CUSTOMER_ASSIST_MARKER_TOOLTIP = 'May also be supported by Customer Assist.';
3626
+
3627
+ /**
3628
+ * Stand-in data used when `CcImportService.useMockData` is on.
3629
+ *
3630
+ * Shapes here mirror exactly what `CcImportService` produces from the real backend,
3631
+ * so switching over is a matter of flipping `useMockData` to false.
3632
+ */
3633
+ const APPLICATION_NAMES = [
3634
+ 'Operations', 'Sales', 'Support', 'Billing', 'Reception', 'Helpdesk', 'Retention',
3635
+ 'Onboarding', 'Escalations', 'Emergency', 'Pharmacy', 'Appointments', 'Claims',
3636
+ 'Collections', 'Dispatch', 'Front Desk', 'IT Service Desk', 'Loyalty', 'Orders', 'Returns'
3637
+ ];
3638
+ /** One tab per group on the wizard's Overview step, in the order they are shown. */
3639
+ const ENTITY_GROUP_TEMPLATE = [
3640
+ { label: 'Channel', suffixes: ['_CC'] },
3641
+ { label: 'Queues', suffixes: ['_Queue'] },
3642
+ { label: 'Audio files', suffixes: [' Welcome', ' Music On Hold', ' Closed Message'] },
3643
+ { label: 'Flows', suffixes: ['_Flow'] },
3644
+ { label: 'Skill', suffixes: ['_Skill'] },
3645
+ { label: 'Contact center users', suffixes: [' Supervisor', ' Agent 1', ' Agent 2'] }
3646
+ ];
3647
+ /**
3648
+ * The ten contact centers that still need a decision - the only ones the wizard
3649
+ * offers, so these are exactly the rows the picker shows, in this order. The flagged
3650
+ * three are "requires review" and carry the marker plus the advisory notice.
3651
+ */
3652
+ const REVIEW_CONTACT_CENTERS = [
3653
+ { name: 'Operations', requiresReview: true },
3654
+ { name: 'Sales_inquiry' },
3655
+ { name: 'Tech Support' },
3656
+ { name: 'Tech_Info' },
3657
+ { name: 'Finance', requiresReview: true },
3658
+ { name: 'Innovation', requiresReview: true },
3659
+ { name: 'Marketing' },
3660
+ { name: 'Gen_Support' },
3661
+ { name: 'Legal' },
3662
+ { name: 'Sales Support' }
3663
+ ];
3664
+ /** 100 contact centers: 70 migratable, 20 unsupported, 10 still to be imported. */
3665
+ function mockContactCenters() {
3666
+ const contactCenters = [];
3667
+ // 90 already-imported ones, split across the two destinations.
3668
+ for (let i = 0; i < 90; i++) {
3669
+ const name = `${APPLICATION_NAMES[i % APPLICATION_NAMES.length]}_${Math.floor(i / APPLICATION_NAMES.length) + 1}`;
3670
+ const compatibilityStatus = i < 70 ? 'migratable' : 'unsupported';
3671
+ contactCenters.push({
3672
+ applicationId: `app-${i + 1}`,
3673
+ applicationName: name,
3674
+ scriptName: `${name}_AA_Queue.aef`,
3675
+ compatibilityStatus,
3676
+ compatibilityScore: compatibilityStatus === 'migratable' ? 92 : 41,
3677
+ migrationState: 'migrated'
3678
+ });
3679
+ }
3680
+ REVIEW_CONTACT_CENTERS.forEach((contactCenter, i) => {
3681
+ const compatibilityStatus = contactCenter.requiresReview ? 'requires-review' : 'unsupported';
3682
+ contactCenters.push({
3683
+ applicationId: `app-${91 + i}`,
3684
+ applicationName: contactCenter.name,
3685
+ scriptName: `${contactCenter.name}_AA_Queue.aef`,
3686
+ compatibilityStatus,
3687
+ compatibilityScore: contactCenter.requiresReview ? 68 : 44,
3688
+ migrationState: 'not-migrated',
3689
+ customerAssistCapable: compatibilityStatus === 'requires-review'
3690
+ });
3691
+ });
3692
+ return contactCenters;
3693
+ }
3694
+ function mockContactCenterEntities(contactCenter) {
3695
+ const base = contactCenter.applicationName;
3696
+ return {
3697
+ applicationId: contactCenter.applicationId,
3698
+ groups: ENTITY_GROUP_TEMPLATE.map(group => ({
3699
+ label: group.label,
3700
+ items: group.suffixes.map(suffix => `${base}${suffix}`)
3701
+ }))
3702
+ };
3703
+ }
3704
+
3705
+ /** Simulated network latency for the mock responses, so loading states are exercised. */
3706
+ const MOCK_LATENCY_MS = 300;
3707
+ class CcImportService {
3708
+ constructor() {
3709
+ this.api = inject(APIService);
3710
+ this.dcpApi = inject(DcpApiService);
3711
+ /**
3712
+ * Answer everything from `mock/cc-import.mock.ts` instead of calling the backend.
3713
+ *
3714
+ * Note this is all-or-nothing: with it off, the contact-center list, the entity
3715
+ * overview and the import all hit real endpoints. Compatibility scoring is the
3716
+ * exception - see {@link resolveCompatibility}.
3717
+ */
3718
+ this.useMockData = true;
3719
+ }
3720
+ setToken(token) {
3721
+ this.api.token = token;
3722
+ this.dcpApi.token = token;
3723
+ }
3724
+ setHost(host) {
3725
+ this.api.apiUrl = host;
3726
+ }
3727
+ /** Base URL of the dcp host, which serves the UCCX application list. */
3728
+ setDcpHost(dcpHost) {
3729
+ this.dcpApi.apiUrl = dcpHost;
3730
+ }
3731
+ /**
3732
+ * Every UCCX contact center Tuki can import.
3733
+ *
3734
+ * A "contact center" is a UCCX application. The list comes from the dcp
3735
+ * application cache; whether each one has already been imported is joined on from
3736
+ * the per-AEF-script call-flow migration states.
3737
+ */
3738
+ fetchContactCenters(customerId) {
3739
+ if (this.useMockData) {
3740
+ return of(mockContactCenters()).pipe(delay(MOCK_LATENCY_MS));
3741
+ }
3742
+ return forkJoin({
3743
+ applications: this.dcpApi.fetch(API.UCCX.APPLICATION_NAMES(customerId)),
3744
+ callFlows: this.api.fetch(API.UCCX.CALL_FLOW_MIGRATION_STATUSES(customerId))
3745
+ }).pipe(map(({ applications, callFlows }) => this.toContactCenters(this.asArray(applications), this.asArray(callFlows))));
3746
+ }
3747
+ /**
3748
+ * Application-centric entity breakdown: everything Tuki will create on import.
3749
+ *
3750
+ * Note this only ever returns entities the backend has actually linked to the
3751
+ * application. Where that linkage is missing the groups come back empty rather
3752
+ * than padded with unrelated entities of the right type.
3753
+ */
3754
+ fetchContactCenterEntities(customerId, contactCenter) {
3755
+ if (this.useMockData) {
3756
+ return of(mockContactCenterEntities(contactCenter)).pipe(delay(MOCK_LATENCY_MS));
3757
+ }
3758
+ return this.fetchApplicationItems(customerId, contactCenter.applicationName).pipe(map(items => ({
3759
+ applicationId: contactCenter.applicationId,
3760
+ groups: this.groupEntities(items)
3761
+ })));
3762
+ }
3763
+ /**
3764
+ * Kicks off the UCCX -> Webex Contact Center import of one contact center, as a
3765
+ * single migration unit: every entity of the application goes in one request.
3766
+ *
3767
+ * The endpoint is synchronous and answers with an XLSX tracker rather than a job
3768
+ * id - execution and progress tracking are defined in a separate ticket.
3769
+ *
3770
+ * @param siteId required by the backend when a Resource Group is in scope.
3771
+ * @param locationId required by the backend when a Trigger is in scope.
3772
+ */
3773
+ importContactCenter(customerId, applicationId, siteId, locationId) {
3774
+ if (this.useMockData) {
3775
+ return of({ applicationId, accepted: true }).pipe(delay(MOCK_LATENCY_MS));
3776
+ }
3777
+ return this.fetchApplicationItems(customerId, applicationId).pipe(switchMap(items => {
3778
+ const payload = {
3779
+ uccxItemsList: items.length ? [items.map(item => ({ ...item, migrate: true }))] : []
3780
+ };
3781
+ return this.api.post(API.UCCX.MIGRATE(customerId), payload, { siteId, locationId }, { responseType: 'blob' });
3782
+ }), map((report) => ({
3783
+ applicationId,
3784
+ accepted: true,
3785
+ report: report instanceof Blob ? report : undefined
3786
+ })));
3787
+ }
3788
+ /**
3789
+ * Every UCCX entity belonging to one application, gathered across the batches.
3790
+ *
3791
+ * UCCX batches hold one entity type each, so this reads them all and keeps the
3792
+ * items whose `applicationName` matches. The narrowing is done here rather than
3793
+ * through the endpoint's own `applicationName` param because that param answers
3794
+ * `[]` on dev2 even for items that plainly carry the name.
3795
+ */
3796
+ fetchApplicationItems(customerId, applicationName) {
3797
+ return this.api.fetch(API.UCCX.BATCHES(customerId)).pipe(switchMap(response => {
3798
+ const batches = this.asArray(response);
3799
+ if (!batches.length) {
3800
+ return of([]);
3801
+ }
3802
+ return forkJoin(batches.map(batch => this.api.fetch(API.UCCX.BATCH_ITEMS(customerId, batch.id))
3803
+ .pipe(map((wrapper) => this.flattenItems(wrapper))))).pipe(map(perBatch => this.dedupeItems(perBatch.flat().filter(item => item.applicationName === applicationName))));
3804
+ }));
3805
+ }
3806
+ /** The items endpoint nests items one level; older responses come back flat. */
3807
+ flattenItems(wrapper) {
3808
+ const items = wrapper?.uccxItemsList ?? [];
3809
+ const flattened = Array.isArray(items[0])
3810
+ ? items.flat()
3811
+ : items;
3812
+ return flattened.filter(Boolean);
3813
+ }
3814
+ /** The same entity can be carried by more than one batch. */
3815
+ dedupeItems(items) {
3816
+ const seen = new Set();
3817
+ return items.filter(item => {
3818
+ const key = `${item.type}::${item.name}::${item.sourceUCCXIp}`;
3819
+ if (seen.has(key)) {
3820
+ return false;
3821
+ }
3822
+ seen.add(key);
3823
+ return true;
3824
+ });
3825
+ }
3826
+ groupEntities(items) {
3827
+ const remaining = new Map();
3828
+ items.forEach(item => {
3829
+ const names = remaining.get(item.type) ?? [];
3830
+ names.push(item.name);
3831
+ remaining.set(item.type, names);
3832
+ });
3833
+ const groups = OVERVIEW_ENTITY_GROUPS.map(group => {
3834
+ const collected = [];
3835
+ group.types.forEach(type => {
3836
+ collected.push(...(remaining.get(type) ?? []));
3837
+ remaining.delete(type);
3838
+ });
3839
+ return { label: group.label, items: collected };
3840
+ });
3841
+ // Anything the backend returned that has no group of its own keeps its raw
3842
+ // type as a label, rather than being dropped from the overview.
3843
+ remaining.forEach((names, type) => groups.push({ label: type, items: names }));
3844
+ return groups;
3845
+ }
3846
+ toContactCenters(applications, callFlows) {
3847
+ return applications
3848
+ .filter(application => !!application?.name)
3849
+ .map(application => {
3850
+ const uccxIp = application.uccx?.host;
3851
+ const scriptName = this.toScriptName(application);
3852
+ const compatibilityStatus = this.resolveCompatibility(application);
3853
+ const contactCenter = {
3854
+ // UCCX identifies an application by name - it is what the entity
3855
+ // records link back to - so it doubles as the widget's key.
3856
+ applicationId: application.name,
3857
+ applicationName: application.name,
3858
+ scriptName,
3859
+ uccxIp,
3860
+ compatibilityStatus,
3861
+ migrationState: this.resolveMigrationState(application, scriptName, uccxIp, callFlows),
3862
+ // Per the ticket, "requires review" is exactly the set that can go
3863
+ // to either destination.
3864
+ customerAssistCapable: compatibilityStatus === 'requires-review'
3865
+ };
3866
+ return contactCenter;
3867
+ });
3868
+ }
3869
+ /** UCCX wraps the backing script as `SCRIPT[Foo.aef]`; the widget shows `Foo.aef`. */
3870
+ toScriptName(application) {
3871
+ const raw = application.scriptName ?? application.aefFiles?.[0] ?? '';
3872
+ return raw.replace(/^SCRIPT\[(.*)\]$/, '$1');
3873
+ }
3874
+ /**
3875
+ * Whether Tuki has already imported this contact center.
3876
+ *
3877
+ * The application record carries its own `migrationStatus`, but it is null
3878
+ * throughout dev2, so this falls back to the per-AEF-script call-flow state.
3879
+ */
3880
+ resolveMigrationState(application, scriptName, uccxIp, callFlows) {
3881
+ if (application.migrationStatus) {
3882
+ return application.migrationStatus === CALL_FLOW_MIGRATED ? 'migrated' : 'not-migrated';
3883
+ }
3884
+ const callFlow = callFlows.find(flow => flow.scriptName === scriptName && (!uccxIp || flow.uccxIp === uccxIp));
3885
+ return callFlow?.status === CALL_FLOW_MIGRATED ? 'migrated' : 'not-migrated';
3886
+ }
3887
+ /**
3888
+ * Turns an AEF compatibility score into a status.
3889
+ *
3890
+ * The scoring API does not exist yet - the AEF step mapping is still a pending
3891
+ * input on the ticket - so when the backend sends no score every contact center
3892
+ * falls back to "requires review": the status that offers both destinations and
3893
+ * claims nothing about compatibility we have not actually measured.
3894
+ *
3895
+ * Once the backend returns `compatibilityScore`, the thresholds below take over
3896
+ * with no further change here.
3897
+ */
3898
+ resolveCompatibility(application) {
3899
+ const score = application.compatibilityScore;
3900
+ if (typeof score !== 'number') {
3901
+ return 'requires-review';
3902
+ }
3903
+ if (score >= COMPATIBILITY_THRESHOLDS.migratable) {
3904
+ return 'migratable';
3905
+ }
3906
+ if (score >= COMPATIBILITY_THRESHOLDS.requiresReview) {
3907
+ return 'requires-review';
3908
+ }
3909
+ return 'unsupported';
3910
+ }
3911
+ asArray(value) {
3912
+ return Array.isArray(value) ? value : [];
3913
+ }
3914
+ }
3915
+ CcImportService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CcImportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3916
+ CcImportService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CcImportService, providedIn: 'root' });
3917
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CcImportService, decorators: [{
3918
+ type: Injectable,
3919
+ args: [{
3920
+ providedIn: 'root'
3921
+ }]
3922
+ }] });
3923
+
3924
+ /**
3925
+ * "Import Contact center" panel: how many UCCX contact centers were detected, how many
3926
+ * have been imported, and an Import button that asks the host to open the import wizard.
3927
+ */
3928
+ class ImportContactCenterPanelComponent {
3929
+ constructor() {
3930
+ /** Serve mock data instead of calling the UCCX migration API. */
3931
+ this.useMockData = true;
3932
+ /**
3933
+ * Asked for the import wizard, carrying the contact centers already loaded here so
3934
+ * the wizard opens without refetching them. The host renders
3935
+ * `cc-import-contact-center-wizard` as a page in response.
3936
+ */
3937
+ this.importRequested = new EventEmitter();
3938
+ this.ccImportService = inject(CcImportService);
3939
+ this.title = IMPORT_PANEL_TITLE;
3940
+ this.tooltip = IMPORT_PANEL_TOOLTIP;
3941
+ this.segments = [];
3942
+ this.total = 0;
3943
+ this.loading = false;
3944
+ this.error = false;
3945
+ this.contactCenters = [];
3946
+ }
3947
+ ngOnInit() {
3948
+ // Render an empty donut up front so the template never reads unset chart options,
3949
+ // including when load() bails out because the widget has no credentials yet.
3950
+ this.buildViewModel();
3951
+ this.load();
3952
+ }
3953
+ ngOnChanges(changes) {
3954
+ const reloadTriggers = ['customerId', 'host', 'dcpHost', 'token', 'useMockData'];
3955
+ if (reloadTriggers.some(input => changes[input] && !changes[input].firstChange)) {
3956
+ this.load();
3957
+ }
3958
+ }
3959
+ ngOnDestroy() {
3960
+ this.subscription?.unsubscribe();
3961
+ }
3962
+ onImport() {
3963
+ this.importRequested.emit(this.contactCenters);
3964
+ }
3965
+ /** Call after an import has run so the donut picks up the new counts. */
3966
+ refresh() {
3967
+ this.load();
3968
+ }
3969
+ load() {
3970
+ const customerId = Number(this.customerId);
3971
+ this.ccImportService.useMockData = this.useMockData;
3972
+ if (!this.useMockData && (!customerId || !this.token)) {
3973
+ return;
3974
+ }
3975
+ if (this.host) {
3976
+ this.ccImportService.setHost(this.host);
3977
+ }
3978
+ if (this.dcpHost) {
3979
+ this.ccImportService.setDcpHost(this.dcpHost);
3980
+ }
3981
+ if (this.token) {
3982
+ this.ccImportService.setToken(this.token);
3983
+ }
3984
+ this.subscription?.unsubscribe();
3985
+ this.loading = true;
3986
+ this.error = false;
3987
+ this.subscription = this.ccImportService.fetchContactCenters(customerId)
3988
+ .pipe(catchError(error => {
3989
+ console.error('Unable to load the contact centers', error);
3990
+ this.error = true;
3991
+ return of([]);
3992
+ }), finalize(() => this.loading = false))
3993
+ .subscribe(contactCenters => {
3994
+ this.contactCenters = contactCenters;
3995
+ this.buildViewModel();
3996
+ });
3997
+ }
3998
+ buildViewModel() {
3999
+ this.total = this.contactCenters.length;
4000
+ this.segments = IMPORT_PANEL_SLICES.map(slice => {
4001
+ const count = this.contactCenters.filter(slice.match).length;
4002
+ return {
4003
+ label: slice.label,
4004
+ color: slice.color,
4005
+ tooltip: slice.tooltip,
4006
+ count,
4007
+ percentage: this.total > 0 ? Math.round((count / this.total) * 100) : 0
4008
+ };
4009
+ });
4010
+ this.chartOptions = this.buildChartOptions();
4011
+ }
4012
+ buildChartOptions() {
4013
+ const charted = this.segments.filter(segment => segment.count > 0);
4014
+ const isEmpty = charted.length === 0;
4015
+ return {
4016
+ series: isEmpty ? [1] : charted.map(segment => segment.count),
4017
+ labels: isEmpty ? ['No contact centers'] : charted.map(segment => segment.label),
4018
+ colors: isEmpty ? [CHART_COLORS.webexContactCenter] : charted.map(segment => segment.color),
4019
+ chart: {
4020
+ type: 'donut',
4021
+ height: 150,
4022
+ width: 150,
4023
+ sparkline: { enabled: true }
4024
+ },
4025
+ legend: { show: false },
4026
+ plotOptions: {
4027
+ pie: {
4028
+ expandOnClick: false,
4029
+ donut: { size: '72%' }
4030
+ }
4031
+ },
4032
+ dataLabels: { enabled: false },
4033
+ tooltip: { enabled: !isEmpty },
4034
+ states: {
4035
+ active: { filter: { type: 'none', value: 0 } }
4036
+ }
4037
+ };
4038
+ }
4039
+ }
4040
+ ImportContactCenterPanelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ImportContactCenterPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4041
+ ImportContactCenterPanelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ImportContactCenterPanelComponent, selector: "cc-import-contact-center-panel", inputs: { customerId: "customerId", host: "host", dcpHost: "dcpHost", token: "token", useMockData: "useMockData" }, outputs: { importRequested: "importRequested" }, usesOnChanges: true, ngImport: i0, template: "<tk-card [title]=\"title\" [dense]=\"true\">\r\n <ng-container ngProjectAs=\"card-title-adornment\">\r\n <span class=\"cc-import-panel__info\" [matTooltip]=\"tooltip\">\r\n <ng-container *ngTemplateOutlet=\"infoIcon\"></ng-container>\r\n </span>\r\n </ng-container>\r\n\r\n <ng-container ngProjectAs=\"card-content\">\r\n <div class=\"cc-import-panel__body\" *ngIf=\"!loading && !error; else panelState\">\r\n <div class=\"cc-import-panel__chart\">\r\n <apx-chart\r\n [series]=\"chartOptions.series\"\r\n [chart]=\"chartOptions.chart\"\r\n [labels]=\"chartOptions.labels\"\r\n [colors]=\"chartOptions.colors\"\r\n [legend]=\"chartOptions.legend\"\r\n [plotOptions]=\"chartOptions.plotOptions\"\r\n [dataLabels]=\"chartOptions.dataLabels\"\r\n [tooltip]=\"chartOptions.tooltip\"\r\n [states]=\"chartOptions.states\"\r\n ></apx-chart>\r\n <div class=\"cc-import-panel__chart-center\">\r\n <span class=\"cc-import-panel__chart-total\">{{ total | number }}</span>\r\n <span class=\"cc-import-panel__chart-caption\">Contact Center</span>\r\n </div>\r\n </div>\r\n\r\n <ul class=\"cc-import-panel__legend\">\r\n <li class=\"cc-import-panel__legend-item\" *ngFor=\"let segment of segments\">\r\n <span class=\"cc-import-panel__legend-marker\" [style.backgroundColor]=\"segment.color\"></span>\r\n <span class=\"cc-import-panel__legend-label\">{{ segment.label }}</span>\r\n <span class=\"cc-import-panel__info\" [matTooltip]=\"segment.tooltip\">\r\n <ng-container *ngTemplateOutlet=\"infoIcon\"></ng-container>\r\n </span>\r\n <span class=\"cc-import-panel__legend-value\">{{ segment.count | number }} ({{ segment.percentage }}%)</span>\r\n </li>\r\n </ul>\r\n </div>\r\n\r\n <ng-template #panelState>\r\n <div class=\"cc-import-panel__state\" *ngIf=\"loading\">Loading contact centers\u2026</div>\r\n <div class=\"cc-import-panel__state cc-import-panel__state--error\" *ngIf=\"!loading && error\">\r\n Unable to load contact centers.\r\n </div>\r\n </ng-template>\r\n\r\n <div class=\"cc-import-panel__actions\">\r\n <button\r\n type=\"button\"\r\n class=\"cc-import-panel__button\"\r\n [disabled]=\"loading || error\"\r\n (click)=\"onImport()\"\r\n >\r\n Import\r\n </button>\r\n </div>\r\n </ng-container>\r\n</tk-card>\r\n\r\n<ng-template #infoIcon>\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\r\n <circle cx=\"8\" cy=\"8\" r=\"6.5\" stroke=\"currentColor\" stroke-width=\"1.2\" />\r\n <path d=\"M8 7.2v4\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" />\r\n <circle cx=\"8\" cy=\"5\" r=\"0.85\" fill=\"currentColor\" />\r\n </svg>\r\n</ng-template>\r\n", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";:host{display:block;box-sizing:border-box;font-family:Inter,Inter,sans-serif}.cc-import-panel__info{display:inline-flex;align-items:center;color:#636363;cursor:help}.cc-import-panel__body{display:flex;align-items:center;gap:1.5rem;flex-wrap:wrap;width:100%}.cc-import-panel__chart{position:relative;width:150px;height:150px;flex-shrink:0}.cc-import-panel__chart-center{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;pointer-events:none}.cc-import-panel__chart-total{font-size:1.625rem;line-height:1.1;color:#252525}.cc-import-panel__chart-caption{font-size:.6875rem;color:#636363}.cc-import-panel__legend{display:flex;flex-direction:column;gap:.625rem;margin:0;padding:0;list-style:none;min-width:17.5rem;flex:1}.cc-import-panel__legend-item{display:flex;align-items:center;gap:.5rem;font-size:.75rem;color:#636363}.cc-import-panel__legend-marker{width:10px;height:10px;border-radius:2px;flex-shrink:0}.cc-import-panel__legend-label{color:#252525}.cc-import-panel__legend-value{margin-left:auto;white-space:nowrap}.cc-import-panel__state{font-size:.875rem;color:#636363}.cc-import-panel__state--error{color:#bc1e1b}.cc-import-panel__actions{display:flex;margin-top:auto}.cc-import-panel__button{display:inline-flex;align-items:center;gap:.25rem;padding:.5rem 1rem;background:#fff;border:1px solid rgba(0,0,0,.5019607843);border-radius:6.25rem;font-family:inherit;font-size:.875rem;font-weight:500;color:#000000f2;cursor:pointer;white-space:nowrap}.cc-import-panel__button:hover:not(:disabled){background:#ededed}.cc-import-panel__button:disabled{color:#babcc5;border-color:#dfe3e7;cursor:not-allowed}@media (max-width: 560px){.cc-import-panel__legend{min-width:0}}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i5.ChartComponent, selector: "apx-chart", inputs: ["chart", "annotations", "colors", "dataLabels", "series", "stroke", "labels", "legend", "markers", "noData", "fill", "tooltip", "plotOptions", "responsive", "xaxis", "yaxis", "forecastDataPoints", "grid", "states", "title", "subtitle", "theme", "autoUpdateSeries"] }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: CardComponent, selector: "tk-card", inputs: ["title", "dense"] }, { kind: "pipe", type: i1$1.DecimalPipe, name: "number" }] });
4042
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ImportContactCenterPanelComponent, decorators: [{
4043
+ type: Component,
4044
+ args: [{ selector: 'cc-import-contact-center-panel', template: "<tk-card [title]=\"title\" [dense]=\"true\">\r\n <ng-container ngProjectAs=\"card-title-adornment\">\r\n <span class=\"cc-import-panel__info\" [matTooltip]=\"tooltip\">\r\n <ng-container *ngTemplateOutlet=\"infoIcon\"></ng-container>\r\n </span>\r\n </ng-container>\r\n\r\n <ng-container ngProjectAs=\"card-content\">\r\n <div class=\"cc-import-panel__body\" *ngIf=\"!loading && !error; else panelState\">\r\n <div class=\"cc-import-panel__chart\">\r\n <apx-chart\r\n [series]=\"chartOptions.series\"\r\n [chart]=\"chartOptions.chart\"\r\n [labels]=\"chartOptions.labels\"\r\n [colors]=\"chartOptions.colors\"\r\n [legend]=\"chartOptions.legend\"\r\n [plotOptions]=\"chartOptions.plotOptions\"\r\n [dataLabels]=\"chartOptions.dataLabels\"\r\n [tooltip]=\"chartOptions.tooltip\"\r\n [states]=\"chartOptions.states\"\r\n ></apx-chart>\r\n <div class=\"cc-import-panel__chart-center\">\r\n <span class=\"cc-import-panel__chart-total\">{{ total | number }}</span>\r\n <span class=\"cc-import-panel__chart-caption\">Contact Center</span>\r\n </div>\r\n </div>\r\n\r\n <ul class=\"cc-import-panel__legend\">\r\n <li class=\"cc-import-panel__legend-item\" *ngFor=\"let segment of segments\">\r\n <span class=\"cc-import-panel__legend-marker\" [style.backgroundColor]=\"segment.color\"></span>\r\n <span class=\"cc-import-panel__legend-label\">{{ segment.label }}</span>\r\n <span class=\"cc-import-panel__info\" [matTooltip]=\"segment.tooltip\">\r\n <ng-container *ngTemplateOutlet=\"infoIcon\"></ng-container>\r\n </span>\r\n <span class=\"cc-import-panel__legend-value\">{{ segment.count | number }} ({{ segment.percentage }}%)</span>\r\n </li>\r\n </ul>\r\n </div>\r\n\r\n <ng-template #panelState>\r\n <div class=\"cc-import-panel__state\" *ngIf=\"loading\">Loading contact centers\u2026</div>\r\n <div class=\"cc-import-panel__state cc-import-panel__state--error\" *ngIf=\"!loading && error\">\r\n Unable to load contact centers.\r\n </div>\r\n </ng-template>\r\n\r\n <div class=\"cc-import-panel__actions\">\r\n <button\r\n type=\"button\"\r\n class=\"cc-import-panel__button\"\r\n [disabled]=\"loading || error\"\r\n (click)=\"onImport()\"\r\n >\r\n Import\r\n </button>\r\n </div>\r\n </ng-container>\r\n</tk-card>\r\n\r\n<ng-template #infoIcon>\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\r\n <circle cx=\"8\" cy=\"8\" r=\"6.5\" stroke=\"currentColor\" stroke-width=\"1.2\" />\r\n <path d=\"M8 7.2v4\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" />\r\n <circle cx=\"8\" cy=\"5\" r=\"0.85\" fill=\"currentColor\" />\r\n </svg>\r\n</ng-template>\r\n", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";:host{display:block;box-sizing:border-box;font-family:Inter,Inter,sans-serif}.cc-import-panel__info{display:inline-flex;align-items:center;color:#636363;cursor:help}.cc-import-panel__body{display:flex;align-items:center;gap:1.5rem;flex-wrap:wrap;width:100%}.cc-import-panel__chart{position:relative;width:150px;height:150px;flex-shrink:0}.cc-import-panel__chart-center{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;pointer-events:none}.cc-import-panel__chart-total{font-size:1.625rem;line-height:1.1;color:#252525}.cc-import-panel__chart-caption{font-size:.6875rem;color:#636363}.cc-import-panel__legend{display:flex;flex-direction:column;gap:.625rem;margin:0;padding:0;list-style:none;min-width:17.5rem;flex:1}.cc-import-panel__legend-item{display:flex;align-items:center;gap:.5rem;font-size:.75rem;color:#636363}.cc-import-panel__legend-marker{width:10px;height:10px;border-radius:2px;flex-shrink:0}.cc-import-panel__legend-label{color:#252525}.cc-import-panel__legend-value{margin-left:auto;white-space:nowrap}.cc-import-panel__state{font-size:.875rem;color:#636363}.cc-import-panel__state--error{color:#bc1e1b}.cc-import-panel__actions{display:flex;margin-top:auto}.cc-import-panel__button{display:inline-flex;align-items:center;gap:.25rem;padding:.5rem 1rem;background:#fff;border:1px solid rgba(0,0,0,.5019607843);border-radius:6.25rem;font-family:inherit;font-size:.875rem;font-weight:500;color:#000000f2;cursor:pointer;white-space:nowrap}.cc-import-panel__button:hover:not(:disabled){background:#ededed}.cc-import-panel__button:disabled{color:#babcc5;border-color:#dfe3e7;cursor:not-allowed}@media (max-width: 560px){.cc-import-panel__legend{min-width:0}}\n"] }]
4045
+ }], propDecorators: { customerId: [{
4046
+ type: Input
4047
+ }], host: [{
4048
+ type: Input
4049
+ }], dcpHost: [{
4050
+ type: Input
4051
+ }], token: [{
4052
+ type: Input
4053
+ }], useMockData: [{
4054
+ type: Input
4055
+ }], importRequested: [{
4056
+ type: Output
4057
+ }] } });
4058
+
4059
+ /** The wizard's steps, in order. Index-aligned with the `mat-stepper` steps. */
4060
+ const IMPORT_WIZARD_STEPS = ['select', 'overview'];
4061
+
4062
+ /**
4063
+ * Full-page "Import contact center" wizard: pick a UCCX contact center, review the
4064
+ * entities Tuki will create for it, then start the import.
4065
+ *
4066
+ * Rendered as a page by the host app (like `tk-user-creation-wizard`), not as a dialog -
4067
+ * the host swaps it in when the panel's Import button is pressed and swaps it back out
4068
+ * on `cancel` / `imported`.
4069
+ */
4070
+ class ImportContactCenterWizardComponent {
4071
+ constructor() {
4072
+ this.title = IMPORT_WIZARD_TITLE;
4073
+ /** Serve mock data instead of calling the UCCX migration API. */
4074
+ this.useMockData = true;
4075
+ /**
4076
+ * Contact centers the caller has already loaded (the panel has them), so the wizard
4077
+ * opens without a second round trip. Left unset, the wizard fetches them itself.
4078
+ */
4079
+ this.contactCenters = null;
4080
+ this.cancel = new EventEmitter();
4081
+ this.imported = new EventEmitter();
4082
+ this.ccImportService = inject(CcImportService);
4083
+ this.subscriptions = new Subscription();
4084
+ this.customerAssistNotice = CUSTOMER_ASSIST_NOTICE;
4085
+ this.customerAssistMarkerTooltip = CUSTOMER_ASSIST_MARKER_TOOLTIP;
4086
+ this.selectedIndex = 0;
4087
+ /** Contact centers awaiting review - the ones there is something to import. */
4088
+ this.options = [];
4089
+ /** `options` narrowed by the picker's search box. */
4090
+ this.filteredOptions = [];
4091
+ this.searchTerm = '';
4092
+ this.selected = null;
4093
+ this.noticeDismissed = false;
4094
+ this.loading = false;
4095
+ this.error = false;
4096
+ this.entityGroups = [];
4097
+ /** Which entity group the Overview step's tab bar is showing. */
4098
+ this.activeGroupIndex = 0;
4099
+ this.entitiesLoading = false;
4100
+ this.entitiesError = false;
4101
+ this.importing = false;
4102
+ this.importError = false;
4103
+ }
4104
+ ngOnInit() {
4105
+ this.load();
4106
+ }
4107
+ ngOnChanges(changes) {
4108
+ const reloadTriggers = ['customerId', 'host', 'dcpHost', 'token', 'useMockData', 'contactCenters'];
4109
+ if (reloadTriggers.some(input => changes[input] && !changes[input].firstChange)) {
4110
+ this.load();
4111
+ }
4112
+ }
4113
+ ngOnDestroy() {
4114
+ this.subscriptions.unsubscribe();
4115
+ }
4116
+ get canGoNext() {
4117
+ return !!this.selected;
4118
+ }
4119
+ /** The Customer Assist advisory, until the user dismisses it or picks something else. */
4120
+ get showCustomerAssistNotice() {
4121
+ return !!this.selected?.customerAssistCapable && !this.noticeDismissed;
4122
+ }
4123
+ get canImport() {
4124
+ return !!this.selected && !this.importing && !this.entitiesLoading && !this.entitiesError;
4125
+ }
4126
+ onCancel() {
4127
+ this.cancel.emit();
4128
+ }
4129
+ onSelect(applicationId) {
4130
+ const selected = this.options.find(option => option.applicationId === applicationId) ?? null;
4131
+ if (selected === this.selected) {
4132
+ return;
4133
+ }
4134
+ this.selected = selected;
4135
+ this.noticeDismissed = false;
4136
+ // Entities belong to the previously selected contact center - drop them so the
4137
+ // overview step refetches for the new one.
4138
+ this.entityGroups = [];
4139
+ this.activeGroupIndex = 0;
4140
+ this.entitiesError = false;
4141
+ }
4142
+ get activeGroup() {
4143
+ return this.entityGroups[this.activeGroupIndex];
4144
+ }
4145
+ selectGroup(index) {
4146
+ this.activeGroupIndex = index;
4147
+ }
4148
+ dismissNotice() {
4149
+ this.noticeDismissed = true;
4150
+ }
4151
+ onSearch(event) {
4152
+ this.searchTerm = event.target.value;
4153
+ this.filter();
4154
+ }
4155
+ /** Resets the search box each time the picker's panel is closed. */
4156
+ onPanelToggle(opened) {
4157
+ if (!opened && this.searchTerm) {
4158
+ this.searchTerm = '';
4159
+ this.filter();
4160
+ }
4161
+ }
4162
+ onStepSelectionChange(event) {
4163
+ this.selectedIndex = event.selectedIndex;
4164
+ if (this.stepIdAt(event.selectedIndex) === 'overview') {
4165
+ this.loadEntities();
4166
+ }
4167
+ }
4168
+ onNext(stepper) {
4169
+ if (this.canGoNext) {
4170
+ stepper.next();
4171
+ }
4172
+ }
4173
+ onPrevious(stepper) {
4174
+ stepper.previous();
4175
+ }
4176
+ runImport() {
4177
+ if (!this.selected || this.importing) {
4178
+ return;
4179
+ }
4180
+ this.importing = true;
4181
+ this.importError = false;
4182
+ this.subscriptions.add(this.ccImportService.importContactCenter(Number(this.customerId), this.selected.applicationId)
4183
+ .pipe(catchError(error => {
4184
+ console.error('Unable to start the contact-center import', error);
4185
+ this.importError = true;
4186
+ return of(null);
4187
+ }), finalize(() => this.importing = false))
4188
+ .subscribe(result => {
4189
+ if (result) {
4190
+ this.imported.emit(result);
4191
+ }
4192
+ }));
4193
+ }
4194
+ stepIdAt(index) {
4195
+ return IMPORT_WIZARD_STEPS[index];
4196
+ }
4197
+ load() {
4198
+ this.ccImportService.useMockData = this.useMockData;
4199
+ if (this.host) {
4200
+ this.ccImportService.setHost(this.host);
4201
+ }
4202
+ if (this.dcpHost) {
4203
+ this.ccImportService.setDcpHost(this.dcpHost);
4204
+ }
4205
+ if (this.token) {
4206
+ this.ccImportService.setToken(this.token);
4207
+ }
4208
+ if (this.contactCenters) {
4209
+ this.setOptions(this.contactCenters);
4210
+ return;
4211
+ }
4212
+ const customerId = Number(this.customerId);
4213
+ if (!this.useMockData && (!customerId || !this.token)) {
4214
+ return;
4215
+ }
4216
+ this.loading = true;
4217
+ this.error = false;
4218
+ this.subscriptions.add(this.ccImportService.fetchContactCenters(customerId)
4219
+ .pipe(catchError(error => {
4220
+ console.error('Unable to load the contact centers', error);
4221
+ this.error = true;
4222
+ return of([]);
4223
+ }), finalize(() => this.loading = false))
4224
+ .subscribe(contactCenters => this.setOptions(contactCenters)));
4225
+ }
4226
+ setOptions(contactCenters) {
4227
+ // Left in source order on purpose - the picker shows them the way the backend
4228
+ // (and the mock) hands them over, not alphabetically.
4229
+ //
4230
+ // Eligible for a Webex Contact Center import: not imported yet, and either
4231
+ // unsupported on Customer Assist or reviewable for full feature coverage.
4232
+ this.options = contactCenters.filter(contactCenter => contactCenter.migrationState !== 'migrated'
4233
+ && (contactCenter.compatibilityStatus === 'unsupported'
4234
+ || contactCenter.compatibilityStatus === 'requires-review'));
4235
+ // A contact center selected before a reload may no longer be importable.
4236
+ if (this.selected && !this.options.some(option => option.applicationId === this.selected?.applicationId)) {
4237
+ this.selected = null;
4238
+ this.entityGroups = [];
4239
+ this.activeGroupIndex = 0;
4240
+ }
4241
+ this.filter();
4242
+ }
4243
+ filter() {
4244
+ const needle = this.searchTerm.trim().toLowerCase();
4245
+ this.filteredOptions = needle
4246
+ ? this.options.filter(option => option.applicationName.toLowerCase().includes(needle))
4247
+ : this.options;
4248
+ }
4249
+ loadEntities() {
4250
+ if (!this.selected || this.entityGroups.length || this.entitiesLoading) {
4251
+ return;
4252
+ }
4253
+ this.entitiesLoading = true;
4254
+ this.entitiesError = false;
4255
+ this.subscriptions.add(this.ccImportService.fetchContactCenterEntities(Number(this.customerId), this.selected)
4256
+ .pipe(catchError(error => {
4257
+ console.error('Unable to load the contact-center entities', error);
4258
+ this.entitiesError = true;
4259
+ return of(null);
4260
+ }), finalize(() => this.entitiesLoading = false))
4261
+ .subscribe(entities => {
4262
+ this.entityGroups = entities ? entities.groups : [];
4263
+ this.activeGroupIndex = 0;
4264
+ }));
4265
+ }
4266
+ }
4267
+ ImportContactCenterWizardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ImportContactCenterWizardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4268
+ ImportContactCenterWizardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ImportContactCenterWizardComponent, selector: "cc-import-contact-center-wizard", inputs: { title: "title", customerId: "customerId", host: "host", dcpHost: "dcpHost", token: "token", useMockData: "useMockData", contactCenters: "contactCenters" }, outputs: { cancel: "cancel", imported: "imported" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"move-user-stepper-container\" [attr.aria-busy]=\"importing\">\r\n <header class=\"move-user-header\">\r\n <div class=\"move-user-header__title\">{{ title }}</div>\r\n <div class=\"move-user-header__close\">\r\n <span class=\"app-icon cc-import-close-icon\" (click)=\"onCancel()\" role=\"button\" aria-label=\"Close\">\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path d=\"M5 5L19 19M19 5L5 19\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linecap=\"round\" />\r\n </svg>\r\n </span>\r\n </div>\r\n </header>\r\n\r\n <div id=\"cc-import-stepper\">\r\n <mat-stepper\r\n #stepper\r\n [linear]=\"true\"\r\n labelPosition=\"bottom\"\r\n [selectedIndex]=\"selectedIndex\"\r\n (selectionChange)=\"onStepSelectionChange($event)\"\r\n >\r\n\r\n <!-- Step 1: pick the UCCX contact center -->\r\n <mat-step [completed]=\"canGoNext\">\r\n <ng-template matStepLabel>Select</ng-template>\r\n\r\n <div class=\"cc-import-notice\" *ngIf=\"showCustomerAssistNotice\" role=\"status\">\r\n <span class=\"cc-import-notice__icon\" aria-hidden=\"true\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n <circle cx=\"8\" cy=\"8\" r=\"7\" fill=\"currentColor\" />\r\n <path d=\"M8 7.1v4.2\" stroke=\"#fff\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\r\n <circle cx=\"8\" cy=\"4.8\" r=\"0.9\" fill=\"#fff\" />\r\n </svg>\r\n </span>\r\n <span class=\"cc-import-notice__text\">{{ customerAssistNotice }}</span>\r\n <button type=\"button\" class=\"cc-import-notice__close\" aria-label=\"Dismiss\" (click)=\"dismissNotice()\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path d=\"M5 5L19 19M19 5L5 19\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <div class=\"step-title\">Step 1: Select contact center</div>\r\n\r\n <div class=\"move-user-tab-content-box\">\r\n <div class=\"cc-import-state\" *ngIf=\"loading\">Loading contact centers&hellip;</div>\r\n <div class=\"cc-import-state cc-import-state--error\" *ngIf=\"!loading && error\">\r\n Unable to load contact centers.\r\n </div>\r\n\r\n <section class=\"cc-import-step-content\" *ngIf=\"!loading && !error\">\r\n <div class=\"cc-import-field\">\r\n <label class=\"cc-import-label\" for=\"cc-import-contact-center\">Contact center</label>\r\n\r\n <mat-form-field class=\"cc-import-select\" appearance=\"outline\">\r\n <mat-select\r\n id=\"cc-import-contact-center\"\r\n panelClass=\"cc-import-select-panel\"\r\n placeholder=\"Select contact center\"\r\n [disableOptionCentering]=\"true\"\r\n [value]=\"selected?.applicationId ?? null\"\r\n (selectionChange)=\"onSelect($event.value)\"\r\n (openedChange)=\"onPanelToggle($event)\"\r\n >\r\n <mat-select-trigger>{{ selected?.applicationName }}</mat-select-trigger>\r\n\r\n <!-- Search box pinned above the options. Keystrokes are stopped here so\r\n mat-select's own typeahead does not steal them. -->\r\n <div class=\"cc-import-select-search\" (click)=\"$event.stopPropagation()\">\r\n <span class=\"cc-import-select-search__icon\" aria-hidden=\"true\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n <circle cx=\"7\" cy=\"7\" r=\"4.6\" stroke=\"currentColor\" stroke-width=\"1.4\" />\r\n <path d=\"M10.6 10.6L14 14\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" />\r\n </svg>\r\n </span>\r\n <input\r\n class=\"cc-import-select-search__input\"\r\n type=\"text\"\r\n autocomplete=\"off\"\r\n placeholder=\"Search\"\r\n aria-label=\"Search contact centers\"\r\n [value]=\"searchTerm\"\r\n (input)=\"onSearch($event)\"\r\n (keydown)=\"$event.stopPropagation()\"\r\n />\r\n </div>\r\n\r\n <mat-option *ngFor=\"let option of filteredOptions\" [value]=\"option.applicationId\">\r\n <div class=\"option-row\">\r\n <span class=\"name\">{{ option.applicationName }}</span>\r\n <span\r\n class=\"cc-import-option-marker\"\r\n *ngIf=\"option.customerAssistCapable\"\r\n [matTooltip]=\"customerAssistMarkerTooltip\"\r\n aria-hidden=\"true\"\r\n >\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n <path d=\"M8 2.2 14.6 13.4H1.4L8 2.2Z\" stroke=\"currentColor\" stroke-width=\"1.2\" stroke-linejoin=\"round\" />\r\n <path d=\"M8 6.5v3\" stroke=\"currentColor\" stroke-width=\"1.2\" stroke-linecap=\"round\" />\r\n <circle cx=\"8\" cy=\"11.3\" r=\"0.7\" fill=\"currentColor\" />\r\n </svg>\r\n </span>\r\n </div>\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n\r\n <p class=\"cc-import-empty\" *ngIf=\"!options.length\">\r\n Every detected contact center has already been imported.\r\n </p>\r\n </div>\r\n </section>\r\n </div>\r\n </mat-step>\r\n\r\n <!-- Step 2: the entities Tuki will create for it -->\r\n <mat-step>\r\n <ng-template matStepLabel>Overview</ng-template>\r\n\r\n <div class=\"step-title\">Overview</div>\r\n\r\n <div class=\"move-user-tab-content-box\">\r\n <h3 class=\"cc-import-card-title\">Review Contact Center Settings</h3>\r\n <p class=\"cc-import-card-text\">\r\n Review the settings for your new Contact center to make sure everything is correct.<br />\r\n You can make changes at any time by clicking on the name of the contact center on the dedicated page.\r\n </p>\r\n\r\n <div class=\"cc-import-state\" *ngIf=\"entitiesLoading\">Loading entities&hellip;</div>\r\n <div class=\"cc-import-state cc-import-state--error\" *ngIf=\"entitiesError\">\r\n Unable to load the related entities.\r\n </div>\r\n\r\n <ng-container *ngIf=\"!entitiesLoading && !entitiesError && entityGroups.length\">\r\n <div class=\"cc-import-tabs\" role=\"tablist\">\r\n <button\r\n type=\"button\"\r\n class=\"cc-import-tab\"\r\n *ngFor=\"let group of entityGroups; index as i\"\r\n role=\"tab\"\r\n [attr.aria-selected]=\"i === activeGroupIndex\"\r\n [class.cc-import-tab--active]=\"i === activeGroupIndex\"\r\n (click)=\"selectGroup(i)\"\r\n >\r\n {{ group.label }}\r\n </button>\r\n </div>\r\n\r\n <ul class=\"cc-import-items\" role=\"tabpanel\">\r\n <li class=\"cc-import-item\" *ngFor=\"let item of activeGroup?.items\">{{ item }}</li>\r\n <li class=\"cc-import-item cc-import-item--empty\" *ngIf=\"!activeGroup?.items?.length\">\r\n Nothing to create for {{ activeGroup?.label }}.\r\n </li>\r\n </ul>\r\n </ng-container>\r\n\r\n <div class=\"cc-import-state cc-import-state--error\" *ngIf=\"importError\">\r\n Unable to start the import. Please try again.\r\n </div>\r\n </div>\r\n </mat-step>\r\n </mat-stepper>\r\n\r\n <div class=\"wizard-actions\">\r\n <ng-container [ngSwitch]=\"stepper.selectedIndex\">\r\n <ng-container *ngSwitchCase=\"0\">\r\n <button\r\n mat-button\r\n class=\"uc-btn uc-btn-primary\"\r\n type=\"button\"\r\n [disabled]=\"!canGoNext\"\r\n (click)=\"onNext(stepper)\"\r\n >\r\n Next\r\n </button>\r\n <button mat-button class=\"uc-btn uc-btn-secondary\" type=\"button\" (click)=\"onCancel()\">\r\n Cancel\r\n </button>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"1\">\r\n <button\r\n mat-button\r\n class=\"uc-btn uc-btn-primary\"\r\n type=\"button\"\r\n [disabled]=\"!canImport\"\r\n (click)=\"runImport()\"\r\n >\r\n <span class=\"uc-btn__inline-content\">\r\n <span class=\"uc-btn__spinner\" *ngIf=\"importing\" aria-hidden=\"true\"></span>\r\n <span>{{ importing ? 'Importing...' : 'Import' }}</span>\r\n </span>\r\n </button>\r\n <button\r\n mat-button\r\n class=\"uc-btn uc-btn-secondary\"\r\n type=\"button\"\r\n [disabled]=\"importing\"\r\n (click)=\"onPrevious(stepper)\"\r\n >\r\n Previous\r\n </button>\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div class=\"wizard-loading-overlay\" [class.wizard-loading-overlay--visible]=\"importing\" aria-hidden=\"true\"></div>\r\n</div>\r\n", styles: ["cc-import-contact-center-wizard{display:block;width:100%;min-height:100vh}.move-user-stepper-container{background-color:#f3f3f3;padding:0 0 16px;position:relative;overflow:hidden;box-sizing:border-box;min-height:100vh;display:flex;flex-direction:column}.move-user-header{background-color:#1170cf;height:45px;padding:1rem 1.5rem;display:flex;align-items:center;justify-content:space-between;color:#fff;font-size:18px;font-weight:500}.move-user-header__close{cursor:pointer;display:flex;align-items:center;justify-content:center;line-height:0}.app-icon{height:20px;width:20px;display:block;cursor:pointer}.cc-import-close-icon{color:#fffffff2}#cc-import-stepper{display:flex;flex-direction:column;width:100%;flex:1 1 auto;min-height:0}#cc-import-stepper .mat-stepper-horizontal{margin:0 auto;width:100%;background-color:transparent;display:flex;flex-direction:column;flex:1 1 auto;min-height:0}#cc-import-stepper .mat-horizontal-stepper-header-container{margin:0 auto;width:800px}#cc-import-stepper .mat-step-icon{width:28px;height:28px;border:3px solid hsl(0,0%,50.2%)}#cc-import-stepper .mat-step-icon-selected{background-color:#c6c6c6!important;border-color:#19487d}#cc-import-stepper .mat-step-icon-state-number{background-color:#fff}#cc-import-stepper .mat-step-icon-state-edit,#cc-import-stepper .mat-step-header .mat-step-icon-state-done{background-color:#1170cf;border-color:#1170cf}#cc-import-stepper .mat-step-icon-content{display:none}#cc-import-stepper .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:not(:first-child):before,#cc-import-stepper [dir=rtl] .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:not(:last-child):before,#cc-import-stepper .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:not(:last-child):after,#cc-import-stepper [dir=rtl] .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:not(:first-child):after{border-top-width:3px!important}#cc-import-stepper .mat-horizontal-stepper-header:before,#cc-import-stepper .mat-horizontal-stepper-header:after,#cc-import-stepper .mat-stepper-horizontal-line{border-top-color:#1170cf!important;border-top-width:3px!important;border-top-style:solid!important}#cc-import-stepper .mat-horizontal-stepper-header[aria-selected=true]~.mat-stepper-horizontal-line,#cc-import-stepper .mat-horizontal-stepper-header[aria-selected=true]~.mat-horizontal-stepper-header:before,#cc-import-stepper .mat-horizontal-stepper-header[aria-selected=true]~.mat-horizontal-stepper-header:after{border-top-width:3px!important;background-color:#7b7b7b!important;border-top-color:#7b7b7b!important}#cc-import-stepper .mat-horizontal-content-container{padding:0!important;margin-top:3rem}#cc-import-stepper .mat-horizontal-stepper-content[aria-expanded=true]{padding-bottom:0}.step-title{font-size:26px;font-weight:500;width:70%;margin:0 auto 1rem;min-height:32px;display:flex;align-items:center}.wizard-actions{display:flex;flex-flow:row-reverse;justify-content:flex-start;align-items:center;margin:16px 16px 0 0;align-self:flex-end;gap:1rem;position:relative;z-index:30}.uc-btn{border-radius:50px!important;padding:8px 16px!important;min-width:80px!important;line-height:normal!important;cursor:pointer}.uc-btn__inline-content{display:inline-flex;align-items:center;gap:8px}.uc-btn__spinner{width:14px;height:14px;border:2px solid rgba(255,255,255,.5);border-top-color:#fff;border-radius:50%;animation:uc-btn-spin .7s linear infinite}@keyframes uc-btn-spin{to{transform:rotate(360deg)}}.uc-btn-primary{background-color:#000!important;color:#fff!important;border:1px solid black!important}.uc-btn-secondary{background-color:#fff!important;color:#000!important;border:1px solid black!important}.wizard-actions .uc-btn-primary.mat-button-disabled{background-color:#bbb;color:#fff;border:1px solid grey;cursor:default!important;opacity:.3}.move-user-tab-content-box{width:70%;margin:0 auto;background-color:#fff;min-height:350px;border:1px solid #c3c1c1;border-radius:8px;box-sizing:border-box;padding:25px}.wizard-loading-overlay{position:absolute;inset:0;background:rgba(243,243,243,.72);backdrop-filter:blur(1px);opacity:0;pointer-events:none;transition:opacity .18s ease;z-index:20}.wizard-loading-overlay--visible{opacity:1;pointer-events:auto}.cc-import-notice{width:70%;margin:0 auto 1rem;box-sizing:border-box;display:flex;align-items:center;gap:10px;padding:10px 14px;border-radius:4px;background-color:#e8f2fc;color:#2a2f3b;font-size:13px;line-height:1.4}.cc-import-notice__icon{display:flex;color:#1170cf;line-height:0}.cc-import-notice__text{flex:1}.cc-import-notice__close{background:none;border:none;padding:0;cursor:pointer;display:flex;color:#5a6172;line-height:0}.cc-import-step-content{display:flex;flex-direction:column;gap:20px;max-width:420px}.cc-import-field{display:flex;flex-direction:column;gap:10px}.cc-import-label{font-size:14px;font-weight:400;line-height:100%;letter-spacing:.1px;color:#2a2f3b}.cc-import-select{width:100%;max-width:333px}.cc-import-empty{margin:0;font-size:13px;color:#5a6172}.cc-import-state{font-size:14px;color:#5a6172}.cc-import-state--error{color:#c0392b}.cc-import-card-title{margin:0 0 8px;font-size:15px;font-weight:700;color:#2a2f3b}.cc-import-card-text{margin:0 0 22px;font-size:14px;line-height:1.6;color:#2a2f3b}.cc-import-tabs{display:flex;flex-wrap:wrap;gap:20px}.cc-import-tab{background:none;border:none;border-bottom:2px solid transparent;padding:0 0 8px;font:inherit;font-size:14px;color:#5a6172;cursor:pointer}.cc-import-tab--active{color:#000;font-weight:600;border-bottom-color:#000}.cc-import-items{list-style:none;margin:18px 0 0;padding:0;display:flex;flex-direction:column;gap:10px}.cc-import-item{font-size:14px;color:#2a2f3b}.cc-import-item--empty{color:#5a6172;font-style:italic}.cc-import-select .mat-form-field-wrapper{padding-bottom:0}.cc-import-select .mat-form-field-flex{align-items:center;height:32px;border:1px solid #767676;border-radius:6px;padding:0 12px}.cc-import-select .mat-form-field-outline,.cc-import-select .mat-form-field-outline-start,.cc-import-select .mat-form-field-outline-end,.cc-import-select .mat-form-field-outline-gap{display:none}.cc-import-select .mat-form-field-infix{width:100%;border-top:0;padding:0}.cc-import-select .mat-select-trigger{display:flex;align-items:center;justify-content:space-between;height:100%}.cc-import-select-panel .option-row{display:flex;justify-content:space-between;align-items:center;width:100%;gap:12px}.cc-import-select-panel .cc-import-option-marker{display:flex;color:#b26a00;line-height:0}.cc-import-select-search{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:8px;margin:4px 8px 8px;padding:0 10px;height:30px;border:1px solid #c3c1c1;border-radius:50px;background-color:#fff}.cc-import-select-search__icon{display:flex;color:#5a6172;line-height:0}.cc-import-select-search__input{flex:1;border:none;outline:none;font:inherit;font-size:13px;color:#2a2f3b;background:transparent}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "component", type: i2$2.MatStep, selector: "mat-step", inputs: ["color"], exportAs: ["matStep"] }, { kind: "directive", type: i2$2.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: i2$2.MatStepper, selector: "mat-stepper, mat-vertical-stepper, mat-horizontal-stepper, [matStepper]", inputs: ["selectedIndex", "disableRipple", "color", "labelPosition", "headerPosition", "animationDuration"], outputs: ["animationDone"], exportAs: ["matStepper", "matVerticalStepper", "matHorizontalStepper"] }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i1$4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "directive", type: i6.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i3.MatOption, selector: "mat-option", exportAs: ["matOption"] }], encapsulation: i0.ViewEncapsulation.None });
4269
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ImportContactCenterWizardComponent, decorators: [{
4270
+ type: Component,
4271
+ args: [{ selector: 'cc-import-contact-center-wizard', encapsulation: ViewEncapsulation.None, template: "<div class=\"move-user-stepper-container\" [attr.aria-busy]=\"importing\">\r\n <header class=\"move-user-header\">\r\n <div class=\"move-user-header__title\">{{ title }}</div>\r\n <div class=\"move-user-header__close\">\r\n <span class=\"app-icon cc-import-close-icon\" (click)=\"onCancel()\" role=\"button\" aria-label=\"Close\">\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path d=\"M5 5L19 19M19 5L5 19\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linecap=\"round\" />\r\n </svg>\r\n </span>\r\n </div>\r\n </header>\r\n\r\n <div id=\"cc-import-stepper\">\r\n <mat-stepper\r\n #stepper\r\n [linear]=\"true\"\r\n labelPosition=\"bottom\"\r\n [selectedIndex]=\"selectedIndex\"\r\n (selectionChange)=\"onStepSelectionChange($event)\"\r\n >\r\n\r\n <!-- Step 1: pick the UCCX contact center -->\r\n <mat-step [completed]=\"canGoNext\">\r\n <ng-template matStepLabel>Select</ng-template>\r\n\r\n <div class=\"cc-import-notice\" *ngIf=\"showCustomerAssistNotice\" role=\"status\">\r\n <span class=\"cc-import-notice__icon\" aria-hidden=\"true\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n <circle cx=\"8\" cy=\"8\" r=\"7\" fill=\"currentColor\" />\r\n <path d=\"M8 7.1v4.2\" stroke=\"#fff\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\r\n <circle cx=\"8\" cy=\"4.8\" r=\"0.9\" fill=\"#fff\" />\r\n </svg>\r\n </span>\r\n <span class=\"cc-import-notice__text\">{{ customerAssistNotice }}</span>\r\n <button type=\"button\" class=\"cc-import-notice__close\" aria-label=\"Dismiss\" (click)=\"dismissNotice()\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path d=\"M5 5L19 19M19 5L5 19\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <div class=\"step-title\">Step 1: Select contact center</div>\r\n\r\n <div class=\"move-user-tab-content-box\">\r\n <div class=\"cc-import-state\" *ngIf=\"loading\">Loading contact centers&hellip;</div>\r\n <div class=\"cc-import-state cc-import-state--error\" *ngIf=\"!loading && error\">\r\n Unable to load contact centers.\r\n </div>\r\n\r\n <section class=\"cc-import-step-content\" *ngIf=\"!loading && !error\">\r\n <div class=\"cc-import-field\">\r\n <label class=\"cc-import-label\" for=\"cc-import-contact-center\">Contact center</label>\r\n\r\n <mat-form-field class=\"cc-import-select\" appearance=\"outline\">\r\n <mat-select\r\n id=\"cc-import-contact-center\"\r\n panelClass=\"cc-import-select-panel\"\r\n placeholder=\"Select contact center\"\r\n [disableOptionCentering]=\"true\"\r\n [value]=\"selected?.applicationId ?? null\"\r\n (selectionChange)=\"onSelect($event.value)\"\r\n (openedChange)=\"onPanelToggle($event)\"\r\n >\r\n <mat-select-trigger>{{ selected?.applicationName }}</mat-select-trigger>\r\n\r\n <!-- Search box pinned above the options. Keystrokes are stopped here so\r\n mat-select's own typeahead does not steal them. -->\r\n <div class=\"cc-import-select-search\" (click)=\"$event.stopPropagation()\">\r\n <span class=\"cc-import-select-search__icon\" aria-hidden=\"true\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n <circle cx=\"7\" cy=\"7\" r=\"4.6\" stroke=\"currentColor\" stroke-width=\"1.4\" />\r\n <path d=\"M10.6 10.6L14 14\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" />\r\n </svg>\r\n </span>\r\n <input\r\n class=\"cc-import-select-search__input\"\r\n type=\"text\"\r\n autocomplete=\"off\"\r\n placeholder=\"Search\"\r\n aria-label=\"Search contact centers\"\r\n [value]=\"searchTerm\"\r\n (input)=\"onSearch($event)\"\r\n (keydown)=\"$event.stopPropagation()\"\r\n />\r\n </div>\r\n\r\n <mat-option *ngFor=\"let option of filteredOptions\" [value]=\"option.applicationId\">\r\n <div class=\"option-row\">\r\n <span class=\"name\">{{ option.applicationName }}</span>\r\n <span\r\n class=\"cc-import-option-marker\"\r\n *ngIf=\"option.customerAssistCapable\"\r\n [matTooltip]=\"customerAssistMarkerTooltip\"\r\n aria-hidden=\"true\"\r\n >\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n <path d=\"M8 2.2 14.6 13.4H1.4L8 2.2Z\" stroke=\"currentColor\" stroke-width=\"1.2\" stroke-linejoin=\"round\" />\r\n <path d=\"M8 6.5v3\" stroke=\"currentColor\" stroke-width=\"1.2\" stroke-linecap=\"round\" />\r\n <circle cx=\"8\" cy=\"11.3\" r=\"0.7\" fill=\"currentColor\" />\r\n </svg>\r\n </span>\r\n </div>\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n\r\n <p class=\"cc-import-empty\" *ngIf=\"!options.length\">\r\n Every detected contact center has already been imported.\r\n </p>\r\n </div>\r\n </section>\r\n </div>\r\n </mat-step>\r\n\r\n <!-- Step 2: the entities Tuki will create for it -->\r\n <mat-step>\r\n <ng-template matStepLabel>Overview</ng-template>\r\n\r\n <div class=\"step-title\">Overview</div>\r\n\r\n <div class=\"move-user-tab-content-box\">\r\n <h3 class=\"cc-import-card-title\">Review Contact Center Settings</h3>\r\n <p class=\"cc-import-card-text\">\r\n Review the settings for your new Contact center to make sure everything is correct.<br />\r\n You can make changes at any time by clicking on the name of the contact center on the dedicated page.\r\n </p>\r\n\r\n <div class=\"cc-import-state\" *ngIf=\"entitiesLoading\">Loading entities&hellip;</div>\r\n <div class=\"cc-import-state cc-import-state--error\" *ngIf=\"entitiesError\">\r\n Unable to load the related entities.\r\n </div>\r\n\r\n <ng-container *ngIf=\"!entitiesLoading && !entitiesError && entityGroups.length\">\r\n <div class=\"cc-import-tabs\" role=\"tablist\">\r\n <button\r\n type=\"button\"\r\n class=\"cc-import-tab\"\r\n *ngFor=\"let group of entityGroups; index as i\"\r\n role=\"tab\"\r\n [attr.aria-selected]=\"i === activeGroupIndex\"\r\n [class.cc-import-tab--active]=\"i === activeGroupIndex\"\r\n (click)=\"selectGroup(i)\"\r\n >\r\n {{ group.label }}\r\n </button>\r\n </div>\r\n\r\n <ul class=\"cc-import-items\" role=\"tabpanel\">\r\n <li class=\"cc-import-item\" *ngFor=\"let item of activeGroup?.items\">{{ item }}</li>\r\n <li class=\"cc-import-item cc-import-item--empty\" *ngIf=\"!activeGroup?.items?.length\">\r\n Nothing to create for {{ activeGroup?.label }}.\r\n </li>\r\n </ul>\r\n </ng-container>\r\n\r\n <div class=\"cc-import-state cc-import-state--error\" *ngIf=\"importError\">\r\n Unable to start the import. Please try again.\r\n </div>\r\n </div>\r\n </mat-step>\r\n </mat-stepper>\r\n\r\n <div class=\"wizard-actions\">\r\n <ng-container [ngSwitch]=\"stepper.selectedIndex\">\r\n <ng-container *ngSwitchCase=\"0\">\r\n <button\r\n mat-button\r\n class=\"uc-btn uc-btn-primary\"\r\n type=\"button\"\r\n [disabled]=\"!canGoNext\"\r\n (click)=\"onNext(stepper)\"\r\n >\r\n Next\r\n </button>\r\n <button mat-button class=\"uc-btn uc-btn-secondary\" type=\"button\" (click)=\"onCancel()\">\r\n Cancel\r\n </button>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"1\">\r\n <button\r\n mat-button\r\n class=\"uc-btn uc-btn-primary\"\r\n type=\"button\"\r\n [disabled]=\"!canImport\"\r\n (click)=\"runImport()\"\r\n >\r\n <span class=\"uc-btn__inline-content\">\r\n <span class=\"uc-btn__spinner\" *ngIf=\"importing\" aria-hidden=\"true\"></span>\r\n <span>{{ importing ? 'Importing...' : 'Import' }}</span>\r\n </span>\r\n </button>\r\n <button\r\n mat-button\r\n class=\"uc-btn uc-btn-secondary\"\r\n type=\"button\"\r\n [disabled]=\"importing\"\r\n (click)=\"onPrevious(stepper)\"\r\n >\r\n Previous\r\n </button>\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div class=\"wizard-loading-overlay\" [class.wizard-loading-overlay--visible]=\"importing\" aria-hidden=\"true\"></div>\r\n</div>\r\n", styles: ["cc-import-contact-center-wizard{display:block;width:100%;min-height:100vh}.move-user-stepper-container{background-color:#f3f3f3;padding:0 0 16px;position:relative;overflow:hidden;box-sizing:border-box;min-height:100vh;display:flex;flex-direction:column}.move-user-header{background-color:#1170cf;height:45px;padding:1rem 1.5rem;display:flex;align-items:center;justify-content:space-between;color:#fff;font-size:18px;font-weight:500}.move-user-header__close{cursor:pointer;display:flex;align-items:center;justify-content:center;line-height:0}.app-icon{height:20px;width:20px;display:block;cursor:pointer}.cc-import-close-icon{color:#fffffff2}#cc-import-stepper{display:flex;flex-direction:column;width:100%;flex:1 1 auto;min-height:0}#cc-import-stepper .mat-stepper-horizontal{margin:0 auto;width:100%;background-color:transparent;display:flex;flex-direction:column;flex:1 1 auto;min-height:0}#cc-import-stepper .mat-horizontal-stepper-header-container{margin:0 auto;width:800px}#cc-import-stepper .mat-step-icon{width:28px;height:28px;border:3px solid hsl(0,0%,50.2%)}#cc-import-stepper .mat-step-icon-selected{background-color:#c6c6c6!important;border-color:#19487d}#cc-import-stepper .mat-step-icon-state-number{background-color:#fff}#cc-import-stepper .mat-step-icon-state-edit,#cc-import-stepper .mat-step-header .mat-step-icon-state-done{background-color:#1170cf;border-color:#1170cf}#cc-import-stepper .mat-step-icon-content{display:none}#cc-import-stepper .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:not(:first-child):before,#cc-import-stepper [dir=rtl] .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:not(:last-child):before,#cc-import-stepper .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:not(:last-child):after,#cc-import-stepper [dir=rtl] .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:not(:first-child):after{border-top-width:3px!important}#cc-import-stepper .mat-horizontal-stepper-header:before,#cc-import-stepper .mat-horizontal-stepper-header:after,#cc-import-stepper .mat-stepper-horizontal-line{border-top-color:#1170cf!important;border-top-width:3px!important;border-top-style:solid!important}#cc-import-stepper .mat-horizontal-stepper-header[aria-selected=true]~.mat-stepper-horizontal-line,#cc-import-stepper .mat-horizontal-stepper-header[aria-selected=true]~.mat-horizontal-stepper-header:before,#cc-import-stepper .mat-horizontal-stepper-header[aria-selected=true]~.mat-horizontal-stepper-header:after{border-top-width:3px!important;background-color:#7b7b7b!important;border-top-color:#7b7b7b!important}#cc-import-stepper .mat-horizontal-content-container{padding:0!important;margin-top:3rem}#cc-import-stepper .mat-horizontal-stepper-content[aria-expanded=true]{padding-bottom:0}.step-title{font-size:26px;font-weight:500;width:70%;margin:0 auto 1rem;min-height:32px;display:flex;align-items:center}.wizard-actions{display:flex;flex-flow:row-reverse;justify-content:flex-start;align-items:center;margin:16px 16px 0 0;align-self:flex-end;gap:1rem;position:relative;z-index:30}.uc-btn{border-radius:50px!important;padding:8px 16px!important;min-width:80px!important;line-height:normal!important;cursor:pointer}.uc-btn__inline-content{display:inline-flex;align-items:center;gap:8px}.uc-btn__spinner{width:14px;height:14px;border:2px solid rgba(255,255,255,.5);border-top-color:#fff;border-radius:50%;animation:uc-btn-spin .7s linear infinite}@keyframes uc-btn-spin{to{transform:rotate(360deg)}}.uc-btn-primary{background-color:#000!important;color:#fff!important;border:1px solid black!important}.uc-btn-secondary{background-color:#fff!important;color:#000!important;border:1px solid black!important}.wizard-actions .uc-btn-primary.mat-button-disabled{background-color:#bbb;color:#fff;border:1px solid grey;cursor:default!important;opacity:.3}.move-user-tab-content-box{width:70%;margin:0 auto;background-color:#fff;min-height:350px;border:1px solid #c3c1c1;border-radius:8px;box-sizing:border-box;padding:25px}.wizard-loading-overlay{position:absolute;inset:0;background:rgba(243,243,243,.72);backdrop-filter:blur(1px);opacity:0;pointer-events:none;transition:opacity .18s ease;z-index:20}.wizard-loading-overlay--visible{opacity:1;pointer-events:auto}.cc-import-notice{width:70%;margin:0 auto 1rem;box-sizing:border-box;display:flex;align-items:center;gap:10px;padding:10px 14px;border-radius:4px;background-color:#e8f2fc;color:#2a2f3b;font-size:13px;line-height:1.4}.cc-import-notice__icon{display:flex;color:#1170cf;line-height:0}.cc-import-notice__text{flex:1}.cc-import-notice__close{background:none;border:none;padding:0;cursor:pointer;display:flex;color:#5a6172;line-height:0}.cc-import-step-content{display:flex;flex-direction:column;gap:20px;max-width:420px}.cc-import-field{display:flex;flex-direction:column;gap:10px}.cc-import-label{font-size:14px;font-weight:400;line-height:100%;letter-spacing:.1px;color:#2a2f3b}.cc-import-select{width:100%;max-width:333px}.cc-import-empty{margin:0;font-size:13px;color:#5a6172}.cc-import-state{font-size:14px;color:#5a6172}.cc-import-state--error{color:#c0392b}.cc-import-card-title{margin:0 0 8px;font-size:15px;font-weight:700;color:#2a2f3b}.cc-import-card-text{margin:0 0 22px;font-size:14px;line-height:1.6;color:#2a2f3b}.cc-import-tabs{display:flex;flex-wrap:wrap;gap:20px}.cc-import-tab{background:none;border:none;border-bottom:2px solid transparent;padding:0 0 8px;font:inherit;font-size:14px;color:#5a6172;cursor:pointer}.cc-import-tab--active{color:#000;font-weight:600;border-bottom-color:#000}.cc-import-items{list-style:none;margin:18px 0 0;padding:0;display:flex;flex-direction:column;gap:10px}.cc-import-item{font-size:14px;color:#2a2f3b}.cc-import-item--empty{color:#5a6172;font-style:italic}.cc-import-select .mat-form-field-wrapper{padding-bottom:0}.cc-import-select .mat-form-field-flex{align-items:center;height:32px;border:1px solid #767676;border-radius:6px;padding:0 12px}.cc-import-select .mat-form-field-outline,.cc-import-select .mat-form-field-outline-start,.cc-import-select .mat-form-field-outline-end,.cc-import-select .mat-form-field-outline-gap{display:none}.cc-import-select .mat-form-field-infix{width:100%;border-top:0;padding:0}.cc-import-select .mat-select-trigger{display:flex;align-items:center;justify-content:space-between;height:100%}.cc-import-select-panel .option-row{display:flex;justify-content:space-between;align-items:center;width:100%;gap:12px}.cc-import-select-panel .cc-import-option-marker{display:flex;color:#b26a00;line-height:0}.cc-import-select-search{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:8px;margin:4px 8px 8px;padding:0 10px;height:30px;border:1px solid #c3c1c1;border-radius:50px;background-color:#fff}.cc-import-select-search__icon{display:flex;color:#5a6172;line-height:0}.cc-import-select-search__input{flex:1;border:none;outline:none;font:inherit;font-size:13px;color:#2a2f3b;background:transparent}\n"] }]
4272
+ }], propDecorators: { title: [{
4273
+ type: Input
4274
+ }], customerId: [{
4275
+ type: Input
4276
+ }], host: [{
4277
+ type: Input
4278
+ }], dcpHost: [{
4279
+ type: Input
4280
+ }], token: [{
4281
+ type: Input
4282
+ }], useMockData: [{
4283
+ type: Input
4284
+ }], contactCenters: [{
4285
+ type: Input
4286
+ }], cancel: [{
4287
+ type: Output
4288
+ }], imported: [{
4289
+ type: Output
4290
+ }] } });
4291
+
4292
+ class CcImportModule {
4293
+ }
4294
+ CcImportModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CcImportModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
4295
+ CcImportModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: CcImportModule, declarations: [ImportContactCenterPanelComponent,
4296
+ ImportContactCenterWizardComponent], imports: [CommonModule,
4297
+ HttpClientModule,
4298
+ NgApexchartsModule,
4299
+ MatStepperModule,
4300
+ SharedModule], exports: [ImportContactCenterPanelComponent,
4301
+ ImportContactCenterWizardComponent] });
4302
+ CcImportModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CcImportModule, imports: [CommonModule,
4303
+ HttpClientModule,
4304
+ NgApexchartsModule,
4305
+ MatStepperModule,
4306
+ SharedModule] });
4307
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CcImportModule, decorators: [{
4308
+ type: NgModule,
4309
+ args: [{
4310
+ declarations: [
4311
+ ImportContactCenterPanelComponent,
4312
+ ImportContactCenterWizardComponent
4313
+ ],
4314
+ imports: [
4315
+ CommonModule,
4316
+ HttpClientModule,
4317
+ NgApexchartsModule,
4318
+ MatStepperModule,
4319
+ SharedModule
4320
+ ],
4321
+ exports: [
4322
+ ImportContactCenterPanelComponent,
4323
+ ImportContactCenterWizardComponent
4324
+ ]
4325
+ }]
4326
+ }] });
4327
+
3466
4328
  /**
3467
4329
  * Generated bundle index. Do not edit.
3468
4330
  */
3469
4331
 
3470
- export { CcReadinessModule, LicencesRequirementComponent, SummaryGridComponent, WxCCFlowchartModule, WxCCFlowchartPageComponent };
4332
+ export { CALL_FLOW_MIGRATED, CHART_COLORS, COMPATIBILITY_THRESHOLDS, CUSTOMER_ASSIST_MARKER_TOOLTIP, CUSTOMER_ASSIST_NOTICE, CcImportModule, CcImportService, CcReadinessModule, IMPORT_PANEL_SLICES, IMPORT_PANEL_TITLE, IMPORT_PANEL_TOOLTIP, IMPORT_WIZARD_STEPS, IMPORT_WIZARD_TITLE, ImportContactCenterPanelComponent, ImportContactCenterWizardComponent, LicencesRequirementComponent, OVERVIEW_ENTITY_GROUPS, SummaryGridComponent, UCCX_ITEM_TYPE, WxCCFlowchartModule, WxCCFlowchartPageComponent };
3471
4333
  //# sourceMappingURL=tuki-io-tuki-widgets-contact-center.mjs.map