@strapi/admin 5.55.1 → 5.57.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 (388) hide show
  1. package/dist/admin/admin/src/components/Filters.js +1 -1
  2. package/dist/admin/admin/src/components/Filters.js.map +1 -1
  3. package/dist/admin/admin/src/components/Filters.mjs +1 -1
  4. package/dist/admin/admin/src/components/Filters.mjs.map +1 -1
  5. package/dist/admin/admin/src/components/FormInputs/Enumeration.js +2 -2
  6. package/dist/admin/admin/src/components/FormInputs/Enumeration.js.map +1 -1
  7. package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs +2 -2
  8. package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs.map +1 -1
  9. package/dist/admin/admin/src/components/MediaLibraryBanner.js +38 -2
  10. package/dist/admin/admin/src/components/MediaLibraryBanner.js.map +1 -1
  11. package/dist/admin/admin/src/components/MediaLibraryBanner.mjs +18 -2
  12. package/dist/admin/admin/src/components/MediaLibraryBanner.mjs.map +1 -1
  13. package/dist/admin/admin/src/components/RelativeTime.js +9 -0
  14. package/dist/admin/admin/src/components/RelativeTime.js.map +1 -1
  15. package/dist/admin/admin/src/components/RelativeTime.mjs +10 -1
  16. package/dist/admin/admin/src/components/RelativeTime.mjs.map +1 -1
  17. package/dist/admin/admin/src/components/TopBanners.js +52 -0
  18. package/dist/admin/admin/src/components/TopBanners.js.map +1 -0
  19. package/dist/admin/admin/src/components/TopBanners.mjs +30 -0
  20. package/dist/admin/admin/src/components/TopBanners.mjs.map +1 -0
  21. package/dist/admin/admin/src/components/UpsellBanner.js +9 -16
  22. package/dist/admin/admin/src/components/UpsellBanner.js.map +1 -1
  23. package/dist/admin/admin/src/components/UpsellBanner.mjs +11 -18
  24. package/dist/admin/admin/src/components/UpsellBanner.mjs.map +1 -1
  25. package/dist/admin/admin/src/features/Tracking.js +28 -8
  26. package/dist/admin/admin/src/features/Tracking.js.map +1 -1
  27. package/dist/admin/admin/src/features/Tracking.mjs +29 -10
  28. package/dist/admin/admin/src/features/Tracking.mjs.map +1 -1
  29. package/dist/admin/admin/src/layouts/AuthenticatedLayout.js +4 -20
  30. package/dist/admin/admin/src/layouts/AuthenticatedLayout.js.map +1 -1
  31. package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs +4 -20
  32. package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs.map +1 -1
  33. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.js +59 -0
  34. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.js.map +1 -0
  35. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.mjs +37 -0
  36. package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.mjs.map +1 -0
  37. package/dist/admin/admin/src/render.js +4 -69
  38. package/dist/admin/admin/src/render.js.map +1 -1
  39. package/dist/admin/admin/src/render.mjs +4 -69
  40. package/dist/admin/admin/src/render.mjs.map +1 -1
  41. package/dist/admin/admin/src/translations/en.json.js +15 -0
  42. package/dist/admin/admin/src/translations/en.json.js.map +1 -1
  43. package/dist/admin/admin/src/translations/en.json.mjs +15 -0
  44. package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
  45. package/dist/admin/admin/src/utils/browserStrapi.js +93 -0
  46. package/dist/admin/admin/src/utils/browserStrapi.js.map +1 -0
  47. package/dist/admin/admin/src/utils/browserStrapi.mjs +91 -0
  48. package/dist/admin/admin/src/utils/browserStrapi.mjs.map +1 -0
  49. package/dist/admin/admin/src/utils/getFetchClient.js +3 -3
  50. package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
  51. package/dist/admin/admin/src/utils/getFetchClient.mjs +2 -2
  52. package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
  53. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js +2 -1
  54. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js.map +1 -1
  55. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs +2 -1
  56. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs.map +1 -1
  57. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js +16 -1
  58. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js.map +1 -1
  59. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs +16 -1
  60. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs.map +1 -1
  61. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.js +3 -1
  62. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.js.map +1 -1
  63. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.mjs +3 -1
  64. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.mjs.map +1 -1
  65. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.js +64 -0
  66. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.js.map +1 -0
  67. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.mjs +60 -0
  68. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.mjs.map +1 -0
  69. package/dist/admin/ee/admin/src/services/auditLogs.js +2 -1
  70. package/dist/admin/ee/admin/src/services/auditLogs.js.map +1 -1
  71. package/dist/admin/ee/admin/src/services/auditLogs.mjs +2 -1
  72. package/dist/admin/ee/admin/src/services/auditLogs.mjs.map +1 -1
  73. package/dist/admin/src/components/MediaLibraryBanner.d.ts +10 -1
  74. package/dist/admin/src/components/SubNav.d.ts +2 -2
  75. package/dist/admin/src/components/TopBanners.d.ts +8 -0
  76. package/dist/admin/src/features/Tracking.d.ts +12 -1
  77. package/dist/admin/src/layouts/useAuthenticatedAccessTracking.d.ts +6 -0
  78. package/dist/admin/src/utils/browserStrapi.d.ts +11 -0
  79. package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.d.ts +15 -0
  80. package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.d.ts +14 -0
  81. package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts +10 -1
  82. package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts.map +1 -1
  83. package/dist/ee/server/src/controllers/admin.d.ts +2 -28
  84. package/dist/ee/server/src/controllers/admin.d.ts.map +1 -1
  85. package/dist/ee/server/src/controllers/authentication-utils/utils.d.ts +8 -2
  86. package/dist/ee/server/src/controllers/authentication-utils/utils.d.ts.map +1 -1
  87. package/dist/ee/server/src/controllers/authentication.d.ts.map +1 -1
  88. package/dist/ee/server/src/controllers/index.d.ts +1 -28
  89. package/dist/ee/server/src/controllers/index.d.ts.map +1 -1
  90. package/dist/ee/server/src/controllers/user.d.ts.map +1 -1
  91. package/dist/ee/server/src/index.d.ts +6 -30
  92. package/dist/ee/server/src/index.d.ts.map +1 -1
  93. package/dist/ee/server/src/services/auth.d.ts +1 -1
  94. package/dist/ee/server/src/services/auth.d.ts.map +1 -1
  95. package/dist/ee/server/src/services/index.d.ts +5 -2
  96. package/dist/ee/server/src/services/index.d.ts.map +1 -1
  97. package/dist/ee/server/src/services/metrics.d.ts.map +1 -1
  98. package/dist/ee/server/src/services/persist-tables.d.ts.map +1 -1
  99. package/dist/ee/server/src/services/seat-enforcement.d.ts +3 -1
  100. package/dist/ee/server/src/services/seat-enforcement.d.ts.map +1 -1
  101. package/dist/ee/server/src/services/user.d.ts.map +1 -1
  102. package/dist/server/ee/server/src/audit-logs/services/lifecycles.js +37 -21
  103. package/dist/server/ee/server/src/audit-logs/services/lifecycles.js.map +1 -1
  104. package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs +37 -21
  105. package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs.map +1 -1
  106. package/dist/server/ee/server/src/controllers/admin.js +8 -7
  107. package/dist/server/ee/server/src/controllers/admin.js.map +1 -1
  108. package/dist/server/ee/server/src/controllers/admin.mjs +8 -7
  109. package/dist/server/ee/server/src/controllers/admin.mjs.map +1 -1
  110. package/dist/server/ee/server/src/controllers/authentication-utils/utils.js +2 -2
  111. package/dist/server/ee/server/src/controllers/authentication-utils/utils.js.map +1 -1
  112. package/dist/server/ee/server/src/controllers/authentication-utils/utils.mjs +2 -2
  113. package/dist/server/ee/server/src/controllers/authentication-utils/utils.mjs.map +1 -1
  114. package/dist/server/ee/server/src/controllers/authentication.js +11 -11
  115. package/dist/server/ee/server/src/controllers/authentication.js.map +1 -1
  116. package/dist/server/ee/server/src/controllers/authentication.mjs +11 -11
  117. package/dist/server/ee/server/src/controllers/authentication.mjs.map +1 -1
  118. package/dist/server/ee/server/src/controllers/user.js +7 -8
  119. package/dist/server/ee/server/src/controllers/user.js.map +1 -1
  120. package/dist/server/ee/server/src/controllers/user.mjs +8 -9
  121. package/dist/server/ee/server/src/controllers/user.mjs.map +1 -1
  122. package/dist/server/ee/server/src/index.js +4 -0
  123. package/dist/server/ee/server/src/index.js.map +1 -1
  124. package/dist/server/ee/server/src/index.mjs +4 -0
  125. package/dist/server/ee/server/src/index.mjs.map +1 -1
  126. package/dist/server/ee/server/src/services/auth.js +1 -6
  127. package/dist/server/ee/server/src/services/auth.js.map +1 -1
  128. package/dist/server/ee/server/src/services/auth.mjs +2 -7
  129. package/dist/server/ee/server/src/services/auth.mjs.map +1 -1
  130. package/dist/server/ee/server/src/services/metrics.js +9 -7
  131. package/dist/server/ee/server/src/services/metrics.js.map +1 -1
  132. package/dist/server/ee/server/src/services/metrics.mjs +9 -7
  133. package/dist/server/ee/server/src/services/metrics.mjs.map +1 -1
  134. package/dist/server/ee/server/src/services/persist-tables.js +3 -4
  135. package/dist/server/ee/server/src/services/persist-tables.js.map +1 -1
  136. package/dist/server/ee/server/src/services/persist-tables.mjs +3 -4
  137. package/dist/server/ee/server/src/services/persist-tables.mjs.map +1 -1
  138. package/dist/server/ee/server/src/services/role.js +2 -2
  139. package/dist/server/ee/server/src/services/role.js.map +1 -1
  140. package/dist/server/ee/server/src/services/role.mjs +1 -1
  141. package/dist/server/ee/server/src/services/role.mjs.map +1 -1
  142. package/dist/server/ee/server/src/services/seat-enforcement.js +20 -20
  143. package/dist/server/ee/server/src/services/seat-enforcement.js.map +1 -1
  144. package/dist/server/ee/server/src/services/seat-enforcement.mjs +20 -20
  145. package/dist/server/ee/server/src/services/seat-enforcement.mjs.map +1 -1
  146. package/dist/server/ee/server/src/services/user.js +37 -6
  147. package/dist/server/ee/server/src/services/user.js.map +1 -1
  148. package/dist/server/ee/server/src/services/user.mjs +38 -7
  149. package/dist/server/ee/server/src/services/user.mjs.map +1 -1
  150. package/dist/server/ee/server/src/utils/sso-lock.js +2 -2
  151. package/dist/server/ee/server/src/utils/sso-lock.js.map +1 -1
  152. package/dist/server/ee/server/src/utils/sso-lock.mjs +1 -1
  153. package/dist/server/ee/server/src/utils/sso-lock.mjs.map +1 -1
  154. package/dist/server/server/src/audit-logs/admin-users.js +169 -0
  155. package/dist/server/server/src/audit-logs/admin-users.js.map +1 -0
  156. package/dist/server/server/src/audit-logs/admin-users.mjs +157 -0
  157. package/dist/server/server/src/audit-logs/admin-users.mjs.map +1 -0
  158. package/dist/server/server/src/audit-logs/tokens.js +3 -3
  159. package/dist/server/server/src/audit-logs/tokens.js.map +1 -1
  160. package/dist/server/server/src/audit-logs/tokens.mjs +2 -2
  161. package/dist/server/server/src/audit-logs/tokens.mjs.map +1 -1
  162. package/dist/server/server/src/audit-logs/webhooks.js +106 -0
  163. package/dist/server/server/src/audit-logs/webhooks.js.map +1 -0
  164. package/dist/server/server/src/audit-logs/webhooks.mjs +100 -0
  165. package/dist/server/server/src/audit-logs/webhooks.mjs.map +1 -0
  166. package/dist/server/server/src/bootstrap.js +6 -4
  167. package/dist/server/server/src/bootstrap.js.map +1 -1
  168. package/dist/server/server/src/bootstrap.mjs +6 -4
  169. package/dist/server/server/src/bootstrap.mjs.map +1 -1
  170. package/dist/server/server/src/controllers/admin-token.js +8 -8
  171. package/dist/server/server/src/controllers/admin-token.js.map +1 -1
  172. package/dist/server/server/src/controllers/admin-token.mjs +4 -4
  173. package/dist/server/server/src/controllers/admin-token.mjs.map +1 -1
  174. package/dist/server/server/src/controllers/admin.js +4 -5
  175. package/dist/server/server/src/controllers/admin.js.map +1 -1
  176. package/dist/server/server/src/controllers/admin.mjs +3 -4
  177. package/dist/server/server/src/controllers/admin.mjs.map +1 -1
  178. package/dist/server/server/src/controllers/api-token.js +8 -8
  179. package/dist/server/server/src/controllers/api-token.js.map +1 -1
  180. package/dist/server/server/src/controllers/api-token.mjs +4 -4
  181. package/dist/server/server/src/controllers/api-token.mjs.map +1 -1
  182. package/dist/server/server/src/controllers/authentication.js +8 -1
  183. package/dist/server/server/src/controllers/authentication.js.map +1 -1
  184. package/dist/server/server/src/controllers/authentication.mjs +8 -1
  185. package/dist/server/server/src/controllers/authentication.mjs.map +1 -1
  186. package/dist/server/server/src/controllers/formatters/conditions.js +2 -2
  187. package/dist/server/server/src/controllers/formatters/conditions.js.map +1 -1
  188. package/dist/server/server/src/controllers/formatters/conditions.mjs +2 -2
  189. package/dist/server/server/src/controllers/formatters/conditions.mjs.map +1 -1
  190. package/dist/server/server/src/controllers/transfer/index.js +2 -2
  191. package/dist/server/server/src/controllers/transfer/index.js.map +1 -1
  192. package/dist/server/server/src/controllers/transfer/index.mjs +2 -2
  193. package/dist/server/server/src/controllers/transfer/index.mjs.map +1 -1
  194. package/dist/server/server/src/controllers/transfer/token.js +8 -8
  195. package/dist/server/server/src/controllers/transfer/token.js.map +1 -1
  196. package/dist/server/server/src/controllers/transfer/token.mjs +4 -4
  197. package/dist/server/server/src/controllers/transfer/token.mjs.map +1 -1
  198. package/dist/server/server/src/controllers/webhooks.js +26 -0
  199. package/dist/server/server/src/controllers/webhooks.js.map +1 -1
  200. package/dist/server/server/src/controllers/webhooks.mjs +27 -1
  201. package/dist/server/server/src/controllers/webhooks.mjs.map +1 -1
  202. package/dist/server/server/src/domain/action/index.js +18 -16
  203. package/dist/server/server/src/domain/action/index.js.map +1 -1
  204. package/dist/server/server/src/domain/action/index.mjs +16 -14
  205. package/dist/server/server/src/domain/action/index.mjs.map +1 -1
  206. package/dist/server/server/src/domain/action/provider.mjs +4 -4
  207. package/dist/server/server/src/domain/action/provider.mjs.map +1 -1
  208. package/dist/server/server/src/domain/condition/index.js +7 -4
  209. package/dist/server/server/src/domain/condition/index.js.map +1 -1
  210. package/dist/server/server/src/domain/condition/index.mjs +7 -4
  211. package/dist/server/server/src/domain/condition/index.mjs.map +1 -1
  212. package/dist/server/server/src/domain/permission/index.js +24 -15
  213. package/dist/server/server/src/domain/permission/index.js.map +1 -1
  214. package/dist/server/server/src/domain/permission/index.mjs +21 -12
  215. package/dist/server/server/src/domain/permission/index.mjs.map +1 -1
  216. package/dist/server/server/src/middlewares/rateLimit.js +5 -5
  217. package/dist/server/server/src/middlewares/rateLimit.js.map +1 -1
  218. package/dist/server/server/src/middlewares/rateLimit.mjs +4 -4
  219. package/dist/server/server/src/middlewares/rateLimit.mjs.map +1 -1
  220. package/dist/server/server/src/register.js +6 -0
  221. package/dist/server/server/src/register.js.map +1 -1
  222. package/dist/server/server/src/register.mjs +6 -0
  223. package/dist/server/server/src/register.mjs.map +1 -1
  224. package/dist/server/server/src/services/action.js +1 -2
  225. package/dist/server/server/src/services/action.js.map +1 -1
  226. package/dist/server/server/src/services/action.mjs +1 -2
  227. package/dist/server/server/src/services/action.mjs.map +1 -1
  228. package/dist/server/server/src/services/api-token.js +61 -49
  229. package/dist/server/server/src/services/api-token.js.map +1 -1
  230. package/dist/server/server/src/services/api-token.mjs +53 -41
  231. package/dist/server/server/src/services/api-token.mjs.map +1 -1
  232. package/dist/server/server/src/services/auth.js +27 -6
  233. package/dist/server/server/src/services/auth.js.map +1 -1
  234. package/dist/server/server/src/services/auth.mjs +28 -8
  235. package/dist/server/server/src/services/auth.mjs.map +1 -1
  236. package/dist/server/server/src/services/condition.js +2 -2
  237. package/dist/server/server/src/services/condition.js.map +1 -1
  238. package/dist/server/server/src/services/condition.mjs +1 -1
  239. package/dist/server/server/src/services/condition.mjs.map +1 -1
  240. package/dist/server/server/src/services/content-type.js +5 -4
  241. package/dist/server/server/src/services/content-type.js.map +1 -1
  242. package/dist/server/server/src/services/content-type.mjs +8 -7
  243. package/dist/server/server/src/services/content-type.mjs.map +1 -1
  244. package/dist/server/server/src/services/homepage.js +2 -1
  245. package/dist/server/server/src/services/homepage.js.map +1 -1
  246. package/dist/server/server/src/services/homepage.mjs +2 -1
  247. package/dist/server/server/src/services/homepage.mjs.map +1 -1
  248. package/dist/server/server/src/services/passport/local-strategy.js +2 -2
  249. package/dist/server/server/src/services/passport/local-strategy.js.map +1 -1
  250. package/dist/server/server/src/services/passport/local-strategy.mjs +1 -1
  251. package/dist/server/server/src/services/passport/local-strategy.mjs.map +1 -1
  252. package/dist/server/server/src/services/passport.js +1 -2
  253. package/dist/server/server/src/services/passport.js.map +1 -1
  254. package/dist/server/server/src/services/passport.mjs +1 -2
  255. package/dist/server/server/src/services/passport.mjs.map +1 -1
  256. package/dist/server/server/src/services/permission/engine.js +4 -4
  257. package/dist/server/server/src/services/permission/engine.js.map +1 -1
  258. package/dist/server/server/src/services/permission/engine.mjs +2 -2
  259. package/dist/server/server/src/services/permission/engine.mjs.map +1 -1
  260. package/dist/server/server/src/services/permission/permissions-manager/index.js +2 -3
  261. package/dist/server/server/src/services/permission/permissions-manager/index.js.map +1 -1
  262. package/dist/server/server/src/services/permission/permissions-manager/index.mjs +1 -2
  263. package/dist/server/server/src/services/permission/permissions-manager/index.mjs.map +1 -1
  264. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.js +6 -6
  265. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.js.map +1 -1
  266. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.mjs +4 -4
  267. package/dist/server/server/src/services/permission/permissions-manager/permission-fields.mjs.map +1 -1
  268. package/dist/server/server/src/services/permission/permissions-manager/sanitize.js +47 -41
  269. package/dist/server/server/src/services/permission/permissions-manager/sanitize.js.map +1 -1
  270. package/dist/server/server/src/services/permission/permissions-manager/sanitize.mjs +44 -38
  271. package/dist/server/server/src/services/permission/permissions-manager/sanitize.mjs.map +1 -1
  272. package/dist/server/server/src/services/permission/permissions-manager/validate.js +30 -26
  273. package/dist/server/server/src/services/permission/permissions-manager/validate.js.map +1 -1
  274. package/dist/server/server/src/services/permission/permissions-manager/validate.mjs +28 -24
  275. package/dist/server/server/src/services/permission/permissions-manager/validate.mjs.map +1 -1
  276. package/dist/server/server/src/services/permission/queries.js +9 -9
  277. package/dist/server/server/src/services/permission/queries.js.map +1 -1
  278. package/dist/server/server/src/services/permission/queries.mjs +9 -9
  279. package/dist/server/server/src/services/permission/queries.mjs.map +1 -1
  280. package/dist/server/server/src/services/permission/rename-fields.js +118 -0
  281. package/dist/server/server/src/services/permission/rename-fields.js.map +1 -0
  282. package/dist/server/server/src/services/permission/rename-fields.mjs +116 -0
  283. package/dist/server/server/src/services/permission/rename-fields.mjs.map +1 -0
  284. package/dist/server/server/src/services/permission/sections-builder/index.js +2 -2
  285. package/dist/server/server/src/services/permission/sections-builder/index.js.map +1 -1
  286. package/dist/server/server/src/services/permission/sections-builder/index.mjs +2 -2
  287. package/dist/server/server/src/services/permission/sections-builder/index.mjs.map +1 -1
  288. package/dist/server/server/src/services/permission/sections-builder/section.js +1 -2
  289. package/dist/server/server/src/services/permission/sections-builder/section.js.map +1 -1
  290. package/dist/server/server/src/services/permission/sections-builder/section.mjs +1 -2
  291. package/dist/server/server/src/services/permission/sections-builder/section.mjs.map +1 -1
  292. package/dist/server/server/src/services/permission/sections-builder/utils.js +6 -6
  293. package/dist/server/server/src/services/permission/sections-builder/utils.js.map +1 -1
  294. package/dist/server/server/src/services/permission/sections-builder/utils.mjs +4 -4
  295. package/dist/server/server/src/services/permission/sections-builder/utils.mjs.map +1 -1
  296. package/dist/server/server/src/services/role.js +20 -19
  297. package/dist/server/server/src/services/role.js.map +1 -1
  298. package/dist/server/server/src/services/role.mjs +20 -19
  299. package/dist/server/server/src/services/role.mjs.map +1 -1
  300. package/dist/server/server/src/services/transfer/token.js +20 -16
  301. package/dist/server/server/src/services/transfer/token.js.map +1 -1
  302. package/dist/server/server/src/services/transfer/token.mjs +14 -10
  303. package/dist/server/server/src/services/transfer/token.mjs.map +1 -1
  304. package/dist/server/server/src/services/user.js +50 -12
  305. package/dist/server/server/src/services/user.js.map +1 -1
  306. package/dist/server/server/src/services/user.mjs +52 -14
  307. package/dist/server/server/src/services/user.mjs.map +1 -1
  308. package/dist/server/server/src/strategies/api-token-utils.js +2 -3
  309. package/dist/server/server/src/strategies/api-token-utils.js.map +1 -1
  310. package/dist/server/server/src/strategies/api-token-utils.mjs +2 -3
  311. package/dist/server/server/src/strategies/api-token-utils.mjs.map +1 -1
  312. package/dist/server/server/src/strategies/content-api-token.js +3 -3
  313. package/dist/server/server/src/strategies/content-api-token.js.map +1 -1
  314. package/dist/server/server/src/strategies/content-api-token.mjs +1 -1
  315. package/dist/server/server/src/strategies/content-api-token.mjs.map +1 -1
  316. package/dist/server/server/src/strategies/data-transfer.js +4 -4
  317. package/dist/server/server/src/strategies/data-transfer.js.map +1 -1
  318. package/dist/server/server/src/strategies/data-transfer.mjs +3 -3
  319. package/dist/server/server/src/strategies/data-transfer.mjs.map +1 -1
  320. package/dist/server/server/src/validation/common-validators.js +9 -10
  321. package/dist/server/server/src/validation/common-validators.js.map +1 -1
  322. package/dist/server/server/src/validation/common-validators.mjs +13 -14
  323. package/dist/server/server/src/validation/common-validators.mjs.map +1 -1
  324. package/dist/server/server/src/validation/user.js +1 -2
  325. package/dist/server/server/src/validation/user.js.map +1 -1
  326. package/dist/server/server/src/validation/user.mjs +1 -2
  327. package/dist/server/server/src/validation/user.mjs.map +1 -1
  328. package/dist/server/src/audit-logs/admin-users.d.ts +119 -0
  329. package/dist/server/src/audit-logs/admin-users.d.ts.map +1 -0
  330. package/dist/server/src/audit-logs/tokens.d.ts.map +1 -1
  331. package/dist/server/src/audit-logs/webhooks.d.ts +59 -0
  332. package/dist/server/src/audit-logs/webhooks.d.ts.map +1 -0
  333. package/dist/server/src/bootstrap.d.ts.map +1 -1
  334. package/dist/server/src/controllers/admin-token.d.ts.map +1 -1
  335. package/dist/server/src/controllers/admin.d.ts +2 -11
  336. package/dist/server/src/controllers/admin.d.ts.map +1 -1
  337. package/dist/server/src/controllers/api-token.d.ts.map +1 -1
  338. package/dist/server/src/controllers/authentication.d.ts.map +1 -1
  339. package/dist/server/src/controllers/formatters/conditions.d.ts +1 -1
  340. package/dist/server/src/controllers/formatters/conditions.d.ts.map +1 -1
  341. package/dist/server/src/controllers/homepage.d.ts +1 -1
  342. package/dist/server/src/controllers/index.d.ts +2 -11
  343. package/dist/server/src/controllers/index.d.ts.map +1 -1
  344. package/dist/server/src/controllers/transfer/index.d.ts.map +1 -1
  345. package/dist/server/src/controllers/transfer/token.d.ts.map +1 -1
  346. package/dist/server/src/controllers/webhooks.d.ts.map +1 -1
  347. package/dist/server/src/domain/action/index.d.ts +1 -0
  348. package/dist/server/src/domain/action/index.d.ts.map +1 -1
  349. package/dist/server/src/domain/condition/index.d.ts +2 -2
  350. package/dist/server/src/domain/condition/index.d.ts.map +1 -1
  351. package/dist/server/src/domain/permission/index.d.ts.map +1 -1
  352. package/dist/server/src/domain/user.d.ts +2 -2
  353. package/dist/server/src/index.d.ts +4 -13
  354. package/dist/server/src/index.d.ts.map +1 -1
  355. package/dist/server/src/middlewares/index.d.ts.map +1 -1
  356. package/dist/server/src/middlewares/rateLimit.d.ts.map +1 -1
  357. package/dist/server/src/register.d.ts.map +1 -1
  358. package/dist/server/src/services/action.d.ts.map +1 -1
  359. package/dist/server/src/services/api-token.d.ts.map +1 -1
  360. package/dist/server/src/services/auth.d.ts +6 -1
  361. package/dist/server/src/services/auth.d.ts.map +1 -1
  362. package/dist/server/src/services/condition.d.ts.map +1 -1
  363. package/dist/server/src/services/content-type.d.ts.map +1 -1
  364. package/dist/server/src/services/homepage.d.ts +1 -1
  365. package/dist/server/src/services/homepage.d.ts.map +1 -1
  366. package/dist/server/src/services/index.d.ts +2 -2
  367. package/dist/server/src/services/index.d.ts.map +1 -1
  368. package/dist/server/src/services/passport/local-strategy.d.ts.map +1 -1
  369. package/dist/server/src/services/passport.d.ts.map +1 -1
  370. package/dist/server/src/services/permission/engine.d.ts.map +1 -1
  371. package/dist/server/src/services/permission/permissions-manager/permission-fields.d.ts.map +1 -1
  372. package/dist/server/src/services/permission/permissions-manager/sanitize.d.ts.map +1 -1
  373. package/dist/server/src/services/permission/permissions-manager/validate.d.ts.map +1 -1
  374. package/dist/server/src/services/permission/queries.d.ts.map +1 -1
  375. package/dist/server/src/services/permission/rename-fields.d.ts +21 -0
  376. package/dist/server/src/services/permission/rename-fields.d.ts.map +1 -0
  377. package/dist/server/src/services/permission/sections-builder/section.d.ts.map +1 -1
  378. package/dist/server/src/services/permission/sections-builder/utils.d.ts +1 -1
  379. package/dist/server/src/services/permission/sections-builder/utils.d.ts.map +1 -1
  380. package/dist/server/src/services/role.d.ts +1 -1
  381. package/dist/server/src/services/role.d.ts.map +1 -1
  382. package/dist/server/src/services/transfer/token.d.ts.map +1 -1
  383. package/dist/server/src/services/user.d.ts.map +1 -1
  384. package/dist/server/src/strategies/content-api-token.d.ts.map +1 -1
  385. package/dist/server/src/validation/user.d.ts.map +1 -1
  386. package/dist/shared/contracts/admin.d.ts +36 -2
  387. package/dist/shared/contracts/admin.d.ts.map +1 -1
  388. package/package.json +13 -13
@@ -1 +1 @@
1
- {"version":3,"file":"MediaLibraryBanner.mjs","sources":["../../../../../admin/src/components/MediaLibraryBanner.tsx"],"sourcesContent":["import { LinkButton, Typography } from '@strapi/design-system';\nimport { ExternalLink } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { useScopedPersistentState } from '../hooks/usePersistentState';\n\nimport { DismissibleBanner } from './DismissibleBanner';\n\nconst Banner = ({\n isLegacyMediaLibrary,\n onDismiss,\n}: {\n isLegacyMediaLibrary: boolean;\n onDismiss: () => void;\n}) => {\n const { formatMessage } = useIntl();\n\n return (\n <DismissibleBanner\n onDismiss={onDismiss}\n closeLabel={formatMessage({\n id: 'app.components.MediaLibraryBanner.close',\n defaultMessage: 'Close',\n })}\n message={\n <>\n <Typography\n variant=\"delta\"\n fontWeight=\"bold\"\n textColor=\"neutral0\"\n textAlign=\"center\"\n fontSize={2}\n >\n {formatMessage({\n id: 'app.components.MediaLibraryBanner.intro',\n defaultMessage: 'Introducing the new Media Library ',\n })}\n </Typography>\n <Typography\n variant=\"delta\"\n textColor=\"neutral0\"\n textAlign=\"center\"\n paddingRight={4}\n fontSize={2}\n >\n {formatMessage(\n isLegacyMediaLibrary\n ? {\n id: 'app.components.MediaLibraryBanner.text',\n defaultMessage:\n 'Check the documentation to learn how to switch to the new one.',\n }\n : {\n id: 'app.components.MediaLibraryBanner.text.enabled',\n defaultMessage: \"You're now using the revamped version.\",\n }\n )}\n </Typography>\n </>\n }\n action={\n isLegacyMediaLibrary ? (\n <LinkButton\n width=\"max-content\"\n variant=\"tertiary\"\n startIcon={<ExternalLink />}\n href=\"https://docs.strapi.io/cms/features/media-library\"\n target=\"_blank\"\n >\n {formatMessage({\n id: 'app.components.MediaLibraryBanner.button',\n defaultMessage: 'Docs',\n })}\n </LinkButton>\n ) : (\n <LinkButton\n width=\"max-content\"\n variant=\"tertiary\"\n href=\"https://strapi.io/blog/strapi-release-roundup-everything-that-changed-between-june-and-august-2026\"\n target=\"_blank\"\n >\n {formatMessage({\n id: 'app.components.MediaLibraryBanner.button.enabled',\n defaultMessage: 'Read blog post',\n })}\n </LinkButton>\n )\n }\n />\n );\n};\n\nconst MediaLibraryBanner = () => {\n const isLegacyMediaLibrary = window.strapi.featureFlags.isEnabled('useLegacyMediaLibrary');\n\n // The flag state is part of the key (not the stored value) so dismissing one\n // message never collides with the other, and toggling `useLegacyMediaLibrary`\n // (enabling it, or rolling it back) brings the banner back with the right message.\n const [isDismissed, setIsDismissed] = useScopedPersistentState<boolean>(\n `STRAPI_MEDIA_LIBRARY_BANNER_DISMISSED_FOR_${isLegacyMediaLibrary}`,\n false\n );\n\n if (isDismissed) {\n return null;\n }\n\n return (\n <Banner isLegacyMediaLibrary={isLegacyMediaLibrary} onDismiss={() => setIsDismissed(true)} />\n );\n};\n\nexport { MediaLibraryBanner };\n"],"names":["Banner","isLegacyMediaLibrary","onDismiss","formatMessage","useIntl","_jsx","DismissibleBanner","closeLabel","id","defaultMessage","message","_jsxs","_Fragment","Typography","variant","fontWeight","textColor","textAlign","fontSize","paddingRight","action","LinkButton","width","startIcon","ExternalLink","href","target","MediaLibraryBanner","window","strapi","featureFlags","isEnabled","isDismissed","setIsDismissed","useScopedPersistentState"],"mappings":";;;;;;;AAQA,MAAMA,SAAS,CAAC,EACdC,oBAAoB,EACpBC,SAAS,EAIV,GAAA;IACC,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAE1B,IAAA,qBACEC,GAAA,CAACC,iBAAAA,EAAAA;QACCJ,SAAAA,EAAWA,SAAAA;AACXK,QAAAA,UAAAA,EAAYJ,aAAAA,CAAc;YACxBK,EAAAA,EAAI,yCAAA;YACJC,cAAAA,EAAgB;AAClB,SAAA,CAAA;QACAC,OAAAA,gBACEC,IAAA,CAAAC,QAAA,EAAA;;8BACEP,GAAA,CAACQ,UAAAA,EAAAA;oBACCC,OAAAA,EAAQ,OAAA;oBACRC,UAAAA,EAAW,MAAA;oBACXC,SAAAA,EAAU,UAAA;oBACVC,SAAAA,EAAU,QAAA;oBACVC,QAAAA,EAAU,CAAA;8BAETf,aAAAA,CAAc;wBACbK,EAAAA,EAAI,yCAAA;wBACJC,cAAAA,EAAgB;AAClB,qBAAA;;8BAEFJ,GAAA,CAACQ,UAAAA,EAAAA;oBACCC,OAAAA,EAAQ,OAAA;oBACRE,SAAAA,EAAU,UAAA;oBACVC,SAAAA,EAAU,QAAA;oBACVE,YAAAA,EAAc,CAAA;oBACdD,QAAAA,EAAU,CAAA;AAETf,oBAAAA,QAAAA,EAAAA,aAAAA,CACCF,oBAAAA,GACI;wBACEO,EAAAA,EAAI,wCAAA;wBACJC,cAAAA,EACE;qBACJ,GACA;wBACED,EAAAA,EAAI,gDAAA;wBACJC,cAAAA,EAAgB;AAClB,qBAAA;;;;AAKZW,QAAAA,MAAAA,EACEnB,qCACEI,GAAA,CAACgB,UAAAA,EAAAA;YACCC,KAAAA,EAAM,aAAA;YACNR,OAAAA,EAAQ,UAAA;AACRS,YAAAA,SAAAA,gBAAWlB,GAAA,CAACmB,YAAAA,EAAAA,EAAAA,CAAAA;YACZC,IAAAA,EAAK,mDAAA;YACLC,MAAAA,EAAO,QAAA;sBAENvB,aAAAA,CAAc;gBACbK,EAAAA,EAAI,0CAAA;gBACJC,cAAAA,EAAgB;AAClB,aAAA;2BAGFJ,GAAA,CAACgB,UAAAA,EAAAA;YACCC,KAAAA,EAAM,aAAA;YACNR,OAAAA,EAAQ,UAAA;YACRW,IAAAA,EAAK,oGAAA;YACLC,MAAAA,EAAO,QAAA;sBAENvB,aAAAA,CAAc;gBACbK,EAAAA,EAAI,kDAAA;gBACJC,cAAAA,EAAgB;AAClB,aAAA;;;AAMZ,CAAA;AAEA,MAAMkB,kBAAAA,GAAqB,IAAA;AACzB,IAAA,MAAM1B,uBAAuB2B,MAAAA,CAAOC,MAAM,CAACC,YAAY,CAACC,SAAS,CAAC,uBAAA,CAAA;;;;IAKlE,MAAM,CAACC,aAAaC,cAAAA,CAAe,GAAGC,yBACpC,CAAC,0CAA0C,EAAEjC,oBAAAA,CAAAA,CAAsB,EACnE,KAAA,CAAA;AAGF,IAAA,IAAI+B,WAAAA,EAAa;QACf,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,qBACE3B,GAAA,CAACL,MAAAA,EAAAA;QAAOC,oBAAAA,EAAsBA,oBAAAA;AAAsBC,QAAAA,SAAAA,EAAW,IAAM+B,cAAAA,CAAe,IAAA;;AAExF;;;;"}
1
+ {"version":3,"file":"MediaLibraryBanner.mjs","sources":["../../../../../admin/src/components/MediaLibraryBanner.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { LinkButton, Typography } from '@strapi/design-system';\nimport { ExternalLink } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { useMatch } from 'react-router-dom';\n\nimport { useScopedPersistentState } from '../hooks/usePersistentState';\n\nimport { DismissibleBanner } from './DismissibleBanner';\n\nconst Banner = ({\n isLegacyMediaLibrary,\n onDismiss,\n}: {\n isLegacyMediaLibrary: boolean;\n onDismiss: () => void;\n}) => {\n const { formatMessage } = useIntl();\n\n return (\n <DismissibleBanner\n onDismiss={onDismiss}\n closeLabel={formatMessage({\n id: 'app.components.MediaLibraryBanner.close',\n defaultMessage: 'Close',\n })}\n message={\n <>\n <Typography\n variant=\"delta\"\n fontWeight=\"bold\"\n textColor=\"neutral0\"\n textAlign=\"center\"\n fontSize={2}\n >\n {formatMessage({\n id: 'app.components.MediaLibraryBanner.intro',\n defaultMessage: 'Introducing the new Media Library ',\n })}\n </Typography>\n <Typography\n variant=\"delta\"\n textColor=\"neutral0\"\n textAlign=\"center\"\n paddingRight={4}\n fontSize={2}\n >\n {formatMessage(\n isLegacyMediaLibrary\n ? {\n id: 'app.components.MediaLibraryBanner.text',\n defaultMessage:\n 'Check the documentation to learn how to switch to the new one.',\n }\n : {\n id: 'app.components.MediaLibraryBanner.text.enabled',\n defaultMessage: \"You're now using the revamped version.\",\n }\n )}\n </Typography>\n </>\n }\n action={\n isLegacyMediaLibrary ? (\n <LinkButton\n width=\"max-content\"\n variant=\"tertiary\"\n startIcon={<ExternalLink />}\n href=\"https://docs.strapi.io/cms/features/media-library\"\n target=\"_blank\"\n >\n {formatMessage({\n id: 'app.components.MediaLibraryBanner.button',\n defaultMessage: 'Docs',\n })}\n </LinkButton>\n ) : (\n <LinkButton\n width=\"max-content\"\n variant=\"tertiary\"\n href=\"https://strapi.io/blog/strapi-release-roundup-everything-that-changed-between-june-and-august-2026\"\n target=\"_blank\"\n >\n {formatMessage({\n id: 'app.components.MediaLibraryBanner.button.enabled',\n defaultMessage: 'Read blog post',\n })}\n </LinkButton>\n )\n }\n />\n );\n};\n\ninterface MediaLibraryBannerProps {\n /**\n * Called synchronously (before paint) whenever this banner's own visibility changes, so a\n * parent rendering it alongside another banner (e.g. `UpsellBanner`) can hide that other one\n * instead of stacking both. This banner owns its dismissal state, so it's the source of truth\n * for whether it's showing — the parent shouldn't have to re-derive that itself.\n */\n onVisibilityChange?: (isVisible: boolean) => void;\n}\n\nconst MediaLibraryBanner = ({ onVisibilityChange }: MediaLibraryBannerProps = {}) => {\n const isLegacyMediaLibrary = window.strapi.featureFlags.isEnabled('useLegacyMediaLibrary');\n\n // The flag state is part of the key (not the stored value) so dismissing one\n // message never collides with the other, and toggling `useLegacyMediaLibrary`\n // (enabling it, or rolling it back) brings the banner back with the right message.\n const [isDismissed, setIsDismissed] = useScopedPersistentState<boolean>(\n `STRAPI_MEDIA_LIBRARY_BANNER_DISMISSED_FOR_${isLegacyMediaLibrary}`,\n false\n );\n\n // `AuthenticatedLayout` renders this banner on every admin page, but it's only\n // relevant on the Media Library itself (both the new and legacy `upload` plugin\n // route share the same `plugins/upload` mount point).\n const isOnMediaLibraryPage = useMatch('/plugins/upload/*') !== null;\n\n const isVisible = isOnMediaLibraryPage && !isDismissed;\n\n // useLayoutEffect (not useEffect) so the parent's re-render from this lands before the\n // browser paints — otherwise a possibly-visible `UpsellBanner` would flash on screen for a\n // frame before being hidden.\n React.useLayoutEffect(() => {\n onVisibilityChange?.(isVisible);\n }, [isVisible, onVisibilityChange]);\n\n if (!isVisible) {\n return null;\n }\n\n return (\n <Banner isLegacyMediaLibrary={isLegacyMediaLibrary} onDismiss={() => setIsDismissed(true)} />\n );\n};\n\nexport { MediaLibraryBanner };\n"],"names":["Banner","isLegacyMediaLibrary","onDismiss","formatMessage","useIntl","_jsx","DismissibleBanner","closeLabel","id","defaultMessage","message","_jsxs","_Fragment","Typography","variant","fontWeight","textColor","textAlign","fontSize","paddingRight","action","LinkButton","width","startIcon","ExternalLink","href","target","MediaLibraryBanner","onVisibilityChange","window","strapi","featureFlags","isEnabled","isDismissed","setIsDismissed","useScopedPersistentState","isOnMediaLibraryPage","useMatch","isVisible","React","useLayoutEffect"],"mappings":";;;;;;;;;AAWA,MAAMA,SAAS,CAAC,EACdC,oBAAoB,EACpBC,SAAS,EAIV,GAAA;IACC,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAE1B,IAAA,qBACEC,GAAA,CAACC,iBAAAA,EAAAA;QACCJ,SAAAA,EAAWA,SAAAA;AACXK,QAAAA,UAAAA,EAAYJ,aAAAA,CAAc;YACxBK,EAAAA,EAAI,yCAAA;YACJC,cAAAA,EAAgB;AAClB,SAAA,CAAA;QACAC,OAAAA,gBACEC,IAAA,CAAAC,QAAA,EAAA;;8BACEP,GAAA,CAACQ,UAAAA,EAAAA;oBACCC,OAAAA,EAAQ,OAAA;oBACRC,UAAAA,EAAW,MAAA;oBACXC,SAAAA,EAAU,UAAA;oBACVC,SAAAA,EAAU,QAAA;oBACVC,QAAAA,EAAU,CAAA;8BAETf,aAAAA,CAAc;wBACbK,EAAAA,EAAI,yCAAA;wBACJC,cAAAA,EAAgB;AAClB,qBAAA;;8BAEFJ,GAAA,CAACQ,UAAAA,EAAAA;oBACCC,OAAAA,EAAQ,OAAA;oBACRE,SAAAA,EAAU,UAAA;oBACVC,SAAAA,EAAU,QAAA;oBACVE,YAAAA,EAAc,CAAA;oBACdD,QAAAA,EAAU,CAAA;AAETf,oBAAAA,QAAAA,EAAAA,aAAAA,CACCF,oBAAAA,GACI;wBACEO,EAAAA,EAAI,wCAAA;wBACJC,cAAAA,EACE;qBACJ,GACA;wBACED,EAAAA,EAAI,gDAAA;wBACJC,cAAAA,EAAgB;AAClB,qBAAA;;;;AAKZW,QAAAA,MAAAA,EACEnB,qCACEI,GAAA,CAACgB,UAAAA,EAAAA;YACCC,KAAAA,EAAM,aAAA;YACNR,OAAAA,EAAQ,UAAA;AACRS,YAAAA,SAAAA,gBAAWlB,GAAA,CAACmB,YAAAA,EAAAA,EAAAA,CAAAA;YACZC,IAAAA,EAAK,mDAAA;YACLC,MAAAA,EAAO,QAAA;sBAENvB,aAAAA,CAAc;gBACbK,EAAAA,EAAI,0CAAA;gBACJC,cAAAA,EAAgB;AAClB,aAAA;2BAGFJ,GAAA,CAACgB,UAAAA,EAAAA;YACCC,KAAAA,EAAM,aAAA;YACNR,OAAAA,EAAQ,UAAA;YACRW,IAAAA,EAAK,oGAAA;YACLC,MAAAA,EAAO,QAAA;sBAENvB,aAAAA,CAAc;gBACbK,EAAAA,EAAI,kDAAA;gBACJC,cAAAA,EAAgB;AAClB,aAAA;;;AAMZ,CAAA;AAYA,MAAMkB,qBAAqB,CAAC,EAAEC,kBAAkB,EAA2B,GAAG,EAAE,GAAA;AAC9E,IAAA,MAAM3B,uBAAuB4B,MAAAA,CAAOC,MAAM,CAACC,YAAY,CAACC,SAAS,CAAC,uBAAA,CAAA;;;;IAKlE,MAAM,CAACC,aAAaC,cAAAA,CAAe,GAAGC,yBACpC,CAAC,0CAA0C,EAAElC,oBAAAA,CAAAA,CAAsB,EACnE,KAAA,CAAA;;;;IAMF,MAAMmC,oBAAAA,GAAuBC,SAAS,mBAAA,CAAA,KAAyB,IAAA;IAE/D,MAAMC,SAAAA,GAAYF,wBAAwB,CAACH,WAAAA;;;;AAK3CM,IAAAA,KAAAA,CAAMC,eAAe,CAAC,IAAA;QACpBZ,kBAAAA,GAAqBU,SAAAA,CAAAA;IACvB,CAAA,EAAG;AAACA,QAAAA,SAAAA;AAAWV,QAAAA;AAAmB,KAAA,CAAA;AAElC,IAAA,IAAI,CAACU,SAAAA,EAAW;QACd,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,qBACEjC,GAAA,CAACL,MAAAA,EAAAA;QAAOC,oBAAAA,EAAsBA,oBAAAA;AAAsBC,QAAAA,SAAAA,EAAW,IAAMgC,cAAAA,CAAe,IAAA;;AAExF;;;;"}
@@ -48,6 +48,15 @@ const intervals = [
48
48
  * ```
49
49
  */ const RelativeTime = /*#__PURE__*/ React__namespace.forwardRef(({ timestamp, customIntervals = [], ...restProps }, forwardedRef)=>{
50
50
  const { formatRelativeTime, formatDate, formatTime } = reactIntl.useIntl();
51
+ // Invalid Date: intervalToDuration throws RangeError (see #27382).
52
+ if (!dateFns.isValid(timestamp)) {
53
+ return /*#__PURE__*/ jsxRuntime.jsx("time", {
54
+ ref: forwardedRef,
55
+ role: "time",
56
+ ...restProps,
57
+ children: "-"
58
+ });
59
+ }
51
60
  /**
52
61
  * TODO: make this auto-update, like a clock.
53
62
  */ const interval = dateFns.intervalToDuration({
@@ -1 +1 @@
1
- {"version":3,"file":"RelativeTime.js","sources":["../../../../../admin/src/components/RelativeTime.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Duration, intervalToDuration, isPast } from 'date-fns';\nimport { useIntl } from 'react-intl';\n\nconst intervals: Array<keyof Duration> = ['years', 'months', 'days', 'hours', 'minutes', 'seconds'];\n\ninterface CustomInterval {\n unit: keyof Duration;\n text: string;\n threshold: number;\n}\n\ninterface RelativeTimeProps extends React.ComponentPropsWithoutRef<'time'> {\n timestamp: Date;\n customIntervals?: CustomInterval[];\n}\n\n/**\n * Displays the relative time between a given timestamp and the current time.\n * You can display a custom message for given time intervals by passing an array of custom intervals.\n *\n * @example\n * ```jsx\n * <caption>Display \"last hour\" if the timestamp is less than an hour ago</caption>\n * <RelativeTime\n * timestamp={new Date('2021-01-01')}\n * customIntervals={[\n * { unit: 'hours', threshold: 1, text: 'last hour' },\n * ]}\n * ```\n */\nconst RelativeTime = React.forwardRef<HTMLTimeElement, RelativeTimeProps>(\n ({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {\n const { formatRelativeTime, formatDate, formatTime } = useIntl();\n\n /**\n * TODO: make this auto-update, like a clock.\n */\n const interval = intervalToDuration({\n start: timestamp,\n end: Date.now(),\n // see https://github.com/date-fns/date-fns/issues/2891 – No idea why it's all partial it returns it every time.\n }) as Required<Duration>;\n\n const unit =\n intervals.find((intervalUnit) => {\n return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);\n }) ?? 'seconds';\n\n const value = interval[unit] ?? 0;\n const relativeTime = isPast(timestamp) ? -value : value;\n\n // Display custom text if interval is less than the threshold\n const customInterval = customIntervals.find(\n (custom) => interval[custom.unit] < custom.threshold\n );\n\n const displayText = customInterval\n ? customInterval.text\n : formatRelativeTime(relativeTime, unit, { numeric: 'auto' });\n\n return (\n <time\n ref={forwardedRef}\n dateTime={timestamp.toISOString()}\n role=\"time\"\n title={`${formatDate(timestamp)} ${formatTime(timestamp)}`}\n {...restProps}\n >\n {displayText}\n </time>\n );\n }\n);\n\nexport { RelativeTime };\nexport type { CustomInterval, RelativeTimeProps };\n"],"names":["intervals","RelativeTime","React","forwardRef","timestamp","customIntervals","restProps","forwardedRef","formatRelativeTime","formatDate","formatTime","useIntl","interval","intervalToDuration","start","end","Date","now","unit","find","intervalUnit","Object","keys","includes","value","relativeTime","isPast","customInterval","custom","threshold","displayText","text","numeric","_jsx","time","ref","dateTime","toISOString","role","title"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,MAAMA,SAAAA,GAAmC;AAAC,IAAA,OAAA;AAAS,IAAA,QAAA;AAAU,IAAA,MAAA;AAAQ,IAAA,OAAA;AAAS,IAAA,SAAA;AAAW,IAAA;AAAU,CAAA;AAanG;;;;;;;;;;;;;AAaC,IACD,MAAMC,YAAAA,iBAAeC,gBAAAA,CAAMC,UAAU,CACnC,CAAC,EAAEC,SAAS,EAAEC,eAAAA,GAAkB,EAAE,EAAE,GAAGC,WAAW,EAAEC,YAAAA,GAAAA;AAClD,IAAA,MAAM,EAAEC,kBAAkB,EAAEC,UAAU,EAAEC,UAAU,EAAE,GAAGC,iBAAAA,EAAAA;AAEvD;;QAGA,MAAMC,WAAWC,0BAAAA,CAAmB;QAClCC,KAAAA,EAAOV,SAAAA;AACPW,QAAAA,GAAAA,EAAKC,KAAKC,GAAG;AAEf,KAAA,CAAA;AAEA,IAAA,MAAMC,IAAAA,GACJlB,SAAAA,CAAUmB,IAAI,CAAC,CAACC,YAAAA,GAAAA;QACd,OAAOR,QAAQ,CAACQ,YAAAA,CAAa,GAAG,CAAA,IAAKC,OAAOC,IAAI,CAACV,QAAAA,CAAAA,CAAUW,QAAQ,CAACH,YAAAA,CAAAA;IACtE,CAAA,CAAA,IAAM,SAAA;AAER,IAAA,MAAMI,KAAAA,GAAQZ,QAAQ,CAACM,IAAAA,CAAK,IAAI,CAAA;AAChC,IAAA,MAAMO,YAAAA,GAAeC,cAAAA,CAAOtB,SAAAA,CAAAA,GAAa,CAACoB,KAAAA,GAAQA,KAAAA;;AAGlD,IAAA,MAAMG,cAAAA,GAAiBtB,eAAAA,CAAgBc,IAAI,CACzC,CAACS,MAAAA,GAAWhB,QAAQ,CAACgB,MAAAA,CAAOV,IAAI,CAAC,GAAGU,OAAOC,SAAS,CAAA;AAGtD,IAAA,MAAMC,cAAcH,cAAAA,GAChBA,cAAAA,CAAeI,IAAI,GACnBvB,kBAAAA,CAAmBiB,cAAcP,IAAAA,EAAM;QAAEc,OAAAA,EAAS;AAAO,KAAA,CAAA;AAE7D,IAAA,qBACEC,cAAA,CAACC,MAAAA,EAAAA;QACCC,GAAAA,EAAK5B,YAAAA;AACL6B,QAAAA,QAAAA,EAAUhC,UAAUiC,WAAW,EAAA;QAC/BC,IAAAA,EAAK,MAAA;AACLC,QAAAA,KAAAA,EAAO,GAAG9B,UAAAA,CAAWL,SAAAA,CAAAA,CAAW,CAAC,EAAEM,WAAWN,SAAAA,CAAAA,CAAAA,CAAY;AACzD,QAAA,GAAGE,SAAS;AAEZwB,QAAAA,QAAAA,EAAAA;;AAGP,CAAA;;;;"}
1
+ {"version":3,"file":"RelativeTime.js","sources":["../../../../../admin/src/components/RelativeTime.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Duration, intervalToDuration, isPast, isValid } from 'date-fns';\nimport { useIntl } from 'react-intl';\n\nconst intervals: Array<keyof Duration> = ['years', 'months', 'days', 'hours', 'minutes', 'seconds'];\n\ninterface CustomInterval {\n unit: keyof Duration;\n text: string;\n threshold: number;\n}\n\ninterface RelativeTimeProps extends React.ComponentPropsWithoutRef<'time'> {\n timestamp: Date;\n customIntervals?: CustomInterval[];\n}\n\n/**\n * Displays the relative time between a given timestamp and the current time.\n * You can display a custom message for given time intervals by passing an array of custom intervals.\n *\n * @example\n * ```jsx\n * <caption>Display \"last hour\" if the timestamp is less than an hour ago</caption>\n * <RelativeTime\n * timestamp={new Date('2021-01-01')}\n * customIntervals={[\n * { unit: 'hours', threshold: 1, text: 'last hour' },\n * ]}\n * ```\n */\nconst RelativeTime = React.forwardRef<HTMLTimeElement, RelativeTimeProps>(\n ({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {\n const { formatRelativeTime, formatDate, formatTime } = useIntl();\n\n // Invalid Date: intervalToDuration throws RangeError (see #27382).\n if (!isValid(timestamp)) {\n return (\n <time ref={forwardedRef} role=\"time\" {...restProps}>\n -\n </time>\n );\n }\n\n /**\n * TODO: make this auto-update, like a clock.\n */\n const interval = intervalToDuration({\n start: timestamp,\n end: Date.now(),\n // see https://github.com/date-fns/date-fns/issues/2891 – No idea why it's all partial it returns it every time.\n }) as Required<Duration>;\n\n const unit =\n intervals.find((intervalUnit) => {\n return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);\n }) ?? 'seconds';\n\n const value = interval[unit] ?? 0;\n const relativeTime = isPast(timestamp) ? -value : value;\n\n // Display custom text if interval is less than the threshold\n const customInterval = customIntervals.find(\n (custom) => interval[custom.unit] < custom.threshold\n );\n\n const displayText = customInterval\n ? customInterval.text\n : formatRelativeTime(relativeTime, unit, { numeric: 'auto' });\n\n return (\n <time\n ref={forwardedRef}\n dateTime={timestamp.toISOString()}\n role=\"time\"\n title={`${formatDate(timestamp)} ${formatTime(timestamp)}`}\n {...restProps}\n >\n {displayText}\n </time>\n );\n }\n);\n\nexport { RelativeTime };\nexport type { CustomInterval, RelativeTimeProps };\n"],"names":["intervals","RelativeTime","React","forwardRef","timestamp","customIntervals","restProps","forwardedRef","formatRelativeTime","formatDate","formatTime","useIntl","isValid","_jsx","time","ref","role","interval","intervalToDuration","start","end","Date","now","unit","find","intervalUnit","Object","keys","includes","value","relativeTime","isPast","customInterval","custom","threshold","displayText","text","numeric","dateTime","toISOString","title"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,MAAMA,SAAAA,GAAmC;AAAC,IAAA,OAAA;AAAS,IAAA,QAAA;AAAU,IAAA,MAAA;AAAQ,IAAA,OAAA;AAAS,IAAA,SAAA;AAAW,IAAA;AAAU,CAAA;AAanG;;;;;;;;;;;;;AAaC,IACD,MAAMC,YAAAA,iBAAeC,gBAAAA,CAAMC,UAAU,CACnC,CAAC,EAAEC,SAAS,EAAEC,eAAAA,GAAkB,EAAE,EAAE,GAAGC,WAAW,EAAEC,YAAAA,GAAAA;AAClD,IAAA,MAAM,EAAEC,kBAAkB,EAAEC,UAAU,EAAEC,UAAU,EAAE,GAAGC,iBAAAA,EAAAA;;IAGvD,IAAI,CAACC,gBAAQR,SAAAA,CAAAA,EAAY;AACvB,QAAA,qBACES,cAAA,CAACC,MAAAA,EAAAA;YAAKC,GAAAA,EAAKR,YAAAA;YAAcS,IAAAA,EAAK,MAAA;AAAQ,YAAA,GAAGV,SAAS;AAAE,YAAA,QAAA,EAAA;;AAIxD,IAAA;AAEA;;QAGA,MAAMW,WAAWC,0BAAAA,CAAmB;QAClCC,KAAAA,EAAOf,SAAAA;AACPgB,QAAAA,GAAAA,EAAKC,KAAKC,GAAG;AAEf,KAAA,CAAA;AAEA,IAAA,MAAMC,IAAAA,GACJvB,SAAAA,CAAUwB,IAAI,CAAC,CAACC,YAAAA,GAAAA;QACd,OAAOR,QAAQ,CAACQ,YAAAA,CAAa,GAAG,CAAA,IAAKC,OAAOC,IAAI,CAACV,QAAAA,CAAAA,CAAUW,QAAQ,CAACH,YAAAA,CAAAA;IACtE,CAAA,CAAA,IAAM,SAAA;AAER,IAAA,MAAMI,KAAAA,GAAQZ,QAAQ,CAACM,IAAAA,CAAK,IAAI,CAAA;AAChC,IAAA,MAAMO,YAAAA,GAAeC,cAAAA,CAAO3B,SAAAA,CAAAA,GAAa,CAACyB,KAAAA,GAAQA,KAAAA;;AAGlD,IAAA,MAAMG,cAAAA,GAAiB3B,eAAAA,CAAgBmB,IAAI,CACzC,CAACS,MAAAA,GAAWhB,QAAQ,CAACgB,MAAAA,CAAOV,IAAI,CAAC,GAAGU,OAAOC,SAAS,CAAA;AAGtD,IAAA,MAAMC,cAAcH,cAAAA,GAChBA,cAAAA,CAAeI,IAAI,GACnB5B,kBAAAA,CAAmBsB,cAAcP,IAAAA,EAAM;QAAEc,OAAAA,EAAS;AAAO,KAAA,CAAA;AAE7D,IAAA,qBACExB,cAAA,CAACC,MAAAA,EAAAA;QACCC,GAAAA,EAAKR,YAAAA;AACL+B,QAAAA,QAAAA,EAAUlC,UAAUmC,WAAW,EAAA;QAC/BvB,IAAAA,EAAK,MAAA;AACLwB,QAAAA,KAAAA,EAAO,GAAG/B,UAAAA,CAAWL,SAAAA,CAAAA,CAAW,CAAC,EAAEM,WAAWN,SAAAA,CAAAA,CAAAA,CAAY;AACzD,QAAA,GAAGE,SAAS;AAEZ6B,QAAAA,QAAAA,EAAAA;;AAGP,CAAA;;;;"}
@@ -1,6 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import { intervalToDuration, isPast } from 'date-fns';
3
+ import { isValid, intervalToDuration, isPast } from 'date-fns';
4
4
  import { useIntl } from 'react-intl';
5
5
 
6
6
  const intervals = [
@@ -26,6 +26,15 @@ const intervals = [
26
26
  * ```
27
27
  */ const RelativeTime = /*#__PURE__*/ React.forwardRef(({ timestamp, customIntervals = [], ...restProps }, forwardedRef)=>{
28
28
  const { formatRelativeTime, formatDate, formatTime } = useIntl();
29
+ // Invalid Date: intervalToDuration throws RangeError (see #27382).
30
+ if (!isValid(timestamp)) {
31
+ return /*#__PURE__*/ jsx("time", {
32
+ ref: forwardedRef,
33
+ role: "time",
34
+ ...restProps,
35
+ children: "-"
36
+ });
37
+ }
29
38
  /**
30
39
  * TODO: make this auto-update, like a clock.
31
40
  */ const interval = intervalToDuration({
@@ -1 +1 @@
1
- {"version":3,"file":"RelativeTime.mjs","sources":["../../../../../admin/src/components/RelativeTime.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Duration, intervalToDuration, isPast } from 'date-fns';\nimport { useIntl } from 'react-intl';\n\nconst intervals: Array<keyof Duration> = ['years', 'months', 'days', 'hours', 'minutes', 'seconds'];\n\ninterface CustomInterval {\n unit: keyof Duration;\n text: string;\n threshold: number;\n}\n\ninterface RelativeTimeProps extends React.ComponentPropsWithoutRef<'time'> {\n timestamp: Date;\n customIntervals?: CustomInterval[];\n}\n\n/**\n * Displays the relative time between a given timestamp and the current time.\n * You can display a custom message for given time intervals by passing an array of custom intervals.\n *\n * @example\n * ```jsx\n * <caption>Display \"last hour\" if the timestamp is less than an hour ago</caption>\n * <RelativeTime\n * timestamp={new Date('2021-01-01')}\n * customIntervals={[\n * { unit: 'hours', threshold: 1, text: 'last hour' },\n * ]}\n * ```\n */\nconst RelativeTime = React.forwardRef<HTMLTimeElement, RelativeTimeProps>(\n ({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {\n const { formatRelativeTime, formatDate, formatTime } = useIntl();\n\n /**\n * TODO: make this auto-update, like a clock.\n */\n const interval = intervalToDuration({\n start: timestamp,\n end: Date.now(),\n // see https://github.com/date-fns/date-fns/issues/2891 – No idea why it's all partial it returns it every time.\n }) as Required<Duration>;\n\n const unit =\n intervals.find((intervalUnit) => {\n return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);\n }) ?? 'seconds';\n\n const value = interval[unit] ?? 0;\n const relativeTime = isPast(timestamp) ? -value : value;\n\n // Display custom text if interval is less than the threshold\n const customInterval = customIntervals.find(\n (custom) => interval[custom.unit] < custom.threshold\n );\n\n const displayText = customInterval\n ? customInterval.text\n : formatRelativeTime(relativeTime, unit, { numeric: 'auto' });\n\n return (\n <time\n ref={forwardedRef}\n dateTime={timestamp.toISOString()}\n role=\"time\"\n title={`${formatDate(timestamp)} ${formatTime(timestamp)}`}\n {...restProps}\n >\n {displayText}\n </time>\n );\n }\n);\n\nexport { RelativeTime };\nexport type { CustomInterval, RelativeTimeProps };\n"],"names":["intervals","RelativeTime","React","forwardRef","timestamp","customIntervals","restProps","forwardedRef","formatRelativeTime","formatDate","formatTime","useIntl","interval","intervalToDuration","start","end","Date","now","unit","find","intervalUnit","Object","keys","includes","value","relativeTime","isPast","customInterval","custom","threshold","displayText","text","numeric","_jsx","time","ref","dateTime","toISOString","role","title"],"mappings":";;;;;AAKA,MAAMA,SAAAA,GAAmC;AAAC,IAAA,OAAA;AAAS,IAAA,QAAA;AAAU,IAAA,MAAA;AAAQ,IAAA,OAAA;AAAS,IAAA,SAAA;AAAW,IAAA;AAAU,CAAA;AAanG;;;;;;;;;;;;;AAaC,IACD,MAAMC,YAAAA,iBAAeC,KAAAA,CAAMC,UAAU,CACnC,CAAC,EAAEC,SAAS,EAAEC,eAAAA,GAAkB,EAAE,EAAE,GAAGC,WAAW,EAAEC,YAAAA,GAAAA;AAClD,IAAA,MAAM,EAAEC,kBAAkB,EAAEC,UAAU,EAAEC,UAAU,EAAE,GAAGC,OAAAA,EAAAA;AAEvD;;QAGA,MAAMC,WAAWC,kBAAAA,CAAmB;QAClCC,KAAAA,EAAOV,SAAAA;AACPW,QAAAA,GAAAA,EAAKC,KAAKC,GAAG;AAEf,KAAA,CAAA;AAEA,IAAA,MAAMC,IAAAA,GACJlB,SAAAA,CAAUmB,IAAI,CAAC,CAACC,YAAAA,GAAAA;QACd,OAAOR,QAAQ,CAACQ,YAAAA,CAAa,GAAG,CAAA,IAAKC,OAAOC,IAAI,CAACV,QAAAA,CAAAA,CAAUW,QAAQ,CAACH,YAAAA,CAAAA;IACtE,CAAA,CAAA,IAAM,SAAA;AAER,IAAA,MAAMI,KAAAA,GAAQZ,QAAQ,CAACM,IAAAA,CAAK,IAAI,CAAA;AAChC,IAAA,MAAMO,YAAAA,GAAeC,MAAAA,CAAOtB,SAAAA,CAAAA,GAAa,CAACoB,KAAAA,GAAQA,KAAAA;;AAGlD,IAAA,MAAMG,cAAAA,GAAiBtB,eAAAA,CAAgBc,IAAI,CACzC,CAACS,MAAAA,GAAWhB,QAAQ,CAACgB,MAAAA,CAAOV,IAAI,CAAC,GAAGU,OAAOC,SAAS,CAAA;AAGtD,IAAA,MAAMC,cAAcH,cAAAA,GAChBA,cAAAA,CAAeI,IAAI,GACnBvB,kBAAAA,CAAmBiB,cAAcP,IAAAA,EAAM;QAAEc,OAAAA,EAAS;AAAO,KAAA,CAAA;AAE7D,IAAA,qBACEC,GAAA,CAACC,MAAAA,EAAAA;QACCC,GAAAA,EAAK5B,YAAAA;AACL6B,QAAAA,QAAAA,EAAUhC,UAAUiC,WAAW,EAAA;QAC/BC,IAAAA,EAAK,MAAA;AACLC,QAAAA,KAAAA,EAAO,GAAG9B,UAAAA,CAAWL,SAAAA,CAAAA,CAAW,CAAC,EAAEM,WAAWN,SAAAA,CAAAA,CAAAA,CAAY;AACzD,QAAA,GAAGE,SAAS;AAEZwB,QAAAA,QAAAA,EAAAA;;AAGP,CAAA;;;;"}
1
+ {"version":3,"file":"RelativeTime.mjs","sources":["../../../../../admin/src/components/RelativeTime.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Duration, intervalToDuration, isPast, isValid } from 'date-fns';\nimport { useIntl } from 'react-intl';\n\nconst intervals: Array<keyof Duration> = ['years', 'months', 'days', 'hours', 'minutes', 'seconds'];\n\ninterface CustomInterval {\n unit: keyof Duration;\n text: string;\n threshold: number;\n}\n\ninterface RelativeTimeProps extends React.ComponentPropsWithoutRef<'time'> {\n timestamp: Date;\n customIntervals?: CustomInterval[];\n}\n\n/**\n * Displays the relative time between a given timestamp and the current time.\n * You can display a custom message for given time intervals by passing an array of custom intervals.\n *\n * @example\n * ```jsx\n * <caption>Display \"last hour\" if the timestamp is less than an hour ago</caption>\n * <RelativeTime\n * timestamp={new Date('2021-01-01')}\n * customIntervals={[\n * { unit: 'hours', threshold: 1, text: 'last hour' },\n * ]}\n * ```\n */\nconst RelativeTime = React.forwardRef<HTMLTimeElement, RelativeTimeProps>(\n ({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {\n const { formatRelativeTime, formatDate, formatTime } = useIntl();\n\n // Invalid Date: intervalToDuration throws RangeError (see #27382).\n if (!isValid(timestamp)) {\n return (\n <time ref={forwardedRef} role=\"time\" {...restProps}>\n -\n </time>\n );\n }\n\n /**\n * TODO: make this auto-update, like a clock.\n */\n const interval = intervalToDuration({\n start: timestamp,\n end: Date.now(),\n // see https://github.com/date-fns/date-fns/issues/2891 – No idea why it's all partial it returns it every time.\n }) as Required<Duration>;\n\n const unit =\n intervals.find((intervalUnit) => {\n return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);\n }) ?? 'seconds';\n\n const value = interval[unit] ?? 0;\n const relativeTime = isPast(timestamp) ? -value : value;\n\n // Display custom text if interval is less than the threshold\n const customInterval = customIntervals.find(\n (custom) => interval[custom.unit] < custom.threshold\n );\n\n const displayText = customInterval\n ? customInterval.text\n : formatRelativeTime(relativeTime, unit, { numeric: 'auto' });\n\n return (\n <time\n ref={forwardedRef}\n dateTime={timestamp.toISOString()}\n role=\"time\"\n title={`${formatDate(timestamp)} ${formatTime(timestamp)}`}\n {...restProps}\n >\n {displayText}\n </time>\n );\n }\n);\n\nexport { RelativeTime };\nexport type { CustomInterval, RelativeTimeProps };\n"],"names":["intervals","RelativeTime","React","forwardRef","timestamp","customIntervals","restProps","forwardedRef","formatRelativeTime","formatDate","formatTime","useIntl","isValid","_jsx","time","ref","role","interval","intervalToDuration","start","end","Date","now","unit","find","intervalUnit","Object","keys","includes","value","relativeTime","isPast","customInterval","custom","threshold","displayText","text","numeric","dateTime","toISOString","title"],"mappings":";;;;;AAKA,MAAMA,SAAAA,GAAmC;AAAC,IAAA,OAAA;AAAS,IAAA,QAAA;AAAU,IAAA,MAAA;AAAQ,IAAA,OAAA;AAAS,IAAA,SAAA;AAAW,IAAA;AAAU,CAAA;AAanG;;;;;;;;;;;;;AAaC,IACD,MAAMC,YAAAA,iBAAeC,KAAAA,CAAMC,UAAU,CACnC,CAAC,EAAEC,SAAS,EAAEC,eAAAA,GAAkB,EAAE,EAAE,GAAGC,WAAW,EAAEC,YAAAA,GAAAA;AAClD,IAAA,MAAM,EAAEC,kBAAkB,EAAEC,UAAU,EAAEC,UAAU,EAAE,GAAGC,OAAAA,EAAAA;;IAGvD,IAAI,CAACC,QAAQR,SAAAA,CAAAA,EAAY;AACvB,QAAA,qBACES,GAAA,CAACC,MAAAA,EAAAA;YAAKC,GAAAA,EAAKR,YAAAA;YAAcS,IAAAA,EAAK,MAAA;AAAQ,YAAA,GAAGV,SAAS;AAAE,YAAA,QAAA,EAAA;;AAIxD,IAAA;AAEA;;QAGA,MAAMW,WAAWC,kBAAAA,CAAmB;QAClCC,KAAAA,EAAOf,SAAAA;AACPgB,QAAAA,GAAAA,EAAKC,KAAKC,GAAG;AAEf,KAAA,CAAA;AAEA,IAAA,MAAMC,IAAAA,GACJvB,SAAAA,CAAUwB,IAAI,CAAC,CAACC,YAAAA,GAAAA;QACd,OAAOR,QAAQ,CAACQ,YAAAA,CAAa,GAAG,CAAA,IAAKC,OAAOC,IAAI,CAACV,QAAAA,CAAAA,CAAUW,QAAQ,CAACH,YAAAA,CAAAA;IACtE,CAAA,CAAA,IAAM,SAAA;AAER,IAAA,MAAMI,KAAAA,GAAQZ,QAAQ,CAACM,IAAAA,CAAK,IAAI,CAAA;AAChC,IAAA,MAAMO,YAAAA,GAAeC,MAAAA,CAAO3B,SAAAA,CAAAA,GAAa,CAACyB,KAAAA,GAAQA,KAAAA;;AAGlD,IAAA,MAAMG,cAAAA,GAAiB3B,eAAAA,CAAgBmB,IAAI,CACzC,CAACS,MAAAA,GAAWhB,QAAQ,CAACgB,MAAAA,CAAOV,IAAI,CAAC,GAAGU,OAAOC,SAAS,CAAA;AAGtD,IAAA,MAAMC,cAAcH,cAAAA,GAChBA,cAAAA,CAAeI,IAAI,GACnB5B,kBAAAA,CAAmBsB,cAAcP,IAAAA,EAAM;QAAEc,OAAAA,EAAS;AAAO,KAAA,CAAA;AAE7D,IAAA,qBACExB,GAAA,CAACC,MAAAA,EAAAA;QACCC,GAAAA,EAAKR,YAAAA;AACL+B,QAAAA,QAAAA,EAAUlC,UAAUmC,WAAW,EAAA;QAC/BvB,IAAAA,EAAK,MAAA;AACLwB,QAAAA,KAAAA,EAAO,GAAG/B,UAAAA,CAAWL,SAAAA,CAAAA,CAAW,CAAC,EAAEM,WAAWN,SAAAA,CAAAA,CAAAA,CAAY;AACzD,QAAA,GAAGE,SAAS;AAEZ6B,QAAAA,QAAAA,EAAAA;;AAGP,CAAA;;;;"}
@@ -0,0 +1,52 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var React = require('react');
5
+ var reactRouterDom = require('react-router-dom');
6
+ var MediaLibraryBanner = require('./MediaLibraryBanner.js');
7
+ var UpsellBanner = require('./UpsellBanner.js');
8
+
9
+ function _interopNamespace(e) {
10
+ if (e && e.__esModule) return e;
11
+ var n = Object.create(null);
12
+ if (e) {
13
+ Object.keys(e).forEach(function (k) {
14
+ if (k !== 'default') {
15
+ var d = Object.getOwnPropertyDescriptor(e, k);
16
+ Object.defineProperty(n, k, d.get ? d : {
17
+ enumerable: true,
18
+ get: function () { return e[k]; }
19
+ });
20
+ }
21
+ });
22
+ }
23
+ n.default = e;
24
+ return Object.freeze(n);
25
+ }
26
+
27
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
28
+
29
+ /**
30
+ * @description Renders the admin's top banners, ensuring only one shows at a time instead of
31
+ * stacking: the Media Library banner takes priority over the upsell one. Kept as its own
32
+ * component (rather than inline in `AuthenticatedLayout`) so this wiring can be unit tested
33
+ * without the rest of the layout's unrelated dependencies (menu, tracking, app info, etc.).
34
+ */ const TopBanners = ()=>{
35
+ // Seeded from the current route so `UpsellBanner` (and its trial-license query) doesn't
36
+ // mount-then-immediately-unmount on first render when landing directly on the Media Library.
37
+ // `MediaLibraryBanner`'s own `onVisibilityChange` corrects this afterwards if it turns out
38
+ // dismissed, same as it does for any other visibility change.
39
+ const isOnMediaLibraryRoute = reactRouterDom.useMatch('/plugins/upload/*') !== null;
40
+ const [isMediaLibraryBannerVisible, setIsMediaLibraryBannerVisible] = React__namespace.useState(isOnMediaLibraryRoute);
41
+ return /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
42
+ children: [
43
+ !isMediaLibraryBannerVisible && /*#__PURE__*/ jsxRuntime.jsx(UpsellBanner.UpsellBanner, {}),
44
+ /*#__PURE__*/ jsxRuntime.jsx(MediaLibraryBanner.MediaLibraryBanner, {
45
+ onVisibilityChange: setIsMediaLibraryBannerVisible
46
+ })
47
+ ]
48
+ });
49
+ };
50
+
51
+ exports.TopBanners = TopBanners;
52
+ //# sourceMappingURL=TopBanners.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TopBanners.js","sources":["../../../../../admin/src/components/TopBanners.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useMatch } from 'react-router-dom';\n\nimport { MediaLibraryBanner } from './MediaLibraryBanner';\nimport { UpsellBanner } from './UpsellBanner';\n\n/**\n * @description Renders the admin's top banners, ensuring only one shows at a time instead of\n * stacking: the Media Library banner takes priority over the upsell one. Kept as its own\n * component (rather than inline in `AuthenticatedLayout`) so this wiring can be unit tested\n * without the rest of the layout's unrelated dependencies (menu, tracking, app info, etc.).\n */\nconst TopBanners = () => {\n // Seeded from the current route so `UpsellBanner` (and its trial-license query) doesn't\n // mount-then-immediately-unmount on first render when landing directly on the Media Library.\n // `MediaLibraryBanner`'s own `onVisibilityChange` corrects this afterwards if it turns out\n // dismissed, same as it does for any other visibility change.\n const isOnMediaLibraryRoute = useMatch('/plugins/upload/*') !== null;\n const [isMediaLibraryBannerVisible, setIsMediaLibraryBannerVisible] =\n React.useState(isOnMediaLibraryRoute);\n\n return (\n <>\n {!isMediaLibraryBannerVisible && <UpsellBanner />}\n <MediaLibraryBanner onVisibilityChange={setIsMediaLibraryBannerVisible} />\n </>\n );\n};\n\nexport { TopBanners };\n"],"names":["TopBanners","isOnMediaLibraryRoute","useMatch","isMediaLibraryBannerVisible","setIsMediaLibraryBannerVisible","React","useState","_jsxs","_Fragment","_jsx","UpsellBanner","MediaLibraryBanner","onVisibilityChange"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA;;;;;AAKC,UACKA,UAAAA,GAAa,IAAA;;;;;IAKjB,MAAMC,qBAAAA,GAAwBC,wBAAS,mBAAA,CAAA,KAAyB,IAAA;AAChE,IAAA,MAAM,CAACC,2BAAAA,EAA6BC,8BAAAA,CAA+B,GACjEC,gBAAAA,CAAMC,QAAQ,CAACL,qBAAAA,CAAAA;IAEjB,qBACEM,eAAA,CAAAC,mBAAA,EAAA;;AACG,YAAA,CAACL,6CAA+BM,cAAA,CAACC,yBAAAA,EAAAA,EAAAA,CAAAA;0BAClCD,cAAA,CAACE,qCAAAA,EAAAA;gBAAmBC,kBAAAA,EAAoBR;;;;AAG9C;;;;"}
@@ -0,0 +1,30 @@
1
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { useMatch } from 'react-router-dom';
4
+ import { MediaLibraryBanner } from './MediaLibraryBanner.mjs';
5
+ import { UpsellBanner } from './UpsellBanner.mjs';
6
+
7
+ /**
8
+ * @description Renders the admin's top banners, ensuring only one shows at a time instead of
9
+ * stacking: the Media Library banner takes priority over the upsell one. Kept as its own
10
+ * component (rather than inline in `AuthenticatedLayout`) so this wiring can be unit tested
11
+ * without the rest of the layout's unrelated dependencies (menu, tracking, app info, etc.).
12
+ */ const TopBanners = ()=>{
13
+ // Seeded from the current route so `UpsellBanner` (and its trial-license query) doesn't
14
+ // mount-then-immediately-unmount on first render when landing directly on the Media Library.
15
+ // `MediaLibraryBanner`'s own `onVisibilityChange` corrects this afterwards if it turns out
16
+ // dismissed, same as it does for any other visibility change.
17
+ const isOnMediaLibraryRoute = useMatch('/plugins/upload/*') !== null;
18
+ const [isMediaLibraryBannerVisible, setIsMediaLibraryBannerVisible] = React.useState(isOnMediaLibraryRoute);
19
+ return /*#__PURE__*/ jsxs(Fragment, {
20
+ children: [
21
+ !isMediaLibraryBannerVisible && /*#__PURE__*/ jsx(UpsellBanner, {}),
22
+ /*#__PURE__*/ jsx(MediaLibraryBanner, {
23
+ onVisibilityChange: setIsMediaLibraryBannerVisible
24
+ })
25
+ ]
26
+ });
27
+ };
28
+
29
+ export { TopBanners };
30
+ //# sourceMappingURL=TopBanners.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TopBanners.mjs","sources":["../../../../../admin/src/components/TopBanners.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useMatch } from 'react-router-dom';\n\nimport { MediaLibraryBanner } from './MediaLibraryBanner';\nimport { UpsellBanner } from './UpsellBanner';\n\n/**\n * @description Renders the admin's top banners, ensuring only one shows at a time instead of\n * stacking: the Media Library banner takes priority over the upsell one. Kept as its own\n * component (rather than inline in `AuthenticatedLayout`) so this wiring can be unit tested\n * without the rest of the layout's unrelated dependencies (menu, tracking, app info, etc.).\n */\nconst TopBanners = () => {\n // Seeded from the current route so `UpsellBanner` (and its trial-license query) doesn't\n // mount-then-immediately-unmount on first render when landing directly on the Media Library.\n // `MediaLibraryBanner`'s own `onVisibilityChange` corrects this afterwards if it turns out\n // dismissed, same as it does for any other visibility change.\n const isOnMediaLibraryRoute = useMatch('/plugins/upload/*') !== null;\n const [isMediaLibraryBannerVisible, setIsMediaLibraryBannerVisible] =\n React.useState(isOnMediaLibraryRoute);\n\n return (\n <>\n {!isMediaLibraryBannerVisible && <UpsellBanner />}\n <MediaLibraryBanner onVisibilityChange={setIsMediaLibraryBannerVisible} />\n </>\n );\n};\n\nexport { TopBanners };\n"],"names":["TopBanners","isOnMediaLibraryRoute","useMatch","isMediaLibraryBannerVisible","setIsMediaLibraryBannerVisible","React","useState","_jsxs","_Fragment","_jsx","UpsellBanner","MediaLibraryBanner","onVisibilityChange"],"mappings":";;;;;;AAOA;;;;;AAKC,UACKA,UAAAA,GAAa,IAAA;;;;;IAKjB,MAAMC,qBAAAA,GAAwBC,SAAS,mBAAA,CAAA,KAAyB,IAAA;AAChE,IAAA,MAAM,CAACC,2BAAAA,EAA6BC,8BAAAA,CAA+B,GACjEC,KAAAA,CAAMC,QAAQ,CAACL,qBAAAA,CAAAA;IAEjB,qBACEM,IAAA,CAAAC,QAAA,EAAA;;AACG,YAAA,CAACL,6CAA+BM,GAAA,CAACC,YAAAA,EAAAA,EAAAA,CAAAA;0BAClCD,GAAA,CAACE,kBAAAA,EAAAA;gBAAmBC,kBAAAA,EAAoBR;;;;AAG9C;;;;"}
@@ -7,24 +7,11 @@ var designSystem = require('@strapi/design-system');
7
7
  var icons = require('@strapi/icons');
8
8
  var dateFns = require('date-fns');
9
9
  var reactIntl = require('react-intl');
10
- var styledComponents = require('styled-components');
11
10
  var admin = require('../services/admin.js');
11
+ var theme = require('../constants/theme.js');
12
12
  var usePersistentState = require('../hooks/usePersistentState.js');
13
13
  var DismissibleBanner = require('./DismissibleBanner.js');
14
14
 
15
- /**
16
- * Unlike `DismissibleBanner`'s own close button, this has no banner box left to
17
- * anchor to once dismissed (the banner unmounts entirely), so it stays pinned
18
- * to the viewport instead.
19
- */ const FixedButtonWrapper = styledComponents.styled(designSystem.Box)`
20
- position: fixed;
21
- display: flex;
22
- flex-direction: column;
23
- z-index: 1;
24
- align-items: flex-end;
25
- top: 9px;
26
- right: 16px;
27
- `;
28
15
  const Banner = ({ isTrialEndedRecently, onDismiss })=>{
29
16
  const { formatMessage } = reactIntl.useIntl();
30
17
  return /*#__PURE__*/ jsxRuntime.jsx(DismissibleBanner.DismissibleBanner, {
@@ -113,15 +100,21 @@ const UpsellBanner = ()=>{
113
100
  return null;
114
101
  }
115
102
  if (isDismissed) {
116
- return /*#__PURE__*/ jsxRuntime.jsx(FixedButtonWrapper, {
103
+ return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Flex, {
104
+ justifyContent: "flex-end",
105
+ paddingTop: 1,
106
+ paddingBottom: 1,
107
+ paddingLeft: theme.RESPONSIVE_DEFAULT_SPACING,
108
+ paddingRight: theme.RESPONSIVE_DEFAULT_SPACING,
117
109
  children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.IconButton, {
110
+ variant: "ghost",
118
111
  withTooltip: false,
119
112
  label: formatMessage({
120
113
  id: 'app.components.UpsellBanner.reopen',
121
114
  defaultMessage: 'Reopen banner'
122
115
  }),
123
116
  onClick: handleReopen,
124
- children: /*#__PURE__*/ jsxRuntime.jsx(icons.ArrowsOut, {})
117
+ children: /*#__PURE__*/ jsxRuntime.jsx(icons.ChevronUp, {})
125
118
  })
126
119
  });
127
120
  }
@@ -1 +1 @@
1
- {"version":3,"file":"UpsellBanner.js","sources":["../../../../../admin/src/components/UpsellBanner.tsx"],"sourcesContent":["import { useEffect } from 'react';\n\nimport { useLicenseLimits } from '@strapi/admin/strapi-admin/ee';\nimport { Box, IconButton, LinkButton, Typography } from '@strapi/design-system';\nimport { ArrowsOut } from '@strapi/icons';\nimport { isAfter, isValid, subDays } from 'date-fns';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useGetLicenseTrialTimeLeftQuery } from '../../src/services/admin';\nimport { useScopedPersistentState } from '../hooks/usePersistentState';\n\nimport { DismissibleBanner } from './DismissibleBanner';\n\n/**\n * Unlike `DismissibleBanner`'s own close button, this has no banner box left to\n * anchor to once dismissed (the banner unmounts entirely), so it stays pinned\n * to the viewport instead.\n */\nconst FixedButtonWrapper = styled(Box)`\n position: fixed;\n display: flex;\n flex-direction: column;\n z-index: 1;\n align-items: flex-end;\n top: 9px;\n right: 16px;\n`;\n\nconst Banner = ({\n isTrialEndedRecently,\n onDismiss,\n}: {\n isTrialEndedRecently: boolean;\n onDismiss: () => void;\n}) => {\n const { formatMessage } = useIntl();\n\n return (\n <DismissibleBanner\n onDismiss={onDismiss}\n closeLabel={formatMessage({\n id: 'app.components.UpsellBanner.close',\n defaultMessage: 'Close',\n })}\n message={\n <>\n <Typography\n variant=\"delta\"\n fontWeight=\"bold\"\n textColor=\"neutral0\"\n textAlign=\"center\"\n fontSize={2}\n >\n {formatMessage(\n isTrialEndedRecently\n ? {\n id: 'app.components.UpsellBanner.intro.ended',\n defaultMessage: 'Your trial has ended: ',\n }\n : {\n id: 'app.components.UpsellBanner.intro',\n defaultMessage: 'Access to Growth plan features: ',\n }\n )}\n </Typography>\n <Typography\n variant=\"delta\"\n textColor=\"neutral0\"\n textAlign=\"center\"\n paddingRight={4}\n fontSize={2}\n >\n {formatMessage(\n isTrialEndedRecently\n ? {\n id: 'app.components.UpsellBanner.text.ended',\n defaultMessage: 'Keep access to Growth features by upgrading now.',\n }\n : {\n id: 'app.components.UpsellBanner.text',\n defaultMessage:\n 'As part of your trial, you can explore premium tools such as Content History, Releases, and Single Sign-On (SSO).',\n }\n )}\n </Typography>\n </>\n }\n action={\n <LinkButton\n width=\"max-content\"\n variant=\"tertiary\"\n href=\"https://billing.strapi.io\"\n target=\"_blank\"\n >\n {formatMessage(\n isTrialEndedRecently\n ? {\n id: 'app.components.UpsellBanner.button.ended',\n defaultMessage: 'Keep Growth plan',\n }\n : {\n id: 'app.components.UpsellBanner.button',\n defaultMessage: 'Upgrade now',\n }\n )}\n </LinkButton>\n }\n />\n );\n};\n\nconst UpsellBanner = () => {\n const { license } = useLicenseLimits();\n const { formatMessage } = useIntl();\n\n const [cachedTrialEndsAt, setCachedTrialEndsAt] = useScopedPersistentState<string | undefined>(\n 'STRAPI_FREE_TRIAL_ENDS_AT',\n undefined\n );\n\n const [dismissedFor, setDismissedFor] = useScopedPersistentState<string | undefined>(\n 'STRAPI_UPSELL_BANNER_DISMISSED_FOR',\n undefined\n );\n\n const sevenDaysAgo = subDays(new Date(), 7);\n\n const timeLeftData = useGetLicenseTrialTimeLeftQuery(undefined, {\n skip: !license?.isTrial,\n });\n\n useEffect(() => {\n if (timeLeftData.data?.trialEndsAt) {\n setCachedTrialEndsAt(timeLeftData.data.trialEndsAt);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [timeLeftData.data?.trialEndsAt]);\n\n // When the license is not a trial + not EE, and the cached trial end date is found in the localstorage, that means the trial has ended\n // We show the banner to encourage the user to upgrade (for 7 days after the trial ends)\n const isTrialEndedRecently = Boolean(\n !license?.isTrial &&\n !window.strapi.isEE &&\n cachedTrialEndsAt &&\n isAfter(new Date(cachedTrialEndsAt), sevenDaysAgo)\n );\n\n const trialEndsAt = timeLeftData.data?.trialEndsAt ?? cachedTrialEndsAt;\n\n const toCanonicalISO = (v: string | undefined): string | undefined => {\n if (!v) return undefined;\n const date = new Date(v);\n return isValid(date) ? date.toISOString() : undefined;\n };\n\n const isDismissed = Boolean(\n trialEndsAt && toCanonicalISO(dismissedFor) === toCanonicalISO(trialEndsAt)\n );\n\n const handleDismiss = () => setDismissedFor(toCanonicalISO(trialEndsAt));\n const handleReopen = () => setDismissedFor(undefined);\n\n if (!(timeLeftData.data?.trialEndsAt || isTrialEndedRecently)) {\n return null;\n }\n\n if (isDismissed) {\n return (\n <FixedButtonWrapper>\n <IconButton\n withTooltip={false}\n label={formatMessage({\n id: 'app.components.UpsellBanner.reopen',\n defaultMessage: 'Reopen banner',\n })}\n onClick={handleReopen}\n >\n <ArrowsOut />\n </IconButton>\n </FixedButtonWrapper>\n );\n }\n\n return <Banner isTrialEndedRecently={isTrialEndedRecently} onDismiss={handleDismiss} />;\n};\n\nexport { UpsellBanner };\n"],"names":["FixedButtonWrapper","styled","Box","Banner","isTrialEndedRecently","onDismiss","formatMessage","useIntl","_jsx","DismissibleBanner","closeLabel","id","defaultMessage","message","_jsxs","_Fragment","Typography","variant","fontWeight","textColor","textAlign","fontSize","paddingRight","action","LinkButton","width","href","target","UpsellBanner","license","useLicenseLimits","cachedTrialEndsAt","setCachedTrialEndsAt","useScopedPersistentState","undefined","dismissedFor","setDismissedFor","sevenDaysAgo","subDays","Date","timeLeftData","useGetLicenseTrialTimeLeftQuery","skip","isTrial","useEffect","data","trialEndsAt","Boolean","window","strapi","isEE","isAfter","toCanonicalISO","v","date","isValid","toISOString","isDismissed","handleDismiss","handleReopen","IconButton","withTooltip","label","onClick","ArrowsOut"],"mappings":"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"}
1
+ {"version":3,"file":"UpsellBanner.js","sources":["../../../../../admin/src/components/UpsellBanner.tsx"],"sourcesContent":["import { useEffect } from 'react';\n\nimport { useLicenseLimits } from '@strapi/admin/strapi-admin/ee';\nimport { Flex, IconButton, LinkButton, Typography } from '@strapi/design-system';\nimport { ChevronUp } from '@strapi/icons';\nimport { isAfter, isValid, subDays } from 'date-fns';\nimport { useIntl } from 'react-intl';\n\nimport { useGetLicenseTrialTimeLeftQuery } from '../../src/services/admin';\nimport { RESPONSIVE_DEFAULT_SPACING } from '../constants/theme';\nimport { useScopedPersistentState } from '../hooks/usePersistentState';\n\nimport { DismissibleBanner } from './DismissibleBanner';\n\nconst Banner = ({\n isTrialEndedRecently,\n onDismiss,\n}: {\n isTrialEndedRecently: boolean;\n onDismiss: () => void;\n}) => {\n const { formatMessage } = useIntl();\n\n return (\n <DismissibleBanner\n onDismiss={onDismiss}\n closeLabel={formatMessage({\n id: 'app.components.UpsellBanner.close',\n defaultMessage: 'Close',\n })}\n message={\n <>\n <Typography\n variant=\"delta\"\n fontWeight=\"bold\"\n textColor=\"neutral0\"\n textAlign=\"center\"\n fontSize={2}\n >\n {formatMessage(\n isTrialEndedRecently\n ? {\n id: 'app.components.UpsellBanner.intro.ended',\n defaultMessage: 'Your trial has ended: ',\n }\n : {\n id: 'app.components.UpsellBanner.intro',\n defaultMessage: 'Access to Growth plan features: ',\n }\n )}\n </Typography>\n <Typography\n variant=\"delta\"\n textColor=\"neutral0\"\n textAlign=\"center\"\n paddingRight={4}\n fontSize={2}\n >\n {formatMessage(\n isTrialEndedRecently\n ? {\n id: 'app.components.UpsellBanner.text.ended',\n defaultMessage: 'Keep access to Growth features by upgrading now.',\n }\n : {\n id: 'app.components.UpsellBanner.text',\n defaultMessage:\n 'As part of your trial, you can explore premium tools such as Content History, Releases, and Single Sign-On (SSO).',\n }\n )}\n </Typography>\n </>\n }\n action={\n <LinkButton\n width=\"max-content\"\n variant=\"tertiary\"\n href=\"https://billing.strapi.io\"\n target=\"_blank\"\n >\n {formatMessage(\n isTrialEndedRecently\n ? {\n id: 'app.components.UpsellBanner.button.ended',\n defaultMessage: 'Keep Growth plan',\n }\n : {\n id: 'app.components.UpsellBanner.button',\n defaultMessage: 'Upgrade now',\n }\n )}\n </LinkButton>\n }\n />\n );\n};\n\nconst UpsellBanner = () => {\n const { license } = useLicenseLimits();\n const { formatMessage } = useIntl();\n\n const [cachedTrialEndsAt, setCachedTrialEndsAt] = useScopedPersistentState<string | undefined>(\n 'STRAPI_FREE_TRIAL_ENDS_AT',\n undefined\n );\n\n const [dismissedFor, setDismissedFor] = useScopedPersistentState<string | undefined>(\n 'STRAPI_UPSELL_BANNER_DISMISSED_FOR',\n undefined\n );\n\n const sevenDaysAgo = subDays(new Date(), 7);\n\n const timeLeftData = useGetLicenseTrialTimeLeftQuery(undefined, {\n skip: !license?.isTrial,\n });\n\n useEffect(() => {\n if (timeLeftData.data?.trialEndsAt) {\n setCachedTrialEndsAt(timeLeftData.data.trialEndsAt);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [timeLeftData.data?.trialEndsAt]);\n\n // When the license is not a trial + not EE, and the cached trial end date is found in the localstorage, that means the trial has ended\n // We show the banner to encourage the user to upgrade (for 7 days after the trial ends)\n const isTrialEndedRecently = Boolean(\n !license?.isTrial &&\n !window.strapi.isEE &&\n cachedTrialEndsAt &&\n isAfter(new Date(cachedTrialEndsAt), sevenDaysAgo)\n );\n\n const trialEndsAt = timeLeftData.data?.trialEndsAt ?? cachedTrialEndsAt;\n\n const toCanonicalISO = (v: string | undefined): string | undefined => {\n if (!v) return undefined;\n const date = new Date(v);\n return isValid(date) ? date.toISOString() : undefined;\n };\n\n const isDismissed = Boolean(\n trialEndsAt && toCanonicalISO(dismissedFor) === toCanonicalISO(trialEndsAt)\n );\n\n const handleDismiss = () => setDismissedFor(toCanonicalISO(trialEndsAt));\n const handleReopen = () => setDismissedFor(undefined);\n\n if (!(timeLeftData.data?.trialEndsAt || isTrialEndedRecently)) {\n return null;\n }\n\n if (isDismissed) {\n return (\n <Flex\n justifyContent=\"flex-end\"\n paddingTop={1}\n paddingBottom={1}\n paddingLeft={RESPONSIVE_DEFAULT_SPACING}\n paddingRight={RESPONSIVE_DEFAULT_SPACING}\n >\n <IconButton\n variant=\"ghost\"\n withTooltip={false}\n label={formatMessage({\n id: 'app.components.UpsellBanner.reopen',\n defaultMessage: 'Reopen banner',\n })}\n onClick={handleReopen}\n >\n <ChevronUp />\n </IconButton>\n </Flex>\n );\n }\n\n return <Banner isTrialEndedRecently={isTrialEndedRecently} onDismiss={handleDismiss} />;\n};\n\nexport { UpsellBanner };\n"],"names":["Banner","isTrialEndedRecently","onDismiss","formatMessage","useIntl","_jsx","DismissibleBanner","closeLabel","id","defaultMessage","message","_jsxs","_Fragment","Typography","variant","fontWeight","textColor","textAlign","fontSize","paddingRight","action","LinkButton","width","href","target","UpsellBanner","license","useLicenseLimits","cachedTrialEndsAt","setCachedTrialEndsAt","useScopedPersistentState","undefined","dismissedFor","setDismissedFor","sevenDaysAgo","subDays","Date","timeLeftData","useGetLicenseTrialTimeLeftQuery","skip","isTrial","useEffect","data","trialEndsAt","Boolean","window","strapi","isEE","isAfter","toCanonicalISO","v","date","isValid","toISOString","isDismissed","handleDismiss","handleReopen","Flex","justifyContent","paddingTop","paddingBottom","paddingLeft","RESPONSIVE_DEFAULT_SPACING","IconButton","withTooltip","label","onClick","ChevronUp"],"mappings":"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"}
@@ -1,28 +1,15 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { useEffect } from 'react';
3
3
  import { useLicenseLimits } from '@strapi/admin/strapi-admin/ee';
4
- import { IconButton, Box, LinkButton, Typography } from '@strapi/design-system';
5
- import { ArrowsOut } from '@strapi/icons';
4
+ import { Flex, IconButton, LinkButton, Typography } from '@strapi/design-system';
5
+ import { ChevronUp } from '@strapi/icons';
6
6
  import { subDays, isAfter, isValid } from 'date-fns';
7
7
  import { useIntl } from 'react-intl';
8
- import { styled } from 'styled-components';
9
8
  import { useGetLicenseTrialTimeLeftQuery } from '../services/admin.mjs';
9
+ import { RESPONSIVE_DEFAULT_SPACING } from '../constants/theme.mjs';
10
10
  import { useScopedPersistentState } from '../hooks/usePersistentState.mjs';
11
11
  import { DismissibleBanner } from './DismissibleBanner.mjs';
12
12
 
13
- /**
14
- * Unlike `DismissibleBanner`'s own close button, this has no banner box left to
15
- * anchor to once dismissed (the banner unmounts entirely), so it stays pinned
16
- * to the viewport instead.
17
- */ const FixedButtonWrapper = styled(Box)`
18
- position: fixed;
19
- display: flex;
20
- flex-direction: column;
21
- z-index: 1;
22
- align-items: flex-end;
23
- top: 9px;
24
- right: 16px;
25
- `;
26
13
  const Banner = ({ isTrialEndedRecently, onDismiss })=>{
27
14
  const { formatMessage } = useIntl();
28
15
  return /*#__PURE__*/ jsx(DismissibleBanner, {
@@ -111,15 +98,21 @@ const UpsellBanner = ()=>{
111
98
  return null;
112
99
  }
113
100
  if (isDismissed) {
114
- return /*#__PURE__*/ jsx(FixedButtonWrapper, {
101
+ return /*#__PURE__*/ jsx(Flex, {
102
+ justifyContent: "flex-end",
103
+ paddingTop: 1,
104
+ paddingBottom: 1,
105
+ paddingLeft: RESPONSIVE_DEFAULT_SPACING,
106
+ paddingRight: RESPONSIVE_DEFAULT_SPACING,
115
107
  children: /*#__PURE__*/ jsx(IconButton, {
108
+ variant: "ghost",
116
109
  withTooltip: false,
117
110
  label: formatMessage({
118
111
  id: 'app.components.UpsellBanner.reopen',
119
112
  defaultMessage: 'Reopen banner'
120
113
  }),
121
114
  onClick: handleReopen,
122
- children: /*#__PURE__*/ jsx(ArrowsOut, {})
115
+ children: /*#__PURE__*/ jsx(ChevronUp, {})
123
116
  })
124
117
  });
125
118
  }
@@ -1 +1 @@
1
- {"version":3,"file":"UpsellBanner.mjs","sources":["../../../../../admin/src/components/UpsellBanner.tsx"],"sourcesContent":["import { useEffect } from 'react';\n\nimport { useLicenseLimits } from '@strapi/admin/strapi-admin/ee';\nimport { Box, IconButton, LinkButton, Typography } from '@strapi/design-system';\nimport { ArrowsOut } from '@strapi/icons';\nimport { isAfter, isValid, subDays } from 'date-fns';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useGetLicenseTrialTimeLeftQuery } from '../../src/services/admin';\nimport { useScopedPersistentState } from '../hooks/usePersistentState';\n\nimport { DismissibleBanner } from './DismissibleBanner';\n\n/**\n * Unlike `DismissibleBanner`'s own close button, this has no banner box left to\n * anchor to once dismissed (the banner unmounts entirely), so it stays pinned\n * to the viewport instead.\n */\nconst FixedButtonWrapper = styled(Box)`\n position: fixed;\n display: flex;\n flex-direction: column;\n z-index: 1;\n align-items: flex-end;\n top: 9px;\n right: 16px;\n`;\n\nconst Banner = ({\n isTrialEndedRecently,\n onDismiss,\n}: {\n isTrialEndedRecently: boolean;\n onDismiss: () => void;\n}) => {\n const { formatMessage } = useIntl();\n\n return (\n <DismissibleBanner\n onDismiss={onDismiss}\n closeLabel={formatMessage({\n id: 'app.components.UpsellBanner.close',\n defaultMessage: 'Close',\n })}\n message={\n <>\n <Typography\n variant=\"delta\"\n fontWeight=\"bold\"\n textColor=\"neutral0\"\n textAlign=\"center\"\n fontSize={2}\n >\n {formatMessage(\n isTrialEndedRecently\n ? {\n id: 'app.components.UpsellBanner.intro.ended',\n defaultMessage: 'Your trial has ended: ',\n }\n : {\n id: 'app.components.UpsellBanner.intro',\n defaultMessage: 'Access to Growth plan features: ',\n }\n )}\n </Typography>\n <Typography\n variant=\"delta\"\n textColor=\"neutral0\"\n textAlign=\"center\"\n paddingRight={4}\n fontSize={2}\n >\n {formatMessage(\n isTrialEndedRecently\n ? {\n id: 'app.components.UpsellBanner.text.ended',\n defaultMessage: 'Keep access to Growth features by upgrading now.',\n }\n : {\n id: 'app.components.UpsellBanner.text',\n defaultMessage:\n 'As part of your trial, you can explore premium tools such as Content History, Releases, and Single Sign-On (SSO).',\n }\n )}\n </Typography>\n </>\n }\n action={\n <LinkButton\n width=\"max-content\"\n variant=\"tertiary\"\n href=\"https://billing.strapi.io\"\n target=\"_blank\"\n >\n {formatMessage(\n isTrialEndedRecently\n ? {\n id: 'app.components.UpsellBanner.button.ended',\n defaultMessage: 'Keep Growth plan',\n }\n : {\n id: 'app.components.UpsellBanner.button',\n defaultMessage: 'Upgrade now',\n }\n )}\n </LinkButton>\n }\n />\n );\n};\n\nconst UpsellBanner = () => {\n const { license } = useLicenseLimits();\n const { formatMessage } = useIntl();\n\n const [cachedTrialEndsAt, setCachedTrialEndsAt] = useScopedPersistentState<string | undefined>(\n 'STRAPI_FREE_TRIAL_ENDS_AT',\n undefined\n );\n\n const [dismissedFor, setDismissedFor] = useScopedPersistentState<string | undefined>(\n 'STRAPI_UPSELL_BANNER_DISMISSED_FOR',\n undefined\n );\n\n const sevenDaysAgo = subDays(new Date(), 7);\n\n const timeLeftData = useGetLicenseTrialTimeLeftQuery(undefined, {\n skip: !license?.isTrial,\n });\n\n useEffect(() => {\n if (timeLeftData.data?.trialEndsAt) {\n setCachedTrialEndsAt(timeLeftData.data.trialEndsAt);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [timeLeftData.data?.trialEndsAt]);\n\n // When the license is not a trial + not EE, and the cached trial end date is found in the localstorage, that means the trial has ended\n // We show the banner to encourage the user to upgrade (for 7 days after the trial ends)\n const isTrialEndedRecently = Boolean(\n !license?.isTrial &&\n !window.strapi.isEE &&\n cachedTrialEndsAt &&\n isAfter(new Date(cachedTrialEndsAt), sevenDaysAgo)\n );\n\n const trialEndsAt = timeLeftData.data?.trialEndsAt ?? cachedTrialEndsAt;\n\n const toCanonicalISO = (v: string | undefined): string | undefined => {\n if (!v) return undefined;\n const date = new Date(v);\n return isValid(date) ? date.toISOString() : undefined;\n };\n\n const isDismissed = Boolean(\n trialEndsAt && toCanonicalISO(dismissedFor) === toCanonicalISO(trialEndsAt)\n );\n\n const handleDismiss = () => setDismissedFor(toCanonicalISO(trialEndsAt));\n const handleReopen = () => setDismissedFor(undefined);\n\n if (!(timeLeftData.data?.trialEndsAt || isTrialEndedRecently)) {\n return null;\n }\n\n if (isDismissed) {\n return (\n <FixedButtonWrapper>\n <IconButton\n withTooltip={false}\n label={formatMessage({\n id: 'app.components.UpsellBanner.reopen',\n defaultMessage: 'Reopen banner',\n })}\n onClick={handleReopen}\n >\n <ArrowsOut />\n </IconButton>\n </FixedButtonWrapper>\n );\n }\n\n return <Banner isTrialEndedRecently={isTrialEndedRecently} onDismiss={handleDismiss} />;\n};\n\nexport { UpsellBanner };\n"],"names":["FixedButtonWrapper","styled","Box","Banner","isTrialEndedRecently","onDismiss","formatMessage","useIntl","_jsx","DismissibleBanner","closeLabel","id","defaultMessage","message","_jsxs","_Fragment","Typography","variant","fontWeight","textColor","textAlign","fontSize","paddingRight","action","LinkButton","width","href","target","UpsellBanner","license","useLicenseLimits","cachedTrialEndsAt","setCachedTrialEndsAt","useScopedPersistentState","undefined","dismissedFor","setDismissedFor","sevenDaysAgo","subDays","Date","timeLeftData","useGetLicenseTrialTimeLeftQuery","skip","isTrial","useEffect","data","trialEndsAt","Boolean","window","strapi","isEE","isAfter","toCanonicalISO","v","date","isValid","toISOString","isDismissed","handleDismiss","handleReopen","IconButton","withTooltip","label","onClick","ArrowsOut"],"mappings":"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"}
1
+ {"version":3,"file":"UpsellBanner.mjs","sources":["../../../../../admin/src/components/UpsellBanner.tsx"],"sourcesContent":["import { useEffect } from 'react';\n\nimport { useLicenseLimits } from '@strapi/admin/strapi-admin/ee';\nimport { Flex, IconButton, LinkButton, Typography } from '@strapi/design-system';\nimport { ChevronUp } from '@strapi/icons';\nimport { isAfter, isValid, subDays } from 'date-fns';\nimport { useIntl } from 'react-intl';\n\nimport { useGetLicenseTrialTimeLeftQuery } from '../../src/services/admin';\nimport { RESPONSIVE_DEFAULT_SPACING } from '../constants/theme';\nimport { useScopedPersistentState } from '../hooks/usePersistentState';\n\nimport { DismissibleBanner } from './DismissibleBanner';\n\nconst Banner = ({\n isTrialEndedRecently,\n onDismiss,\n}: {\n isTrialEndedRecently: boolean;\n onDismiss: () => void;\n}) => {\n const { formatMessage } = useIntl();\n\n return (\n <DismissibleBanner\n onDismiss={onDismiss}\n closeLabel={formatMessage({\n id: 'app.components.UpsellBanner.close',\n defaultMessage: 'Close',\n })}\n message={\n <>\n <Typography\n variant=\"delta\"\n fontWeight=\"bold\"\n textColor=\"neutral0\"\n textAlign=\"center\"\n fontSize={2}\n >\n {formatMessage(\n isTrialEndedRecently\n ? {\n id: 'app.components.UpsellBanner.intro.ended',\n defaultMessage: 'Your trial has ended: ',\n }\n : {\n id: 'app.components.UpsellBanner.intro',\n defaultMessage: 'Access to Growth plan features: ',\n }\n )}\n </Typography>\n <Typography\n variant=\"delta\"\n textColor=\"neutral0\"\n textAlign=\"center\"\n paddingRight={4}\n fontSize={2}\n >\n {formatMessage(\n isTrialEndedRecently\n ? {\n id: 'app.components.UpsellBanner.text.ended',\n defaultMessage: 'Keep access to Growth features by upgrading now.',\n }\n : {\n id: 'app.components.UpsellBanner.text',\n defaultMessage:\n 'As part of your trial, you can explore premium tools such as Content History, Releases, and Single Sign-On (SSO).',\n }\n )}\n </Typography>\n </>\n }\n action={\n <LinkButton\n width=\"max-content\"\n variant=\"tertiary\"\n href=\"https://billing.strapi.io\"\n target=\"_blank\"\n >\n {formatMessage(\n isTrialEndedRecently\n ? {\n id: 'app.components.UpsellBanner.button.ended',\n defaultMessage: 'Keep Growth plan',\n }\n : {\n id: 'app.components.UpsellBanner.button',\n defaultMessage: 'Upgrade now',\n }\n )}\n </LinkButton>\n }\n />\n );\n};\n\nconst UpsellBanner = () => {\n const { license } = useLicenseLimits();\n const { formatMessage } = useIntl();\n\n const [cachedTrialEndsAt, setCachedTrialEndsAt] = useScopedPersistentState<string | undefined>(\n 'STRAPI_FREE_TRIAL_ENDS_AT',\n undefined\n );\n\n const [dismissedFor, setDismissedFor] = useScopedPersistentState<string | undefined>(\n 'STRAPI_UPSELL_BANNER_DISMISSED_FOR',\n undefined\n );\n\n const sevenDaysAgo = subDays(new Date(), 7);\n\n const timeLeftData = useGetLicenseTrialTimeLeftQuery(undefined, {\n skip: !license?.isTrial,\n });\n\n useEffect(() => {\n if (timeLeftData.data?.trialEndsAt) {\n setCachedTrialEndsAt(timeLeftData.data.trialEndsAt);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [timeLeftData.data?.trialEndsAt]);\n\n // When the license is not a trial + not EE, and the cached trial end date is found in the localstorage, that means the trial has ended\n // We show the banner to encourage the user to upgrade (for 7 days after the trial ends)\n const isTrialEndedRecently = Boolean(\n !license?.isTrial &&\n !window.strapi.isEE &&\n cachedTrialEndsAt &&\n isAfter(new Date(cachedTrialEndsAt), sevenDaysAgo)\n );\n\n const trialEndsAt = timeLeftData.data?.trialEndsAt ?? cachedTrialEndsAt;\n\n const toCanonicalISO = (v: string | undefined): string | undefined => {\n if (!v) return undefined;\n const date = new Date(v);\n return isValid(date) ? date.toISOString() : undefined;\n };\n\n const isDismissed = Boolean(\n trialEndsAt && toCanonicalISO(dismissedFor) === toCanonicalISO(trialEndsAt)\n );\n\n const handleDismiss = () => setDismissedFor(toCanonicalISO(trialEndsAt));\n const handleReopen = () => setDismissedFor(undefined);\n\n if (!(timeLeftData.data?.trialEndsAt || isTrialEndedRecently)) {\n return null;\n }\n\n if (isDismissed) {\n return (\n <Flex\n justifyContent=\"flex-end\"\n paddingTop={1}\n paddingBottom={1}\n paddingLeft={RESPONSIVE_DEFAULT_SPACING}\n paddingRight={RESPONSIVE_DEFAULT_SPACING}\n >\n <IconButton\n variant=\"ghost\"\n withTooltip={false}\n label={formatMessage({\n id: 'app.components.UpsellBanner.reopen',\n defaultMessage: 'Reopen banner',\n })}\n onClick={handleReopen}\n >\n <ChevronUp />\n </IconButton>\n </Flex>\n );\n }\n\n return <Banner isTrialEndedRecently={isTrialEndedRecently} onDismiss={handleDismiss} />;\n};\n\nexport { UpsellBanner };\n"],"names":["Banner","isTrialEndedRecently","onDismiss","formatMessage","useIntl","_jsx","DismissibleBanner","closeLabel","id","defaultMessage","message","_jsxs","_Fragment","Typography","variant","fontWeight","textColor","textAlign","fontSize","paddingRight","action","LinkButton","width","href","target","UpsellBanner","license","useLicenseLimits","cachedTrialEndsAt","setCachedTrialEndsAt","useScopedPersistentState","undefined","dismissedFor","setDismissedFor","sevenDaysAgo","subDays","Date","timeLeftData","useGetLicenseTrialTimeLeftQuery","skip","isTrial","useEffect","data","trialEndsAt","Boolean","window","strapi","isEE","isAfter","toCanonicalISO","v","date","isValid","toISOString","isDismissed","handleDismiss","handleReopen","Flex","justifyContent","paddingTop","paddingBottom","paddingLeft","RESPONSIVE_DEFAULT_SPACING","IconButton","withTooltip","label","onClick","ChevronUp"],"mappings":"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"}
@@ -35,7 +35,8 @@ var axios__default = /*#__PURE__*/_interopDefault(axios);
35
35
  /* -------------------------------------------------------------------------------------------------
36
36
  * Context
37
37
  * -----------------------------------------------------------------------------------------------*/ const TrackingContext = /*#__PURE__*/ React__namespace.createContext({
38
- uuid: false
38
+ uuid: false,
39
+ isStrapiVersionReady: false
39
40
  });
40
41
  const TrackingProvider = ({ children })=>{
41
42
  const token = Auth.useAuth('App', (state)=>state.token);
@@ -45,8 +46,14 @@ const TrackingProvider = ({ children })=>{
45
46
  const { data } = admin.useTelemetryPropertiesQuery(undefined, {
46
47
  skip: !initData?.uuid || !token
47
48
  });
49
+ const versionQueryEnabled = Boolean(initData?.uuid && token);
50
+ const { data: appInfo, isLoading: isLoadingAppInfo, isError: isInformationError } = admin.useInformationQuery(undefined, {
51
+ skip: !versionQueryEnabled
52
+ });
53
+ const strapiVersion = appInfo?.strapiVersion;
54
+ const isStrapiVersionReady = Boolean(strapiVersion) || versionQueryEnabled && isInformationError;
48
55
  React__namespace.useEffect(()=>{
49
- if (uuid && data) {
56
+ if (uuid && data && !isLoadingAppInfo) {
50
57
  const event = 'didInitializeAdministration';
51
58
  try {
52
59
  fetch(`${process.env.STRAPI_ANALYTICS_URL || 'https://analytics.strapi.io'}/api/v2/track`, {
@@ -59,7 +66,8 @@ const TrackingProvider = ({ children })=>{
59
66
  groupProperties: {
60
67
  ...data,
61
68
  projectId: uuid,
62
- registeredWidgets: getAllWidgets().map((widget)=>widget.uid)
69
+ registeredWidgets: getAllWidgets().map((widget)=>widget.uid),
70
+ version: strapiVersion
63
71
  }
64
72
  }),
65
73
  headers: {
@@ -74,14 +82,20 @@ const TrackingProvider = ({ children })=>{
74
82
  }, [
75
83
  data,
76
84
  uuid,
77
- getAllWidgets
85
+ getAllWidgets,
86
+ isLoadingAppInfo,
87
+ strapiVersion
78
88
  ]);
79
89
  const value = React__namespace.useMemo(()=>({
80
90
  uuid,
81
- telemetryProperties: data
91
+ telemetryProperties: data,
92
+ strapiVersion,
93
+ isStrapiVersionReady
82
94
  }), [
83
95
  uuid,
84
- data
96
+ data,
97
+ strapiVersion,
98
+ isStrapiVersionReady
85
99
  ]);
86
100
  return /*#__PURE__*/ jsxRuntime.jsx(TrackingContext.Provider, {
87
101
  value: value,
@@ -109,7 +123,7 @@ const TrackingProvider = ({ children })=>{
109
123
  const deviceType = useDeviceType.useDeviceType();
110
124
  const deviceTypeRef = React__namespace.useRef(deviceType);
111
125
  deviceTypeRef.current = deviceType;
112
- const { uuid, telemetryProperties } = React__namespace.useContext(TrackingContext);
126
+ const { uuid, telemetryProperties, strapiVersion } = React__namespace.useContext(TrackingContext);
113
127
  const userId = AppInfo.useAppInfo('useTracking', (state)=>state.userId);
114
128
  const trackUsage = React__namespace.useCallback(async (event, properties)=>{
115
129
  try {
@@ -126,7 +140,8 @@ const TrackingProvider = ({ children })=>{
126
140
  groupProperties: {
127
141
  ...telemetryProperties,
128
142
  projectId: uuid,
129
- projectType: window.strapi.projectType
143
+ projectType: window.strapi.projectType,
144
+ version: strapiVersion
130
145
  }
131
146
  }, {
132
147
  headers: {
@@ -141,6 +156,7 @@ const TrackingProvider = ({ children })=>{
141
156
  }
142
157
  return null;
143
158
  }, [
159
+ strapiVersion,
144
160
  telemetryProperties,
145
161
  userId,
146
162
  uuid
@@ -149,7 +165,11 @@ const TrackingProvider = ({ children })=>{
149
165
  trackUsage
150
166
  };
151
167
  };
168
+ /**
169
+ * Internal readiness signal for events that must wait for the provider's version.
170
+ */ const useStrapiVersionReady = ()=>React__namespace.useContext(TrackingContext).isStrapiVersionReady;
152
171
 
153
172
  exports.TrackingProvider = TrackingProvider;
173
+ exports.useStrapiVersionReady = useStrapiVersionReady;
154
174
  exports.useTracking = useTracking;
155
175
  //# sourceMappingURL=Tracking.js.map