http-request-manager 18.15.32 → 18.15.34

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 (301) hide show
  1. package/README.md +2 -0
  2. package/TEST_COVERAGE_SUMMARY.md +458 -0
  3. package/ng-package.json +8 -0
  4. package/package.json +5 -13
  5. package/src/docs/ADVANCED_WEBSOCKET.md +633 -0
  6. package/src/docs/ARCHITECTURE.md +633 -0
  7. package/src/docs/BATCH_REQUEST_README.md +467 -0
  8. package/src/docs/COMPLETE_API_REFERENCE.md +1037 -0
  9. package/src/docs/DATABASE_README.md +1195 -0
  10. package/src/docs/ENCRYPTION_README.md +403 -0
  11. package/src/docs/HTTP_MANAGER_README.md +628 -0
  12. package/src/docs/HTTP_SINGNALS_MANAGER_README.md +654 -0
  13. package/src/docs/HTTP_STATE_MANAGER_README.md +1391 -0
  14. package/src/docs/INTERCEPTOR_README.md +549 -0
  15. package/src/docs/LOCAL_STORAGE_README.md +1056 -0
  16. package/src/docs/LOCAL_STORAGE_SIGNALS_README.md +338 -0
  17. package/src/docs/LOGGER_README.md +310 -0
  18. package/src/docs/MESSAGE_TRACKER_README.md +518 -0
  19. package/src/docs/MESSAGE_TRACKER_SIGNALS_README.md +563 -0
  20. package/src/docs/MODELS_README.md +1264 -0
  21. package/src/docs/SIGNAL_SERVICES_README.md +238 -0
  22. package/src/docs/SQL_DIXIE_README.md +574 -0
  23. package/src/docs/STORE_STATE_MANAGER_README.md +556 -0
  24. package/src/docs/STORE_STATE_SIGNALS_README.md +600 -0
  25. package/src/docs/UPLOAD_REQUEST_README.md +324 -0
  26. package/src/docs/UTILS_README.md +1604 -0
  27. package/src/docs/WEBSOCKET_MESSAGE_SERVICE.md +799 -0
  28. package/src/docs/WEBSOCKET_SIGNALS_README.md +641 -0
  29. package/src/docs/WEBSOCKET_SINGLETON_REFACTORING.md +201 -0
  30. package/src/docs/WS_MANAGER_README.md +613 -0
  31. package/src/lib/http-request-manager.module.ts +147 -0
  32. package/src/lib/http-request-services-demo/database-data-demo/database-data-demo.component.html +116 -0
  33. package/src/lib/http-request-services-demo/database-data-demo/database-data-demo.component.scss +0 -0
  34. package/src/lib/http-request-services-demo/database-data-demo/database-data-demo.component.ts +255 -0
  35. package/src/lib/http-request-services-demo/http-request-services-demo.component.html +123 -0
  36. package/src/lib/http-request-services-demo/http-request-services-demo.component.scss +6 -0
  37. package/src/lib/http-request-services-demo/http-request-services-demo.component.ts +53 -0
  38. package/src/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.html +195 -0
  39. package/src/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.scss +17 -0
  40. package/src/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.ts +208 -0
  41. package/src/lib/http-request-services-demo/local-storage-signals-demo/local-storage-signals-demo.component.html +200 -0
  42. package/src/lib/http-request-services-demo/local-storage-signals-demo/local-storage-signals-demo.component.scss +17 -0
  43. package/src/lib/http-request-services-demo/local-storage-signals-demo/local-storage-signals-demo.component.ts +214 -0
  44. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/download-file/download-file.component.html +53 -0
  45. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/download-file/download-file.component.scss +60 -0
  46. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/download-file/download-file.component.ts +72 -0
  47. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/file-download.module.ts +28 -0
  48. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/file-downloader.component.html +10 -0
  49. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/file-downloader.component.scss +29 -0
  50. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/file-downloader.component.ts +100 -0
  51. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/models/download-labels-model.ts +22 -0
  52. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/spinner/spinner.component.html +8 -0
  53. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/spinner/spinner.component.scss +19 -0
  54. package/src/lib/http-request-services-demo/request-manager-basic-demo/file-downloader/spinner/spinner.component.ts +26 -0
  55. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/app-session.model.ts +30 -0
  56. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/app.model.ts +19 -0
  57. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/get-sample.model.ts +25 -0
  58. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/sample-ai-prompt.ts +19 -0
  59. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/sample-client-details.ts +24 -0
  60. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/sample-client-info.ts +30 -0
  61. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/sample-client.model.ts +49 -0
  62. package/src/lib/http-request-services-demo/request-manager-basic-demo/models/sample-mapper-client-info.ts +33 -0
  63. package/src/lib/http-request-services-demo/request-manager-basic-demo/request-manager-basic-demo.component.html +279 -0
  64. package/src/lib/http-request-services-demo/request-manager-basic-demo/request-manager-basic-demo.component.scss +24 -0
  65. package/src/lib/http-request-services-demo/request-manager-basic-demo/request-manager-basic-demo.component.ts +461 -0
  66. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.html +53 -0
  67. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.scss +60 -0
  68. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.ts +72 -0
  69. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-download.module.ts +28 -0
  70. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.html +10 -0
  71. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.scss +29 -0
  72. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.ts +100 -0
  73. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/models/download-labels-model.ts +22 -0
  74. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.html +8 -0
  75. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.scss +19 -0
  76. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.ts +26 -0
  77. package/src/lib/http-request-services-demo/request-manager-demo/models/app-session.model.ts +30 -0
  78. package/src/lib/http-request-services-demo/request-manager-demo/models/app.model.ts +19 -0
  79. package/src/lib/http-request-services-demo/request-manager-demo/models/get-sample.model.ts +25 -0
  80. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-ai-prompt.ts +19 -0
  81. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-client-details.ts +24 -0
  82. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-client-info.ts +30 -0
  83. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-client.model.ts +49 -0
  84. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-mapper-client-info.ts +33 -0
  85. package/src/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.html +622 -0
  86. package/src/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.scss +106 -0
  87. package/src/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.ts +687 -0
  88. package/src/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.html +418 -0
  89. package/src/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.scss +24 -0
  90. package/src/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.ts +576 -0
  91. package/src/lib/http-request-services-demo/request-manager-state-demo/services/state-manager-demo.service.ts +89 -0
  92. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/services/state-data-request.service.ts +119 -0
  93. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-ai-messaging/ws-ai-messaging.component.css +0 -0
  94. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-ai-messaging/ws-ai-messaging.component.html +3 -0
  95. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-ai-messaging/ws-ai-messaging.component.ts +16 -0
  96. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-chats/ws-chats.component.css +0 -0
  97. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-chats/ws-chats.component.html +3 -0
  98. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-chats/ws-chats.component.ts +16 -0
  99. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.css +31 -0
  100. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.html +94 -0
  101. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.scss +41 -0
  102. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.spec.ts +203 -0
  103. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.ts +144 -0
  104. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-messaging/ws-messaging.component.css +11 -0
  105. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-messaging/ws-messaging.component.html +102 -0
  106. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-messaging/ws-messaging.component.spec.ts +40 -0
  107. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-messaging/ws-messaging.component.ts +230 -0
  108. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-notifications/ws-notifications.component.css +30 -0
  109. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-notifications/ws-notifications.component.html +172 -0
  110. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-notifications/ws-notifications.component.spec.ts +31 -0
  111. package/src/lib/http-request-services-demo/request-manager-ws-demo/components/ws-notifications/ws-notifications.component.ts +239 -0
  112. package/src/lib/http-request-services-demo/request-manager-ws-demo/models/oidc-client.model.ts +31 -0
  113. package/src/lib/http-request-services-demo/request-manager-ws-demo/models/user-data.model.ts +32 -0
  114. package/src/lib/http-request-services-demo/request-manager-ws-demo/request-manager-ws-demo.component.css +0 -0
  115. package/src/lib/http-request-services-demo/request-manager-ws-demo/request-manager-ws-demo.component.html +84 -0
  116. package/src/lib/http-request-services-demo/request-manager-ws-demo/request-manager-ws-demo.component.ts +40 -0
  117. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/index.ts +3 -0
  118. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/jwt-token.service.ts +62 -0
  119. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/message-service-demo.service.ts +83 -0
  120. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/notification-service-demo.service.ts +147 -0
  121. package/src/lib/http-request-services-demo/request-manager-ws-demo/services/state-service-demo.service.ts +168 -0
  122. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/download-file/download-file.component.html +53 -0
  123. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/download-file/download-file.component.scss +60 -0
  124. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/download-file/download-file.component.ts +72 -0
  125. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/file-download.module.ts +28 -0
  126. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/file-downloader.component.html +10 -0
  127. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/file-downloader.component.scss +29 -0
  128. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/file-downloader.component.ts +100 -0
  129. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/models/download-labels-model.ts +22 -0
  130. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/spinner/spinner.component.html +8 -0
  131. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/spinner/spinner.component.scss +19 -0
  132. package/src/lib/http-request-services-demo/request-signals-manager-demo/file-downloader/spinner/spinner.component.ts +26 -0
  133. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/app-session.model.ts +30 -0
  134. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/app.model.ts +19 -0
  135. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/get-sample.model.ts +25 -0
  136. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-ai-prompt.ts +19 -0
  137. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-client-details.ts +24 -0
  138. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-client-info.ts +30 -0
  139. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-client.model.ts +49 -0
  140. package/src/lib/http-request-services-demo/request-signals-manager-demo/models/sample-mapper-client-info.ts +33 -0
  141. package/src/lib/http-request-services-demo/request-signals-manager-demo/request-signals-manager-demo.component.html +380 -0
  142. package/src/lib/http-request-services-demo/request-signals-manager-demo/request-signals-manager-demo.component.scss +24 -0
  143. package/src/lib/http-request-services-demo/request-signals-manager-demo/request-signals-manager-demo.component.ts +410 -0
  144. package/src/lib/http-request-services-demo/store-state-manager-demo/models/settings.model.ts +28 -0
  145. package/src/lib/http-request-services-demo/store-state-manager-demo/services/settings-state.service.ts +49 -0
  146. package/src/lib/http-request-services-demo/store-state-manager-demo/store-state-manager-demo.component.css +0 -0
  147. package/src/lib/http-request-services-demo/store-state-manager-demo/store-state-manager-demo.component.html +23 -0
  148. package/src/lib/http-request-services-demo/store-state-manager-demo/store-state-manager-demo.component.ts +36 -0
  149. package/src/lib/http-request-services-demo/store-state-signals-demo/store-state-signals-demo.component.ts +161 -0
  150. package/src/lib/http-request-services-demo/upload-demo/models/index.ts +1 -0
  151. package/src/lib/http-request-services-demo/upload-demo/models/upload-state.model.ts +30 -0
  152. package/src/lib/http-request-services-demo/upload-demo/upload-demo.component.html +89 -0
  153. package/src/lib/http-request-services-demo/upload-demo/upload-demo.component.scss +160 -0
  154. package/src/lib/http-request-services-demo/upload-demo/upload-demo.component.spec.ts +101 -0
  155. package/src/lib/http-request-services-demo/upload-demo/upload-demo.component.ts +136 -0
  156. package/src/lib/index.ts +3 -0
  157. package/src/lib/interceptors/credentials.interceptor.ts +16 -0
  158. package/src/lib/interceptors/index.ts +6 -0
  159. package/src/lib/interceptors/models/error-settings.model.ts +22 -0
  160. package/src/lib/interceptors/models/index.ts +2 -0
  161. package/src/lib/interceptors/proxy-debugger.interceptor.ts +46 -0
  162. package/src/lib/interceptors/request-error.interceptor.ts +65 -0
  163. package/src/lib/interceptors/request-header.interceptor.ts +56 -0
  164. package/src/lib/message-display/README.md +509 -0
  165. package/src/lib/message-display/index.ts +4 -0
  166. package/src/lib/message-display/models/action.model.ts +27 -0
  167. package/src/lib/message-display/models/communication-message.model.ts +77 -0
  168. package/src/lib/message-display/models/display-config.model.ts +35 -0
  169. package/src/lib/message-display/models/display-rule.interface.ts +28 -0
  170. package/src/lib/message-display/models/display-strategy.interface.ts +8 -0
  171. package/src/lib/message-display/models/index.ts +6 -0
  172. package/src/lib/message-display/models/slide.model.ts +24 -0
  173. package/src/lib/message-display/rules/default-display-rules.ts +35 -0
  174. package/src/lib/message-display/services/message-display-router.service.ts +63 -0
  175. package/src/lib/message-display/strategies/snackbar.strategy.ts +46 -0
  176. package/src/lib/models/batch-options.model.ts +33 -0
  177. package/src/lib/models/batch-progress.model.ts +19 -0
  178. package/src/lib/models/batch-request-state.model.ts +40 -0
  179. package/src/lib/models/batch-result.model.ts +30 -0
  180. package/src/lib/models/config-http-options.model.ts +45 -0
  181. package/src/lib/models/config-local-storage-options.model.ts +27 -0
  182. package/src/lib/models/config-options.model.ts +27 -0
  183. package/src/lib/models/config-token.model.ts +9 -0
  184. package/src/lib/models/data-type.enum.ts +5 -0
  185. package/src/lib/models/database-storage.model.ts +24 -0
  186. package/src/lib/models/index.ts +16 -0
  187. package/src/lib/models/retry-options.model.ts +22 -0
  188. package/src/lib/models/upload-validation-error.model.ts +46 -0
  189. package/src/lib/services/SQL-DixieJS service/dexie-query-executor.ts +246 -0
  190. package/src/lib/services/SQL-DixieJS service/dexie-sql.service.ts +31 -0
  191. package/src/lib/services/SQL-DixieJS service/index.ts +4 -0
  192. package/src/lib/services/SQL-DixieJS service/models/execution-plan.model.ts +52 -0
  193. package/src/lib/services/SQL-DixieJS service/models/index.ts +3 -0
  194. package/src/lib/services/SQL-DixieJS service/models/sql-errors.model.ts +13 -0
  195. package/src/lib/services/SQL-DixieJS service/models/sql-options.model.ts +3 -0
  196. package/src/lib/services/SQL-DixieJS service/query-planner.ts +284 -0
  197. package/src/lib/services/SQL-DixieJS service/schema-validator.ts +217 -0
  198. package/src/lib/services/SQL-DixieJS service/sql-parser.ts +35 -0
  199. package/src/lib/services/database-manager-service/database.manager.service.ts +384 -0
  200. package/src/lib/services/database-manager-service/db.storage.service.ts +240 -0
  201. package/src/lib/services/database-manager-service/index.ts +4 -0
  202. package/src/lib/services/database-manager-service/models/index.ts +2 -0
  203. package/src/lib/services/database-manager-service/models/table-schema.ts +33 -0
  204. package/src/lib/services/index.ts +20 -0
  205. package/src/lib/services/local-storage-manager-service/index.ts +4 -0
  206. package/src/lib/services/local-storage-manager-service/local-storage-manager.service.spec.ts +71 -0
  207. package/src/lib/services/local-storage-manager-service/local-storage-manager.service.ts +567 -0
  208. package/src/lib/services/local-storage-manager-service/local-storage-signals-manager.service.spec.ts +67 -0
  209. package/src/lib/services/local-storage-manager-service/local-storage-signals-manager.service.ts +437 -0
  210. package/src/lib/services/local-storage-manager-service/models/global-store-options.model.ts +30 -0
  211. package/src/lib/services/local-storage-manager-service/models/index.ts +6 -0
  212. package/src/lib/services/local-storage-manager-service/models/setting-options.model.ts +35 -0
  213. package/src/lib/services/local-storage-manager-service/models/storage-data.model.ts +24 -0
  214. package/src/lib/services/local-storage-manager-service/models/storage-option.model.ts +32 -0
  215. package/src/lib/services/local-storage-manager-service/models/storage-type.enum.ts +5 -0
  216. package/src/lib/services/request-manager-services/README.md +282 -0
  217. package/src/lib/services/request-manager-services/http-manager-signals.service.ts +674 -0
  218. package/src/lib/services/request-manager-services/http-manager.service.spec.ts +353 -0
  219. package/src/lib/services/request-manager-services/http-manager.service.ts +727 -0
  220. package/src/lib/services/request-manager-services/index.ts +8 -0
  221. package/src/lib/services/request-manager-services/request-signals.service.ts +372 -0
  222. package/src/lib/services/request-manager-services/request.service.ts +435 -0
  223. package/src/lib/services/request-manager-services/rxjs-operators/countdown.ts +17 -0
  224. package/src/lib/services/request-manager-services/rxjs-operators/delay-retry.ts +16 -0
  225. package/src/lib/services/request-manager-services/rxjs-operators/index.ts +4 -0
  226. package/src/lib/services/request-manager-services/rxjs-operators/request-polling.ts +35 -0
  227. package/src/lib/services/request-manager-services/rxjs-operators/request-streaming.ts +468 -0
  228. package/src/lib/services/request-manager-state-service/http-manager-state.store.spec.ts +665 -0
  229. package/src/lib/services/request-manager-state-service/http-manager-state.store.ts +2395 -0
  230. package/src/lib/services/request-manager-state-service/index.ts +3 -0
  231. package/src/lib/services/request-manager-state-service/models/api-request.model.ts +86 -0
  232. package/src/lib/services/request-manager-state-service/models/index.ts +14 -0
  233. package/src/lib/services/request-manager-state-service/models/operation-result.model.ts +18 -0
  234. package/src/lib/services/request-manager-state-service/models/parsing-result.model.ts +21 -0
  235. package/src/lib/services/request-manager-state-service/models/request-options.model.ts +37 -0
  236. package/src/lib/services/request-manager-state-service/models/stream-config.model.ts +20 -0
  237. package/src/lib/services/request-manager-state-service/models/stream-event-metadata.model.ts +23 -0
  238. package/src/lib/services/request-manager-state-service/models/stream-event.model.ts +23 -0
  239. package/src/lib/services/request-manager-state-service/models/stream-output.model.ts +23 -0
  240. package/src/lib/services/request-manager-state-service/models/stream-progress.model.ts +24 -0
  241. package/src/lib/services/request-manager-state-service/models/stream-type.enum.ts +13 -0
  242. package/src/lib/services/request-manager-state-service/models/ws-options.model.ts +42 -0
  243. package/src/lib/services/store-state-manager-service/index.ts +4 -0
  244. package/src/lib/services/store-state-manager-service/models/index.ts +3 -0
  245. package/src/lib/services/store-state-manager-service/models/state-operation-result.model.ts +30 -0
  246. package/src/lib/services/store-state-manager-service/models/state-storage-options.model.ts +24 -0
  247. package/src/lib/services/store-state-manager-service/store-state-manager-signals.service.ts +169 -0
  248. package/src/lib/services/store-state-manager-service/store-state-manager.service.ts +153 -0
  249. package/src/lib/services/utils/app.service.spec.ts +25 -0
  250. package/src/lib/services/utils/app.service.ts +21 -0
  251. package/src/lib/services/utils/encryption/README.md +79 -0
  252. package/src/lib/services/utils/encryption/asymmetrical-encryption.service.ts +282 -0
  253. package/src/lib/services/utils/encryption/encryption-test.service.ts +39 -0
  254. package/src/lib/services/utils/encryption/index.ts +5 -0
  255. package/src/lib/services/utils/encryption/random.ts +81 -0
  256. package/src/lib/services/utils/encryption/symmetrical-encryption.service.ts +106 -0
  257. package/src/lib/services/utils/headers.service.spec.ts +80 -0
  258. package/src/lib/services/utils/headers.service.ts +18 -0
  259. package/src/lib/services/utils/index.ts +9 -0
  260. package/src/lib/services/utils/logger.service.ts +90 -0
  261. package/src/lib/services/utils/models/index.ts +4 -0
  262. package/src/lib/services/utils/models/normalized-request-options.model.ts +24 -0
  263. package/src/lib/services/utils/models/path-tracker-state.model.ts +20 -0
  264. package/src/lib/services/utils/models/query-params-tracker-options.model.ts +24 -0
  265. package/src/lib/services/utils/models/query-tracker-state.model.ts +23 -0
  266. package/src/lib/services/utils/object-merger.service.spec.ts +18 -0
  267. package/src/lib/services/utils/object-merger.service.ts +78 -0
  268. package/src/lib/services/utils/path-query.service.spec.ts +117 -0
  269. package/src/lib/services/utils/path-query.service.ts +69 -0
  270. package/src/lib/services/utils/query-params-tracker.service.ts +442 -0
  271. package/src/lib/services/utils/random-color.utils.ts +83 -0
  272. package/src/lib/services/utils/utils.service.spec.ts +165 -0
  273. package/src/lib/services/utils/utils.service.ts +192 -0
  274. package/src/lib/services/ws-manager-service/index.ts +13 -0
  275. package/src/lib/services/ws-manager-service/message-tracker-signals.service.ts +147 -0
  276. package/src/lib/services/ws-manager-service/message-tracker.service.ts +477 -0
  277. package/src/lib/services/ws-manager-service/models/channel-info.model.ts +29 -0
  278. package/src/lib/services/ws-manager-service/models/channel-message-data.model.ts +24 -0
  279. package/src/lib/services/ws-manager-service/models/channel-message.model.ts +36 -0
  280. package/src/lib/services/ws-manager-service/models/channel-type.enum.ts +6 -0
  281. package/src/lib/services/ws-manager-service/models/communication-type.enum.ts +5 -0
  282. package/src/lib/services/ws-manager-service/models/index.ts +10 -0
  283. package/src/lib/services/ws-manager-service/models/notification-message.model.ts +29 -0
  284. package/src/lib/services/ws-manager-service/models/public-message.model.ts +18 -0
  285. package/src/lib/services/ws-manager-service/models/state-message.model.ts +18 -0
  286. package/src/lib/services/ws-manager-service/models/ws-user.model.ts +38 -0
  287. package/src/lib/services/ws-manager-service/services/index.ts +4 -0
  288. package/src/lib/services/ws-manager-service/services/websocket-message.service.ts +129 -0
  289. package/src/lib/services/ws-manager-service/services/websocket.service.ts +434 -0
  290. package/src/lib/services/ws-manager-service/websocket-service/index.ts +1 -0
  291. package/src/lib/services/ws-manager-service/websocket-service/websocket-manager.service.ts +716 -0
  292. package/src/lib/services/ws-manager-service/websocket-services-complete.spec.ts +596 -0
  293. package/src/lib/services/ws-manager-service/websocket-signals-manager.service.ts +141 -0
  294. package/src/public-api.ts +19 -0
  295. package/tsconfig.lib.json +34 -0
  296. package/tsconfig.lib.prod.json +10 -0
  297. package/tsconfig.spec.json +14 -0
  298. package/fesm2022/http-request-manager.mjs +0 -13297
  299. package/fesm2022/http-request-manager.mjs.map +0 -1
  300. package/http-request-manager-18.15.32.tgz +0 -0
  301. package/types/http-request-manager.d.ts +0 -3875
@@ -0,0 +1,11 @@
1
+ button[mat-raised-button],
2
+ button[mat-stroked-button] {
3
+ min-width: 120px;
4
+ }
5
+
6
+ mat-chip-option {
7
+ min-width: 120px;
8
+ justify-content: center;
9
+ border-radius: 4px !important;
10
+ padding: 0.25rem !important;
11
+ }
@@ -0,0 +1,102 @@
1
+
2
+ @if ((data$ | async); as data) {
3
+ @if ((user$ | async); as user) {
4
+ <div style="display: flex; gap: 1rem; flex-direction: column; margin-top: 1rem;">
5
+
6
+ <!-- Channel Creation Section -->
7
+ <div style="padding: 1rem; background: #e3f2fd; border-radius: 4px;">
8
+ <strong>Create New Channel</strong>
9
+ <div style="display: flex; flex-direction: column; margin-top: 0.5rem;">
10
+ <mat-form-field appearance="outline" style="width: 100%;">
11
+ <mat-label>Channel Name</mat-label>
12
+ <input matInput [formControl]="newChannelName" placeholder="Enter channel name"
13
+ (keydown.enter)="onCreateChannel()">
14
+ </mat-form-field>
15
+ <div style="display: flex; justify-content: flex-end; margin-top: -0.5rem;">
16
+ <button mat-raised-button color="primary" (click)="onCreateChannel()"
17
+ [disabled]="newChannelName.invalid">
18
+ Create Channel
19
+ </button>
20
+ </div>
21
+ </div>
22
+ </div>
23
+
24
+ <!-- Messaging Section - only show when subscribed to channels -->
25
+ @if ((subscribedChannels$ | async); as subscribedChannels) {
26
+ @if (subscribedChannels.length > 0) {
27
+ <div style="padding: 1rem; background: #fff3e0; border-radius: 4px;" [formGroup]="messages">
28
+ <strong>Send Message</strong>
29
+ <!-- Debug: Show subscribed channels count -->
30
+ <div style="font-size: 0.8rem; color: #666; margin-bottom: 0.5rem;">
31
+ Subscribed to {{ subscribedChannels.length }} channel(s): {{ subscribedChannels | json }}
32
+ </div>
33
+
34
+ <!-- Channel Selection with Checkboxes -->
35
+ <div style="margin-top: 0.5rem;">
36
+ <mat-form-field appearance="outline" style="width: 100%;">
37
+ <mat-label>Select Channels</mat-label>
38
+ <mat-select formControlName="selectedChannels" multiple>
39
+ <mat-select-trigger>
40
+ @if (selectedChannels.value?.length === 1) {
41
+ {{ selectedChannels.value[0] }}
42
+ } @else if (selectedChannels.value?.length > 1) {
43
+ {{ selectedChannels.value[0] }} (+{{ selectedChannels.value.length - 1 }} {{ selectedChannels.value.length === 2 ? 'other' : 'others' }})
44
+ }
45
+ </mat-select-trigger>
46
+ @for (channel of subscribedChannels; track channel; let i = $index) {
47
+ <mat-option [value]="channel">{{ channel }}</mat-option>
48
+ }
49
+ </mat-select>
50
+ </mat-form-field>
51
+ </div>
52
+
53
+ <!-- Message Input -->
54
+ <div style="display: flex; flex-direction: column;">
55
+ <mat-form-field style="width: 100%;" appearance="outline">
56
+ <mat-label>Message</mat-label>
57
+ <textarea
58
+ matInput placeholder="Type your message..."
59
+ formControlName="content"
60
+ (keydown.enter)="onSendMessage(); $event.preventDefault()"
61
+ ></textarea>
62
+ </mat-form-field>
63
+ <div style="display: flex; justify-content: flex-end; margin-top: -0.5rem;">
64
+ <button mat-raised-button color="primary" (click)="onSendMessage()"
65
+ [disabled]="messages.invalid">
66
+ Send
67
+ </button>
68
+ </div>
69
+ </div>
70
+ </div>
71
+ }
72
+ }
73
+
74
+ </div>
75
+ }
76
+ }
77
+
78
+ <!-- Channel List with Subscription Controls using Chips -->
79
+ @if ((channels$ | async); as channels) {
80
+ @if ((subscribedChannels$ | async); as subscribedChannels) {
81
+ <div style="padding: 1rem; background: #f5f5f5; border-radius: 4px; margin-top: 1rem;">
82
+ <strong>Subscribe to Channel(s)</strong>
83
+ <div style="margin-top: 0.5rem;">
84
+ @if (channels.length === 0) {
85
+ <div style="color: #666; font-style: italic;">No channels available. Create one above.</div>
86
+ } @else {
87
+ <mat-chip-listbox
88
+ aria-label="Channel selection"
89
+ [multiple]="true">
90
+ @for (channel of channels; track channel; let i = $index) {
91
+ <mat-chip-option
92
+ [selected]="isSubscribed(channel, subscribedChannels)"
93
+ (selectionChange)="onChipToggle($event, channel)">
94
+ {{ channel }}
95
+ </mat-chip-option>
96
+ }
97
+ </mat-chip-listbox>
98
+ }
99
+ </div>
100
+ </div>
101
+ }
102
+ }
@@ -0,0 +1,40 @@
1
+ /* tslint:disable:no-unused-variable */
2
+ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
3
+ import { HttpClientTestingModule } from '@angular/common/http/testing';
4
+ import { By } from '@angular/platform-browser';
5
+ import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
6
+ import { ToastMessageDisplayService } from 'toast-message-display';
7
+ import { SnackbarStrategy } from '../../../../message-display/strategies/snackbar.strategy';
8
+
9
+ import { WsMessagingComponent } from './ws-messaging.component';
10
+
11
+ describe('WsMessagingComponent', () => {
12
+ let component: WsMessagingComponent;
13
+ let fixture: ComponentFixture<WsMessagingComponent>;
14
+ let toastMessageServiceSpy: jasmine.SpyObj<ToastMessageDisplayService>;
15
+
16
+ beforeEach(waitForAsync(() => {
17
+ toastMessageServiceSpy = jasmine.createSpyObj('ToastMessageDisplayService', ['toastMessage']);
18
+
19
+ TestBed.configureTestingModule({
20
+ imports: [ HttpClientTestingModule ],
21
+ declarations: [ WsMessagingComponent ],
22
+ schemas: [ NO_ERRORS_SCHEMA ],
23
+ providers: [
24
+ SnackbarStrategy,
25
+ { provide: ToastMessageDisplayService, useValue: toastMessageServiceSpy }
26
+ ]
27
+ })
28
+ .compileComponents();
29
+ }));
30
+
31
+ beforeEach(() => {
32
+ fixture = TestBed.createComponent(WsMessagingComponent);
33
+ component = fixture.componentInstance;
34
+ fixture.detectChanges();
35
+ });
36
+
37
+ it('should create', () => {
38
+ expect(component).toBeTruthy();
39
+ });
40
+ });
@@ -0,0 +1,230 @@
1
+ import { Component, inject, Input, OnInit, OnDestroy } from '@angular/core';
2
+ import { MessageServiceDemo } from '../../services/message-service-demo.service';
3
+ import { StateServiceDemo } from '../../services/state-service-demo.service';
4
+ import { FormBuilder, FormControl, Validators } from '@angular/forms';
5
+ import { Observable, combineLatest, map, EMPTY, Subject, takeUntil, filter, take, startWith, distinctUntilChanged } from 'rxjs';
6
+
7
+ import { ChannelMessage } from '../../../../services/ws-manager-service/models/channel-message.model';
8
+ import { MessageDisplayRouterService } from '../../../../message-display/services/message-display-router.service';
9
+
10
+ @Component({
11
+ selector: 'app-ws-messaging',
12
+ templateUrl: './ws-messaging.component.html',
13
+ styleUrls: ['./ws-messaging.component.css'],
14
+ standalone: false
15
+ })
16
+ export class WsMessagingComponent implements OnInit, OnDestroy {
17
+
18
+ @Input() server!: string;
19
+ @Input() wsServer!: string;
20
+ @Input() jwtToken!: string;
21
+ @Input() user!: any;
22
+ @Input() path: (string|number)[] = ['ai','tests']; // Default path for channel name
23
+
24
+ private destroy$ = new Subject<void>();
25
+
26
+ fb = inject(FormBuilder);
27
+ messageService = inject(MessageServiceDemo);
28
+ stateService = inject(StateServiceDemo);
29
+ messageDisplayService = inject(MessageDisplayRouterService);
30
+
31
+ // Only show public channels (starting with "PUB-"), strip prefix for display
32
+ // SYS- channels are private/internal and hidden from users
33
+ channels$ = this.messageService.channels$.pipe(
34
+ map(channels => channels
35
+ ?.filter(channel => channel.startsWith('PUB-'))
36
+ .map(channel => channel.replace('PUB-', '')) || []
37
+ ),
38
+ startWith([] as string[]),
39
+ distinctUntilChanged((prev, curr) => prev.length === curr.length && prev.every((v, i) => v === curr[i]))
40
+ );
41
+
42
+ // Track subscribed public channels only, strip prefix for display
43
+ subscribedChannels$ = this.messageService.subscribedChannels$.pipe(
44
+ map(set => Array.from(set)
45
+ .filter(channel => channel.startsWith('PUB-'))
46
+ .map(channel => channel.replace('PUB-', ''))
47
+ ),
48
+ startWith([] as string[]),
49
+ distinctUntilChanged((prev, curr) => prev.length === curr.length && prev.every((v, i) => v === curr[i]))
50
+ );
51
+
52
+ user$ = this.stateService.user$;
53
+
54
+ data$ = this.stateService.data$;
55
+
56
+ connectionStatus$ = this.stateService.connectionStatus$;
57
+
58
+ // Form for creating new channels
59
+ newChannelName = this.fb.control<string>('', [Validators.required, Validators.minLength(2)])
60
+
61
+ // Form for selecting channels to send to and message content
62
+ messages = this.fb.group({
63
+ selectedChannels: this.fb.control<string[]>([], Validators.required),
64
+ content: this.fb.control<string|null>(null, Validators.required),
65
+ })
66
+
67
+ get selectedChannels() {
68
+ return this.messages.get('selectedChannels') as FormControl
69
+ }
70
+
71
+ get content() {
72
+ return this.messages.get('content') as FormControl
73
+ }
74
+
75
+ communicationMessages$ = this.messageService.communicationMessages$;
76
+ latestCommunicationMessages$ = this.messageService.latestCommunicationMessages$;
77
+
78
+ chat$: Observable<{ user: any, messages: any[]}|any> = combineLatest([this.user$, this.communicationMessages$])
79
+ .pipe(
80
+ map(([user, messages]: any) => ({ user, messages })),
81
+ map(obj => {
82
+
83
+ if(!obj.user) return EMPTY
84
+
85
+ const mainUser = ''
86
+
87
+ const messages = obj.messages.map((item: any) => {
88
+ // Message transformation logic
89
+ })
90
+
91
+ return { user: mainUser, messages }
92
+
93
+ })
94
+ );
95
+
96
+ ngOnInit() {
97
+
98
+ this.stateService.updateConnection(this.server, this.wsServer, this.jwtToken, this.user, this.path);
99
+
100
+ // Only trigger once when connection becomes true
101
+ this.connectionStatus$.pipe(
102
+ filter(status => status === true),
103
+ take(1),
104
+ takeUntil(this.destroy$)
105
+ ).subscribe(() => {
106
+ console.log('📋 Fetching channels after connection...');
107
+ this.messageService.getAllChannels();
108
+ });
109
+
110
+ // Subscribe to latest messages and display using rule-based routing
111
+ this.latestCommunicationMessages$.pipe(
112
+ filter(message => !!message),
113
+ takeUntil(this.destroy$)
114
+ ).subscribe((message: any) => {
115
+ console.log('🔔 Message received, routing to display:', message);
116
+
117
+ // NEW: Delegate to MessageDisplayRouterService
118
+ // The message payload determines the display type via rules
119
+ this.messageDisplayService.display(message);
120
+
121
+ // OLD: Hardcoded snackbar (removed)
122
+ // const messageContent = message.content?.content?.message || message.content?.message || '';
123
+ // this.toastService.toastMessage(...);
124
+ });
125
+
126
+ }
127
+
128
+ ngOnDestroy() {
129
+ this.destroy$.next();
130
+ this.destroy$.complete();
131
+ }
132
+
133
+ /**
134
+ * Create a new public channel without auto-subscribing
135
+ * NOTE: PUB- prefix is added by messageService.createChannel
136
+ */
137
+ onCreateChannel() {
138
+ if (this.newChannelName.invalid) return;
139
+
140
+ const channelName = this.newChannelName.value?.trim();
141
+ if (channelName) {
142
+ // Pass base channel name - service adds PUB- prefix
143
+ this.messageService.createChannel(channelName);
144
+ this.newChannelName.reset();
145
+ // Server will broadcast updated channel list to all clients automatically
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Subscribe to a channel to receive messages
151
+ * NOTE: PUB- prefix is added by messageService.subscribeToChannel
152
+ */
153
+ onSubscribeToChannel(channel: string) {
154
+ // Pass base channel name - service adds PUB- prefix
155
+ this.messageService.subscribeToChannel(channel);
156
+ // Reset channel selection when subscriptions change
157
+ this.selectedChannels.reset([]);
158
+ }
159
+
160
+ /**
161
+ * Unsubscribe from a channel
162
+ * NOTE: PUB- prefix is added by messageService.unsubscribeFromChannel
163
+ */
164
+ onUnsubscribeFromChannel(channel: string) {
165
+ // Pass base channel name - service adds PUB- prefix
166
+ this.messageService.unsubscribeFromChannel(channel);
167
+ // Reset channel selection when subscriptions change
168
+ this.selectedChannels.reset([]);
169
+ }
170
+
171
+ /**
172
+ * Handle chip toggle for subscribe/unsubscribe
173
+ */
174
+ onChipToggle(event: any, channel: string) {
175
+ const isSelected = event.selected;
176
+
177
+ console.log('🎯 Chip toggle event:', {
178
+ channel,
179
+ isSelected,
180
+ option: event.source
181
+ });
182
+
183
+ if (isSelected) {
184
+ this.onSubscribeToChannel(channel);
185
+ } else {
186
+ this.onUnsubscribeFromChannel(channel);
187
+ }
188
+ }
189
+
190
+ /**
191
+ * Check if currently subscribed to a channel
192
+ * Compares display names (without PUB- prefix)
193
+ */
194
+ isSubscribed(channel: string, subscribedChannels: string[]): boolean {
195
+ return subscribedChannels.includes(channel);
196
+ }
197
+
198
+ onSendMessage() {
199
+ this.messages.markAllAsTouched()
200
+
201
+ if (this.messages.invalid) return
202
+
203
+ const channelsToSend = this.selectedChannels.value as string[]
204
+ if (channelsToSend.length === 0) return
205
+
206
+ // Get user from observable - subscribe once
207
+ this.user$.pipe(take(1)).subscribe(user => {
208
+ if (!user) {
209
+ console.error('❌ No user found');
210
+ return;
211
+ }
212
+
213
+ // Pass base channel names - service adds PUB- prefix
214
+ const message = ChannelMessage.adapt({
215
+ sessionId: { // user object with 'id' as the ID field
216
+ id: user.id,
217
+ ldap: user.ldap,
218
+ name: user.name,
219
+ email: user.email,
220
+ },
221
+ content: { message: this.messages.value.content },
222
+ })
223
+
224
+ this.messageService.sendMessage(message, channelsToSend);
225
+ this.content.reset();
226
+ });
227
+
228
+ }
229
+
230
+ }
@@ -0,0 +1,30 @@
1
+ /* Style for colored notification messages */
2
+ .colored-message {
3
+ font-weight: 500;
4
+ padding: 4px 8px;
5
+ border-radius: 4px;
6
+ display: inline-block;
7
+ max-width: 100%;
8
+ word-wrap: break-word;
9
+ }
10
+
11
+ /* Ensure good contrast for colored text */
12
+ .colored-message.black-text {
13
+ color: #000000 !important;
14
+ }
15
+
16
+ .colored-message.white-text {
17
+ color: #ffffff !important;
18
+ text-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
19
+ }
20
+
21
+ /* Table cell styling */
22
+ td.mat-mdc-cell {
23
+ padding: 8px 12px;
24
+ }
25
+
26
+ .pill {
27
+ border-radius: 1rem;
28
+ padding: .5rem 1rem;
29
+ color: #ffffff;
30
+ }
@@ -0,0 +1,172 @@
1
+ <div style="display: flex; gap: 1rem; flex-direction: column; margin-top: 1rem;">
2
+
3
+ <!-- Channel Creation Section -->
4
+ <div style="padding: 1rem; background: #e8f5e9; border-radius: 4px;">
5
+ <strong>Create Notification Channel</strong>
6
+ <div style="display: flex; flex-direction: column; margin-top: 0.5rem;">
7
+ <mat-form-field appearance="outline" style="width: 100%;">
8
+ <mat-label>Channel Name</mat-label>
9
+ <input
10
+ matInput
11
+ [formControl]="newChannelName"
12
+ placeholder="Enter notification channel name"
13
+ (keydown.enter)="onCreateChannel()"
14
+ >
15
+ </mat-form-field>
16
+ <div style="display: flex; justify-content: flex-end; gap: 0.5rem;">
17
+ <!-- <button mat-raised-button color="accent" (click)="onDefinePreviousChannels()">
18
+ Define Previous Channels
19
+ </button> -->
20
+ <button mat-raised-button color="primary" (click)="onCreateChannel()"
21
+ [disabled]="newChannelName.invalid">
22
+ Create Channel 1
23
+ </button>
24
+ </div>
25
+ </div>
26
+ </div>
27
+
28
+ <!-- Channel Connection Section - Only shown when NOT connected -->
29
+ @if ((subscribedNotificationChannels$ | async); as subscribedChannels) {
30
+ @if (!isChannelConnected(subscribedChannels)) {
31
+ <div style="padding: 1rem; background: #e3f2fd; border-radius: 4px;">
32
+ <strong>Connect to Channel</strong>
33
+ <div style="display: flex; gap: 1rem; margin-top: 0.5rem; flex-wrap: wrap; align-items: flex-start;">
34
+ <!-- Channel Selection (from today's DB data) -->
35
+ <mat-form-field appearance="outline" style="flex: 1; min-width: 200px;">
36
+ <mat-label>Select Channel</mat-label>
37
+ <mat-select [formControl]="selectedConnectionChannel" placeholder="Select a notification channel">
38
+ @for (channel of (todaysNotificationChannels$ | async) || []; track channel) {
39
+ <mat-option [value]="channel">{{ channel }}</mat-option>
40
+ }
41
+ @empty {
42
+ <mat-option disabled>No channels with data for today</mat-option>
43
+ }
44
+ </mat-select>
45
+ </mat-form-field>
46
+
47
+ <!-- Date Filter -->
48
+ <mat-form-field appearance="outline" style="flex: 1; min-width: 200px;" [formGroup]="dateFilter">
49
+ <mat-label>Start Date</mat-label>
50
+ <input matInput [matDatepicker]="startPicker" formControlName="startDate">
51
+ <mat-datepicker-toggle matIconSuffix [for]="startPicker"></mat-datepicker-toggle>
52
+ <mat-datepicker #startPicker></mat-datepicker>
53
+ </mat-form-field>
54
+
55
+ <mat-form-field appearance="outline" style="flex: 1; min-width: 200px;" [formGroup]="dateFilter">
56
+ <mat-label>End Date</mat-label>
57
+ <input matInput [matDatepicker]="endPicker" formControlName="endDate">
58
+ <mat-datepicker-toggle matIconSuffix [for]="endPicker"></mat-datepicker-toggle>
59
+ <mat-datepicker #endPicker></mat-datepicker>
60
+ </mat-form-field>
61
+ </div>
62
+
63
+ <div style="display: flex; gap: 0.5rem;">
64
+ <span style="flex:1"></span>
65
+ <button
66
+ mat-raised-button color="primary"
67
+ (click)="onConnectToChannel()"
68
+ [disabled]="!selectedConnectionChannel.value"
69
+ >
70
+ Connect
71
+ </button>
72
+ </div>
73
+ </div>
74
+ }
75
+ }
76
+
77
+ <!-- Send Notification Section -->
78
+ @if ((subscribedNotificationChannels$ | async); as subscribedChannels) {
79
+ @if (subscribedChannels.length > 0) {
80
+ <div
81
+ style="padding: 1rem; background: #fff8e1; border-radius: 4px;"
82
+ [formGroup]="notificationForm"
83
+ >
84
+ <strong>Send Notification</strong>
85
+
86
+ <!-- Notification Content -->
87
+ <div style="display: flex; flex-direction: column; margin-top: 0.5rem;">
88
+ <mat-form-field style="width: 100%;" appearance="outline">
89
+ <mat-label>Notification Message</mat-label>
90
+ <textarea
91
+ matInput placeholder="Type your notification..."
92
+ formControlName="content"
93
+ rows="2"
94
+ (keydown.enter)="onSendNotification(); $event.preventDefault()"
95
+ ></textarea>
96
+ </mat-form-field>
97
+ <div style="display: flex; justify-content: flex-end; margin-top: -0.5rem;">
98
+ <button
99
+ mat-raised-button color="accent"
100
+ (click)="onSendNotification()"
101
+ [disabled]="notificationForm.invalid"
102
+ >
103
+ Send Notification
104
+ </button>
105
+ </div>
106
+ </div>
107
+ </div>
108
+ }
109
+ }
110
+
111
+ <!-- Notifications Table - Only shown when connected -->
112
+ @if ((subscribedNotificationChannels$ | async); as subscribedChannels) {
113
+ @if (isChannelConnected(subscribedChannels)) {
114
+ @if ((notificationMessages$ | async); as notifications) {
115
+ <div>
116
+ <div style="display: flex; justify-content: space-between; align-items: center;">
117
+ <strong>Notifications ({{ notifications.length }})</strong>
118
+ </div>
119
+
120
+ @if (notifications.length > 0) {
121
+ <div style="margin-top: 0.5rem; height: 400px; overflow: auto; border: 1px solid #888; border-radius: 4px;">
122
+ <table mat-table [dataSource]="notifications" style="width: 100%;">
123
+
124
+ <!-- Date Column -->
125
+ <ng-container matColumnDef="date">
126
+ <th mat-header-cell *matHeaderCellDef style="width: 180px;">Date</th>
127
+ <td mat-cell *matCellDef="let notification">
128
+ {{ formatTimestamp(notification.created) | date }}
129
+ </td>
130
+ </ng-container>
131
+
132
+ <!-- User Column -->
133
+ <ng-container matColumnDef="user">
134
+ <th mat-header-cell *matHeaderCellDef style="width: 150px;">User</th>
135
+ <td mat-cell *matCellDef="let notification">
136
+ <strong>{{ notification.user_name }}</strong>
137
+ </td>
138
+ </ng-container>
139
+
140
+ <!-- Message Column -->
141
+ <ng-container matColumnDef="message">
142
+ <th mat-header-cell *matHeaderCellDef>Message</th>
143
+ <td mat-cell *matCellDef="let notification">
144
+ <div class="pill" [style.background-color]="notification.content.sessionId.color || '#000000'">
145
+ {{ notification.content?.message || notification.content }}
146
+ </div>
147
+ </td>
148
+ </ng-container>
149
+
150
+ <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
151
+ <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
152
+ </table>
153
+ </div>
154
+ } @else {
155
+ <div style="text-align: center; color: #666; padding: 2rem;">
156
+ <mat-icon style="font-size: 48px; height: 48px; width: 48px; opacity: 0.5;">notifications_none</mat-icon>
157
+ <p>No notifications yet. Waiting for notifications on this channel...</p>
158
+ </div>
159
+ }
160
+ </div>
161
+
162
+ <!-- Disconnect Button - Below the table -->
163
+ <div style="display: flex; justify-content: right; padding: 1rem;">
164
+ <button mat-raised-button color="warn" (click)="onDisconnectFromChannel()">
165
+ Disconnect from Channel
166
+ </button>
167
+ </div>
168
+ }
169
+ }
170
+ }
171
+
172
+ </div>
@@ -0,0 +1,31 @@
1
+ /* tslint:disable:no-unused-variable */
2
+ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
3
+ import { HttpClientTestingModule } from '@angular/common/http/testing';
4
+ import { By } from '@angular/platform-browser';
5
+ import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
6
+
7
+ import { WsNotificationsComponent } from './ws-notifications.component';
8
+
9
+ describe('WsNotificationsComponent', () => {
10
+ let component: WsNotificationsComponent;
11
+ let fixture: ComponentFixture<WsNotificationsComponent>;
12
+
13
+ beforeEach(waitForAsync(() => {
14
+ TestBed.configureTestingModule({
15
+ imports: [ HttpClientTestingModule ],
16
+ declarations: [ WsNotificationsComponent ],
17
+ schemas: [ NO_ERRORS_SCHEMA ]
18
+ })
19
+ .compileComponents();
20
+ }));
21
+
22
+ beforeEach(() => {
23
+ fixture = TestBed.createComponent(WsNotificationsComponent);
24
+ component = fixture.componentInstance;
25
+ fixture.detectChanges();
26
+ });
27
+
28
+ it('should create', () => {
29
+ expect(component).toBeTruthy();
30
+ });
31
+ });