@cleavelandprice/ngx-lib 3.14.6 → 4.0.0

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 (283) hide show
  1. package/README.md +5 -5
  2. package/active-directory/{public_api.d.ts → active-directory.api.d.ts} +2 -4
  3. package/active-directory/active-directory.module.d.ts +2 -2
  4. package/active-directory/index.d.ts +1 -1
  5. package/active-directory/{gui → material}/components/user-chooser/user-chooser.component.d.ts +11 -31
  6. package/active-directory/{gui → material}/components/user-form-field/user-form-field.component.d.ts +5 -8
  7. package/active-directory/{gui → material}/index.d.ts +2 -2
  8. package/active-directory/{gui/public_api.d.ts → material/mat-active-directory.api.d.ts} +1 -1
  9. package/active-directory/material/mat-active-directory.module.d.ts +25 -0
  10. package/active-directory/model/active-directory-service-options.d.ts +7 -0
  11. package/active-directory/services/active-directory.service.d.ts +7 -7
  12. package/authentication/{public_api.d.ts → authentication.api.d.ts} +1 -1
  13. package/authentication/authentication.base.module.d.ts +5 -1
  14. package/authentication/index.d.ts +1 -1
  15. package/authentication/{token/gui → material}/components/login/login.component.d.ts +6 -4
  16. package/authentication/{token/gui → material}/components/login-form/login-form.component.d.ts +9 -10
  17. package/authentication/material/index.d.ts +5 -0
  18. package/authentication/material/mat-authentication.api.d.ts +6 -0
  19. package/authentication/material/mat-authentication.module.d.ts +21 -0
  20. package/authentication/material/model/mat-authentication-service-options.d.ts +6 -0
  21. package/authentication/material/services/mat-authentication.service.d.ts +11 -0
  22. package/authentication/model/abstract-authentication-service.d.ts +4 -4
  23. package/authentication/model/authentication-service-options.d.ts +8 -0
  24. package/authentication/object/authentication-object.api.d.ts +2 -0
  25. package/authentication/object/authentication-object.module.d.ts +11 -0
  26. package/authentication/object/index.d.ts +1 -1
  27. package/authentication/object/services/authentication-object.service.d.ts +23 -0
  28. package/authentication/token/authentication-token.api.d.ts +4 -0
  29. package/authentication/token/authetiction-token.module.d.ts +11 -0
  30. package/authentication/token/index.d.ts +1 -1
  31. package/authentication/token/model/authentication-token-service-options.d.ts +6 -0
  32. package/authentication/token/services/authentication-token.service.d.ts +23 -0
  33. package/dialog/components/base/base.component.d.ts +3 -3
  34. package/dialog/components/choice/choice.component.d.ts +5 -3
  35. package/dialog/components/confirmation/confirmation.component.d.ts +5 -3
  36. package/dialog/components/input/input.component.d.ts +5 -3
  37. package/dialog/components/message/message.component.d.ts +5 -3
  38. package/dialog/dialog.module.d.ts +13 -13
  39. package/dialog/index.d.ts +1 -1
  40. package/esm2022/active-directory/active-directory.api.mjs +12 -0
  41. package/esm2022/active-directory/active-directory.module.mjs +20 -10
  42. package/esm2022/active-directory/cleavelandprice-ngx-lib-active-directory.mjs +2 -2
  43. package/esm2022/active-directory/material/cleavelandprice-ngx-lib-active-directory-material.mjs +5 -0
  44. package/esm2022/active-directory/material/components/user-chooser/user-chooser.component.mjs +406 -0
  45. package/esm2022/active-directory/material/components/user-form-field/user-form-field.component.mjs +136 -0
  46. package/esm2022/active-directory/material/mat-active-directory.api.mjs +9 -0
  47. package/esm2022/active-directory/material/mat-active-directory.module.mjs +109 -0
  48. package/esm2022/active-directory/material/model/selectable-group.mjs +2 -0
  49. package/esm2022/active-directory/material/model/selectable-user.mjs +2 -0
  50. package/esm2022/active-directory/material/model/user-chooser-data.mjs +33 -0
  51. package/esm2022/active-directory/material/model/user-chooser-filter-options.mjs +10 -0
  52. package/esm2022/active-directory/{gui → material}/model/user-chooser-mode.mjs +1 -1
  53. package/esm2022/active-directory/material/model/user-chooser-pre-processing-group.mjs +9 -0
  54. package/esm2022/active-directory/model/active-directory-service-options.mjs +3 -0
  55. package/esm2022/active-directory/services/active-directory.service.mjs +61 -41
  56. package/esm2022/authentication/authentication.api.mjs +6 -0
  57. package/esm2022/authentication/authentication.base.module.mjs +28 -7
  58. package/esm2022/authentication/cleavelandprice-ngx-lib-authentication.mjs +2 -2
  59. package/esm2022/authentication/material/cleavelandprice-ngx-lib-authentication-material.mjs +5 -0
  60. package/esm2022/authentication/material/components/login/login.component.mjs +49 -0
  61. package/esm2022/authentication/material/components/login-form/login-form.component.mjs +82 -0
  62. package/esm2022/authentication/material/mat-authentication.api.mjs +7 -0
  63. package/esm2022/authentication/material/mat-authentication.module.mjs +84 -0
  64. package/esm2022/authentication/material/model/login-form-data.mjs +2 -0
  65. package/esm2022/authentication/material/model/mat-authentication-service-options.mjs +3 -0
  66. package/esm2022/authentication/material/services/mat-authentication.service.mjs +67 -0
  67. package/esm2022/authentication/model/abstract-authentication-service.mjs +1 -1
  68. package/esm2022/authentication/model/authentication-service-options.mjs +3 -0
  69. package/esm2022/authentication/object/authentication-object.api.mjs +4 -0
  70. package/esm2022/authentication/object/authentication-object.module.mjs +40 -0
  71. package/esm2022/authentication/object/cleavelandprice-ngx-lib-authentication-object.mjs +2 -2
  72. package/esm2022/authentication/object/services/authentication-object.service.mjs +119 -0
  73. package/esm2022/authentication/token/authentication-token.api.mjs +5 -0
  74. package/esm2022/authentication/token/authetiction-token.module.mjs +40 -0
  75. package/esm2022/authentication/token/cleavelandprice-ngx-lib-authentication-token.mjs +2 -2
  76. package/esm2022/authentication/token/model/authentication-token-service-options.mjs +3 -0
  77. package/esm2022/authentication/token/services/authentication-token.service.mjs +128 -0
  78. package/esm2022/dialog/cleavelandprice-ngx-lib-dialog.mjs +2 -2
  79. package/esm2022/dialog/components/base/base.component.mjs +27 -16
  80. package/esm2022/dialog/components/choice/choice.component.mjs +11 -11
  81. package/esm2022/dialog/components/confirmation/confirmation.component.mjs +11 -11
  82. package/esm2022/dialog/components/input/input.component.mjs +11 -11
  83. package/esm2022/dialog/components/message/message.component.mjs +11 -11
  84. package/esm2022/dialog/dialog.api.mjs +20 -0
  85. package/esm2022/dialog/dialog.module.mjs +25 -20
  86. package/esm2022/lib/model/caching-config.mjs +2 -0
  87. package/esm2022/lib/model/credentials.mjs +2 -0
  88. package/esm2022/lib/model/logging-config.mjs +2 -0
  89. package/esm2022/lib/model/service-options.mjs +3 -0
  90. package/esm2022/lib/ngx-lib.module.mjs +20 -10
  91. package/esm2022/lib/services/app-path-config.service.mjs +31 -24
  92. package/esm2022/lib/services/service-base.mjs +26 -0
  93. package/esm2022/msgraph/cleavelandprice-ngx-lib-msgraph.mjs +2 -2
  94. package/esm2022/msgraph/msgraph.api.mjs +19 -0
  95. package/esm2022/msgraph/msgraph.module.mjs +6 -11
  96. package/esm2022/public_api.mjs +6 -2
  97. package/esm2022/quill/cleavelandprice-ngx-lib-quill.mjs +2 -2
  98. package/esm2022/quill/components/editor/editor.component.mjs +29 -39
  99. package/esm2022/quill/components/raw/raw.component.mjs +18 -11
  100. package/esm2022/quill/mention/cleavelandprice-ngx-lib-quill-mention.mjs +2 -2
  101. package/esm2022/quill/mention/components/editor/editor.component.mjs +20 -14
  102. package/esm2022/quill/mention/quill-mention.api.mjs +8 -0
  103. package/esm2022/quill/mention/quill-mention.module.mjs +12 -12
  104. package/esm2022/quill/quill.api.mjs +9 -0
  105. package/esm2022/quill/quill.module.mjs +20 -18
  106. package/esm2022/sharepoint/cleavelandprice-ngx-lib-sharepoint.mjs +2 -2
  107. package/esm2022/sharepoint/components/user-photo/user-photo.component.mjs +13 -9
  108. package/esm2022/sharepoint/model/sharepoint-service-options.mjs +3 -0
  109. package/esm2022/sharepoint/pipes/user-photo-url.pipe.mjs +8 -9
  110. package/esm2022/sharepoint/services/sharepoint.service.mjs +74 -65
  111. package/esm2022/sharepoint/sharepoint.api.mjs +17 -0
  112. package/esm2022/sharepoint/sharepoint.module.mjs +25 -15
  113. package/esm2022/table/cleavelandprice-ngx-lib-table.mjs +2 -2
  114. package/esm2022/table/components/table/table.component.mjs +76 -74
  115. package/esm2022/table/table.api.mjs +4 -0
  116. package/esm2022/table/table.module.mjs +16 -15
  117. package/esm2022/upload/cleavelandprice-ngx-lib-upload.mjs +2 -2
  118. package/esm2022/upload/components/upload/upload.component.mjs +16 -20
  119. package/esm2022/upload/components/upload-dialog/upload-dialog.component.mjs +49 -39
  120. package/esm2022/upload/model/upload-service-options.mjs +4 -0
  121. package/esm2022/upload/model/upload-status.mjs +2 -0
  122. package/esm2022/upload/services/upload.service.mjs +44 -29
  123. package/esm2022/upload/upload.api.mjs +9 -0
  124. package/esm2022/upload/upload.module.mjs +33 -20
  125. package/esm2022/url-utilities/cleavelandprice-ngx-lib-url-utilities.mjs +2 -2
  126. package/esm2022/url-utilities/pipes/safe-resource-url.pipe.mjs +8 -9
  127. package/esm2022/url-utilities/pipes/safe-url.pipe.mjs +8 -9
  128. package/esm2022/url-utilities/pipes/uri-scheme.pipe.mjs +9 -8
  129. package/esm2022/url-utilities/url-utilities.api.mjs +13 -0
  130. package/esm2022/url-utilities/url-utilities.module.mjs +11 -11
  131. package/fesm2022/cleavelandprice-ngx-lib-active-directory-material.mjs +683 -0
  132. package/fesm2022/cleavelandprice-ngx-lib-active-directory-material.mjs.map +1 -0
  133. package/fesm2022/cleavelandprice-ngx-lib-active-directory.mjs +79 -72
  134. package/fesm2022/cleavelandprice-ngx-lib-active-directory.mjs.map +1 -1
  135. package/fesm2022/cleavelandprice-ngx-lib-authentication-material.mjs +268 -0
  136. package/fesm2022/cleavelandprice-ngx-lib-authentication-material.mjs.map +1 -0
  137. package/fesm2022/cleavelandprice-ngx-lib-authentication-object.mjs +54 -49
  138. package/fesm2022/cleavelandprice-ngx-lib-authentication-object.mjs.map +1 -1
  139. package/fesm2022/cleavelandprice-ngx-lib-authentication-token.mjs +50 -51
  140. package/fesm2022/cleavelandprice-ngx-lib-authentication-token.mjs.map +1 -1
  141. package/fesm2022/cleavelandprice-ngx-lib-authentication.mjs +28 -18
  142. package/fesm2022/cleavelandprice-ngx-lib-authentication.mjs.map +1 -1
  143. package/fesm2022/cleavelandprice-ngx-lib-dialog.mjs +87 -66
  144. package/fesm2022/cleavelandprice-ngx-lib-dialog.mjs.map +1 -1
  145. package/fesm2022/cleavelandprice-ngx-lib-msgraph.mjs +5 -10
  146. package/fesm2022/cleavelandprice-ngx-lib-msgraph.mjs.map +1 -1
  147. package/fesm2022/cleavelandprice-ngx-lib-quill-mention.mjs +29 -26
  148. package/fesm2022/cleavelandprice-ngx-lib-quill-mention.mjs.map +1 -1
  149. package/fesm2022/cleavelandprice-ngx-lib-quill.mjs +61 -67
  150. package/fesm2022/cleavelandprice-ngx-lib-quill.mjs.map +1 -1
  151. package/fesm2022/cleavelandprice-ngx-lib-sharepoint.mjs +115 -118
  152. package/fesm2022/cleavelandprice-ngx-lib-sharepoint.mjs.map +1 -1
  153. package/fesm2022/cleavelandprice-ngx-lib-table.mjs +85 -90
  154. package/fesm2022/cleavelandprice-ngx-lib-table.mjs.map +1 -1
  155. package/fesm2022/cleavelandprice-ngx-lib-upload.mjs +134 -117
  156. package/fesm2022/cleavelandprice-ngx-lib-upload.mjs.map +1 -1
  157. package/fesm2022/cleavelandprice-ngx-lib-url-utilities.mjs +38 -33
  158. package/fesm2022/cleavelandprice-ngx-lib-url-utilities.mjs.map +1 -1
  159. package/fesm2022/cleavelandprice-ngx-lib.mjs +66 -45
  160. package/fesm2022/cleavelandprice-ngx-lib.mjs.map +1 -1
  161. package/lib/model/caching-config.d.ts +4 -0
  162. package/lib/model/credentials.d.ts +4 -0
  163. package/lib/model/logging-config.d.ts +6 -0
  164. package/lib/model/service-options.d.ts +6 -0
  165. package/lib/ngx-lib.module.d.ts +2 -2
  166. package/lib/services/app-path-config.service.d.ts +5 -4
  167. package/lib/services/service-base.d.ts +7 -0
  168. package/msgraph/index.d.ts +1 -1
  169. package/msgraph/msgraph.module.d.ts +0 -2
  170. package/package.json +27 -27
  171. package/public_api.d.ts +5 -1
  172. package/quill/components/editor/editor.component.d.ts +10 -10
  173. package/quill/components/raw/raw.component.d.ts +1 -1
  174. package/quill/index.d.ts +1 -1
  175. package/quill/mention/components/editor/editor.component.d.ts +3 -3
  176. package/quill/mention/index.d.ts +1 -1
  177. package/quill/mention/quill-mention.module.d.ts +9 -9
  178. package/quill/quill.module.d.ts +12 -14
  179. package/sharepoint/components/user-photo/user-photo.component.d.ts +2 -2
  180. package/sharepoint/index.d.ts +1 -1
  181. package/sharepoint/model/sharepoint-service-options.d.ts +19 -0
  182. package/sharepoint/pipes/user-photo-url.pipe.d.ts +2 -2
  183. package/sharepoint/services/sharepoint.service.d.ts +7 -10
  184. package/sharepoint/{public_api.d.ts → sharepoint.api.d.ts} +1 -1
  185. package/sharepoint/sharepoint.module.d.ts +6 -6
  186. package/table/components/table/table.component.d.ts +21 -22
  187. package/table/index.d.ts +1 -1
  188. package/table/table.module.d.ts +13 -13
  189. package/upload/components/upload/upload.component.d.ts +4 -8
  190. package/upload/components/upload-dialog/upload-dialog.component.d.ts +11 -9
  191. package/upload/index.d.ts +1 -1
  192. package/upload/model/upload-service-options.d.ts +16 -0
  193. package/upload/model/upload-status.d.ts +6 -0
  194. package/upload/services/upload.service.d.ts +9 -6
  195. package/upload/{public_api.d.ts → upload.api.d.ts} +2 -2
  196. package/upload/upload.module.d.ts +10 -10
  197. package/url-utilities/index.d.ts +1 -1
  198. package/url-utilities/pipes/safe-resource-url.pipe.d.ts +2 -2
  199. package/url-utilities/pipes/safe-url.pipe.d.ts +2 -2
  200. package/url-utilities/pipes/uri-scheme.pipe.d.ts +2 -3
  201. package/url-utilities/url-utilities.api.d.ts +8 -0
  202. package/url-utilities/url-utilities.module.d.ts +5 -5
  203. package/active-directory/gui/gui.module.d.ts +0 -25
  204. package/active-directory/model/caching-config.d.ts +0 -4
  205. package/active-directory/model/logging-config.d.ts +0 -6
  206. package/active-directory/model/service-config.d.ts +0 -8
  207. package/authentication/model/service-config.d.ts +0 -8
  208. package/authentication/object/model/service-config.d.ts +0 -4
  209. package/authentication/object/object.module.d.ts +0 -11
  210. package/authentication/object/public_api.d.ts +0 -3
  211. package/authentication/object/services/authentication.service.d.ts +0 -23
  212. package/authentication/token/gui/index.d.ts +0 -5
  213. package/authentication/token/gui/model/service-config.d.ts +0 -5
  214. package/authentication/token/gui/public_api.d.ts +0 -6
  215. package/authentication/token/gui/services/authentication.service.d.ts +0 -12
  216. package/authentication/token/gui/token-gui.module.d.ts +0 -21
  217. package/authentication/token/model/service-config.d.ts +0 -5
  218. package/authentication/token/public_api.d.ts +0 -4
  219. package/authentication/token/services/authentication.service.d.ts +0 -23
  220. package/authentication/token/token.module.d.ts +0 -11
  221. package/esm2022/active-directory/gui/cleavelandprice-ngx-lib-active-directory-gui.mjs +0 -5
  222. package/esm2022/active-directory/gui/components/user-chooser/user-chooser.component.mjs +0 -393
  223. package/esm2022/active-directory/gui/components/user-form-field/user-form-field.component.mjs +0 -132
  224. package/esm2022/active-directory/gui/gui.module.mjs +0 -96
  225. package/esm2022/active-directory/gui/model/selectable-group.mjs +0 -2
  226. package/esm2022/active-directory/gui/model/selectable-user.mjs +0 -2
  227. package/esm2022/active-directory/gui/model/user-chooser-data.mjs +0 -33
  228. package/esm2022/active-directory/gui/model/user-chooser-filter-options.mjs +0 -10
  229. package/esm2022/active-directory/gui/model/user-chooser-pre-processing-group.mjs +0 -9
  230. package/esm2022/active-directory/gui/public_api.mjs +0 -9
  231. package/esm2022/active-directory/model/caching-config.mjs +0 -7
  232. package/esm2022/active-directory/model/logging-config.mjs +0 -9
  233. package/esm2022/active-directory/model/service-config.mjs +0 -12
  234. package/esm2022/active-directory/public_api.mjs +0 -12
  235. package/esm2022/authentication/model/service-config.mjs +0 -12
  236. package/esm2022/authentication/object/model/service-config.mjs +0 -9
  237. package/esm2022/authentication/object/object.module.mjs +0 -39
  238. package/esm2022/authentication/object/public_api.mjs +0 -4
  239. package/esm2022/authentication/object/services/authentication.service.mjs +0 -110
  240. package/esm2022/authentication/public_api.mjs +0 -6
  241. package/esm2022/authentication/token/gui/cleavelandprice-ngx-lib-authentication-token-gui.mjs +0 -5
  242. package/esm2022/authentication/token/gui/components/login/login.component.mjs +0 -43
  243. package/esm2022/authentication/token/gui/components/login-form/login-form.component.mjs +0 -72
  244. package/esm2022/authentication/token/gui/model/login-form-data.mjs +0 -2
  245. package/esm2022/authentication/token/gui/model/service-config.mjs +0 -10
  246. package/esm2022/authentication/token/gui/public_api.mjs +0 -7
  247. package/esm2022/authentication/token/gui/services/authentication.service.mjs +0 -78
  248. package/esm2022/authentication/token/gui/token-gui.module.mjs +0 -81
  249. package/esm2022/authentication/token/model/service-config.mjs +0 -10
  250. package/esm2022/authentication/token/public_api.mjs +0 -5
  251. package/esm2022/authentication/token/services/authentication.service.mjs +0 -124
  252. package/esm2022/authentication/token/token.module.mjs +0 -39
  253. package/esm2022/dialog/public_api.mjs +0 -10
  254. package/esm2022/lib/model/service-config.mjs +0 -21
  255. package/esm2022/msgraph/public_api.mjs +0 -19
  256. package/esm2022/quill/mention/public_api.mjs +0 -8
  257. package/esm2022/quill/public_api.mjs +0 -9
  258. package/esm2022/sharepoint/model/service-config.mjs +0 -27
  259. package/esm2022/sharepoint/public_api.mjs +0 -17
  260. package/esm2022/table/public_api.mjs +0 -4
  261. package/esm2022/upload/model/service-config.mjs +0 -16
  262. package/esm2022/upload/public_api.mjs +0 -9
  263. package/esm2022/url-utilities/public_api.mjs +0 -5
  264. package/fesm2022/cleavelandprice-ngx-lib-active-directory-gui.mjs +0 -660
  265. package/fesm2022/cleavelandprice-ngx-lib-active-directory-gui.mjs.map +0 -1
  266. package/fesm2022/cleavelandprice-ngx-lib-authentication-token-gui.mjs +0 -271
  267. package/fesm2022/cleavelandprice-ngx-lib-authentication-token-gui.mjs.map +0 -1
  268. package/lib/model/service-config.d.ts +0 -6
  269. package/sharepoint/model/service-config.d.ts +0 -23
  270. package/upload/model/service-config.d.ts +0 -15
  271. package/url-utilities/public_api.d.ts +0 -4
  272. /package/active-directory/{gui → material}/model/selectable-group.d.ts +0 -0
  273. /package/active-directory/{gui → material}/model/selectable-user.d.ts +0 -0
  274. /package/active-directory/{gui → material}/model/user-chooser-data.d.ts +0 -0
  275. /package/active-directory/{gui → material}/model/user-chooser-filter-options.d.ts +0 -0
  276. /package/active-directory/{gui → material}/model/user-chooser-mode.d.ts +0 -0
  277. /package/active-directory/{gui → material}/model/user-chooser-pre-processing-group.d.ts +0 -0
  278. /package/authentication/{token/gui → material}/model/login-form-data.d.ts +0 -0
  279. /package/dialog/{public_api.d.ts → dialog.api.d.ts} +0 -0
  280. /package/msgraph/{public_api.d.ts → msgraph.api.d.ts} +0 -0
  281. /package/quill/mention/{public_api.d.ts → quill-mention.api.d.ts} +0 -0
  282. /package/quill/{public_api.d.ts → quill.api.d.ts} +0 -0
  283. /package/table/{public_api.d.ts → table.api.d.ts} +0 -0
@@ -1,42 +1,34 @@
1
- import { ServiceConfig as ServiceConfig$1 } from '@cleavelandprice/ngx-lib';
2
1
  import * as i0 from '@angular/core';
3
- import { inject, Injectable, Component, ViewChild, EventEmitter, Output, NgModule, Optional, SkipSelf } from '@angular/core';
4
- import * as i2 from '@angular/material/dialog';
5
- import { MatDialogRef, MatDialog, MatDialogModule } from '@angular/material/dialog';
6
- import { HttpClient, HttpHeaders, HttpRequest, HttpEventType, HttpResponse } from '@angular/common/http';
2
+ import { InjectionToken, inject, Injectable, Optional, Inject, viewChild, Component, output, NgModule, SkipSelf } from '@angular/core';
3
+ import { AsyncPipe, CommonModule } from '@angular/common';
4
+ import { MatButton, MatButtonModule } from '@angular/material/button';
5
+ import { MatDialogRef, MatDialogActions, MatDialogClose, MatDialogContent, MatDialog, MatDialogModule } from '@angular/material/dialog';
6
+ import { MatList, MatListItem, MatListModule } from '@angular/material/list';
7
+ import { MatProgressBar, MatProgressBarModule } from '@angular/material/progress-bar';
7
8
  import { Subject, forkJoin } from 'rxjs';
8
- import * as i1 from '@angular/material/button';
9
- import { MatButtonModule } from '@angular/material/button';
10
- import * as i3 from '@angular/material/list';
11
- import { MatListModule } from '@angular/material/list';
12
- import * as i4 from '@angular/material/progress-bar';
13
- import { MatProgressBarModule } from '@angular/material/progress-bar';
14
- import * as i5 from '@angular/common';
15
- import { CommonModule } from '@angular/common';
9
+ import { HttpClient, HttpHeaders, HttpRequest, HttpEventType, HttpResponse } from '@angular/common/http';
10
+ import { NgxLibServiceBase } from '@cleavelandprice/ngx-lib';
16
11
 
17
- class ServiceConfig extends ServiceConfig$1 {
18
- // See the comment in the library's main service-config.ts file for an explanation
19
- constructor(useSsl_or_customApiUrl = false) {
20
- super(useSsl_or_customApiUrl);
21
- this.databaseEndpoint = '/upload/database';
22
- this.uploadDialogTitle = 'Upload Files';
23
- // UI configuration
24
- this.uploadButtonText = 'Upload';
25
- this.uploadDialogCancelButtonText = 'Cancel';
26
- this.uploadDialogFinishButtonText = 'Finish';
27
- this.uploadDialogUploadButtonText = 'Upload';
28
- this.uploadDialogAddFilesButtonText = 'Add Files';
29
- }
30
- }
12
+ ;
13
+ const UploadServiceOptionsToken = new InjectionToken('');
31
14
 
32
15
  // https://malcoded.com/posts/angular-file-upload-component-with-express
33
- class UploadService {
34
- constructor() {
35
- //#region Services
36
- this.http = inject(HttpClient);
37
- this.config = inject(ServiceConfig, { optional: true }) ?? new ServiceConfig();
16
+ class UploadService extends NgxLibServiceBase {
17
+ #http = inject(HttpClient);
18
+ constructor(options) {
19
+ super(options);
20
+ this.options = options;
21
+ this.options = {
22
+ ...options,
23
+ databaseEndpoint: options?.databaseEndpoint ?? '/upload/database',
24
+ uploadDialogTitle: options?.uploadDialogTitle ?? 'Upload Files',
25
+ uploadButtonText: options?.uploadButtonText ?? 'Upload',
26
+ uploadDialogCancelButtonText: options?.uploadDialogCancelButtonText ?? 'Cancel',
27
+ uploadDialogFinishButtonText: options?.uploadDialogFinishButtonText ?? 'Finish',
28
+ uploadDialogUploadButtonText: options?.uploadButtonText ?? 'Upload',
29
+ uploadDialogAddFilesButtonText: options?.uploadDialogAddFilesButtonText ?? 'Add Files'
30
+ };
38
31
  }
39
- //#endregion
40
32
  upload(files) {
41
33
  // this will be the our resulting map
42
34
  const status = {};
@@ -49,19 +41,19 @@ class UploadService {
49
41
  // A 'Destination' header is used to optionally configure the file upload destination (filesystem)
50
42
  // A 'DbAppId' header is used to configure the unique identifier of database uploads
51
43
  let headers = new HttpHeaders();
52
- if (this.config.uploadPath) {
53
- headers = headers.set('Destination', this.config.uploadPath);
44
+ if (this.options.uploadPath) {
45
+ headers = headers.set('Destination', this.options.uploadPath);
54
46
  }
55
- if (this.config.dbAppId) {
56
- headers = headers.set('DbAppId', this.config.dbAppId);
47
+ if (this.options.dbAppId) {
48
+ headers = headers.set('DbAppId', this.options.dbAppId);
57
49
  }
58
- if (this.config.externalReferenceId) {
59
- headers = headers.set('ExternalReferenceId', this.config.externalReferenceId);
50
+ if (this.options.externalReferenceId) {
51
+ headers = headers.set('ExternalReferenceId', this.options.externalReferenceId);
60
52
  }
61
- if (this.config.comment) {
62
- headers = headers.set('Comment', this.config.comment);
53
+ if (this.options.comment) {
54
+ headers = headers.set('Comment', this.options.comment);
63
55
  }
64
- const req = new HttpRequest('POST', `${this.config.apiUrl}${this.config.databaseEndpoint}`, formData, {
56
+ const req = new HttpRequest('POST', `${this.apiUrl}${this.options.databaseEndpoint}`, formData, {
65
57
  reportProgress: true,
66
58
  responseType: 'blob',
67
59
  headers
@@ -69,7 +61,7 @@ class UploadService {
69
61
  // create a new progress-subject for every file
70
62
  const progress = new Subject();
71
63
  // send the http-request and subscribe for progress-updates
72
- this.http.request(req).subscribe(event => {
64
+ this.#http.request(req).subscribe(event => {
73
65
  if (event.type === HttpEventType.UploadProgress) {
74
66
  // calculate the progress percentage
75
67
  const percentDone = Math.round(100 * event.loaded / (event.total ?? 1));
@@ -91,50 +83,55 @@ class UploadService {
91
83
  return status;
92
84
  }
93
85
  exists(fileName) {
94
- const query = `${this.config.apiUrl}${this.config.databaseEndpoint}`.toLowerCase().indexOf('filesystem') === -1 ?
95
- { name: fileName, dbAppId: this.config.dbAppId } :
96
- { name: fileName, destination: this.config.uploadPath };
97
- return this.http.post(`${this.config.apiUrl}${this.config.databaseEndpoint}/exists`, query);
86
+ const query = `${this.apiUrl}${this.options.databaseEndpoint}`.toLowerCase().includes('filesystem') ?
87
+ { name: fileName, destination: this.options.uploadPath } :
88
+ { name: fileName, dbAppId: this.options.dbAppId };
89
+ return this.#http.post(`${this.apiUrl}${this.options.databaseEndpoint}/exists`, query);
98
90
  }
99
91
  download(request) {
100
- return this.http.post(`${this.config.apiUrl}${this.config.databaseEndpoint}/stream`, request, { responseType: 'blob' });
92
+ return this.#http.post(`${this.apiUrl}${this.options.databaseEndpoint}/stream`, request, { responseType: 'blob' });
101
93
  }
102
94
  getUploadInfo(request) {
103
- return this.http.post(`${this.config.apiUrl}${this.config.databaseEndpoint}/info`, request);
95
+ return this.#http.post(`${this.apiUrl}${this.options.databaseEndpoint}/info`, request);
104
96
  }
105
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: UploadService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
106
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: UploadService, providedIn: 'root' }); }
97
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: UploadService, deps: [{ token: UploadServiceOptionsToken, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
98
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: UploadService, providedIn: 'root' }); }
107
99
  }
108
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: UploadService, decorators: [{
100
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: UploadService, decorators: [{
109
101
  type: Injectable,
110
102
  args: [{
111
103
  providedIn: 'root'
112
104
  }]
113
- }] });
105
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
106
+ type: Optional
107
+ }, {
108
+ type: Inject,
109
+ args: [UploadServiceOptionsToken]
110
+ }] }] });
114
111
 
115
112
  class UploadDialogComponent {
116
113
  constructor() {
117
- //#region Services
118
- this.dialogRef = inject((MatDialogRef));
119
- this.uploadService = inject(UploadService);
114
+ this.services = {
115
+ dialogRef: inject((MatDialogRef)),
116
+ upload: inject(UploadService)
117
+ };
118
+ this.file = viewChild.required('file');
120
119
  this.files = new Set();
121
120
  this.canBeClosed = true;
121
+ this.primaryButtonText = this.services.upload.options.uploadDialogUploadButtonText;
122
122
  this.showCancelButton = true;
123
123
  this.uploading = false;
124
124
  this.uploadSuccessful = false;
125
125
  }
126
- ngOnInit() {
127
- this.primaryButtonText = this.uploadService.config.uploadDialogUploadButtonText;
128
- }
129
126
  addFiles() {
130
- this.file.nativeElement.click();
127
+ this.file().nativeElement.click();
131
128
  }
132
129
  onFilesAdded() {
133
- const files = this.file.nativeElement.files;
130
+ const files = this.file().nativeElement.files;
134
131
  for (const key in files) {
135
132
  if (!isNaN(parseInt(key))) {
136
133
  // See if the file already exists
137
- this.uploadService.exists(files[key].name)
134
+ this.services.upload.exists(files[key].name)
138
135
  .subscribe(exists => {
139
136
  if (exists) {
140
137
  this.existingFileConflict = files[key].name;
@@ -149,84 +146,102 @@ class UploadDialogComponent {
149
146
  closeDialog() {
150
147
  // if everything was uploaded already, just close the dialog
151
148
  if (this.uploadSuccessful) {
152
- return this.dialogRef.close();
149
+ return this.services.dialogRef.close();
153
150
  }
154
151
  // set the component state to "uploading"
155
152
  this.uploading = true;
156
153
  // start the upload and save the progress map
157
- this.progress = this.uploadService.upload(this.files);
154
+ this.progress = this.services.upload.upload(this.files);
158
155
  // convert the progress map into an array
159
- const allProgressObservables = [];
156
+ const allProgressObservables$ = [];
160
157
  for (let key in this.progress) {
161
- allProgressObservables.push(this.progress[key].progress);
158
+ allProgressObservables$.push(this.progress[key].progress);
162
159
  }
163
160
  // Adjust the state variables
164
161
  // The OK-button should have the text "Finish" now
165
- this.primaryButtonText = this.uploadService.config.uploadDialogFinishButtonText;
162
+ this.primaryButtonText = this.services.upload.options.uploadDialogFinishButtonText;
166
163
  // The dialog should not be closed while uploading
167
164
  this.canBeClosed = false;
168
- this.dialogRef.disableClose = true;
165
+ this.services.dialogRef.disableClose = true;
169
166
  // Hide the cancel-button
170
167
  this.showCancelButton = false;
171
168
  // When all progress-observables are completed...
172
- forkJoin(allProgressObservables).subscribe(end => {
173
- // ... the dialog can be closed again...
174
- this.canBeClosed = true;
175
- this.dialogRef.disableClose = false;
176
- // ... the upload was successful...
177
- this.uploadSuccessful = true;
178
- // ... and the component is no longer uploading
179
- this.uploading = false;
169
+ forkJoin(allProgressObservables$)
170
+ .subscribe({
171
+ complete: () => {
172
+ // ... the dialog can be closed again...
173
+ this.canBeClosed = true;
174
+ this.services.dialogRef.disableClose = false;
175
+ // ... the upload was successful...
176
+ this.uploadSuccessful = true;
177
+ // ... and the component is no longer uploading
178
+ this.uploading = false;
179
+ console.log('Upload complete', this.files);
180
+ this.services.dialogRef.close();
181
+ }
180
182
  });
181
183
  }
182
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: UploadDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
183
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.0", type: UploadDialogComponent, selector: "ng-component", viewQueries: [{ propertyName: "file", first: true, predicate: ["file"], descendants: true, static: true }], ngImport: i0, template: "<input type=\"file\" #file style=\"display: none\" (change)=\"onFilesAdded()\" multiple />\r\n\r\n<div mat-dialog-title id=\"title\">\r\n <div>{{ uploadService.config.uploadDialogTitle }}</div>\r\n <button [disabled]=\"uploading || uploadSuccessful\" mat-raised-button color=\"primary\" class=\"add-files-btn\" (click)=\"addFiles()\">\r\n {{ uploadService.config.uploadDialogAddFilesButtonText }}\r\n </button>\r\n</div>\r\n\r\n@if (existingFileConflict) {\r\n <div id=\"conflict\">\r\n {{ existingFileConflict }} already exists on the server and cannot be overwritten\r\n </div>\r\n}\r\n\r\n<mat-dialog-content>\r\n <mat-list>\r\n @for (file of files; track file) {\r\n <mat-list-item>\r\n <h4 mat-line>{{file.name}}</h4>\r\n @if (progress) {\r\n <mat-progress-bar mode=\"determinate\" [value]=\"progress[file.name].progress | async\"/>\r\n }\r\n </mat-list-item>\r\n }\r\n </mat-list>\r\n</mat-dialog-content>\r\n\r\n<mat-dialog-actions id=\"actions\">\r\n @if (showCancelButton) {\r\n <button mat-button mat-dialog-close>{{ uploadService.config.uploadDialogCancelButtonText }}</button>\r\n }\r\n @if (files.size > 0) {\r\n <button mat-raised-button color=\"primary\" [disabled]=\"!canBeClosed\" (click)=\"closeDialog()\">{{ primaryButtonText }}</button>\r\n }\r\n</mat-dialog-actions>\r\n", styles: ["#title{display:flex;justify-content:space-between}#actions{display:flex;justify-content:flex-end}#conflict{font-size:.8em;color:red;margin-top:.5em}\n"], dependencies: [{ kind: "component", type: i1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i2.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i3.MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: i3.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "component", type: i4.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }] }); }
184
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: UploadDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
185
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.3", type: UploadDialogComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "file", first: true, predicate: ["file"], descendants: true, isSignal: true }], ngImport: i0, template: "<input type=\"file\" #file style=\"display: none\" (change)=\"onFilesAdded()\" multiple />\n\n<div mat-dialog-title id=\"title\">\n <div>{{ services.upload.options.uploadDialogTitle }}</div>\n <button [disabled]=\"uploading || uploadSuccessful\" mat-raised-button color=\"primary\" class=\"add-files-btn\" (click)=\"addFiles()\">\n {{ services.upload.options.uploadDialogAddFilesButtonText }}\n </button>\n</div>\n\n@if (existingFileConflict) {\n <div id=\"conflict\">\n {{ existingFileConflict }} already exists on the server and cannot be overwritten\n </div>\n}\n\n<mat-dialog-content>\n <mat-list>\n @for (file of files; track file) {\n <mat-list-item>\n <h4 mat-line>{{file.name}}</h4>\n @if (progress) {\n <mat-progress-bar mode=\"determinate\" [value]=\"progress[file.name].progress | async\"/>\n }\n </mat-list-item>\n }\n </mat-list>\n</mat-dialog-content>\n\n<mat-dialog-actions id=\"actions\">\n @if (showCancelButton) {\n <button mat-button mat-dialog-close>{{ services.upload.options.uploadDialogCancelButtonText }}</button>\n }\n @if (files.size > 0) {\n <button mat-raised-button color=\"primary\" [disabled]=\"!canBeClosed\" (click)=\"closeDialog()\">{{ primaryButtonText }}</button>\n }\n</mat-dialog-actions>\n", styles: ["#title{display:flex;justify-content:space-between}#actions{display:flex;justify-content:flex-end}#conflict{font-size:.8em;color:red;margin-top:.5em}\n"], dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "component", type: MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }] }); }
184
186
  }
185
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: UploadDialogComponent, decorators: [{
187
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: UploadDialogComponent, decorators: [{
186
188
  type: Component,
187
- args: [{ template: "<input type=\"file\" #file style=\"display: none\" (change)=\"onFilesAdded()\" multiple />\r\n\r\n<div mat-dialog-title id=\"title\">\r\n <div>{{ uploadService.config.uploadDialogTitle }}</div>\r\n <button [disabled]=\"uploading || uploadSuccessful\" mat-raised-button color=\"primary\" class=\"add-files-btn\" (click)=\"addFiles()\">\r\n {{ uploadService.config.uploadDialogAddFilesButtonText }}\r\n </button>\r\n</div>\r\n\r\n@if (existingFileConflict) {\r\n <div id=\"conflict\">\r\n {{ existingFileConflict }} already exists on the server and cannot be overwritten\r\n </div>\r\n}\r\n\r\n<mat-dialog-content>\r\n <mat-list>\r\n @for (file of files; track file) {\r\n <mat-list-item>\r\n <h4 mat-line>{{file.name}}</h4>\r\n @if (progress) {\r\n <mat-progress-bar mode=\"determinate\" [value]=\"progress[file.name].progress | async\"/>\r\n }\r\n </mat-list-item>\r\n }\r\n </mat-list>\r\n</mat-dialog-content>\r\n\r\n<mat-dialog-actions id=\"actions\">\r\n @if (showCancelButton) {\r\n <button mat-button mat-dialog-close>{{ uploadService.config.uploadDialogCancelButtonText }}</button>\r\n }\r\n @if (files.size > 0) {\r\n <button mat-raised-button color=\"primary\" [disabled]=\"!canBeClosed\" (click)=\"closeDialog()\">{{ primaryButtonText }}</button>\r\n }\r\n</mat-dialog-actions>\r\n", styles: ["#title{display:flex;justify-content:space-between}#actions{display:flex;justify-content:flex-end}#conflict{font-size:.8em;color:red;margin-top:.5em}\n"] }]
188
- }], propDecorators: { file: [{
189
- type: ViewChild,
190
- args: ['file', { static: true }]
191
- }] } });
189
+ args: [{ standalone: true, imports: [
190
+ AsyncPipe,
191
+ MatButton,
192
+ MatDialogActions,
193
+ MatDialogClose,
194
+ MatDialogContent,
195
+ MatList,
196
+ MatListItem,
197
+ MatProgressBar
198
+ ], template: "<input type=\"file\" #file style=\"display: none\" (change)=\"onFilesAdded()\" multiple />\n\n<div mat-dialog-title id=\"title\">\n <div>{{ services.upload.options.uploadDialogTitle }}</div>\n <button [disabled]=\"uploading || uploadSuccessful\" mat-raised-button color=\"primary\" class=\"add-files-btn\" (click)=\"addFiles()\">\n {{ services.upload.options.uploadDialogAddFilesButtonText }}\n </button>\n</div>\n\n@if (existingFileConflict) {\n <div id=\"conflict\">\n {{ existingFileConflict }} already exists on the server and cannot be overwritten\n </div>\n}\n\n<mat-dialog-content>\n <mat-list>\n @for (file of files; track file) {\n <mat-list-item>\n <h4 mat-line>{{file.name}}</h4>\n @if (progress) {\n <mat-progress-bar mode=\"determinate\" [value]=\"progress[file.name].progress | async\"/>\n }\n </mat-list-item>\n }\n </mat-list>\n</mat-dialog-content>\n\n<mat-dialog-actions id=\"actions\">\n @if (showCancelButton) {\n <button mat-button mat-dialog-close>{{ services.upload.options.uploadDialogCancelButtonText }}</button>\n }\n @if (files.size > 0) {\n <button mat-raised-button color=\"primary\" [disabled]=\"!canBeClosed\" (click)=\"closeDialog()\">{{ primaryButtonText }}</button>\n }\n</mat-dialog-actions>\n", styles: ["#title{display:flex;justify-content:space-between}#actions{display:flex;justify-content:flex-end}#conflict{font-size:.8em;color:red;margin-top:.5em}\n"] }]
199
+ }] });
192
200
 
193
201
  class UploadComponent {
194
202
  constructor() {
195
- //#region Services
196
- this.dialog = inject(MatDialog);
203
+ this.#dialogService = inject(MatDialog);
197
204
  this.uploadService = inject(UploadService);
198
- //#endregion
199
- this.dialogClosed = new EventEmitter();
200
- }
201
- ngOnInit() {
202
- this.uploadButtonText = this.uploadService.config.uploadButtonText ?
203
- this.uploadService.config.uploadButtonText :
204
- 'Upload';
205
+ this.dialogClosed = output();
205
206
  }
207
+ #dialogService;
206
208
  openUploadDialog() {
207
- this.dialog.open(UploadDialogComponent, { width: '50%' })
209
+ this.#dialogService.open(UploadDialogComponent, { width: '50%' })
208
210
  .afterClosed().subscribe(() => this.dialogClosed.emit());
209
211
  }
210
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: UploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
211
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.0", type: UploadComponent, selector: "cp-upload", outputs: { dialogClosed: "dialogClosed" }, ngImport: i0, template: '<button mat-raised-button (click)="openUploadDialog()">{{ uploadButtonText }}</button>', isInline: true, dependencies: [{ kind: "component", type: i1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }] }); }
212
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: UploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
213
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.3", type: UploadComponent, isStandalone: true, selector: "cp-upload", outputs: { dialogClosed: "dialogClosed" }, ngImport: i0, template: '<button mat-raised-button (click)="openUploadDialog()">{{ uploadService.options.uploadButtonText }}</button>', isInline: true, dependencies: [{ kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }] }); }
212
214
  }
213
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: UploadComponent, decorators: [{
215
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: UploadComponent, decorators: [{
214
216
  type: Component,
215
217
  args: [{
216
218
  selector: 'cp-upload',
217
- template: '<button mat-raised-button (click)="openUploadDialog()">{{ uploadButtonText }}</button>'
219
+ standalone: true,
220
+ imports: [
221
+ MatButton
222
+ ],
223
+ template: '<button mat-raised-button (click)="openUploadDialog()">{{ uploadService.options.uploadButtonText }}</button>'
218
224
  }]
219
- }], propDecorators: { dialogClosed: [{
220
- type: Output
221
- }] } });
225
+ }] });
222
226
 
223
227
  class UploadModule {
224
- static forRoot(uploadConfig) {
228
+ /*static forRoot(uploadConfig: ServiceConfig): ModuleWithProviders<UploadModule> {
229
+ return {
230
+ ngModule: UploadModule,
231
+ providers: [
232
+ UploadService,
233
+ { provide: ServiceConfig, useValue: uploadConfig }
234
+ ]
235
+ };
236
+ }*/
237
+ static forRoot(options) {
225
238
  return {
226
239
  ngModule: UploadModule,
227
240
  providers: [
228
- UploadService,
229
- { provide: ServiceConfig, useValue: uploadConfig }
241
+ {
242
+ provide: UploadServiceOptionsToken,
243
+ useValue: options
244
+ }
230
245
  ]
231
246
  };
232
247
  }
@@ -235,33 +250,35 @@ class UploadModule {
235
250
  throw new Error('UploadModule is already loaded. Import it in the AppModule only');
236
251
  }
237
252
  }
238
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: UploadModule, deps: [{ token: UploadModule, optional: true, skipSelf: true }], target: i0.ɵɵFactoryTarget.NgModule }); }
239
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.0", ngImport: i0, type: UploadModule, declarations: [UploadComponent,
240
- UploadDialogComponent], imports: [CommonModule,
253
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: UploadModule, deps: [{ token: UploadModule, optional: true, skipSelf: true }], target: i0.ɵɵFactoryTarget.NgModule }); }
254
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.3", ngImport: i0, type: UploadModule, imports: [CommonModule,
241
255
  MatButtonModule,
242
256
  MatDialogModule,
243
257
  MatListModule,
244
- MatProgressBarModule], exports: [UploadComponent,
258
+ MatProgressBarModule,
259
+ UploadComponent,
260
+ UploadDialogComponent], exports: [UploadComponent,
245
261
  UploadDialogComponent] }); }
246
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: UploadModule, imports: [CommonModule,
262
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: UploadModule, imports: [CommonModule,
247
263
  MatButtonModule,
248
264
  MatDialogModule,
249
265
  MatListModule,
250
- MatProgressBarModule] }); }
266
+ MatProgressBarModule,
267
+ UploadComponent,
268
+ UploadDialogComponent] }); }
251
269
  }
252
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: UploadModule, decorators: [{
270
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: UploadModule, decorators: [{
253
271
  type: NgModule,
254
272
  args: [{
255
- declarations: [
256
- UploadComponent,
257
- UploadDialogComponent
258
- ],
273
+ declarations: [],
259
274
  imports: [
260
275
  CommonModule,
261
276
  MatButtonModule,
262
277
  MatDialogModule,
263
278
  MatListModule,
264
- MatProgressBarModule
279
+ MatProgressBarModule,
280
+ UploadComponent,
281
+ UploadDialogComponent
265
282
  ],
266
283
  exports: [
267
284
  UploadComponent,
@@ -278,5 +295,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImpor
278
295
  * Generated bundle index. Do not edit.
279
296
  */
280
297
 
281
- export { ServiceConfig, UploadComponent, UploadDialogComponent, UploadModule, UploadService };
298
+ export { UploadComponent, UploadDialogComponent, UploadModule, UploadService, UploadServiceOptionsToken };
282
299
  //# sourceMappingURL=cleavelandprice-ngx-lib-upload.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"cleavelandprice-ngx-lib-upload.mjs","sources":["../../../../projects/cleavelandprice/ngx-lib/upload/src/model/service-config.ts","../../../../projects/cleavelandprice/ngx-lib/upload/src/services/upload.service.ts","../../../../projects/cleavelandprice/ngx-lib/upload/src/components/upload-dialog/upload-dialog.component.ts","../../../../projects/cleavelandprice/ngx-lib/upload/src/components/upload-dialog/upload-dialog.component.html","../../../../projects/cleavelandprice/ngx-lib/upload/src/components/upload/upload.component.ts","../../../../projects/cleavelandprice/ngx-lib/upload/src/upload.module.ts","../../../../projects/cleavelandprice/ngx-lib/upload/src/cleavelandprice-ngx-lib-upload.ts"],"sourcesContent":["import { ServiceConfig as NgxLibServiceConfig } from '@cleavelandprice/ngx-lib';\r\n\r\nexport class ServiceConfig extends NgxLibServiceConfig {\r\n databaseEndpoint = '/upload/database';\r\n uploadDialogTitle = 'Upload Files';\r\n uploadPath?: string;\r\n comment?: string;\r\n dbAppId?: string;\r\n externalReferenceId?: string;\r\n \r\n // UI configuration\r\n uploadButtonText = 'Upload';\r\n uploadDialogCancelButtonText = 'Cancel';\r\n uploadDialogFinishButtonText = 'Finish';\r\n uploadDialogUploadButtonText = 'Upload';\r\n uploadDialogAddFilesButtonText = 'Add Files';\r\n\r\n // See the comment in the library's main service-config.ts file for an explanation\r\n constructor(useSsl_or_customApiUrl: boolean | string = false) {\r\n super(useSsl_or_customApiUrl);\r\n }\r\n}","import { HttpClient, HttpEventType, HttpHeaders, HttpRequest, HttpResponse } from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { Observable, Subject } from 'rxjs';\r\n\r\nimport { DatabaseFileInfo } from '../model/database-file-info';\r\nimport { FileUploadRequest } from '../model/file-upload-request';\r\nimport { FilesystemFileInfo } from '../model/filesystem-file-info';\r\nimport { ServiceConfig } from '../model/service-config';\r\n\r\n// https://malcoded.com/posts/angular-file-upload-component-with-express\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class UploadService {\r\n //#region Services\r\n private http = inject(HttpClient);\r\n public config = inject(ServiceConfig, { optional: true }) ?? new ServiceConfig();\r\n //#endregion\r\n\r\n\r\n public upload(files: Set<File>): any { // {[key: string]: Observable<number>} {\r\n // this will be the our resulting map\r\n const status: {[key: string]: {progress: Observable<number>}} = {};\r\n\r\n files.forEach(file => {\r\n // create a new multipart-form for every file\r\n const formData: FormData = new FormData();\r\n formData.append('file', file, file.name);\r\n\r\n // create a http-post request and pass the form\r\n // tell it to report the upload progress\r\n\r\n // A 'Destination' header is used to optionally configure the file upload destination (filesystem)\r\n // A 'DbAppId' header is used to configure the unique identifier of database uploads\r\n \r\n let headers = new HttpHeaders();\r\n if (this.config.uploadPath) {\r\n headers = headers.set('Destination', this.config.uploadPath);\r\n }\r\n if (this.config.dbAppId) {\r\n headers = headers.set('DbAppId', this.config.dbAppId);\r\n }\r\n if (this.config.externalReferenceId) {\r\n headers = headers.set('ExternalReferenceId', this.config.externalReferenceId);\r\n }\r\n if (this.config.comment) {\r\n headers = headers.set('Comment', this.config.comment);\r\n }\r\n\r\n const req = new HttpRequest('POST', `${this.config.apiUrl}${this.config.databaseEndpoint}`, formData, {\r\n reportProgress: true,\r\n responseType: 'blob',\r\n headers\r\n });\r\n\r\n // create a new progress-subject for every file\r\n const progress = new Subject<number>();\r\n\r\n // send the http-request and subscribe for progress-updates\r\n this.http.request(req).subscribe(event => {\r\n if (event.type === HttpEventType.UploadProgress) {\r\n\r\n // calculate the progress percentage\r\n const percentDone = Math.round(100 * event.loaded / (event.total ?? 1));\r\n\r\n // pass the percentage into the progress-stream\r\n progress.next(percentDone);\r\n } else if (event instanceof HttpResponse) {\r\n\r\n // Close the progress-stream if we get an answer form the API\r\n // The upload is complete\r\n progress.complete();\r\n }\r\n });\r\n\r\n // Save every progress-observable in a map of all observables\r\n status[file.name] = {\r\n progress: progress.asObservable()\r\n };\r\n });\r\n\r\n // return the map of progress.observables\r\n return status;\r\n }\r\n\r\n public exists(fileName: string): Observable<boolean> {\r\n const query = `${this.config.apiUrl}${this.config.databaseEndpoint}`.toLowerCase().indexOf('filesystem') === -1 ?\r\n { name: fileName, dbAppId: this.config.dbAppId } :\r\n { name: fileName, destination: this.config.uploadPath };\r\n\r\n return this.http.post<boolean>(`${this.config.apiUrl}${this.config.databaseEndpoint}/exists`, query);\r\n }\r\n\r\n public download(request: FileUploadRequest): Observable<Blob> {\r\n return this.http.post(`${this.config.apiUrl}${this.config.databaseEndpoint}/stream`, request, { responseType: 'blob' });\r\n }\r\n\r\n public getUploadInfo(request: FileUploadRequest):\r\n Observable<DatabaseFileInfo | DatabaseFileInfo[] | FilesystemFileInfo | FilesystemFileInfo[]> {\r\n return this.http.post<DatabaseFileInfo | DatabaseFileInfo[] | FilesystemFileInfo | FilesystemFileInfo[]>\r\n (`${this.config.apiUrl}${this.config.databaseEndpoint}/info`, request);\r\n }\r\n}\r\n","import { Component, ElementRef, inject, OnInit, ViewChild } from '@angular/core';\r\nimport { MatDialogRef } from '@angular/material/dialog';\r\nimport { forkJoin } from 'rxjs';\r\n\r\nimport { UploadService } from './../../services/upload.service';\r\n\r\n@Component({\r\n templateUrl: './upload-dialog.component.html',\r\n styleUrls: ['./upload-dialog.component.css']\r\n})\r\nexport class UploadDialogComponent implements OnInit {\r\n //#region Services\r\n public dialogRef = inject(MatDialogRef<UploadDialogComponent>);\r\n public uploadService = inject(UploadService);\r\n //#endregion\r\n\r\n @ViewChild('file', { static: true }) file!: ElementRef;\r\n public files: Set<File> = new Set();\r\n existingFileConflict?: string;\r\n\r\n // State\r\n progress: any;\r\n canBeClosed = true;\r\n primaryButtonText?: string;\r\n showCancelButton = true;\r\n uploading = false;\r\n uploadSuccessful = false;\r\n\r\n ngOnInit() {\r\n this.primaryButtonText = this.uploadService.config.uploadDialogUploadButtonText;\r\n }\r\n\r\n addFiles() {\r\n this.file.nativeElement.click();\r\n }\r\n\r\n onFilesAdded() {\r\n const files: { [key: string]: File } = this.file.nativeElement.files;\r\n for (const key in files) {\r\n if (!isNaN(parseInt(key))) {\r\n // See if the file already exists\r\n this.uploadService.exists(files[key].name)\r\n .subscribe(exists => {\r\n if (exists) {\r\n this.existingFileConflict = files[key].name;\r\n }\r\n\r\n if (!exists) {\r\n this.files.add(files[key]);\r\n }\r\n });\r\n }\r\n }\r\n }\r\n\r\n closeDialog() {\r\n // if everything was uploaded already, just close the dialog\r\n if (this.uploadSuccessful) {\r\n return this.dialogRef.close();\r\n }\r\n\r\n // set the component state to \"uploading\"\r\n this.uploading = true;\r\n\r\n // start the upload and save the progress map\r\n this.progress = this.uploadService.upload(this.files);\r\n\r\n // convert the progress map into an array\r\n const allProgressObservables: any[] = [];\r\n\r\n for (let key in this.progress) {\r\n allProgressObservables.push(this.progress[key].progress);\r\n }\r\n\r\n // Adjust the state variables\r\n\r\n // The OK-button should have the text \"Finish\" now\r\n this.primaryButtonText = this.uploadService.config.uploadDialogFinishButtonText;\r\n\r\n // The dialog should not be closed while uploading\r\n this.canBeClosed = false;\r\n this.dialogRef.disableClose = true;\r\n\r\n // Hide the cancel-button\r\n this.showCancelButton = false;\r\n\r\n // When all progress-observables are completed...\r\n forkJoin(allProgressObservables).subscribe(end => {\r\n // ... the dialog can be closed again...\r\n this.canBeClosed = true;\r\n this.dialogRef.disableClose = false;\r\n\r\n // ... the upload was successful...\r\n this.uploadSuccessful = true;\r\n\r\n // ... and the component is no longer uploading\r\n this.uploading = false;\r\n });\r\n }\r\n}\r\n","<input type=\"file\" #file style=\"display: none\" (change)=\"onFilesAdded()\" multiple />\r\n\r\n<div mat-dialog-title id=\"title\">\r\n <div>{{ uploadService.config.uploadDialogTitle }}</div>\r\n <button [disabled]=\"uploading || uploadSuccessful\" mat-raised-button color=\"primary\" class=\"add-files-btn\" (click)=\"addFiles()\">\r\n {{ uploadService.config.uploadDialogAddFilesButtonText }}\r\n </button>\r\n</div>\r\n\r\n@if (existingFileConflict) {\r\n <div id=\"conflict\">\r\n {{ existingFileConflict }} already exists on the server and cannot be overwritten\r\n </div>\r\n}\r\n\r\n<mat-dialog-content>\r\n <mat-list>\r\n @for (file of files; track file) {\r\n <mat-list-item>\r\n <h4 mat-line>{{file.name}}</h4>\r\n @if (progress) {\r\n <mat-progress-bar mode=\"determinate\" [value]=\"progress[file.name].progress | async\"/>\r\n }\r\n </mat-list-item>\r\n }\r\n </mat-list>\r\n</mat-dialog-content>\r\n\r\n<mat-dialog-actions id=\"actions\">\r\n @if (showCancelButton) {\r\n <button mat-button mat-dialog-close>{{ uploadService.config.uploadDialogCancelButtonText }}</button>\r\n }\r\n @if (files.size > 0) {\r\n <button mat-raised-button color=\"primary\" [disabled]=\"!canBeClosed\" (click)=\"closeDialog()\">{{ primaryButtonText }}</button>\r\n }\r\n</mat-dialog-actions>\r\n","import { Component, EventEmitter, inject, OnInit, Output } from '@angular/core';\r\nimport { MatDialog } from '@angular/material/dialog';\r\n\r\nimport { UploadService } from './../../services/upload.service';\r\nimport { UploadDialogComponent } from './../upload-dialog/upload-dialog.component';\r\n\r\n@Component({\r\n selector: 'cp-upload',\r\n template: '<button mat-raised-button (click)=\"openUploadDialog()\">{{ uploadButtonText }}</button>'\r\n})\r\nexport class UploadComponent implements OnInit {\r\n //#region Services\r\n public dialog = inject(MatDialog);\r\n public uploadService = inject(UploadService);\r\n //#endregion\r\n\r\n @Output() dialogClosed = new EventEmitter();\r\n uploadButtonText!: string;\r\n\r\n ngOnInit(): void {\r\n this.uploadButtonText = this.uploadService.config.uploadButtonText ?\r\n this.uploadService.config.uploadButtonText :\r\n 'Upload';\r\n }\r\n\r\n public openUploadDialog() {\r\n this.dialog.open(UploadDialogComponent, { width: '50%' })\r\n .afterClosed().subscribe(() => this.dialogClosed.emit());\r\n }\r\n}\r\n","import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\nimport { MatButtonModule } from '@angular/material/button';\r\nimport { MatDialogModule } from '@angular/material/dialog';\r\nimport { MatListModule } from '@angular/material/list';\r\nimport { MatProgressBarModule } from '@angular/material/progress-bar';\r\n\r\nimport { ServiceConfig } from './model/service-config';\r\n\r\nimport { UploadService } from './services/upload.service';\r\n\r\nimport { UploadComponent } from './components/upload/upload.component';\r\nimport { UploadDialogComponent } from './components/upload-dialog/upload-dialog.component';\r\n\r\n@NgModule({\r\n declarations: [\r\n UploadComponent,\r\n UploadDialogComponent\r\n ],\r\n imports: [\r\n CommonModule,\r\n MatButtonModule,\r\n MatDialogModule,\r\n MatListModule,\r\n MatProgressBarModule\r\n ],\r\n exports: [\r\n UploadComponent,\r\n UploadDialogComponent\r\n ]\r\n})\r\nexport class UploadModule {\r\n static forRoot(uploadConfig: ServiceConfig): ModuleWithProviders<UploadModule> {\r\n return {\r\n ngModule: UploadModule,\r\n providers: [\r\n UploadService,\r\n { provide: ServiceConfig, useValue: uploadConfig }\r\n ]\r\n };\r\n }\r\n\r\n constructor(@Optional() @SkipSelf() parentModule: UploadModule) {\r\n if (parentModule) {\r\n throw new Error(\r\n 'UploadModule is already loaded. Import it in the AppModule only');\r\n }\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["NgxLibServiceConfig"],"mappings":"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"}
1
+ {"version":3,"file":"cleavelandprice-ngx-lib-upload.mjs","sources":["../../../../projects/cleavelandprice/ngx-lib/upload/src/model/upload-service-options.ts","../../../../projects/cleavelandprice/ngx-lib/upload/src/services/upload.service.ts","../../../../projects/cleavelandprice/ngx-lib/upload/src/components/upload-dialog/upload-dialog.component.ts","../../../../projects/cleavelandprice/ngx-lib/upload/src/components/upload-dialog/upload-dialog.component.html","../../../../projects/cleavelandprice/ngx-lib/upload/src/components/upload/upload.component.ts","../../../../projects/cleavelandprice/ngx-lib/upload/src/upload.module.ts","../../../../projects/cleavelandprice/ngx-lib/upload/src/cleavelandprice-ngx-lib-upload.ts"],"sourcesContent":["import { InjectionToken } from \"@angular/core\";\r\nimport { NgxLibServiceOptions } from \"@cleavelandprice/ngx-lib\";\r\n\r\nexport interface UploadServiceOptions extends NgxLibServiceOptions {\r\n databaseEndpoint?: string;\r\n uploadPath?: string;\r\n comment?: string;\r\n dbAppId?: string;\r\n externalReferenceId?: string;\r\n // UI configuration\r\n uploadDialogTitle?: string;\r\n uploadButtonText?: string;\r\n uploadDialogCancelButtonText?: string;\r\n uploadDialogFinishButtonText?: string;\r\n uploadDialogUploadButtonText?: string;\r\n uploadDialogAddFilesButtonText?: string;\r\n};\r\nexport const UploadServiceOptionsToken = new InjectionToken<UploadServiceOptions>('');","import { HttpClient, HttpEventType, HttpHeaders, HttpRequest, HttpResponse } from '@angular/common/http';\r\nimport { Inject, Injectable, Optional, inject } from '@angular/core';\r\nimport { Observable, Subject } from 'rxjs';\r\n\r\nimport { NgxLibServiceBase } from '@cleavelandprice/ngx-lib';\r\nimport { DatabaseFileInfo } from '../model/database-file-info';\r\nimport { FileUploadRequest } from '../model/file-upload-request';\r\nimport { FilesystemFileInfo } from '../model/filesystem-file-info';\r\nimport { UploadServiceOptions, UploadServiceOptionsToken } from '../model/upload-service-options';\r\nimport { UploadStatus } from '../model/upload-status';\r\n\r\n// https://malcoded.com/posts/angular-file-upload-component-with-express\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class UploadService extends NgxLibServiceBase {\r\n #http = inject(HttpClient);\r\n\r\n constructor(@Optional() @Inject(UploadServiceOptionsToken) public options: UploadServiceOptions) {\r\n super(options);\r\n \r\n this.options = {\r\n ...options,\r\n databaseEndpoint: options?.databaseEndpoint ?? '/upload/database',\r\n uploadDialogTitle: options?.uploadDialogTitle ?? 'Upload Files',\r\n uploadButtonText: options?.uploadButtonText ?? 'Upload',\r\n uploadDialogCancelButtonText: options?.uploadDialogCancelButtonText ?? 'Cancel',\r\n uploadDialogFinishButtonText: options?.uploadDialogFinishButtonText ?? 'Finish',\r\n uploadDialogUploadButtonText: options?.uploadButtonText ?? 'Upload',\r\n uploadDialogAddFilesButtonText: options?.uploadDialogAddFilesButtonText ?? 'Add Files'\r\n };\r\n }\r\n\r\n upload(files: Set<File>): UploadStatus { // {[key: string]: Observable<number>} {\r\n // this will be the our resulting map\r\n const status: UploadStatus = {};\r\n\r\n files.forEach(file => {\r\n // create a new multipart-form for every file\r\n const formData: FormData = new FormData();\r\n formData.append('file', file, file.name);\r\n\r\n // create a http-post request and pass the form\r\n // tell it to report the upload progress\r\n\r\n // A 'Destination' header is used to optionally configure the file upload destination (filesystem)\r\n // A 'DbAppId' header is used to configure the unique identifier of database uploads\r\n \r\n let headers = new HttpHeaders();\r\n if (this.options.uploadPath) {\r\n headers = headers.set('Destination', this.options.uploadPath);\r\n }\r\n if (this.options.dbAppId) {\r\n headers = headers.set('DbAppId', this.options.dbAppId);\r\n }\r\n if (this.options.externalReferenceId) {\r\n headers = headers.set('ExternalReferenceId', this.options.externalReferenceId);\r\n }\r\n if (this.options.comment) {\r\n headers = headers.set('Comment', this.options.comment);\r\n }\r\n\r\n const req = new HttpRequest('POST', `${this.apiUrl}${this.options.databaseEndpoint}`, formData, {\r\n reportProgress: true,\r\n responseType: 'blob',\r\n headers\r\n });\r\n\r\n // create a new progress-subject for every file\r\n const progress = new Subject<number>();\r\n\r\n // send the http-request and subscribe for progress-updates\r\n this.#http.request(req).subscribe(event => {\r\n if (event.type === HttpEventType.UploadProgress) {\r\n\r\n // calculate the progress percentage\r\n const percentDone = Math.round(100 * event.loaded / (event.total ?? 1));\r\n\r\n // pass the percentage into the progress-stream\r\n progress.next(percentDone);\r\n } else if (event instanceof HttpResponse) {\r\n\r\n // Close the progress-stream if we get an answer form the API\r\n // The upload is complete\r\n progress.complete();\r\n }\r\n });\r\n\r\n // Save every progress-observable in a map of all observables\r\n status[file.name] = {\r\n progress: progress.asObservable()\r\n };\r\n });\r\n\r\n // return the map of progress.observables\r\n return status;\r\n }\r\n\r\n exists(fileName: string): Observable<boolean> {\r\n const query = `${this.apiUrl}${this.options.databaseEndpoint}`.toLowerCase().includes('filesystem') ?\r\n { name: fileName, destination: this.options.uploadPath } :\r\n { name: fileName, dbAppId: this.options.dbAppId };\r\n\r\n return this.#http.post<boolean>(`${this.apiUrl}${this.options.databaseEndpoint}/exists`, query);\r\n }\r\n\r\n download(request: FileUploadRequest): Observable<Blob> {\r\n return this.#http.post(`${this.apiUrl}${this.options.databaseEndpoint}/stream`, request, { responseType: 'blob' });\r\n }\r\n\r\n getUploadInfo(request: FileUploadRequest):\r\n Observable<DatabaseFileInfo | DatabaseFileInfo[] | FilesystemFileInfo | FilesystemFileInfo[]> {\r\n return this.#http.post<DatabaseFileInfo | DatabaseFileInfo[] | FilesystemFileInfo | FilesystemFileInfo[]>\r\n (`${this.apiUrl}${this.options.databaseEndpoint}/info`, request);\r\n }\r\n}","import { AsyncPipe } from '@angular/common';\r\nimport { Component, ElementRef, inject, viewChild } from '@angular/core';\r\nimport { MatButton } from '@angular/material/button';\r\nimport { MatDialogActions, MatDialogClose, MatDialogContent, MatDialogRef } from '@angular/material/dialog';\r\nimport { MatList, MatListItem } from '@angular/material/list';\r\nimport { MatProgressBar } from '@angular/material/progress-bar';\r\nimport { Observable, forkJoin } from 'rxjs';\r\nimport { UploadStatus } from '../../model/upload-status';\r\nimport { UploadService } from './../../services/upload.service';\r\n\r\n@Component({\r\n templateUrl: './upload-dialog.component.html',\r\n standalone: true,\r\n imports: [\r\n AsyncPipe,\r\n MatButton,\r\n MatDialogActions,\r\n MatDialogClose,\r\n MatDialogContent,\r\n MatList,\r\n MatListItem,\r\n MatProgressBar\r\n ],\r\n styleUrl: './upload-dialog.component.scss'\r\n})\r\nexport class UploadDialogComponent {\r\n services = {\r\n dialogRef: inject(MatDialogRef<UploadDialogComponent>),\r\n upload: inject(UploadService)\r\n };\r\n\r\n file = viewChild.required<ElementRef>('file');\r\n\r\n files: Set<File> = new Set();\r\n existingFileConflict?: string;\r\n\r\n // State\r\n progress?: UploadStatus;\r\n canBeClosed = true;\r\n primaryButtonText = this.services.upload.options.uploadDialogUploadButtonText;\r\n showCancelButton = true;\r\n uploading = false;\r\n uploadSuccessful = false;\r\n\r\n addFiles() {\r\n this.file().nativeElement.click();\r\n }\r\n\r\n onFilesAdded() {\r\n const files: { [key: string]: File } = this.file().nativeElement.files;\r\n for (const key in files) {\r\n if (!isNaN(parseInt(key))) {\r\n // See if the file already exists\r\n this.services.upload.exists(files[key].name)\r\n .subscribe(exists => {\r\n if (exists) {\r\n this.existingFileConflict = files[key].name;\r\n }\r\n\r\n if (!exists) {\r\n this.files.add(files[key]);\r\n }\r\n });\r\n }\r\n }\r\n }\r\n\r\n closeDialog() {\r\n // if everything was uploaded already, just close the dialog\r\n if (this.uploadSuccessful) {\r\n return this.services.dialogRef.close();\r\n }\r\n\r\n // set the component state to \"uploading\"\r\n this.uploading = true;\r\n\r\n // start the upload and save the progress map\r\n this.progress = this.services.upload.upload(this.files);\r\n\r\n // convert the progress map into an array\r\n const allProgressObservables$: Observable<number>[] = [];\r\n\r\n for (let key in this.progress) {\r\n allProgressObservables$.push(this.progress[key].progress);\r\n }\r\n\r\n // Adjust the state variables\r\n\r\n // The OK-button should have the text \"Finish\" now\r\n this.primaryButtonText = this.services.upload.options.uploadDialogFinishButtonText;\r\n\r\n // The dialog should not be closed while uploading\r\n this.canBeClosed = false;\r\n this.services.dialogRef.disableClose = true;\r\n\r\n // Hide the cancel-button\r\n this.showCancelButton = false;\r\n\r\n // When all progress-observables are completed...\r\n forkJoin(allProgressObservables$)\r\n .subscribe({\r\n complete: () => {\r\n // ... the dialog can be closed again...\r\n this.canBeClosed = true;\r\n this.services.dialogRef.disableClose = false;\r\n \r\n // ... the upload was successful...\r\n this.uploadSuccessful = true;\r\n \r\n // ... and the component is no longer uploading\r\n this.uploading = false;\r\n\r\n console.log('Upload complete', this.files);\r\n\r\n this.services.dialogRef.close();\r\n }\r\n });\r\n }\r\n}\r\n","<input type=\"file\" #file style=\"display: none\" (change)=\"onFilesAdded()\" multiple />\n\n<div mat-dialog-title id=\"title\">\n <div>{{ services.upload.options.uploadDialogTitle }}</div>\n <button [disabled]=\"uploading || uploadSuccessful\" mat-raised-button color=\"primary\" class=\"add-files-btn\" (click)=\"addFiles()\">\n {{ services.upload.options.uploadDialogAddFilesButtonText }}\n </button>\n</div>\n\n@if (existingFileConflict) {\n <div id=\"conflict\">\n {{ existingFileConflict }} already exists on the server and cannot be overwritten\n </div>\n}\n\n<mat-dialog-content>\n <mat-list>\n @for (file of files; track file) {\n <mat-list-item>\n <h4 mat-line>{{file.name}}</h4>\n @if (progress) {\n <mat-progress-bar mode=\"determinate\" [value]=\"progress[file.name].progress | async\"/>\n }\n </mat-list-item>\n }\n </mat-list>\n</mat-dialog-content>\n\n<mat-dialog-actions id=\"actions\">\n @if (showCancelButton) {\n <button mat-button mat-dialog-close>{{ services.upload.options.uploadDialogCancelButtonText }}</button>\n }\n @if (files.size > 0) {\n <button mat-raised-button color=\"primary\" [disabled]=\"!canBeClosed\" (click)=\"closeDialog()\">{{ primaryButtonText }}</button>\n }\n</mat-dialog-actions>\n","import { Component, inject, output } from '@angular/core';\r\nimport { MatDialog } from '@angular/material/dialog';\r\n\r\nimport { MatButton } from '@angular/material/button';\r\nimport { UploadService } from './../../services/upload.service';\r\nimport { UploadDialogComponent } from './../upload-dialog/upload-dialog.component';\r\n\r\n@Component({\r\n selector: 'cp-upload',\r\n standalone: true,\r\n imports: [\r\n MatButton\r\n ],\r\n template: '<button mat-raised-button (click)=\"openUploadDialog()\">{{ uploadService.options.uploadButtonText }}</button>'\r\n})\r\nexport class UploadComponent {\r\n #dialogService = inject(MatDialog);\r\n uploadService = inject(UploadService);\r\n\r\n dialogClosed = output();\r\n\r\n openUploadDialog() {\r\n this.#dialogService.open(UploadDialogComponent, { width: '50%' })\r\n .afterClosed().subscribe(() => this.dialogClosed.emit());\r\n }\r\n}\r\n","import { CommonModule } from '@angular/common';\r\nimport { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core';\r\n\r\nimport { MatButtonModule } from '@angular/material/button';\r\nimport { MatDialogModule } from '@angular/material/dialog';\r\nimport { MatListModule } from '@angular/material/list';\r\nimport { MatProgressBarModule } from '@angular/material/progress-bar';\r\n\r\n//import { ServiceConfig } from './model/service-config';\r\n\r\n\r\nimport { UploadDialogComponent } from './components/upload-dialog/upload-dialog.component';\r\nimport { UploadComponent } from './components/upload/upload.component';\r\nimport { UploadServiceOptions, UploadServiceOptionsToken } from './model/upload-service-options';\r\n\r\n@NgModule({\r\n declarations: [],\r\n imports: [\r\n CommonModule,\r\n MatButtonModule,\r\n MatDialogModule,\r\n MatListModule,\r\n MatProgressBarModule,\r\n\r\n UploadComponent,\r\n UploadDialogComponent\r\n ],\r\n exports: [\r\n UploadComponent,\r\n UploadDialogComponent\r\n ]\r\n})\r\nexport class UploadModule {\r\n /*static forRoot(uploadConfig: ServiceConfig): ModuleWithProviders<UploadModule> {\r\n return {\r\n ngModule: UploadModule,\r\n providers: [\r\n UploadService,\r\n { provide: ServiceConfig, useValue: uploadConfig }\r\n ]\r\n };\r\n }*/\r\n static forRoot(options: UploadServiceOptions): ModuleWithProviders<UploadModule> {\r\n return {\r\n ngModule: UploadModule,\r\n providers: [\r\n {\r\n provide: UploadServiceOptionsToken,\r\n useValue: options\r\n }\r\n ]\r\n }\r\n }\r\n\r\n constructor(@Optional() @SkipSelf() parentModule: UploadModule) {\r\n if (parentModule) {\r\n throw new Error(\r\n 'UploadModule is already loaded. Import it in the AppModule only');\r\n }\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './upload.api';\n"],"names":[],"mappings":"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"}