@sigmaott/base-next 1.4.0 → 1.4.2

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 (714) hide show
  1. package/hyrd-ui.preset.ts +463 -463
  2. package/i18n.config.ts +3 -3
  3. package/locales/en.yaml +719 -719
  4. package/locales/vi.yaml +726 -726
  5. package/nuxt-config.ts +23 -23
  6. package/nuxt.config.ts +281 -281
  7. package/package.json +130 -130
  8. package/public/routes.json +33 -33
  9. package/src/api/api.ts +15 -15
  10. package/src/api/axios.ts +133 -133
  11. package/src/api/service-loading.ts +50 -50
  12. package/src/api-client-auth/.openapi-generator/FILES +83 -83
  13. package/src/api-client-auth/.openapi-generator-ignore +23 -23
  14. package/src/api-client-auth/api/admin-groups-api.ts +612 -612
  15. package/src/api-client-auth/api/admin-members-api.ts +708 -708
  16. package/src/api-client-auth/api/administration-api-groups-api.ts +547 -547
  17. package/src/api-client-auth/api/administration-apps-api.ts +709 -709
  18. package/src/api-client-auth/api/administration-packages-api.ts +547 -547
  19. package/src/api-client-auth/api/api-groups-api.ts +296 -296
  20. package/src/api-client-auth/api/apps-api.ts +1613 -1613
  21. package/src/api-client-auth/api/basic-credential-api.ts +950 -950
  22. package/src/api-client-auth/api/groups-api.ts +702 -702
  23. package/src/api-client-auth/api/members-api.ts +708 -708
  24. package/src/api-client-auth/api/members-on-premise-api.ts +351 -351
  25. package/src/api-client-auth/api/packages-api.ts +296 -296
  26. package/src/api-client-auth/api/users-api.ts +1387 -1387
  27. package/src/api-client-auth/api.ts +30 -30
  28. package/src/api-client-auth/base.ts +72 -72
  29. package/src/api-client-auth/common.ts +150 -150
  30. package/src/api-client-auth/configuration.ts +101 -101
  31. package/src/api-client-auth/git_push.sh +57 -57
  32. package/src/api-client-auth/index.ts +18 -18
  33. package/src/api-client-auth/models/add-member-dto.ts +42 -42
  34. package/src/api-client-auth/models/admin-permission.ts +44 -44
  35. package/src/api-client-auth/models/api-group-collection.ts +57 -57
  36. package/src/api-client-auth/models/api-group.ts +80 -80
  37. package/src/api-client-auth/models/api.ts +44 -44
  38. package/src/api-client-auth/models/app-collection.ts +57 -57
  39. package/src/api-client-auth/models/app.ts +147 -147
  40. package/src/api-client-auth/models/backdoor-cred.ts +39 -39
  41. package/src/api-client-auth/models/basic-cred-collection.ts +57 -57
  42. package/src/api-client-auth/models/basic-cred.ts +83 -83
  43. package/src/api-client-auth/models/change-password-dto.ts +42 -42
  44. package/src/api-client-auth/models/create-admin-group-dto.ts +39 -39
  45. package/src/api-client-auth/models/create-api-group-dto.ts +42 -42
  46. package/src/api-client-auth/models/create-app-by-user-dto.ts +36 -36
  47. package/src/api-client-auth/models/create-app-dto.ts +65 -65
  48. package/src/api-client-auth/models/create-basic-cred-dto.ts +39 -39
  49. package/src/api-client-auth/models/create-group-dto.ts +39 -39
  50. package/src/api-client-auth/models/create-package-dto.ts +48 -48
  51. package/src/api-client-auth/models/create-user-dto.ts +60 -60
  52. package/src/api-client-auth/models/free-trial.ts +54 -54
  53. package/src/api-client-auth/models/general-app.ts +48 -48
  54. package/src/api-client-auth/models/generate-app-id.ts +30 -30
  55. package/src/api-client-auth/models/group-collection.ts +57 -57
  56. package/src/api-client-auth/models/group.ts +75 -75
  57. package/src/api-client-auth/models/index.ts +60 -60
  58. package/src/api-client-auth/models/invite-email-dto.ts +30 -30
  59. package/src/api-client-auth/models/invite-member-dto.ts +36 -36
  60. package/src/api-client-auth/models/live-stream-quota.ts +42 -42
  61. package/src/api-client-auth/models/login-dto.ts +36 -36
  62. package/src/api-client-auth/models/login-result.ts +39 -39
  63. package/src/api-client-auth/models/member-collection.ts +57 -57
  64. package/src/api-client-auth/models/member.ts +92 -92
  65. package/src/api-client-auth/models/package-collection.ts +57 -57
  66. package/src/api-client-auth/models/package-permission.ts +44 -44
  67. package/src/api-client-auth/models/package.ts +66 -66
  68. package/src/api-client-auth/models/permission.ts +44 -44
  69. package/src/api-client-auth/models/quota.ts +45 -45
  70. package/src/api-client-auth/models/re-get-password-dto.ts +30 -30
  71. package/src/api-client-auth/models/register-dto.ts +54 -54
  72. package/src/api-client-auth/models/register-through-email-dto.ts +36 -36
  73. package/src/api-client-auth/models/rename-app-dto.ts +30 -30
  74. package/src/api-client-auth/models/resend-confirmation-dto.ts +30 -30
  75. package/src/api-client-auth/models/resend-invitation-dto.ts +30 -30
  76. package/src/api-client-auth/models/resend-result.ts +36 -36
  77. package/src/api-client-auth/models/reset-password-dto.ts +36 -36
  78. package/src/api-client-auth/models/revoke-basic-dto.ts +38 -38
  79. package/src/api-client-auth/models/signup-result.ts +45 -45
  80. package/src/api-client-auth/models/token-check-result.ts +36 -36
  81. package/src/api-client-auth/models/trial-remaining-days.ts +42 -42
  82. package/src/api-client-auth/models/update-admin-group-dto.ts +39 -39
  83. package/src/api-client-auth/models/update-api-group-dto.ts +30 -30
  84. package/src/api-client-auth/models/update-app-by-admin-dto.ts +48 -48
  85. package/src/api-client-auth/models/update-app-by-user-dto.ts +36 -36
  86. package/src/api-client-auth/models/update-basic-cred-dto.ts +30 -30
  87. package/src/api-client-auth/models/update-group-dto.ts +39 -39
  88. package/src/api-client-auth/models/update-member-dto.ts +30 -30
  89. package/src/api-client-auth/models/update-package-dto.ts +42 -42
  90. package/src/api-client-auth/models/update-password-member-dto.ts +30 -30
  91. package/src/api-client-auth/models/update-user-by-user-dto.ts +48 -48
  92. package/src/api-client-auth/models/user.ts +120 -120
  93. package/src/api-client-auth/models/validate-app-id.ts +36 -36
  94. package/src/api-client-billing/.openapi-generator/FILES +38 -38
  95. package/src/api-client-billing/.openapi-generator-ignore +23 -23
  96. package/src/api-client-billing/api/invoice-api.ts +363 -363
  97. package/src/api-client-billing/api/payment-methods-api.ts +414 -414
  98. package/src/api-client-billing/api/payment-plan-api.ts +121 -121
  99. package/src/api-client-billing/api/subscriptions-api.ts +121 -121
  100. package/src/api-client-billing/api/usages-api.ts +121 -121
  101. package/src/api-client-billing/api/vnpay-provider-api.ts +327 -327
  102. package/src/api-client-billing/api.ts +23 -23
  103. package/src/api-client-billing/base.ts +72 -72
  104. package/src/api-client-billing/common.ts +150 -150
  105. package/src/api-client-billing/configuration.ts +101 -101
  106. package/src/api-client-billing/git_push.sh +57 -57
  107. package/src/api-client-billing/index.ts +18 -18
  108. package/src/api-client-billing/models/common-paginate-response.ts +48 -48
  109. package/src/api-client-billing/models/dto-billing-item-info.ts +60 -60
  110. package/src/api-client-billing/models/dto-billing-item.ts +36 -36
  111. package/src/api-client-billing/models/dto-create-draft-invoice-request.ts +33 -33
  112. package/src/api-client-billing/models/dto-create-draft-invoice-response.ts +57 -57
  113. package/src/api-client-billing/models/dto-create-vnpay-card-form.ts +48 -48
  114. package/src/api-client-billing/models/dto-return-uri-response.ts +30 -30
  115. package/src/api-client-billing/models/index.ts +22 -22
  116. package/src/api-client-billing/models/invoices-get200-response.ts +42 -42
  117. package/src/api-client-billing/models/model-charge.ts +47 -47
  118. package/src/api-client-billing/models/model-charges-usage.ts +57 -57
  119. package/src/api-client-billing/models/model-graduated-range.ts +48 -48
  120. package/src/api-client-billing/models/model-info.ts +42 -42
  121. package/src/api-client-billing/models/model-invoice.ts +105 -105
  122. package/src/api-client-billing/models/model-item-usage.ts +54 -54
  123. package/src/api-client-billing/models/model-payment-method.ts +135 -135
  124. package/src/api-client-billing/models/model-product.ts +51 -51
  125. package/src/api-client-billing/models/model-properties.ts +39 -39
  126. package/src/api-client-billing/models/model-quota.ts +48 -48
  127. package/src/api-client-billing/models/model-subscription.ts +51 -51
  128. package/src/api-client-billing/models/model-usage-payment.ts +87 -87
  129. package/src/api-client-billing/models/payment-methods-get200-response.ts +42 -42
  130. package/src/api-client-billing/models/subscriptions-get200-response.ts +42 -42
  131. package/src/api-client-machine/.openapi-generator/FILES +90 -90
  132. package/src/api-client-machine/.openapi-generator-ignore +23 -23
  133. package/src/api-client-machine/api/apps-config-api.ts +523 -523
  134. package/src/api-client-machine/api/component-clusters-api.ts +741 -741
  135. package/src/api-client-machine/api/expose-api.ts +141 -141
  136. package/src/api-client-machine/api/machine-actions-api.ts +850 -850
  137. package/src/api-client-machine/api/machines-api.ts +524 -524
  138. package/src/api-client-machine/api/networks-api.ts +375 -375
  139. package/src/api-client-machine/api/sigma-clusters-api.ts +741 -741
  140. package/src/api-client-machine/api/sigma-machine-actions-api.ts +292 -292
  141. package/src/api-client-machine/api/sigma-machine-apps-configuration-api.ts +523 -523
  142. package/src/api-client-machine/api/sigma-machines-api.ts +557 -557
  143. package/src/api-client-machine/api/sigma-vod-server-api.ts +478 -478
  144. package/src/api-client-machine/api/sigma-vod-server-app-config-api.ts +980 -980
  145. package/src/api-client-machine/api/transcoder-configuration-api.ts +359 -359
  146. package/src/api-client-machine/api.ts +30 -30
  147. package/src/api-client-machine/base.ts +72 -72
  148. package/src/api-client-machine/common.ts +150 -150
  149. package/src/api-client-machine/configuration.ts +101 -101
  150. package/src/api-client-machine/git_push.sh +57 -57
  151. package/src/api-client-machine/index.ts +18 -18
  152. package/src/api-client-machine/models/actions-to-app-dto.ts +38 -38
  153. package/src/api-client-machine/models/add-license-machine-dto.ts +30 -30
  154. package/src/api-client-machine/models/app-status.ts +47 -47
  155. package/src/api-client-machine/models/check-quota-limit-result.ts +36 -36
  156. package/src/api-client-machine/models/cluster-log.ts +54 -54
  157. package/src/api-client-machine/models/component-cluster-collection.ts +57 -57
  158. package/src/api-client-machine/models/component-cluster.ts +116 -116
  159. package/src/api-client-machine/models/create-component-machine-cluster-dto.ts +86 -86
  160. package/src/api-client-machine/models/create-sigma-machine-cluster-dto.ts +77 -77
  161. package/src/api-client-machine/models/create-vodroute-dto.ts +42 -42
  162. package/src/api-client-machine/models/decklink-collection.ts +57 -57
  163. package/src/api-client-machine/models/decklink.ts +42 -42
  164. package/src/api-client-machine/models/http-app.ts +45 -45
  165. package/src/api-client-machine/models/https-config.ts +42 -42
  166. package/src/api-client-machine/models/index.ts +67 -67
  167. package/src/api-client-machine/models/info-channel.ts +42 -42
  168. package/src/api-client-machine/models/ingest-app.ts +60 -60
  169. package/src/api-client-machine/models/ingest-config.ts +74 -74
  170. package/src/api-client-machine/models/ingest-update-config-dto.ts +68 -68
  171. package/src/api-client-machine/models/machine-cluster-collection.ts +57 -57
  172. package/src/api-client-machine/models/machine-cluster.ts +120 -120
  173. package/src/api-client-machine/models/machine-details-license.ts +42 -42
  174. package/src/api-client-machine/models/machine-details.ts +127 -127
  175. package/src/api-client-machine/models/machine-dto.ts +42 -42
  176. package/src/api-client-machine/models/machine-dump.ts +108 -108
  177. package/src/api-client-machine/models/machine.ts +42 -42
  178. package/src/api-client-machine/models/network-collection.ts +57 -57
  179. package/src/api-client-machine/models/network-interface.ts +36 -36
  180. package/src/api-client-machine/models/network.ts +66 -66
  181. package/src/api-client-machine/models/origin-config.ts +50 -50
  182. package/src/api-client-machine/models/origin-update-config-dto.ts +59 -59
  183. package/src/api-client-machine/models/packager-component-cluster.ts +42 -42
  184. package/src/api-client-machine/models/packager-live-cluster.ts +42 -42
  185. package/src/api-client-machine/models/packager-to-component-cluster.ts +51 -51
  186. package/src/api-client-machine/models/quotas-result.ts +30 -30
  187. package/src/api-client-machine/models/registration-config.ts +48 -48
  188. package/src/api-client-machine/models/sigma-cluster-ingest-config.ts +42 -42
  189. package/src/api-client-machine/models/sigma-cluster-origin-config.ts +30 -30
  190. package/src/api-client-machine/models/sigma-ingest-config-entity.ts +42 -42
  191. package/src/api-client-machine/models/sigma-ingest-config.ts +42 -42
  192. package/src/api-client-machine/models/sigma-origin-config-entity.ts +30 -30
  193. package/src/api-client-machine/models/sigma-origin-config.ts +30 -30
  194. package/src/api-client-machine/models/stats.ts +57 -57
  195. package/src/api-client-machine/models/status.ts +36 -36
  196. package/src/api-client-machine/models/stop-channel.ts +48 -48
  197. package/src/api-client-machine/models/transcoder-apps.ts +42 -42
  198. package/src/api-client-machine/models/transcoder-collection.ts +57 -57
  199. package/src/api-client-machine/models/transcoder-component-cluster.ts +42 -42
  200. package/src/api-client-machine/models/transcoder-license.ts +42 -42
  201. package/src/api-client-machine/models/transcoder-live-cluster.ts +42 -42
  202. package/src/api-client-machine/models/transcoder-live-to-component-cluster.ts +45 -45
  203. package/src/api-client-machine/models/transcoder-network.ts +42 -42
  204. package/src/api-client-machine/models/transcoder.ts +276 -276
  205. package/src/api-client-machine/models/update-app-config-dto-config-data.ts +33 -33
  206. package/src/api-client-machine/models/update-app-config-dto.ts +33 -33
  207. package/src/api-client-machine/models/update-app-config-of-sigma-vod-server-dto-config-data.ts +30 -30
  208. package/src/api-client-machine/models/update-app-config-of-sigma-vod-server-dto.ts +33 -33
  209. package/src/api-client-machine/models/update-component-cluster-dto.ts +72 -72
  210. package/src/api-client-machine/models/update-machine-cluster-dto.ts +63 -63
  211. package/src/api-client-machine/models/update-machine-dto.ts +42 -42
  212. package/src/api-client-machine/models/update-packager-live-cluster.ts +42 -42
  213. package/src/api-client-machine/models/update-packager-to-component-cluster.ts +51 -51
  214. package/src/api-client-machine/models/update-route-config-of-sigma-vod-server.ts +33 -33
  215. package/src/api-client-machine/models/update-route-config-sigma-machine.ts +42 -42
  216. package/src/api-client-machine/models/update-transcoder-live-cluster.ts +42 -42
  217. package/src/api-client-machine/models/update-transcoder-to-component-cluster.ts +45 -45
  218. package/src/api-client-machine/models/video-encoder.ts +56 -56
  219. package/src/api-client-machine/models/vodroute.ts +60 -60
  220. package/src/api-client-noti/.openapi-generator/FILES +13 -13
  221. package/src/api-client-noti/.openapi-generator-ignore +23 -23
  222. package/src/api-client-noti/api/notification-api.ts +386 -386
  223. package/src/api-client-noti/api.ts +18 -18
  224. package/src/api-client-noti/base.ts +72 -72
  225. package/src/api-client-noti/common.ts +150 -150
  226. package/src/api-client-noti/configuration.ts +101 -101
  227. package/src/api-client-noti/git_push.sh +57 -57
  228. package/src/api-client-noti/index.ts +18 -18
  229. package/src/api-client-noti/models/index.ts +2 -2
  230. package/src/api-client-noti/models/notification-collection.ts +57 -57
  231. package/src/api-client-noti/models/notification.ts +101 -101
  232. package/src/api-client-transcode/.openapi-generator/FILES +129 -129
  233. package/src/api-client-transcode/.openapi-generator-ignore +23 -23
  234. package/src/api-client-transcode/api/alert-logs-apiapi.ts +281 -281
  235. package/src/api-client-transcode/api/channel-package-inputs-apiapi.ts +650 -650
  236. package/src/api-client-transcode/api/channel-transcode-inputs-apiapi.ts +650 -650
  237. package/src/api-client-transcode/api/channels-crudapiapi.ts +869 -869
  238. package/src/api-client-transcode/api/channels-job-action-apiapi.ts +434 -434
  239. package/src/api-client-transcode/api/drm-credentials-api.ts +525 -525
  240. package/src/api-client-transcode/api/event-channel-action-apiapi.ts +363 -363
  241. package/src/api-client-transcode/api/event-channel-crudapiapi.ts +545 -545
  242. package/src/api-client-transcode/api/fast-channel-action-apiapi.ts +301 -301
  243. package/src/api-client-transcode/api/fast-channel-apiapi.ts +525 -525
  244. package/src/api-client-transcode/api/fast-channel-programs-api-api.ts +525 -525
  245. package/src/api-client-transcode/api/multi-channel-action-apiapi.ts +387 -387
  246. package/src/api-client-transcode/api/sigma-transcode-live-interactive-action-api.ts +152 -152
  247. package/src/api-client-transcode/api/single-channel-action-apiapi.ts +1155 -1155
  248. package/src/api-client-transcode/api/transcode-templates-apiapi.ts +541 -541
  249. package/src/api-client-transcode/api.ts +32 -32
  250. package/src/api-client-transcode/base.ts +71 -71
  251. package/src/api-client-transcode/common.ts +138 -138
  252. package/src/api-client-transcode/configuration.ts +101 -101
  253. package/src/api-client-transcode/git_push.sh +57 -57
  254. package/src/api-client-transcode/index.ts +18 -18
  255. package/src/api-client-transcode/models/ads-dto.ts +137 -137
  256. package/src/api-client-transcode/models/alert-log-collection.ts +55 -55
  257. package/src/api-client-transcode/models/audio-watermark-dto.ts +59 -59
  258. package/src/api-client-transcode/models/blackout-slate-dto.ts +36 -36
  259. package/src/api-client-transcode/models/catchup-dto.ts +43 -43
  260. package/src/api-client-transcode/models/channel-collection.ts +55 -55
  261. package/src/api-client-transcode/models/channel-config-advance-dto-info.ts +25 -25
  262. package/src/api-client-transcode/models/channel-config-advance-dto.ts +121 -121
  263. package/src/api-client-transcode/models/channel-config-advance-info-dto.ts +78 -78
  264. package/src/api-client-transcode/models/channel-config-base.ts +69 -69
  265. package/src/api-client-transcode/models/channel-config-blackout-entity.ts +36 -36
  266. package/src/api-client-transcode/models/channel-config-dto.ts +72 -72
  267. package/src/api-client-transcode/models/channel-config-interactive-entity.ts +30 -30
  268. package/src/api-client-transcode/models/channel-config-template-dto.ts +66 -66
  269. package/src/api-client-transcode/models/channel-detail-catchup-dto.ts +37 -37
  270. package/src/api-client-transcode/models/channel-detail-dto.ts +69 -69
  271. package/src/api-client-transcode/models/channel-detail-input.ts +43 -43
  272. package/src/api-client-transcode/models/channel-detail-package.ts +50 -50
  273. package/src/api-client-transcode/models/channel-detail-transcode.ts +37 -37
  274. package/src/api-client-transcode/models/channel-job-detail.ts +84 -84
  275. package/src/api-client-transcode/models/channel-stats.ts +36 -36
  276. package/src/api-client-transcode/models/channel-template-data-dto.ts +59 -59
  277. package/src/api-client-transcode/models/channel-template-dto-data.ts +28 -28
  278. package/src/api-client-transcode/models/channel-template-dto.ts +63 -63
  279. package/src/api-client-transcode/models/channel.ts +168 -168
  280. package/src/api-client-transcode/models/create-alert-log-dto.ts +138 -138
  281. package/src/api-client-transcode/models/create-channel-dto.ts +84 -84
  282. package/src/api-client-transcode/models/create-drm-credential-dto.ts +63 -63
  283. package/src/api-client-transcode/models/create-event-channel-dto-targets.ts +26 -26
  284. package/src/api-client-transcode/models/create-event-channel-dto.ts +76 -76
  285. package/src/api-client-transcode/models/create-fast-channel-dto.ts +42 -42
  286. package/src/api-client-transcode/models/create-fast-program-dto.ts +72 -72
  287. package/src/api-client-transcode/models/drm-credential-collection.ts +55 -55
  288. package/src/api-client-transcode/models/drm-credential-entity.ts +87 -87
  289. package/src/api-client-transcode/models/drm-data-dto.ts +54 -54
  290. package/src/api-client-transcode/models/drm-data-entity.ts +54 -54
  291. package/src/api-client-transcode/models/drm-dto.ts +103 -103
  292. package/src/api-client-transcode/models/event-channel-collection.ts +55 -55
  293. package/src/api-client-transcode/models/event-channel-config-dto.ts +78 -78
  294. package/src/api-client-transcode/models/event-channel-config-entity.ts +75 -75
  295. package/src/api-client-transcode/models/event-channel-input-dto.ts +45 -45
  296. package/src/api-client-transcode/models/event-channel-input-entity.ts +45 -45
  297. package/src/api-client-transcode/models/event-channel-transcoder-dto.ts +56 -56
  298. package/src/api-client-transcode/models/event-channel.ts +147 -147
  299. package/src/api-client-transcode/models/event-profile-dto.ts +62 -62
  300. package/src/api-client-transcode/models/event-target-data-dto.ts +95 -95
  301. package/src/api-client-transcode/models/event-target-dto.ts +49 -49
  302. package/src/api-client-transcode/models/fast-channel-collection.ts +55 -55
  303. package/src/api-client-transcode/models/fast-channel.ts +75 -75
  304. package/src/api-client-transcode/models/fast-program-collection.ts +55 -55
  305. package/src/api-client-transcode/models/fast-program.ts +84 -84
  306. package/src/api-client-transcode/models/fingerprint-dto.ts +42 -42
  307. package/src/api-client-transcode/models/index.ts +104 -104
  308. package/src/api-client-transcode/models/input-collection.ts +55 -55
  309. package/src/api-client-transcode/models/input-data-dto.ts +104 -104
  310. package/src/api-client-transcode/models/input-data-item-dto.ts +42 -42
  311. package/src/api-client-transcode/models/input-dto.ts +30 -30
  312. package/src/api-client-transcode/models/input-entity.ts +30 -30
  313. package/src/api-client-transcode/models/input-info-response.ts +31 -31
  314. package/src/api-client-transcode/models/input-info.ts +123 -123
  315. package/src/api-client-transcode/models/input-machine-config.ts +45 -45
  316. package/src/api-client-transcode/models/input-program.ts +66 -66
  317. package/src/api-client-transcode/models/interactive-dto.ts +30 -30
  318. package/src/api-client-transcode/models/interactive-publish-dto.ts +30 -30
  319. package/src/api-client-transcode/models/job-entity.ts +102 -102
  320. package/src/api-client-transcode/models/low-latency-dto.ts +68 -68
  321. package/src/api-client-transcode/models/machine-config-dto.ts +75 -75
  322. package/src/api-client-transcode/models/main-input-dto.ts +62 -62
  323. package/src/api-client-transcode/models/main-input-entity.ts +54 -54
  324. package/src/api-client-transcode/models/maintenance-dto.ts +30 -30
  325. package/src/api-client-transcode/models/manifest-dto.ts +62 -62
  326. package/src/api-client-transcode/models/package-input-collection.ts +55 -55
  327. package/src/api-client-transcode/models/package-input-data-dto.ts +99 -99
  328. package/src/api-client-transcode/models/package-input-list.ts +36 -36
  329. package/src/api-client-transcode/models/package-input.ts +115 -115
  330. package/src/api-client-transcode/models/post-input-dto.ts +48 -48
  331. package/src/api-client-transcode/models/post-input-entity.ts +48 -48
  332. package/src/api-client-transcode/models/pre-input-dto.ts +54 -54
  333. package/src/api-client-transcode/models/pre-input-entity.ts +54 -54
  334. package/src/api-client-transcode/models/preset-dto.ts +247 -247
  335. package/src/api-client-transcode/models/profile-default-response-dto.ts +30 -30
  336. package/src/api-client-transcode/models/profile-dto.ts +62 -62
  337. package/src/api-client-transcode/models/profile-entity.ts +60 -60
  338. package/src/api-client-transcode/models/scte35-dto.ts +36 -36
  339. package/src/api-client-transcode/models/start-over-dto.ts +30 -30
  340. package/src/api-client-transcode/models/switch-input-dto.ts +56 -56
  341. package/src/api-client-transcode/models/switch-input-entity.ts +44 -44
  342. package/src/api-client-transcode/models/target-data-dto.ts +101 -101
  343. package/src/api-client-transcode/models/target-dto.ts +44 -44
  344. package/src/api-client-transcode/models/target-entity.ts +55 -55
  345. package/src/api-client-transcode/models/target-profile-dto.ts +71 -71
  346. package/src/api-client-transcode/models/target-profile.ts +71 -71
  347. package/src/api-client-transcode/models/target-template-dto.ts +44 -44
  348. package/src/api-client-transcode/models/target-update-dto.ts +50 -50
  349. package/src/api-client-transcode/models/transcode-input.ts +144 -144
  350. package/src/api-client-transcode/models/transcoder.ts +36 -36
  351. package/src/api-client-transcode/models/trick-play-dto.ts +54 -54
  352. package/src/api-client-transcode/models/update-channel-dto-targets.ts +27 -27
  353. package/src/api-client-transcode/models/update-channel-dto.ts +84 -84
  354. package/src/api-client-transcode/models/update-drm-management-dto.ts +63 -63
  355. package/src/api-client-transcode/models/update-event-channel-dto.ts +76 -76
  356. package/src/api-client-transcode/models/update-fast-channel-dto.ts +42 -42
  357. package/src/api-client-transcode/models/update-fast-program-dto.ts +30 -30
  358. package/src/api-client-transcode/models/watermark-dto.ts +66 -66
  359. package/src/api-client-transcode/models/watermark-entity.ts +102 -102
  360. package/src/app/spa-loading-template.html +127 -127
  361. package/src/app.config.ts +2 -2
  362. package/src/assets/global.css.ts +3 -3
  363. package/src/assets/scss/element/dark.scss +13 -13
  364. package/src/assets/scss/element/index.scss +26 -26
  365. package/src/assets/scss/index.scss +180 -180
  366. package/src/components/AdvancedFilter/SSAdvancedFilterItem.vue +180 -180
  367. package/src/components/AdvancedFilter/SSAdvancedFilterItemCustom.vue +165 -165
  368. package/src/components/AdvancedFilter/SSAdvancedFilterItemDefined.vue +298 -298
  369. package/src/components/AdvancedFilter/SSAdvancedFilterItemSchedule.vue +293 -293
  370. package/src/components/AdvancedFilter/SSAdvancedFilterMain.vue +196 -196
  371. package/src/components/AdvancedFilter/types.ts +37 -37
  372. package/src/components/AdvancedFilterReport/SSAdvancedFilterReportItem.vue +110 -110
  373. package/src/components/AdvancedFilterReport/SSAdvancedFilterReportItemDefined.vue +159 -159
  374. package/src/components/AdvancedFilterReport/SSAdvancedFilterReportMain.vue +197 -197
  375. package/src/components/AdvancedFilterReport/types.ts +19 -19
  376. package/src/components/AdvancedFilterSsai/SSAdvancedFilterSsaiItem.vue +102 -102
  377. package/src/components/AdvancedFilterSsai/SSAdvancedFilterSsaiItemDefined.vue +119 -119
  378. package/src/components/AdvancedFilterSsai/SSAdvancedFilterSsaiMain.vue +194 -194
  379. package/src/components/AdvancedFilterSsai/types.ts +19 -19
  380. package/src/components/Asset/AssetAddPlaylist.vue +169 -169
  381. package/src/components/Asset/AssetExtra.vue +46 -46
  382. package/src/components/Asset/AssetImportLinks.vue +281 -281
  383. package/src/components/Asset/AssetInfiniteSelect.vue +62 -62
  384. package/src/components/Asset/AssetItem.vue +194 -194
  385. package/src/components/Asset/AssetItemPreview.vue +117 -117
  386. package/src/components/Asset/AssetList.vue +869 -869
  387. package/src/components/Asset/AssetMeta.vue +97 -97
  388. package/src/components/Asset/AssetPicker.vue +204 -204
  389. package/src/components/Asset/AssetPlaylist.vue +414 -414
  390. package/src/components/Asset/AssetPlaylistInfiniteSelect.vue +136 -136
  391. package/src/components/Asset/AssetPlaylistModalAdd.vue +138 -138
  392. package/src/components/Asset/AssetPreview.vue +89 -89
  393. package/src/components/Asset/AssetShareModal.vue +131 -131
  394. package/src/components/Asset/AssetTable.vue +365 -365
  395. package/src/components/Asset/FormUploadAsset.vue +647 -647
  396. package/src/components/Asset/FormUploadAssetItem.vue +115 -115
  397. package/src/components/Asset/FormUploadAssetProgress.vue +161 -161
  398. package/src/components/Asset/Scrubber.vue +57 -57
  399. package/src/components/Asset/VideoPlayer.vue +226 -226
  400. package/src/components/Asset/VideoPreview.vue +102 -102
  401. package/src/components/Asset/VideoPreviewConfig.vue +329 -329
  402. package/src/components/Asset/VideoPreviewConfigMessage.vue +120 -120
  403. package/src/components/Asset/VideoPreviewConfigVod.vue +287 -287
  404. package/src/components/Asset/VideoPreviewNew.vue +66 -66
  405. package/src/components/Asset/VideoPreviewNewLoader.vue +144 -144
  406. package/src/components/Asset/VideoPreviewWrapper.vue +208 -208
  407. package/src/components/Asset/asset-context.ts +24 -24
  408. package/src/components/Asset/usePickerStore.ts +55 -55
  409. package/src/components/AuthLayout/AuthLayoutSimple.vue +150 -150
  410. package/src/components/AuthLayout/index.vue +151 -151
  411. package/src/components/AutoRefresh/AutoRefresh.vue +91 -91
  412. package/src/components/AutoRefresh/AutoRefreshOld.vue +87 -87
  413. package/src/components/AutoRefresh/useRefresh.ts +93 -93
  414. package/src/components/BackButton.vue +13 -13
  415. package/src/components/Card/CardInfo.vue +21 -21
  416. package/src/components/Channel/AIConfig.vue +101 -101
  417. package/src/components/Channel/AdvancedForm.vue +542 -542
  418. package/src/components/Channel/ChannelListGrid.vue +154 -154
  419. package/src/components/Channel/ConfigBlackout.vue +98 -98
  420. package/src/components/Channel/ConfigCensorship.vue +387 -387
  421. package/src/components/Channel/ConfigForensicWatermark.vue +152 -152
  422. package/src/components/Channel/ConfigForm.vue +102 -102
  423. package/src/components/Channel/ConfigInformation.vue +191 -191
  424. package/src/components/Channel/ConfigInteraction.vue +11 -11
  425. package/src/components/Channel/ConfigNameModifier.vue +15 -15
  426. package/src/components/Channel/ConfigOptionItem.vue +114 -114
  427. package/src/components/Channel/ConfigOptions.vue +181 -181
  428. package/src/components/Channel/ConfigPte.vue +368 -368
  429. package/src/components/Channel/ConfigScte.vue +442 -442
  430. package/src/components/Channel/ConfigTranscoder.vue +353 -353
  431. package/src/components/Channel/ConfigWaterMarkAudio.vue +52 -52
  432. package/src/components/Channel/ConfigWatermark.vue +76 -76
  433. package/src/components/Channel/ConfigWatermarkEventChannel.vue +86 -86
  434. package/src/components/Channel/ConfigWatermarkItem.vue +239 -239
  435. package/src/components/Channel/HeaderItem.vue +75 -75
  436. package/src/components/Channel/InputDetail.vue +68 -68
  437. package/src/components/Channel/InputForm.vue +175 -175
  438. package/src/components/Channel/InputList.vue +38 -38
  439. package/src/components/Channel/InputPackageDetail.vue +125 -125
  440. package/src/components/Channel/MediaProfileFormModal.vue +79 -79
  441. package/src/components/Channel/MediaProfileModify.vue +229 -229
  442. package/src/components/Channel/MessageButtonGetHelp.vue +30 -30
  443. package/src/components/Channel/MessageTooltipAi.vue +29 -29
  444. package/src/components/Channel/MultipleSelectProfile.vue +312 -312
  445. package/src/components/Channel/PackageInputItem.vue +13 -13
  446. package/src/components/Channel/PresetConfigItem.vue +1957 -1957
  447. package/src/components/Channel/PresetConfigItemExtra.vue +59 -59
  448. package/src/components/Channel/PresetConfigItemPId.vue +145 -145
  449. package/src/components/Channel/ProfileConfigItem.vue +829 -829
  450. package/src/components/Channel/ProfileDetailsList.vue +160 -160
  451. package/src/components/Channel/ProfileForm.vue +134 -134
  452. package/src/components/Channel/ProfileList.vue +228 -228
  453. package/src/components/Channel/SelectServer.vue +134 -134
  454. package/src/components/Channel/SignalLoss.vue +92 -92
  455. package/src/components/Channel/SwitchInputButton.vue +38 -38
  456. package/src/components/Channel/TargetCatchup.vue +75 -75
  457. package/src/components/Channel/TargetDataInfo.vue +100 -100
  458. package/src/components/Channel/TargetDestination.vue +375 -375
  459. package/src/components/Channel/TargetDrm.vue +518 -518
  460. package/src/components/Channel/TargetForm.vue +136 -136
  461. package/src/components/Channel/TargetList.vue +159 -159
  462. package/src/components/Channel/TargetLowLatency.vue +107 -107
  463. package/src/components/Channel/TargetMabrOutput.vue +58 -58
  464. package/src/components/Channel/TargetMabrOutputItem.vue +91 -91
  465. package/src/components/Channel/TargetManifest.vue +94 -94
  466. package/src/components/Channel/TargetNetworkInterface.vue +95 -95
  467. package/src/components/Channel/TargetOutputMultiplex.vue +237 -237
  468. package/src/components/Channel/TargetOutputType.vue +201 -201
  469. package/src/components/Channel/TargetOutputUdp.vue +200 -200
  470. package/src/components/Channel/TargetPreset.vue +541 -541
  471. package/src/components/Channel/TargetProfileAudioGroup.vue +27 -27
  472. package/src/components/Channel/TargetProfileProgram.vue +43 -43
  473. package/src/components/Channel/TargetProfileURI.vue +68 -68
  474. package/src/components/Channel/TargetSrtOutput.vue +35 -35
  475. package/src/components/Channel/TargetSrtOutputItem.vue +83 -83
  476. package/src/components/Channel/TargetStartover.vue +40 -40
  477. package/src/components/Channel/WarningName.vue +39 -39
  478. package/src/components/Channel/WarningOutput.vue +40 -40
  479. package/src/components/CollapseTagsTooltip/CollapseTagsTooltip.vue +87 -87
  480. package/src/components/CollapseTagsTooltip/index.ts +1 -1
  481. package/src/components/CopyButton.vue +46 -46
  482. package/src/components/CopyText.vue +40 -40
  483. package/src/components/CopyTextButton.vue +40 -40
  484. package/src/components/DefaultLayout/DefaultLayout.vue +134 -134
  485. package/src/components/DefaultLayout/GlobalASide.vue +75 -75
  486. package/src/components/DefaultLayout/GlobalFooter.vue +15 -15
  487. package/src/components/DefaultLayout/GlobalHeader.vue +43 -43
  488. package/src/components/DefaultLayout/Logo.vue +35 -35
  489. package/src/components/DefaultLayout/Menu.vue +464 -464
  490. package/src/components/DefaultLayout/RightMenu.vue +93 -93
  491. package/src/components/DialogWarningAddLicense.vue +37 -37
  492. package/src/components/Epg/Epg.vue +24 -24
  493. package/src/components/Epg/components/Channel.vue +28 -28
  494. package/src/components/Epg/components/Channels.vue +33 -33
  495. package/src/components/Epg/components/Layout.vue +121 -121
  496. package/src/components/Epg/components/Line.vue +41 -41
  497. package/src/components/Epg/components/Loader.vue +23 -23
  498. package/src/components/Epg/components/Program.vue +101 -101
  499. package/src/components/Epg/components/SideBar.vue +18 -18
  500. package/src/components/Epg/components/Timeline.vue +72 -72
  501. package/src/components/Epg/helpers/common.ts +68 -68
  502. package/src/components/Epg/helpers/epg.ts +192 -192
  503. package/src/components/Epg/helpers/index.ts +5 -5
  504. package/src/components/Epg/helpers/interfaces.ts +54 -54
  505. package/src/components/Epg/helpers/time.ts +51 -51
  506. package/src/components/Epg/helpers/types.ts +26 -26
  507. package/src/components/Epg/helpers/variables.ts +33 -33
  508. package/src/components/Epg/hooks/index.ts +2 -2
  509. package/src/components/Epg/hooks/useEpg.ts +160 -160
  510. package/src/components/Epg/hooks/useLayout.ts +187 -187
  511. package/src/components/Epg/hooks/useProgram.ts +63 -63
  512. package/src/components/Epg/hooks/useTimeline.ts +35 -35
  513. package/src/components/Epg/index.ts +4 -4
  514. package/src/components/Epg/store.ts +85 -85
  515. package/src/components/Epg/theme.ts +44 -44
  516. package/src/components/Exception/403.vue +58 -58
  517. package/src/components/Exception/404.vue +59 -59
  518. package/src/components/Exception/500.vue +39 -39
  519. package/src/components/Exception/index.scss +30 -30
  520. package/src/components/Field.vue +193 -193
  521. package/src/components/FilterQuerySchema/FilterQuerySchemaForm.vue +200 -200
  522. package/src/components/FilterQuerySchema/QueryTag.vue +109 -109
  523. package/src/components/FilterQuerySchema/Tag.vue +68 -68
  524. package/src/components/FilterTimeDimensions.vue +265 -265
  525. package/src/components/FilterTimeDimensionsSingle.vue +214 -214
  526. package/src/components/HelpPanel.vue +87 -87
  527. package/src/components/HexagonPro.vue +7 -7
  528. package/src/components/IconCopyButton.vue +43 -43
  529. package/src/components/InformationLabel.vue +67 -67
  530. package/src/components/Input/InputTags.vue +136 -136
  531. package/src/components/Input/index.ts +1 -1
  532. package/src/components/MainDefaultLayout/index.vue +120 -120
  533. package/src/components/NoticeAddLicense.vue +20 -20
  534. package/src/components/NoticeRunningOutResources.vue +20 -20
  535. package/src/components/Pagination.vue +61 -61
  536. package/src/components/QueryBuilder/components/inputs/DateInputField.vue +105 -105
  537. package/src/components/QueryBuilder/components/inputs/FieldSelect.vue +44 -44
  538. package/src/components/QueryBuilder/components/inputs/InputMultiSelect.vue +60 -60
  539. package/src/components/QueryBuilder/components/inputs/InputSelect.vue +39 -39
  540. package/src/components/QueryBuilder/components/inputs/NumberInputField.vue +91 -91
  541. package/src/components/QueryBuilder/components/inputs/OperatorSelect.vue +59 -59
  542. package/src/components/QueryBuilder/components/inputs/TextInput.vue +40 -40
  543. package/src/components/QueryBuilder/components/inputs/TimeInputField.vue +114 -114
  544. package/src/components/QueryBuilder/components/inputs/logics.ts +27 -27
  545. package/src/components/QueryBuilder/components/item/InputMultiOptions.vue +56 -56
  546. package/src/components/QueryBuilder/components/item/QueryRule.vue +233 -233
  547. package/src/components/QueryBuilder/useConfigStore.ts +27 -27
  548. package/src/components/QueryBuilder/utils/config.ts +194 -194
  549. package/src/components/QueryBuilder/utils/rules.ts +213 -213
  550. package/src/components/RecommendedConfigurationPTE.vue +238 -238
  551. package/src/components/Server/MachineConfig.vue +333 -333
  552. package/src/components/Server/ServerConfig.vue +599 -599
  553. package/src/components/Server/useQueryMachine.ts +380 -380
  554. package/src/components/Server/validator.ts +13 -13
  555. package/src/components/SwitchDark.vue +19 -19
  556. package/src/components/SwitchLang.vue +31 -31
  557. package/src/components/TableEmpty.vue +50 -50
  558. package/src/components/Toast/ToastNoti.vue +52 -52
  559. package/src/components/Tool/ForensicWatermarkingDialog.vue +39 -39
  560. package/src/components/Tool/FormRecord.vue +162 -162
  561. package/src/components/Tool/FormUpload.vue +118 -118
  562. package/src/components/Tool/ResultChecking.vue +103 -103
  563. package/src/components/Tool/Watermarking.vue +159 -159
  564. package/src/components/Tool/record.js +92 -92
  565. package/src/components/Tooltip/Ellipsis.vue +52 -52
  566. package/src/components/Tooltip/index.vue +47 -47
  567. package/src/components/app/AppList.vue +50 -50
  568. package/src/components/button/Button.vue +27 -27
  569. package/src/components/button/index.ts +37 -37
  570. package/src/components/context-menu/ContextMenu.vue +15 -15
  571. package/src/components/context-menu/ContextMenuCheckboxItem.vue +39 -39
  572. package/src/components/context-menu/ContextMenuContent.vue +35 -35
  573. package/src/components/context-menu/ContextMenuGroup.vue +11 -11
  574. package/src/components/context-menu/ContextMenuItem.vue +33 -33
  575. package/src/components/context-menu/ContextMenuLabel.vue +24 -24
  576. package/src/components/context-menu/ContextMenuPortal.vue +11 -11
  577. package/src/components/context-menu/ContextMenuRadioGroup.vue +19 -19
  578. package/src/components/context-menu/ContextMenuRadioItem.vue +39 -39
  579. package/src/components/context-menu/ContextMenuSeparator.vue +19 -19
  580. package/src/components/context-menu/ContextMenuShortcut.vue +13 -13
  581. package/src/components/context-menu/ContextMenuSub.vue +19 -19
  582. package/src/components/context-menu/ContextMenuSubContent.vue +34 -34
  583. package/src/components/context-menu/ContextMenuSubTrigger.vue +33 -33
  584. package/src/components/context-menu/ContextMenuTrigger.vue +13 -13
  585. package/src/components/context-menu/index.ts +14 -14
  586. package/src/components/dashboard/SSDashboard.vue +82 -0
  587. package/src/components/dashboard/SSDashboardChartRoot.vue +18 -18
  588. package/src/components/dashboard/SSDashboardDocument.vue +45 -45
  589. package/src/components/dashboard/SSDashboardEmpty.vue +16 -16
  590. package/src/components/dashboard/SSDashboardGuideline.vue +45 -45
  591. package/src/components/dashboard/SSDashboardInfo.vue +36 -36
  592. package/src/components/dashboard/SSDashboardInfoRoot.vue +9 -9
  593. package/src/components/dashboard/SSDashboardInfoTime.vue +38 -38
  594. package/src/components/markdown/Markdown.vue +295 -295
  595. package/src/components/tabs/Tabs.vue +15 -15
  596. package/src/components/tabs/TabsContent.vue +22 -22
  597. package/src/components/tabs/TabsList.vue +22 -22
  598. package/src/components/tabs/TabsTrigger.vue +26 -26
  599. package/src/composables/asset.ts +13 -13
  600. package/src/composables/channel.ts +333 -333
  601. package/src/composables/country.ts +788 -788
  602. package/src/composables/error.ts +24 -24
  603. package/src/composables/form.ts +351 -351
  604. package/src/composables/getBuildTime.ts +7 -7
  605. package/src/composables/micro.ts +113 -113
  606. package/src/composables/microState.ts +22 -22
  607. package/src/composables/notiGlobal.ts +18 -18
  608. package/src/composables/plan.ts +162 -162
  609. package/src/composables/refReset.ts +12 -12
  610. package/src/composables/resetInfiniteQueryPagination.ts +18 -18
  611. package/src/composables/route.ts +19 -19
  612. package/src/composables/toast.ts +21 -21
  613. package/src/composables/useApp.ts +6 -6
  614. package/src/composables/useAsyncSchema.ts +58 -58
  615. package/src/composables/useChannelActions.ts +151 -151
  616. package/src/composables/useComplexSearchParam.ts +293 -293
  617. package/src/composables/useFilterSchema.ts +105 -105
  618. package/src/composables/useGetInputDetail.ts +36 -36
  619. package/src/composables/useGetServerAddLicense.ts +21 -21
  620. package/src/composables/useJobPreview.ts +438 -438
  621. package/src/composables/useLayoutStore.ts +106 -106
  622. package/src/composables/usePermission.ts +5 -5
  623. package/src/composables/usePickerStore.ts +53 -53
  624. package/src/composables/useQueryAssets.ts +56 -56
  625. package/src/composables/useQueryParams.ts +20 -20
  626. package/src/composables/useRouteParams.ts +36 -36
  627. package/src/composables/useRouteQueries.ts +54 -54
  628. package/src/composables/useRouterHistory.ts +76 -76
  629. package/src/composables/useSearchQuery.ts +27 -27
  630. package/src/composables/useTooltipEllipsis.ts +12 -12
  631. package/src/constants/env.ts +12 -12
  632. package/src/constants/filterable.ts +32 -32
  633. package/src/constants/languageCode.ts +185 -185
  634. package/src/constants/micro.ts +1 -1
  635. package/src/constants/queryKeys.ts +11 -11
  636. package/src/constants/regex.ts +8 -8
  637. package/src/constants/storage.ts +42 -42
  638. package/src/enums/index.ts +24 -24
  639. package/src/layouts/empty.vue +7 -7
  640. package/src/modules/api-party/kit.ts +30 -30
  641. package/src/modules/api-party/module.ts +259 -259
  642. package/src/modules/api-party/openapi.ts +74 -74
  643. package/src/modules/api-party/runtime/composables/$api.ts +157 -157
  644. package/src/modules/api-party/runtime/composables/useApiData.ts +229 -229
  645. package/src/modules/api-party/runtime/constants.ts +1 -1
  646. package/src/modules/api-party/runtime/formData.ts +85 -85
  647. package/src/modules/api-party/runtime/server/$api.ts +29 -29
  648. package/src/modules/api-party/runtime/server/handler.ts +92 -92
  649. package/src/modules/api-party/runtime/types.ts +97 -97
  650. package/src/modules/api-party/runtime/utils.ts +43 -43
  651. package/src/pages/403.vue +11 -11
  652. package/src/pages/500.vue +11 -11
  653. package/src/pages/[...all].vue +11 -11
  654. package/src/pages/login.vue +67 -67
  655. package/src/plugins/auth.ts +10 -10
  656. package/src/plugins/build-time.ts +5 -5
  657. package/src/plugins/dayjs.ts +13 -13
  658. package/src/plugins/i18n.ts +6 -6
  659. package/src/plugins/router.ts +6 -6
  660. package/src/plugins/vue-json-pretty.ts +5 -5
  661. package/src/plugins/vue-query.ts +41 -41
  662. package/src/plugins/wujie.ts +19 -19
  663. package/src/public/audio-recorder.js +30 -30
  664. package/src/public/nuxt.svg +3 -3
  665. package/src/public/robots.txt +2 -2
  666. package/src/pwa/config.ts +61 -61
  667. package/src/pwa/index.ts +194 -194
  668. package/src/pwa/runtime/VitePwaManifest.ts +33 -33
  669. package/src/pwa/types.ts +56 -56
  670. package/src/pwa/utils.ts +16 -16
  671. package/src/schemas/authServiceApi.json +6708 -6708
  672. package/src/schemas/billingApi.json +1082 -1082
  673. package/src/schemas/chatApi.json +496 -496
  674. package/src/schemas/libraryApi.json +2008 -2008
  675. package/src/schemas/licenseApi.json +771 -771
  676. package/src/schemas/livestreamApi.json +3353 -3353
  677. package/src/schemas/lrmApi.json +2847 -2847
  678. package/src/schemas/machineApi.json +4603 -4603
  679. package/src/schemas/metricApi.json +140 -140
  680. package/src/schemas/playoutApi.json +8314 -8314
  681. package/src/schemas/ssaiApi.json +1107 -1107
  682. package/src/schemas/transcodeApi.json +9669 -9669
  683. package/src/schemas/vastControlApi.json +960 -960
  684. package/src/schemas/vodApi.json +3973 -3973
  685. package/src/server/plugins/loading.css +111 -111
  686. package/src/server/plugins/loading.html +12 -12
  687. package/src/server/plugins/loading.ts +134 -134
  688. package/src/templates/pwa.client.ts +135 -135
  689. package/src/utils/$apiOptions.ts +80 -80
  690. package/src/utils/app.ts +23 -23
  691. package/src/utils/cn.ts +3 -3
  692. package/src/utils/env.ts +11 -11
  693. package/src/utils/filterable.ts +32 -32
  694. package/src/utils/format.ts +88 -88
  695. package/src/utils/gen-routes.ts +100 -100
  696. package/src/utils/helper.ts +56 -56
  697. package/src/utils/languageCode.ts +185 -185
  698. package/src/utils/micro.ts +208 -208
  699. package/src/utils/popoverSelectAttrs.ts +24 -24
  700. package/src/utils/popup.ts +96 -96
  701. package/src/utils/pwa.ts +86 -86
  702. package/src/utils/query-filter.ts +111 -111
  703. package/src/utils/queryKeys.ts +11 -11
  704. package/src/utils/regex.ts +8 -8
  705. package/src/utils/storage.ts +42 -42
  706. package/src/utils/table.ts +35 -35
  707. package/src/utils/tryCatch.ts +25 -25
  708. package/src/utils/utils.ts +58 -58
  709. package/src/utils/validator.ts +185 -185
  710. package/src/utils/videojs.ts +490 -490
  711. package/src/utils/wujie.ts +1 -1
  712. package/tsconfig.json +3 -3
  713. package/uno.config.ts +375 -375
  714. package/src/public/build-time.json +0 -1
@@ -1,647 +1,647 @@
1
- <script setup lang="ts">
2
- import axios from 'axios'
3
- import * as R from 'remeda'
4
- import MediaInfo from 'mediainfo.js'
5
- import FormUploadAssetProgress from './FormUploadAssetProgress.vue'
6
-
7
- const props = withDefaults(
8
- defineProps<{ limit?: string[] }>(),
9
- {
10
- limit: () => ['image', 'video', 'audio'],
11
- },
12
- )
13
-
14
- const emit = defineEmits<{
15
- (e: 'uploadSuccess', assetId: string): void
16
- }>()
17
-
18
- const { modelValue: visible } = defineModels<{
19
- modelValue: boolean
20
- }>()
21
-
22
- function getInitialValues() {
23
- return {
24
- playlistIds: [],
25
- tags: [],
26
- category: 'Promo Video',
27
- expire: null,
28
- files: [],
29
- name: '',
30
- }
31
- }
32
-
33
- const { assetDomain } = usePickerStore()
34
- const { t } = useI18n()
35
- const qc = useQueryClient()
36
- const isDisabled = ref(false)
37
-
38
- const enableAdd = ref(false)
39
- const SPECIAL_CHARACTERS_NAME_SPACE = /[`!@#$%^&*()+=[\]{};':"\\|,.<>/?~]/
40
- const CONTAIN_NAME_SPACE = /^[\w -]*$/
41
- function validNamePlaylist(value) {
42
- if (!value.trim()) {
43
- ElMessage.error($t('base.cannot_contain_all_space', { name: 'Name Playlist' }))
44
- return false
45
- }
46
- else if (SPECIAL_CHARACTERS_NAME_SPACE.test(value)) {
47
- ElMessage.error($t('base.name_can_not_special_characters', { name: 'Name Playlist' }))
48
- return false
49
- }
50
- else if (!CONTAIN_NAME_SPACE.test(value)) {
51
- ElMessage.error($t('base.name_cannot_contain_accented_characters', { name: 'Name Playlist' }))
52
- return false
53
- }
54
- else {
55
- return true
56
- }
57
- }
58
- function checkPlaylists(lists) {
59
- return !lists.some(value => !validNamePlaylist(value))
60
- }
61
- const { formRef, formValue, handleSubmit, handleValidate, isError, register, registerArray } = useElForm({
62
- initialValues: getInitialValues(),
63
- async onSubmit(values) {
64
- enableAdd.value = checkPlaylists(values.playlistIds)
65
- if (enableAdd.value) {
66
- isDisabled.value = true
67
- setTimeout(() => {
68
- showProgress()
69
- visible.value = false
70
- }, 1000)
71
- clearErrorFiles()
72
-
73
- const promises = values.files.map((item, index) => startUpload({
74
- ...item,
75
- playlistIds: values.playlistIds,
76
- tags: values.tags,
77
- category: values.category,
78
- expire: values.expire ? values.expire * 24 * 60 * 60 : null,
79
- }, item.id))
80
-
81
- const res = await Promise.all(promises)
82
- const successLength = res.filter(item => Boolean(item)).length
83
- qc.invalidateQueries(['api/library/assets'])
84
- formValue.value = getInitialValues()
85
-
86
- if (successLength) {
87
- ElMessage.success(t('message.success'))
88
- }
89
-
90
- isDisabled.value = false
91
- }
92
- },
93
- })
94
- const analyzing = ref(false)
95
-
96
- function getProp(path: string) {
97
- return path
98
- }
99
- const [playlistIdsValue, playlistIdsAttrs] = register<string[]>(getProp('playlistIds'), [])
100
- const [tagValue, tagAttrs] = register<string[]>(getProp('tags'), [
101
- {
102
- trigger: ['blur', 'change'],
103
- validator: tagValidator(35),
104
- },
105
- ])
106
- const [categoryValue, categoryAttrs] = register<string[]>(getProp('category'), [])
107
- const [expireDateValue, expireDateAttrs] = register<number>(getProp('expire'), [])
108
-
109
- const [filesValue, filesAttrs, { add, remove, addFirst }] = registerArray<{
110
- name: string
111
- file: File
112
- error: string | boolean
113
- }>(getProp('files'), [])
114
-
115
- function clearErrorFiles() {
116
- filesValue.value = filesValue.value.filter(file => !file.error)
117
- }
118
-
119
- const { files, open, reset: resetFiles } = useFileDialog({
120
- accept: '.png, .jpg, .mp3, .mp4, .wav',
121
- })
122
-
123
- const { ignoreUpdates } = watchIgnorable(files, () => {
124
- handleDropFiles(files.value)
125
- })
126
-
127
- async function handleDropFiles(files: FileList | null) {
128
- if (!files)
129
- return
130
-
131
- const limitFiles = 100
132
- let i = 0
133
- for (const file of files) {
134
- i++
135
- if (i > limitFiles) {
136
- ElMessage.warning(t('base_library.maximum_files_per_upload_is_100_files'))
137
- break
138
- }
139
- const error = await validateFiles(file)
140
- const payload = {
141
- file,
142
- error,
143
- name: file.name,
144
- percentage: 0,
145
- controller: new AbortController(),
146
- aborted: false,
147
- }
148
- if (!error) {
149
- addFirst(payload)
150
- }
151
- else {
152
- add(payload)
153
- }
154
- }
155
-
156
- ignoreUpdates(() => {
157
- resetFiles()
158
- })
159
- // reset file input
160
- }
161
-
162
- function onDrop(_files: FileList | null) {
163
- handleDropFiles(_files)
164
- ignoreUpdates(() => {
165
- files.value = _files
166
- })
167
- }
168
-
169
- const dropZoneRef = ref<HTMLElement>()
170
- const { isOverDropZone } = useDropZone(dropZoneRef, onDrop)
171
-
172
- async function validateFiles(file: File) {
173
- analyzing.value = true
174
- const mediainfo = await MediaInfo({
175
- locateFile: () => {
176
- // HARD Code media info wasm path
177
- return 'https://resource-ott.gviet.vn/sdk/assets/MediaInfoModule.wasm'
178
- },
179
- })
180
-
181
- const readChunk = file => (chunkSize, offset) =>
182
- new Promise((resolve, reject) => {
183
- const reader = new FileReader()
184
- reader.onload = (event) => {
185
- if (event.target.error)
186
- reject(event.target.error)
187
-
188
- resolve(new Uint8Array(event.target.result))
189
- }
190
- reader.readAsArrayBuffer(file.slice(offset, offset + chunkSize))
191
- })
192
-
193
- const result = await mediainfo.analyzeData(() => file?.size, readChunk(file))
194
- analyzing.value = false
195
-
196
- let type = result.media.track.find(track => track['@type'] !== 'General')
197
- // Video | Image | Audio
198
- if (!type) {
199
- return t('validate.file.unknown')
200
- }
201
-
202
- type = type['@type'].toLowerCase()
203
-
204
- if (!props.limit.includes(type)) {
205
- return t('validate.file.unknown')
206
- }
207
-
208
- const fileSize = file.size! / (1024 * 1024) // MB
209
-
210
- const sizeErrorMsg = {
211
- video: t('validate.file.size.video'),
212
- image: t('validate.file.size.image'),
213
- audio: t('validate.file.size.audio'),
214
- }
215
-
216
- const sizeLimit = {
217
- video: 100 * 1024,
218
- image: 1024,
219
- audio: 100,
220
- }
221
- if (!sizeLimit[type]) {
222
- return t('validate.file.unknown')
223
- }
224
-
225
- if (fileSize > sizeLimit[type]) {
226
- return sizeErrorMsg[type]
227
- }
228
- // everything is ok
229
-
230
- return false
231
- }
232
-
233
- const isLoading = ref(false)
234
-
235
- function updatePercentageFiles(id: string, percentage: number) {
236
- const index = filesValue.value.findIndex(file => file.id === id)
237
- if (index !== -1) {
238
- filesValue.value[index].percentage = percentage
239
- }
240
- }
241
-
242
- async function startUpload(item: any, id: string) {
243
- try {
244
- isLoading.value = true
245
- const data = await $libraryApi('api/library/assets/create-multipart-upload', {
246
- method: 'POST',
247
- body: {
248
- name: item.name,
249
- tags: item.tags,
250
- originFileName: item.file.name,
251
- category: item.category,
252
- playlistIds: item.playlistIds,
253
- expire: item.expire,
254
- },
255
- headers: {
256
- noLoading: true,
257
- },
258
- })
259
-
260
- const { assetId, uploadId } = data
261
- const index = filesValue.value.findIndex(file => file.id === id)
262
- if (index !== -1) {
263
- filesValue.value[index].assetId = assetId
264
- }
265
-
266
- const res = await uploadMultipartFile(assetId, uploadId, item, id)
267
- return res
268
- }
269
- catch (err) {
270
- console.log('[LOG] ~ err:', err)
271
- }
272
- finally {
273
- isLoading.value = false
274
- }
275
- }
276
-
277
- async function uploadMultipartFile(assetId: string, uploadId: string, item: any, itemId: string) {
278
- try {
279
- const FILE_CHUNK_SIZE = 10000000 // 10MB
280
- const fileSize = item.file.size
281
- const NUM_CHUNKS = Math.floor(fileSize / FILE_CHUNK_SIZE) + 1
282
- const promisesArray = []
283
- let start, end, blob
284
- for (let index = 1; index < NUM_CHUNKS + 1; index++) {
285
- start = (index - 1) * FILE_CHUNK_SIZE
286
- end = index * FILE_CHUNK_SIZE
287
- blob
288
- = index < NUM_CHUNKS
289
- ? item.file.slice(start, end)
290
- : item.file.slice(start)
291
-
292
- // Generate presigned URL for each part
293
- const getUploadUrlResp = await $libraryApi('api/library/assets/presign-multipart-upload-url', {
294
- method: 'POST',
295
- body: {
296
- assetId,
297
- partNumber: index,
298
- uploadId,
299
- },
300
- headers: {
301
- noLoading: true,
302
- noNotify: true,
303
- },
304
- signal: item.controller.signal,
305
- })
306
-
307
- const { preSignUrl } = getUploadUrlResp
308
-
309
- const preSignUrlWithHost = getAssetURI(preSignUrl, `${ensureSuffix('/', assetDomain.value)}`)
310
-
311
- // Puts each file part into the storage server
312
- const uploadResp = await axios.put(preSignUrlWithHost, blob, {
313
- signal: item.controller.signal,
314
- })
315
-
316
- updatePercentageFiles(itemId, 25 + Math.floor((index / NUM_CHUNKS) * 50))
317
- promisesArray.push(uploadResp)
318
- }
319
-
320
- const resolvedArray = await Promise.all(promisesArray)
321
- const uploadPartsArray: any[] = []
322
- resolvedArray.forEach((resolvedPromise, index) => {
323
- uploadPartsArray.push({
324
- ETag: resolvedPromise.headers.etag,
325
- PartNumber: index + 1,
326
- })
327
- })
328
- updatePercentageFiles(itemId, 99)
329
-
330
- // Calls the CompleteMultipartUpload endpoint in the backend server
331
- const completeUploadResp = await $libraryApi('api/library/assets/complete-multipart-upload', {
332
- method: 'POST',
333
- body: {
334
- assetId,
335
- uploadId,
336
- parts: uploadPartsArray,
337
- },
338
- headers: {
339
- noLoading: true,
340
- noNotify: true,
341
- },
342
- signal: item.controller.signal,
343
- })
344
-
345
- updatePercentageFiles(itemId, 100)
346
-
347
- await sleep(1500)
348
- return completeUploadResp
349
- }
350
- catch (err) {
351
- const index = filesValue.value.findIndex(file => file.id === itemId)
352
- if (index !== -1) {
353
- filesValue.value[index].error = 'Upload fail'
354
- }
355
- }
356
- }
357
- const hasExpiration = ref(false)
358
-
359
- function handleClose(done: () => void) {
360
- if (!R.equals(formValue.value, getInitialValues())) {
361
- ElMessageBox.confirm(t('message.close'), t('message.Warning'), {
362
- type: 'warning',
363
- })
364
- .then(() => {
365
- formValue.value = getInitialValues()
366
- hasExpiration.value = false
367
- done()
368
- })
369
- .catch(() => {
370
- // catch error
371
- })
372
- }
373
- else {
374
- formValue.value = getInitialValues()
375
- hasExpiration.value = false
376
- done()
377
- }
378
- }
379
-
380
- function onDeleteTag() {
381
- formRef.value?.validateField('tags')
382
- }
383
-
384
- const suggestLimit = computed(() => {
385
- const suggests = [
386
- { label: t('suggest.video'), value: 'video' },
387
- { label: t('suggest.image'), value: 'image' },
388
- { label: t('suggest.audio'), value: 'audio' },
389
- ]
390
- return suggests.filter(suggest => props.limit.find(limit => limit === suggest.value))
391
- })
392
-
393
- const categories = computed(() => [
394
- 'Promo Video',
395
- 'Film',
396
- 'Video Short',
397
- 'Podcast',
398
- 'Series',
399
- 'Sport Clip',
400
- 'Song',
401
- 'Voice Over',
402
- 'Graphics File',
403
- 'Presentation',
404
- ])
405
-
406
- const hasFile = computed(() => filesValue.value?.length > 0)
407
- const errorFiles = computed(() => filesValue.value.filter(file => file.error).length)
408
- const validFiles = computed(() => filesValue.value.filter(file => !file.error).length)
409
-
410
- const { appContext } = getCurrentInstance()!
411
-
412
- function showProgress() {
413
- ElNotification({
414
- message: h(FormUploadAssetProgress, {
415
- files: filesValue.value,
416
- }),
417
- position: 'bottom-right',
418
- duration: 0,
419
- customClass: 'w-600px! [--el-notification-padding:14px_26px_14px_13px]',
420
- }, appContext)
421
- }
422
-
423
- watch(hasExpiration, (newValue) => {
424
- expireDateValue.value = newValue ? 365 : null
425
- })
426
- </script>
427
-
428
- <template>
429
- <el-dialog
430
- v-model="visible"
431
- center
432
- :title="t('title')"
433
- width="750px"
434
- :before-close="handleClose"
435
- >
436
- <template v-if="!hasFile">
437
- <div
438
- v-loading="analyzing"
439
- class="relative w-full border-1 border-$el-border-color rounded-lg border-dashed p-10"
440
- :class="[isOverDropZone ? 'bg-$el-color-info-light-7' : '']"
441
- >
442
- <div v-if="formValue.file" class="flex items-center justify-center gap-4">
443
- <div class="line-clamp-1 flex items-center gap-2 overflow-hidden">
444
- <div class="i-carbon:document text-18px" />
445
- <span>{{ formValue.file.name }}</span>
446
- </div>
447
-
448
- <el-button
449
- class=""
450
- circle
451
- size="small"
452
- @click="() => formValue.file = null"
453
- >
454
- <div class="i-carbon:close" />
455
- </el-button>
456
- </div>
457
- <div v-else class="flex flex-col items-center justify-center gap-4">
458
- <div ref="dropZoneRef" class="w-full flex flex-col select-none items-center justify-center gap-2">
459
- <div class="i-ri:upload-cloud-2-fill text-7" />
460
- <div class="text-base">
461
- {{ t('label.dropFile') }}
462
- </div>
463
- </div>
464
-
465
- <el-button type="primary" @click="open()">
466
- {{ t('label.chooseFile') }}
467
- </el-button>
468
- </div>
469
- </div>
470
-
471
- <el-alert show-icon :closable="false" class="mx-auto mt-4 w-1/2">
472
- <div class="flex flex-col leading-20px">
473
- <div v-for="suggest in suggestLimit" :key="suggest.value">
474
- {{ suggest.label }}
475
- </div>
476
- <div>
477
- {{ t('base.maximum_files_per_upload_100_files') }}
478
- </div>
479
- </div>
480
- </el-alert>
481
- </template>
482
-
483
- <template v-else>
484
- <div class="mb-4 text-center text-balance text-sm font-400">
485
- <p class="">
486
- {{ $t('base_library.you_have_0_files_ready_to_upload_please_review_your_files_before', [filesValue.length
487
- - errorFiles]) }}
488
- </p>
489
- <p>{{ $t('base_library.the_system_is_ready_to_upload_the_checked_files') }}</p>
490
- </div>
491
- <DevOnly>
492
- <VueJsonPretty :data="formValue" />
493
- </DevOnly>
494
- <el-form
495
- ref="formRef"
496
- :model="formValue"
497
- label-position="left"
498
- label-width="120px"
499
- @validate="handleValidate"
500
- @submit.prevent
501
- >
502
- <el-form-item label="Playlist" v-bind="playlistIdsAttrs">
503
- <SSAssetPlaylistInfiniteSelect v-model="playlistIdsValue" />
504
- </el-form-item>
505
- <el-form-item :label="t('label.tag')" v-bind="tagAttrs">
506
- <SSInputTags v-model="tagValue" @delete-tag="onDeleteTag" />
507
- </el-form-item>
508
- <el-form-item label="Category" v-bind="categoryAttrs">
509
- <el-select v-model="categoryValue" class="w-full">
510
- <el-option
511
- v-for="item in categories"
512
- :key="item"
513
- :label="item"
514
- :value="item"
515
- />
516
- </el-select>
517
- </el-form-item>
518
- <el-form-item label="Expiration" v-bind="expireDateAttrs">
519
- <div class="flex items-center gap-2">
520
- <el-switch v-model="hasExpiration" />
521
- <template v-if="hasExpiration">
522
- <el-input-number
523
- v-model="expireDateValue"
524
- :min="1"
525
- :max="365"
526
- :step="1"
527
- step-strictly
528
- controls-position="right"
529
- :clearable="true"
530
- />
531
- <span class="ml-2 text-sm">
532
- Days
533
- </span>
534
- </template>
535
- </div>
536
- </el-form-item>
537
-
538
- <p class="my-4 text-sm font-bold">
539
- {{ $t('base_library.total') }}: {{ filesValue.length }} files | {{ filesValue.length - errorFiles }} files
540
- valid - {{ errorFiles }} file invalid
541
- </p>
542
- <div class="grid grid-cols-1 max-h-500px items-start gap-x-4 gap-y-2 of-y-auto px-2 py-2">
543
- <template v-for="(item, i) in filesValue" :key="item.id">
544
- <SSAssetFormUploadAssetItem :item="item" :prop="`files[${i}]`" @remove="remove(item.id)" />
545
- </template>
546
- </div>
547
- </el-form>
548
- <span class="flex justify-end">
549
- <el-button :disabled="isDisabled" @click="handleClose(() => visible = false)">{{ t('actions.cancel')
550
- }}</el-button>
551
- <el-button
552
- :disabled="isDisabled || validFiles === 0"
553
- type="primary"
554
- :loading="isLoading"
555
- @click="handleSubmit"
556
- >{{ t('actions.submit') }}</el-button>
557
- </span>
558
- </template>
559
- </el-dialog>
560
- </template>
561
-
562
- <i18n lang="yaml">
563
- en:
564
- title: Upload multimedia content
565
- label:
566
- chooseFile: Choose files
567
- dropFile: Drag & drog files to upload
568
- name: Name
569
- tag: Tag
570
- file: File
571
- placeholder:
572
- name: Enter media name
573
- tag: New tag
574
- file: Choose file asset
575
- url: Enter url
576
- actions:
577
- submit: Submit
578
- cancel: Cancel
579
- message:
580
- close: Are you sure you want to close this?
581
- success: Upload success
582
- fail: Upload fail
583
- uploadLoading: File upload may take await a few minutes. Please await!
584
- validate:
585
- name:
586
- required: Please input name asset
587
- length: Length should be 1 to 50 characters
588
- file:
589
- unknown: File type is not supported
590
- required: Please input file asset
591
- size:
592
- image: Image size should not exceed 100MB!
593
- video: Video size should not exceed 100GB!
594
- audio: Audio file size should not exceed 1GB!
595
- tags:
596
- accentedCharacters: The tag cannot contain accented and spaced characters
597
- noSpecialCharacters: Tag item can not contain special characters
598
- itemLength: Tag item can not contain more than 35 characters
599
- duplicate: Tag item can not contain duplicate
600
- limit: The number of tags should not exceed 50
601
- suggest:
602
- image: 'Maximum image size: 100MB'
603
- video: 'Maximum video size: 100GB'
604
- audio: 'Maximum audio size: 1GB'
605
- vi:
606
- title: Tải lên nội dung đa phương tiện
607
- label:
608
- chooseFile: Chọn tệp
609
- dropFile: Kéo và thả tệp để tải lên
610
- name: Tên
611
- tag: Thẻ
612
- file: Tệp
613
- placeholder:
614
- name: Nhập tên đa phương tiện
615
- tag: Thẻ mới
616
- file: Chọn tệp nội dung
617
- url: Nhập liên kết
618
- actions:
619
- submit: Tải lên
620
- cancel: Hủy
621
- message:
622
- close: Bạn có chắc chắn muốn đóng?
623
- success: Tải lên thành công
624
- fail: Tải lên thất bại
625
- uploadLoading: Tải lên có thể mất một vài phút. Vui lòng đợi!
626
- suggest:
627
- image: 'Ảnh kích thước tối đa: 100MB'
628
- video: 'Video kích thước tối đa: 100GB'
629
- audio: 'Âm thanh kích thước tối đa: 1GB'
630
- validate:
631
- name:
632
- required: Vui lòng nhập tên nội dung
633
- length: Độ dài phải từ 1 đến 50 ký tự
634
- file:
635
- unknown: Định dạng tệp không hỗ trợ
636
- required: Vui lòng nhập chọn tệp nội dung
637
- size:
638
- image: Kích thước ảnh không được vượt quá 100MB!
639
- video: Kích thước video không được vượt quá 100GB!
640
- audio: Kích thước tệp âm thanh không được vượt quá 1GB!
641
- tags:
642
- accentedCharacters: Thẻ không được chứa ký tự có dấu và khoảng cách
643
- noSpecialCharacters: Mục thẻ không được chứa các ký tự đặc biệt
644
- itemLength: Mục thẻ không được chứa nhiều hơn 35 ký tự
645
- duplicate: Mục thẻ không được chứa trùng lặp
646
- limit: Số lượng thẻ không vượt quá 50
647
- </i18n>
1
+ <script setup lang="ts">
2
+ import axios from 'axios'
3
+ import * as R from 'remeda'
4
+ import MediaInfo from 'mediainfo.js'
5
+ import FormUploadAssetProgress from './FormUploadAssetProgress.vue'
6
+
7
+ const props = withDefaults(
8
+ defineProps<{ limit?: string[] }>(),
9
+ {
10
+ limit: () => ['image', 'video', 'audio'],
11
+ },
12
+ )
13
+
14
+ const emit = defineEmits<{
15
+ (e: 'uploadSuccess', assetId: string): void
16
+ }>()
17
+
18
+ const { modelValue: visible } = defineModels<{
19
+ modelValue: boolean
20
+ }>()
21
+
22
+ function getInitialValues() {
23
+ return {
24
+ playlistIds: [],
25
+ tags: [],
26
+ category: 'Promo Video',
27
+ expire: null,
28
+ files: [],
29
+ name: '',
30
+ }
31
+ }
32
+
33
+ const { assetDomain } = usePickerStore()
34
+ const { t } = useI18n()
35
+ const qc = useQueryClient()
36
+ const isDisabled = ref(false)
37
+
38
+ const enableAdd = ref(false)
39
+ const SPECIAL_CHARACTERS_NAME_SPACE = /[`!@#$%^&*()+=[\]{};':"\\|,.<>/?~]/
40
+ const CONTAIN_NAME_SPACE = /^[\w -]*$/
41
+ function validNamePlaylist(value) {
42
+ if (!value.trim()) {
43
+ ElMessage.error($t('base.cannot_contain_all_space', { name: 'Name Playlist' }))
44
+ return false
45
+ }
46
+ else if (SPECIAL_CHARACTERS_NAME_SPACE.test(value)) {
47
+ ElMessage.error($t('base.name_can_not_special_characters', { name: 'Name Playlist' }))
48
+ return false
49
+ }
50
+ else if (!CONTAIN_NAME_SPACE.test(value)) {
51
+ ElMessage.error($t('base.name_cannot_contain_accented_characters', { name: 'Name Playlist' }))
52
+ return false
53
+ }
54
+ else {
55
+ return true
56
+ }
57
+ }
58
+ function checkPlaylists(lists) {
59
+ return !lists.some(value => !validNamePlaylist(value))
60
+ }
61
+ const { formRef, formValue, handleSubmit, handleValidate, isError, register, registerArray } = useElForm({
62
+ initialValues: getInitialValues(),
63
+ async onSubmit(values) {
64
+ enableAdd.value = checkPlaylists(values.playlistIds)
65
+ if (enableAdd.value) {
66
+ isDisabled.value = true
67
+ setTimeout(() => {
68
+ showProgress()
69
+ visible.value = false
70
+ }, 1000)
71
+ clearErrorFiles()
72
+
73
+ const promises = values.files.map((item, index) => startUpload({
74
+ ...item,
75
+ playlistIds: values.playlistIds,
76
+ tags: values.tags,
77
+ category: values.category,
78
+ expire: values.expire ? values.expire * 24 * 60 * 60 : null,
79
+ }, item.id))
80
+
81
+ const res = await Promise.all(promises)
82
+ const successLength = res.filter(item => Boolean(item)).length
83
+ qc.invalidateQueries(['api/library/assets'])
84
+ formValue.value = getInitialValues()
85
+
86
+ if (successLength) {
87
+ ElMessage.success(t('message.success'))
88
+ }
89
+
90
+ isDisabled.value = false
91
+ }
92
+ },
93
+ })
94
+ const analyzing = ref(false)
95
+
96
+ function getProp(path: string) {
97
+ return path
98
+ }
99
+ const [playlistIdsValue, playlistIdsAttrs] = register<string[]>(getProp('playlistIds'), [])
100
+ const [tagValue, tagAttrs] = register<string[]>(getProp('tags'), [
101
+ {
102
+ trigger: ['blur', 'change'],
103
+ validator: tagValidator(35),
104
+ },
105
+ ])
106
+ const [categoryValue, categoryAttrs] = register<string[]>(getProp('category'), [])
107
+ const [expireDateValue, expireDateAttrs] = register<number>(getProp('expire'), [])
108
+
109
+ const [filesValue, filesAttrs, { add, remove, addFirst }] = registerArray<{
110
+ name: string
111
+ file: File
112
+ error: string | boolean
113
+ }>(getProp('files'), [])
114
+
115
+ function clearErrorFiles() {
116
+ filesValue.value = filesValue.value.filter(file => !file.error)
117
+ }
118
+
119
+ const { files, open, reset: resetFiles } = useFileDialog({
120
+ accept: '.png, .jpg, .mp3, .mp4, .wav',
121
+ })
122
+
123
+ const { ignoreUpdates } = watchIgnorable(files, () => {
124
+ handleDropFiles(files.value)
125
+ })
126
+
127
+ async function handleDropFiles(files: FileList | null) {
128
+ if (!files)
129
+ return
130
+
131
+ const limitFiles = 100
132
+ let i = 0
133
+ for (const file of files) {
134
+ i++
135
+ if (i > limitFiles) {
136
+ ElMessage.warning(t('base_library.maximum_files_per_upload_is_100_files'))
137
+ break
138
+ }
139
+ const error = await validateFiles(file)
140
+ const payload = {
141
+ file,
142
+ error,
143
+ name: file.name,
144
+ percentage: 0,
145
+ controller: new AbortController(),
146
+ aborted: false,
147
+ }
148
+ if (!error) {
149
+ addFirst(payload)
150
+ }
151
+ else {
152
+ add(payload)
153
+ }
154
+ }
155
+
156
+ ignoreUpdates(() => {
157
+ resetFiles()
158
+ })
159
+ // reset file input
160
+ }
161
+
162
+ function onDrop(_files: FileList | null) {
163
+ handleDropFiles(_files)
164
+ ignoreUpdates(() => {
165
+ files.value = _files
166
+ })
167
+ }
168
+
169
+ const dropZoneRef = ref<HTMLElement>()
170
+ const { isOverDropZone } = useDropZone(dropZoneRef, onDrop)
171
+
172
+ async function validateFiles(file: File) {
173
+ analyzing.value = true
174
+ const mediainfo = await MediaInfo({
175
+ locateFile: () => {
176
+ // HARD Code media info wasm path
177
+ return 'https://resource-ott.gviet.vn/sdk/assets/MediaInfoModule.wasm'
178
+ },
179
+ })
180
+
181
+ const readChunk = file => (chunkSize, offset) =>
182
+ new Promise((resolve, reject) => {
183
+ const reader = new FileReader()
184
+ reader.onload = (event) => {
185
+ if (event.target.error)
186
+ reject(event.target.error)
187
+
188
+ resolve(new Uint8Array(event.target.result))
189
+ }
190
+ reader.readAsArrayBuffer(file.slice(offset, offset + chunkSize))
191
+ })
192
+
193
+ const result = await mediainfo.analyzeData(() => file?.size, readChunk(file))
194
+ analyzing.value = false
195
+
196
+ let type = result.media.track.find(track => track['@type'] !== 'General')
197
+ // Video | Image | Audio
198
+ if (!type) {
199
+ return t('validate.file.unknown')
200
+ }
201
+
202
+ type = type['@type'].toLowerCase()
203
+
204
+ if (!props.limit.includes(type)) {
205
+ return t('validate.file.unknown')
206
+ }
207
+
208
+ const fileSize = file.size! / (1024 * 1024) // MB
209
+
210
+ const sizeErrorMsg = {
211
+ video: t('validate.file.size.video'),
212
+ image: t('validate.file.size.image'),
213
+ audio: t('validate.file.size.audio'),
214
+ }
215
+
216
+ const sizeLimit = {
217
+ video: 100 * 1024,
218
+ image: 1024,
219
+ audio: 100,
220
+ }
221
+ if (!sizeLimit[type]) {
222
+ return t('validate.file.unknown')
223
+ }
224
+
225
+ if (fileSize > sizeLimit[type]) {
226
+ return sizeErrorMsg[type]
227
+ }
228
+ // everything is ok
229
+
230
+ return false
231
+ }
232
+
233
+ const isLoading = ref(false)
234
+
235
+ function updatePercentageFiles(id: string, percentage: number) {
236
+ const index = filesValue.value.findIndex(file => file.id === id)
237
+ if (index !== -1) {
238
+ filesValue.value[index].percentage = percentage
239
+ }
240
+ }
241
+
242
+ async function startUpload(item: any, id: string) {
243
+ try {
244
+ isLoading.value = true
245
+ const data = await $libraryApi('api/library/assets/create-multipart-upload', {
246
+ method: 'POST',
247
+ body: {
248
+ name: item.name,
249
+ tags: item.tags,
250
+ originFileName: item.file.name,
251
+ category: item.category,
252
+ playlistIds: item.playlistIds,
253
+ expire: item.expire,
254
+ },
255
+ headers: {
256
+ noLoading: true,
257
+ },
258
+ })
259
+
260
+ const { assetId, uploadId } = data
261
+ const index = filesValue.value.findIndex(file => file.id === id)
262
+ if (index !== -1) {
263
+ filesValue.value[index].assetId = assetId
264
+ }
265
+
266
+ const res = await uploadMultipartFile(assetId, uploadId, item, id)
267
+ return res
268
+ }
269
+ catch (err) {
270
+ console.log('[LOG] ~ err:', err)
271
+ }
272
+ finally {
273
+ isLoading.value = false
274
+ }
275
+ }
276
+
277
+ async function uploadMultipartFile(assetId: string, uploadId: string, item: any, itemId: string) {
278
+ try {
279
+ const FILE_CHUNK_SIZE = 10000000 // 10MB
280
+ const fileSize = item.file.size
281
+ const NUM_CHUNKS = Math.floor(fileSize / FILE_CHUNK_SIZE) + 1
282
+ const promisesArray = []
283
+ let start, end, blob
284
+ for (let index = 1; index < NUM_CHUNKS + 1; index++) {
285
+ start = (index - 1) * FILE_CHUNK_SIZE
286
+ end = index * FILE_CHUNK_SIZE
287
+ blob
288
+ = index < NUM_CHUNKS
289
+ ? item.file.slice(start, end)
290
+ : item.file.slice(start)
291
+
292
+ // Generate presigned URL for each part
293
+ const getUploadUrlResp = await $libraryApi('api/library/assets/presign-multipart-upload-url', {
294
+ method: 'POST',
295
+ body: {
296
+ assetId,
297
+ partNumber: index,
298
+ uploadId,
299
+ },
300
+ headers: {
301
+ noLoading: true,
302
+ noNotify: true,
303
+ },
304
+ signal: item.controller.signal,
305
+ })
306
+
307
+ const { preSignUrl } = getUploadUrlResp
308
+
309
+ const preSignUrlWithHost = getAssetURI(preSignUrl, `${ensureSuffix('/', assetDomain.value)}`)
310
+
311
+ // Puts each file part into the storage server
312
+ const uploadResp = await axios.put(preSignUrlWithHost, blob, {
313
+ signal: item.controller.signal,
314
+ })
315
+
316
+ updatePercentageFiles(itemId, 25 + Math.floor((index / NUM_CHUNKS) * 50))
317
+ promisesArray.push(uploadResp)
318
+ }
319
+
320
+ const resolvedArray = await Promise.all(promisesArray)
321
+ const uploadPartsArray: any[] = []
322
+ resolvedArray.forEach((resolvedPromise, index) => {
323
+ uploadPartsArray.push({
324
+ ETag: resolvedPromise.headers.etag,
325
+ PartNumber: index + 1,
326
+ })
327
+ })
328
+ updatePercentageFiles(itemId, 99)
329
+
330
+ // Calls the CompleteMultipartUpload endpoint in the backend server
331
+ const completeUploadResp = await $libraryApi('api/library/assets/complete-multipart-upload', {
332
+ method: 'POST',
333
+ body: {
334
+ assetId,
335
+ uploadId,
336
+ parts: uploadPartsArray,
337
+ },
338
+ headers: {
339
+ noLoading: true,
340
+ noNotify: true,
341
+ },
342
+ signal: item.controller.signal,
343
+ })
344
+
345
+ updatePercentageFiles(itemId, 100)
346
+
347
+ await sleep(1500)
348
+ return completeUploadResp
349
+ }
350
+ catch (err) {
351
+ const index = filesValue.value.findIndex(file => file.id === itemId)
352
+ if (index !== -1) {
353
+ filesValue.value[index].error = 'Upload fail'
354
+ }
355
+ }
356
+ }
357
+ const hasExpiration = ref(false)
358
+
359
+ function handleClose(done: () => void) {
360
+ if (!R.equals(formValue.value, getInitialValues())) {
361
+ ElMessageBox.confirm(t('message.close'), t('message.Warning'), {
362
+ type: 'warning',
363
+ })
364
+ .then(() => {
365
+ formValue.value = getInitialValues()
366
+ hasExpiration.value = false
367
+ done()
368
+ })
369
+ .catch(() => {
370
+ // catch error
371
+ })
372
+ }
373
+ else {
374
+ formValue.value = getInitialValues()
375
+ hasExpiration.value = false
376
+ done()
377
+ }
378
+ }
379
+
380
+ function onDeleteTag() {
381
+ formRef.value?.validateField('tags')
382
+ }
383
+
384
+ const suggestLimit = computed(() => {
385
+ const suggests = [
386
+ { label: t('suggest.video'), value: 'video' },
387
+ { label: t('suggest.image'), value: 'image' },
388
+ { label: t('suggest.audio'), value: 'audio' },
389
+ ]
390
+ return suggests.filter(suggest => props.limit.find(limit => limit === suggest.value))
391
+ })
392
+
393
+ const categories = computed(() => [
394
+ 'Promo Video',
395
+ 'Film',
396
+ 'Video Short',
397
+ 'Podcast',
398
+ 'Series',
399
+ 'Sport Clip',
400
+ 'Song',
401
+ 'Voice Over',
402
+ 'Graphics File',
403
+ 'Presentation',
404
+ ])
405
+
406
+ const hasFile = computed(() => filesValue.value?.length > 0)
407
+ const errorFiles = computed(() => filesValue.value.filter(file => file.error).length)
408
+ const validFiles = computed(() => filesValue.value.filter(file => !file.error).length)
409
+
410
+ const { appContext } = getCurrentInstance()!
411
+
412
+ function showProgress() {
413
+ ElNotification({
414
+ message: h(FormUploadAssetProgress, {
415
+ files: filesValue.value,
416
+ }),
417
+ position: 'bottom-right',
418
+ duration: 0,
419
+ customClass: 'w-600px! [--el-notification-padding:14px_26px_14px_13px]',
420
+ }, appContext)
421
+ }
422
+
423
+ watch(hasExpiration, (newValue) => {
424
+ expireDateValue.value = newValue ? 365 : null
425
+ })
426
+ </script>
427
+
428
+ <template>
429
+ <el-dialog
430
+ v-model="visible"
431
+ center
432
+ :title="t('title')"
433
+ width="750px"
434
+ :before-close="handleClose"
435
+ >
436
+ <template v-if="!hasFile">
437
+ <div
438
+ v-loading="analyzing"
439
+ class="relative w-full border-1 border-$el-border-color rounded-lg border-dashed p-10"
440
+ :class="[isOverDropZone ? 'bg-$el-color-info-light-7' : '']"
441
+ >
442
+ <div v-if="formValue.file" class="flex items-center justify-center gap-4">
443
+ <div class="line-clamp-1 flex items-center gap-2 overflow-hidden">
444
+ <div class="i-carbon:document text-18px" />
445
+ <span>{{ formValue.file.name }}</span>
446
+ </div>
447
+
448
+ <el-button
449
+ class=""
450
+ circle
451
+ size="small"
452
+ @click="() => formValue.file = null"
453
+ >
454
+ <div class="i-carbon:close" />
455
+ </el-button>
456
+ </div>
457
+ <div v-else class="flex flex-col items-center justify-center gap-4">
458
+ <div ref="dropZoneRef" class="w-full flex flex-col select-none items-center justify-center gap-2">
459
+ <div class="i-ri:upload-cloud-2-fill text-7" />
460
+ <div class="text-base">
461
+ {{ t('label.dropFile') }}
462
+ </div>
463
+ </div>
464
+
465
+ <el-button type="primary" @click="open()">
466
+ {{ t('label.chooseFile') }}
467
+ </el-button>
468
+ </div>
469
+ </div>
470
+
471
+ <el-alert show-icon :closable="false" class="mx-auto mt-4 w-1/2">
472
+ <div class="flex flex-col leading-20px">
473
+ <div v-for="suggest in suggestLimit" :key="suggest.value">
474
+ {{ suggest.label }}
475
+ </div>
476
+ <div>
477
+ {{ t('base.maximum_files_per_upload_100_files') }}
478
+ </div>
479
+ </div>
480
+ </el-alert>
481
+ </template>
482
+
483
+ <template v-else>
484
+ <div class="mb-4 text-center text-balance text-sm font-400">
485
+ <p class="">
486
+ {{ $t('base_library.you_have_0_files_ready_to_upload_please_review_your_files_before', [filesValue.length
487
+ - errorFiles]) }}
488
+ </p>
489
+ <p>{{ $t('base_library.the_system_is_ready_to_upload_the_checked_files') }}</p>
490
+ </div>
491
+ <DevOnly>
492
+ <VueJsonPretty :data="formValue" />
493
+ </DevOnly>
494
+ <el-form
495
+ ref="formRef"
496
+ :model="formValue"
497
+ label-position="left"
498
+ label-width="120px"
499
+ @validate="handleValidate"
500
+ @submit.prevent
501
+ >
502
+ <el-form-item label="Playlist" v-bind="playlistIdsAttrs">
503
+ <SSAssetPlaylistInfiniteSelect v-model="playlistIdsValue" />
504
+ </el-form-item>
505
+ <el-form-item :label="t('label.tag')" v-bind="tagAttrs">
506
+ <SSInputTags v-model="tagValue" @delete-tag="onDeleteTag" />
507
+ </el-form-item>
508
+ <el-form-item label="Category" v-bind="categoryAttrs">
509
+ <el-select v-model="categoryValue" class="w-full">
510
+ <el-option
511
+ v-for="item in categories"
512
+ :key="item"
513
+ :label="item"
514
+ :value="item"
515
+ />
516
+ </el-select>
517
+ </el-form-item>
518
+ <el-form-item label="Expiration" v-bind="expireDateAttrs">
519
+ <div class="flex items-center gap-2">
520
+ <el-switch v-model="hasExpiration" />
521
+ <template v-if="hasExpiration">
522
+ <el-input-number
523
+ v-model="expireDateValue"
524
+ :min="1"
525
+ :max="365"
526
+ :step="1"
527
+ step-strictly
528
+ controls-position="right"
529
+ :clearable="true"
530
+ />
531
+ <span class="ml-2 text-sm">
532
+ Days
533
+ </span>
534
+ </template>
535
+ </div>
536
+ </el-form-item>
537
+
538
+ <p class="my-4 text-sm font-bold">
539
+ {{ $t('base_library.total') }}: {{ filesValue.length }} files | {{ filesValue.length - errorFiles }} files
540
+ valid - {{ errorFiles }} file invalid
541
+ </p>
542
+ <div class="grid grid-cols-1 max-h-500px items-start gap-x-4 gap-y-2 of-y-auto px-2 py-2">
543
+ <template v-for="(item, i) in filesValue" :key="item.id">
544
+ <SSAssetFormUploadAssetItem :item="item" :prop="`files[${i}]`" @remove="remove(item.id)" />
545
+ </template>
546
+ </div>
547
+ </el-form>
548
+ <span class="flex justify-end">
549
+ <el-button :disabled="isDisabled" @click="handleClose(() => visible = false)">{{ t('actions.cancel')
550
+ }}</el-button>
551
+ <el-button
552
+ :disabled="isDisabled || validFiles === 0"
553
+ type="primary"
554
+ :loading="isLoading"
555
+ @click="handleSubmit"
556
+ >{{ t('actions.submit') }}</el-button>
557
+ </span>
558
+ </template>
559
+ </el-dialog>
560
+ </template>
561
+
562
+ <i18n lang="yaml">
563
+ en:
564
+ title: Upload multimedia content
565
+ label:
566
+ chooseFile: Choose files
567
+ dropFile: Drag & drog files to upload
568
+ name: Name
569
+ tag: Tag
570
+ file: File
571
+ placeholder:
572
+ name: Enter media name
573
+ tag: New tag
574
+ file: Choose file asset
575
+ url: Enter url
576
+ actions:
577
+ submit: Submit
578
+ cancel: Cancel
579
+ message:
580
+ close: Are you sure you want to close this?
581
+ success: Upload success
582
+ fail: Upload fail
583
+ uploadLoading: File upload may take await a few minutes. Please await!
584
+ validate:
585
+ name:
586
+ required: Please input name asset
587
+ length: Length should be 1 to 50 characters
588
+ file:
589
+ unknown: File type is not supported
590
+ required: Please input file asset
591
+ size:
592
+ image: Image size should not exceed 100MB!
593
+ video: Video size should not exceed 100GB!
594
+ audio: Audio file size should not exceed 1GB!
595
+ tags:
596
+ accentedCharacters: The tag cannot contain accented and spaced characters
597
+ noSpecialCharacters: Tag item can not contain special characters
598
+ itemLength: Tag item can not contain more than 35 characters
599
+ duplicate: Tag item can not contain duplicate
600
+ limit: The number of tags should not exceed 50
601
+ suggest:
602
+ image: 'Maximum image size: 100MB'
603
+ video: 'Maximum video size: 100GB'
604
+ audio: 'Maximum audio size: 1GB'
605
+ vi:
606
+ title: Tải lên nội dung đa phương tiện
607
+ label:
608
+ chooseFile: Chọn tệp
609
+ dropFile: Kéo và thả tệp để tải lên
610
+ name: Tên
611
+ tag: Thẻ
612
+ file: Tệp
613
+ placeholder:
614
+ name: Nhập tên đa phương tiện
615
+ tag: Thẻ mới
616
+ file: Chọn tệp nội dung
617
+ url: Nhập liên kết
618
+ actions:
619
+ submit: Tải lên
620
+ cancel: Hủy
621
+ message:
622
+ close: Bạn có chắc chắn muốn đóng?
623
+ success: Tải lên thành công
624
+ fail: Tải lên thất bại
625
+ uploadLoading: Tải lên có thể mất một vài phút. Vui lòng đợi!
626
+ suggest:
627
+ image: 'Ảnh kích thước tối đa: 100MB'
628
+ video: 'Video kích thước tối đa: 100GB'
629
+ audio: 'Âm thanh kích thước tối đa: 1GB'
630
+ validate:
631
+ name:
632
+ required: Vui lòng nhập tên nội dung
633
+ length: Độ dài phải từ 1 đến 50 ký tự
634
+ file:
635
+ unknown: Định dạng tệp không hỗ trợ
636
+ required: Vui lòng nhập chọn tệp nội dung
637
+ size:
638
+ image: Kích thước ảnh không được vượt quá 100MB!
639
+ video: Kích thước video không được vượt quá 100GB!
640
+ audio: Kích thước tệp âm thanh không được vượt quá 1GB!
641
+ tags:
642
+ accentedCharacters: Thẻ không được chứa ký tự có dấu và khoảng cách
643
+ noSpecialCharacters: Mục thẻ không được chứa các ký tự đặc biệt
644
+ itemLength: Mục thẻ không được chứa nhiều hơn 35 ký tự
645
+ duplicate: Mục thẻ không được chứa trùng lặp
646
+ limit: Số lượng thẻ không vượt quá 50
647
+ </i18n>