@strapi/admin 5.52.3 → 5.54.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 (196) hide show
  1. package/dist/admin/admin/src/App.js +1 -1
  2. package/dist/admin/admin/src/App.js.map +1 -1
  3. package/dist/admin/admin/src/App.mjs +1 -1
  4. package/dist/admin/admin/src/App.mjs.map +1 -1
  5. package/dist/admin/admin/src/components/DismissibleBanner.js +60 -0
  6. package/dist/admin/admin/src/components/DismissibleBanner.js.map +1 -0
  7. package/dist/admin/admin/src/components/DismissibleBanner.mjs +58 -0
  8. package/dist/admin/admin/src/components/DismissibleBanner.mjs.map +1 -0
  9. package/dist/admin/admin/src/components/Form.js +11 -2
  10. package/dist/admin/admin/src/components/Form.js.map +1 -1
  11. package/dist/admin/admin/src/components/Form.mjs +11 -2
  12. package/dist/admin/admin/src/components/Form.mjs.map +1 -1
  13. package/dist/admin/admin/src/components/FormInputs/DateTime.js +1 -1
  14. package/dist/admin/admin/src/components/FormInputs/DateTime.js.map +1 -1
  15. package/dist/admin/admin/src/components/FormInputs/DateTime.mjs +1 -1
  16. package/dist/admin/admin/src/components/FormInputs/DateTime.mjs.map +1 -1
  17. package/dist/admin/admin/src/components/FormInputs/Time.js +1 -1
  18. package/dist/admin/admin/src/components/FormInputs/Time.js.map +1 -1
  19. package/dist/admin/admin/src/components/FormInputs/Time.mjs +1 -1
  20. package/dist/admin/admin/src/components/FormInputs/Time.mjs.map +1 -1
  21. package/dist/admin/admin/src/components/MainNav/NavUser.js +1 -2
  22. package/dist/admin/admin/src/components/MainNav/NavUser.js.map +1 -1
  23. package/dist/admin/admin/src/components/MainNav/NavUser.mjs +1 -2
  24. package/dist/admin/admin/src/components/MainNav/NavUser.mjs.map +1 -1
  25. package/dist/admin/admin/src/components/MediaLibraryBanner.js +85 -0
  26. package/dist/admin/admin/src/components/MediaLibraryBanner.js.map +1 -0
  27. package/dist/admin/admin/src/components/MediaLibraryBanner.mjs +83 -0
  28. package/dist/admin/admin/src/components/MediaLibraryBanner.mjs.map +1 -0
  29. package/dist/admin/admin/src/components/Providers.js +6 -6
  30. package/dist/admin/admin/src/components/Providers.js.map +1 -1
  31. package/dist/admin/admin/src/components/Providers.mjs +6 -6
  32. package/dist/admin/admin/src/components/Providers.mjs.map +1 -1
  33. package/dist/admin/admin/src/components/UpsellBanner.js +56 -86
  34. package/dist/admin/admin/src/components/UpsellBanner.js.map +1 -1
  35. package/dist/admin/admin/src/components/UpsellBanner.mjs +58 -88
  36. package/dist/admin/admin/src/components/UpsellBanner.mjs.map +1 -1
  37. package/dist/admin/admin/src/core/store/configure.js +14 -2
  38. package/dist/admin/admin/src/core/store/configure.js.map +1 -1
  39. package/dist/admin/admin/src/core/store/configure.mjs +14 -2
  40. package/dist/admin/admin/src/core/store/configure.mjs.map +1 -1
  41. package/dist/admin/admin/src/core/store/hooks.mjs +1 -1
  42. package/dist/admin/admin/src/features/Auth.js +162 -46
  43. package/dist/admin/admin/src/features/Auth.js.map +1 -1
  44. package/dist/admin/admin/src/features/Auth.mjs +164 -48
  45. package/dist/admin/admin/src/features/Auth.mjs.map +1 -1
  46. package/dist/admin/admin/src/hooks/useRegisterUnsavedChanges.js +19 -0
  47. package/dist/admin/admin/src/hooks/useRegisterUnsavedChanges.js.map +1 -0
  48. package/dist/admin/admin/src/hooks/useRegisterUnsavedChanges.mjs +17 -0
  49. package/dist/admin/admin/src/hooks/useRegisterUnsavedChanges.mjs.map +1 -0
  50. package/dist/admin/admin/src/hooks/{useIdleSessionLogout.js → useSessionKeepalive.js} +34 -27
  51. package/dist/admin/admin/src/hooks/useSessionKeepalive.js.map +1 -0
  52. package/dist/admin/admin/src/hooks/{useIdleSessionLogout.mjs → useSessionKeepalive.mjs} +34 -27
  53. package/dist/admin/admin/src/hooks/useSessionKeepalive.mjs.map +1 -0
  54. package/dist/admin/admin/src/layouts/AuthenticatedLayout.js +2 -0
  55. package/dist/admin/admin/src/layouts/AuthenticatedLayout.js.map +1 -1
  56. package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs +2 -0
  57. package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs.map +1 -1
  58. package/dist/admin/admin/src/pages/SessionsPage.js +2 -5
  59. package/dist/admin/admin/src/pages/SessionsPage.js.map +1 -1
  60. package/dist/admin/admin/src/pages/SessionsPage.mjs +2 -5
  61. package/dist/admin/admin/src/pages/SessionsPage.mjs.map +1 -1
  62. package/dist/admin/admin/src/render.js +5 -0
  63. package/dist/admin/admin/src/render.js.map +1 -1
  64. package/dist/admin/admin/src/render.mjs +5 -0
  65. package/dist/admin/admin/src/render.mjs.map +1 -1
  66. package/dist/admin/admin/src/translations/en.json.js +30 -0
  67. package/dist/admin/admin/src/translations/en.json.js.map +1 -1
  68. package/dist/admin/admin/src/translations/en.json.mjs +30 -0
  69. package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
  70. package/dist/admin/admin/src/utils/baseQuery.js +3 -13
  71. package/dist/admin/admin/src/utils/baseQuery.js.map +1 -1
  72. package/dist/admin/admin/src/utils/baseQuery.mjs +3 -13
  73. package/dist/admin/admin/src/utils/baseQuery.mjs.map +1 -1
  74. package/dist/admin/admin/src/utils/getFetchClient.js +152 -48
  75. package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
  76. package/dist/admin/admin/src/utils/getFetchClient.mjs +151 -50
  77. package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
  78. package/dist/admin/admin/src/utils/unsavedChangesRegistry.js +25 -0
  79. package/dist/admin/admin/src/utils/unsavedChangesRegistry.js.map +1 -0
  80. package/dist/admin/admin/src/utils/unsavedChangesRegistry.mjs +22 -0
  81. package/dist/admin/admin/src/utils/unsavedChangesRegistry.mjs.map +1 -0
  82. package/dist/admin/admin/tests/utils.js +14 -14
  83. package/dist/admin/admin/tests/utils.js.map +1 -1
  84. package/dist/admin/admin/tests/utils.mjs +14 -14
  85. package/dist/admin/admin/tests/utils.mjs.map +1 -1
  86. package/dist/admin/ee/admin/src/constants.js +6 -0
  87. package/dist/admin/ee/admin/src/constants.js.map +1 -1
  88. package/dist/admin/ee/admin/src/constants.mjs +6 -0
  89. package/dist/admin/ee/admin/src/constants.mjs.map +1 -1
  90. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.js +31 -3
  91. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.js.map +1 -1
  92. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.mjs +33 -5
  93. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.mjs.map +1 -1
  94. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.js +177 -0
  95. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.js.map +1 -0
  96. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.mjs +175 -0
  97. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.mjs.map +1 -0
  98. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js +173 -0
  99. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js.map +1 -0
  100. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs +151 -0
  101. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs.map +1 -0
  102. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js +14 -1
  103. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js.map +1 -1
  104. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs +14 -1
  105. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs.map +1 -1
  106. package/dist/admin/index.js +3 -0
  107. package/dist/admin/index.js.map +1 -1
  108. package/dist/admin/index.mjs +1 -1
  109. package/dist/admin/shared/utils/audit-log-export.js +16 -0
  110. package/dist/admin/shared/utils/audit-log-export.js.map +1 -0
  111. package/dist/admin/shared/utils/audit-log-export.mjs +9 -0
  112. package/dist/admin/shared/utils/audit-log-export.mjs.map +1 -0
  113. package/dist/admin/src/components/DismissibleBanner.d.ts +8 -0
  114. package/dist/admin/src/components/MediaLibraryBanner.d.ts +2 -0
  115. package/dist/admin/src/hooks/useRegisterUnsavedChanges.d.ts +6 -0
  116. package/dist/admin/src/hooks/useSessionKeepalive.d.ts +88 -0
  117. package/dist/admin/src/utils/getFetchClient.d.ts +22 -7
  118. package/dist/admin/src/utils/unsavedChangesRegistry.d.ts +11 -0
  119. package/dist/admin/tests/store.d.ts +4 -0
  120. package/dist/admin/tests/utils.d.ts +4 -0
  121. package/dist/ee/admin/src/constants.d.ts +4 -0
  122. package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.d.ts +10 -0
  123. package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.d.ts +18 -0
  124. package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.d.ts +13 -0
  125. package/dist/ee/server/src/audit-logs/controllers/audit-logs.d.ts +1 -0
  126. package/dist/ee/server/src/audit-logs/controllers/audit-logs.d.ts.map +1 -1
  127. package/dist/ee/server/src/audit-logs/routes/audit-logs.d.ts.map +1 -1
  128. package/dist/ee/server/src/audit-logs/services/audit-logs.d.ts +24 -3
  129. package/dist/ee/server/src/audit-logs/services/audit-logs.d.ts.map +1 -1
  130. package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts +8 -2
  131. package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts.map +1 -1
  132. package/dist/ee/server/src/audit-logs/utils/csv.d.ts +5 -0
  133. package/dist/ee/server/src/audit-logs/utils/csv.d.ts.map +1 -0
  134. package/dist/ee/server/src/audit-logs/utils/export-token.d.ts +5 -0
  135. package/dist/ee/server/src/audit-logs/utils/export-token.d.ts.map +1 -0
  136. package/dist/ee/server/src/audit-logs/utils.d.ts +10 -0
  137. package/dist/ee/server/src/audit-logs/utils.d.ts.map +1 -0
  138. package/dist/ee/server/src/audit-logs/validation/audit-logs.d.ts +2 -0
  139. package/dist/ee/server/src/audit-logs/validation/audit-logs.d.ts.map +1 -1
  140. package/dist/ee/server/src/config/admin-actions.d.ts.map +1 -1
  141. package/dist/ee/server/src/index.d.ts +1 -0
  142. package/dist/ee/server/src/index.d.ts.map +1 -1
  143. package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.js +50 -0
  144. package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.js.map +1 -1
  145. package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.mjs +51 -1
  146. package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.mjs.map +1 -1
  147. package/dist/server/ee/server/src/audit-logs/routes/audit-logs.js +13 -4
  148. package/dist/server/ee/server/src/audit-logs/routes/audit-logs.js.map +1 -1
  149. package/dist/server/ee/server/src/audit-logs/routes/audit-logs.mjs +13 -4
  150. package/dist/server/ee/server/src/audit-logs/routes/audit-logs.mjs.map +1 -1
  151. package/dist/server/ee/server/src/audit-logs/services/audit-logs.js +201 -7
  152. package/dist/server/ee/server/src/audit-logs/services/audit-logs.js.map +1 -1
  153. package/dist/server/ee/server/src/audit-logs/services/audit-logs.mjs +201 -8
  154. package/dist/server/ee/server/src/audit-logs/services/audit-logs.mjs.map +1 -1
  155. package/dist/server/ee/server/src/audit-logs/services/lifecycles.js +119 -34
  156. package/dist/server/ee/server/src/audit-logs/services/lifecycles.js.map +1 -1
  157. package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs +119 -34
  158. package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs.map +1 -1
  159. package/dist/server/ee/server/src/audit-logs/utils/csv.js +33 -0
  160. package/dist/server/ee/server/src/audit-logs/utils/csv.js.map +1 -0
  161. package/dist/server/ee/server/src/audit-logs/utils/csv.mjs +29 -0
  162. package/dist/server/ee/server/src/audit-logs/utils/csv.mjs.map +1 -0
  163. package/dist/server/ee/server/src/audit-logs/utils/export-token.js +33 -0
  164. package/dist/server/ee/server/src/audit-logs/utils/export-token.js.map +1 -0
  165. package/dist/server/ee/server/src/audit-logs/utils/export-token.mjs +29 -0
  166. package/dist/server/ee/server/src/audit-logs/utils/export-token.mjs.map +1 -0
  167. package/dist/server/ee/server/src/audit-logs/utils.js +14 -0
  168. package/dist/server/ee/server/src/audit-logs/utils.js.map +1 -0
  169. package/dist/server/ee/server/src/audit-logs/utils.mjs +12 -0
  170. package/dist/server/ee/server/src/audit-logs/utils.mjs.map +1 -0
  171. package/dist/server/ee/server/src/audit-logs/validation/audit-logs.js +11 -0
  172. package/dist/server/ee/server/src/audit-logs/validation/audit-logs.js.map +1 -1
  173. package/dist/server/ee/server/src/audit-logs/validation/audit-logs.mjs +11 -1
  174. package/dist/server/ee/server/src/audit-logs/validation/audit-logs.mjs.map +1 -1
  175. package/dist/server/ee/server/src/config/admin-actions.js +8 -0
  176. package/dist/server/ee/server/src/config/admin-actions.js.map +1 -1
  177. package/dist/server/ee/server/src/config/admin-actions.mjs +8 -0
  178. package/dist/server/ee/server/src/config/admin-actions.mjs.map +1 -1
  179. package/dist/server/ee/server/src/index.js +10 -0
  180. package/dist/server/ee/server/src/index.js.map +1 -1
  181. package/dist/server/ee/server/src/index.mjs +10 -0
  182. package/dist/server/ee/server/src/index.mjs.map +1 -1
  183. package/dist/server/shared/utils/audit-log-export.js +22 -0
  184. package/dist/server/shared/utils/audit-log-export.js.map +1 -0
  185. package/dist/server/shared/utils/audit-log-export.mjs +12 -0
  186. package/dist/server/shared/utils/audit-log-export.mjs.map +1 -0
  187. package/dist/shared/contracts/audit-logs.d.ts +15 -1
  188. package/dist/shared/contracts/audit-logs.d.ts.map +1 -1
  189. package/dist/shared/contracts/shared.d.ts +1 -0
  190. package/dist/shared/contracts/shared.d.ts.map +1 -1
  191. package/dist/shared/utils/audit-log-export.d.ts +9 -0
  192. package/dist/shared/utils/audit-log-export.d.ts.map +1 -0
  193. package/package.json +7 -7
  194. package/dist/admin/admin/src/hooks/useIdleSessionLogout.js.map +0 -1
  195. package/dist/admin/admin/src/hooks/useIdleSessionLogout.mjs.map +0 -1
  196. package/dist/admin/src/hooks/useIdleSessionLogout.d.ts +0 -87
@@ -1 +1 @@
1
- {"version":3,"file":"render.js","sources":["../../../../admin/src/render.ts"],"sourcesContent":["/* eslint-disable no-undef */\nimport { createRoot } from 'react-dom/client';\n\nimport { StrapiApp, StrapiAppConstructorArgs } from './StrapiApp';\nimport { getFetchClient } from './utils/getFetchClient';\nimport { getProjectType } from './utils/getProjectType';\nimport { createAbsoluteUrl } from './utils/urls';\n\nimport type { Modules } from '@strapi/types';\n\ninterface RenderAdminArgs {\n customisations: {\n register?: (app: StrapiApp) => Promise<void> | void;\n bootstrap?: (app: StrapiApp) => Promise<void> | void;\n config?: StrapiAppConstructorArgs['config'];\n };\n plugins: StrapiAppConstructorArgs['appPlugins'];\n features?: Modules.Features.FeaturesService['config'];\n}\n\nconst renderAdmin = async (\n mountNode: HTMLElement | null,\n { plugins, customisations, features }: RenderAdminArgs\n) => {\n if (!mountNode) {\n throw new Error('[@strapi/admin]: Could not find the root element to mount the admin app');\n }\n\n window.strapi = {\n /**\n * This ENV variable is passed from the strapi instance, by default no url is set\n * in the config and therefore the instance returns you an empty string so URLs are relative.\n *\n * To ensure that the backendURL is always set, we use the window.location.origin as a fallback.\n */\n backendURL: createAbsoluteUrl(process.env.STRAPI_ADMIN_BACKEND_URL),\n isEE: false,\n isTrial: false,\n telemetryDisabled: process.env.STRAPI_TELEMETRY_DISABLED === 'true',\n future: {\n isEnabled: (name: keyof NonNullable<Modules.Features.FeaturesConfig['future']>) => {\n return features?.future?.[name] === true;\n },\n },\n // eslint-disable-next-line\n // @ts-ignore – there's pollution from the global scope of Node. Cannot use @ts-expect-error because of build:code and build:types context collision. Cannot use @ts-expect-error because of build:code and build:types context collision.\n features: {\n SSO: 'sso',\n AUDIT_LOGS: 'audit-logs',\n REVIEW_WORKFLOWS: 'review-workflows',\n /**\n * If we don't get the license then we know it's not EE\n * so no feature is enabled.\n */\n isEnabled: () => false,\n },\n projectType: 'Community',\n flags: {\n nps: false,\n promoteEE: true,\n docLinks: true,\n },\n // eslint-disable-next-line\n // @ts-ignore – there's pollution from the global scope of Node. Cannot use @ts-expect-error because of build:code and build:types context collision.\n ai: {\n enabled: true,\n },\n };\n\n const { get } = getFetchClient();\n\n interface ProjectType extends Pick<Window['strapi'], 'flags'> {\n isEE: boolean;\n isTrial: boolean;\n /**\n * The licensed plan price id, sent by the license registry (EE only).\n * Used to distinguish the Growth plan from other Enterprise plans.\n */\n planPriceId?: string;\n features: {\n name: string;\n }[];\n ai: {\n enabled: boolean;\n };\n }\n\n try {\n const {\n data: {\n data: { isEE, isTrial, features, flags, ai, planPriceId },\n },\n } = await get<{ data: ProjectType }>('/admin/project-type');\n\n window.strapi.isEE = isEE;\n window.strapi.isTrialLicense = isTrial;\n window.strapi.flags = flags;\n window.strapi.features = {\n ...window.strapi.features,\n isEnabled: (featureName: string | undefined) =>\n features.some((feature) => feature.name === featureName),\n };\n window.strapi.projectType = getProjectType({ isEE, planPriceId });\n // eslint-disable-next-line\n // @ts-ignore – there's pollution from the global scope of Node. Cannot use @ts-expect-error because of build:code and build:types context collision.\n window.strapi.ai = ai;\n } catch (err) {\n /**\n * If this fails, we simply don't activate any EE features.\n * Should we warn clearer in the UI?\n */\n console.error(err);\n }\n\n const app = new StrapiApp({\n config: customisations?.config,\n appPlugins: plugins,\n });\n\n await app.register(customisations?.register);\n await app.bootstrap(customisations?.bootstrap);\n await app.loadTrads(customisations?.config?.translations);\n\n createRoot(mountNode).render(app.render());\n\n if (\n typeof module !== 'undefined' &&\n module &&\n 'hot' in module &&\n typeof module.hot === 'object' &&\n module.hot !== null &&\n 'accept' in module.hot &&\n typeof module.hot.accept === 'function'\n ) {\n module.hot.accept();\n }\n\n if (typeof import.meta.hot?.accept === 'function') {\n import.meta.hot.accept();\n }\n};\n\nexport { renderAdmin };\nexport type { RenderAdminArgs };\n"],"names":["renderAdmin","mountNode","plugins","customisations","features","Error","window","strapi","backendURL","createAbsoluteUrl","process","env","STRAPI_ADMIN_BACKEND_URL","isEE","isTrial","telemetryDisabled","STRAPI_TELEMETRY_DISABLED","future","isEnabled","name","SSO","AUDIT_LOGS","REVIEW_WORKFLOWS","projectType","flags","nps","promoteEE","docLinks","ai","enabled","get","getFetchClient","data","planPriceId","isTrialLicense","featureName","some","feature","getProjectType","err","console","error","app","StrapiApp","config","appPlugins","register","bootstrap","loadTrads","translations","createRoot","render","module","hot","accept"],"mappings":"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"}
1
+ {"version":3,"file":"render.js","sources":["../../../../admin/src/render.ts"],"sourcesContent":["/* eslint-disable no-undef */\nimport { createRoot } from 'react-dom/client';\n\nimport { StrapiApp, StrapiAppConstructorArgs } from './StrapiApp';\nimport { getFetchClient } from './utils/getFetchClient';\nimport { getProjectType } from './utils/getProjectType';\nimport { createAbsoluteUrl } from './utils/urls';\n\nimport type { Modules } from '@strapi/types';\n\ninterface RenderAdminArgs {\n customisations: {\n register?: (app: StrapiApp) => Promise<void> | void;\n bootstrap?: (app: StrapiApp) => Promise<void> | void;\n config?: StrapiAppConstructorArgs['config'];\n };\n plugins: StrapiAppConstructorArgs['appPlugins'];\n features?: Modules.Features.FeaturesService['config'];\n}\n\nconst renderAdmin = async (\n mountNode: HTMLElement | null,\n { plugins, customisations, features }: RenderAdminArgs\n) => {\n if (!mountNode) {\n throw new Error('[@strapi/admin]: Could not find the root element to mount the admin app');\n }\n\n window.strapi = {\n /**\n * This ENV variable is passed from the strapi instance, by default no url is set\n * in the config and therefore the instance returns you an empty string so URLs are relative.\n *\n * To ensure that the backendURL is always set, we use the window.location.origin as a fallback.\n */\n backendURL: createAbsoluteUrl(process.env.STRAPI_ADMIN_BACKEND_URL),\n isEE: false,\n isTrial: false,\n telemetryDisabled: process.env.STRAPI_TELEMETRY_DISABLED === 'true',\n future: {\n isEnabled: (name: keyof NonNullable<Modules.Features.FeaturesConfig['future']>) => {\n return features?.future?.[name] === true;\n },\n },\n featureFlags: {\n isEnabled: (name: keyof Omit<Modules.Features.FeaturesConfig, 'future'>) => {\n return features?.[name] === true;\n },\n },\n // eslint-disable-next-line\n // @ts-ignore – there's pollution from the global scope of Node. Cannot use @ts-expect-error because of build:code and build:types context collision. Cannot use @ts-expect-error because of build:code and build:types context collision.\n features: {\n SSO: 'sso',\n AUDIT_LOGS: 'audit-logs',\n REVIEW_WORKFLOWS: 'review-workflows',\n /**\n * If we don't get the license then we know it's not EE\n * so no feature is enabled.\n */\n isEnabled: () => false,\n },\n projectType: 'Community',\n flags: {\n nps: false,\n promoteEE: true,\n docLinks: true,\n },\n // eslint-disable-next-line\n // @ts-ignore – there's pollution from the global scope of Node. Cannot use @ts-expect-error because of build:code and build:types context collision.\n ai: {\n enabled: true,\n },\n };\n\n const { get } = getFetchClient();\n\n interface ProjectType extends Pick<Window['strapi'], 'flags'> {\n isEE: boolean;\n isTrial: boolean;\n /**\n * The licensed plan price id, sent by the license registry (EE only).\n * Used to distinguish the Growth plan from other Enterprise plans.\n */\n planPriceId?: string;\n features: {\n name: string;\n }[];\n ai: {\n enabled: boolean;\n };\n }\n\n try {\n const {\n data: {\n data: { isEE, isTrial, features, flags, ai, planPriceId },\n },\n } = await get<{ data: ProjectType }>('/admin/project-type');\n\n window.strapi.isEE = isEE;\n window.strapi.isTrialLicense = isTrial;\n window.strapi.flags = flags;\n window.strapi.features = {\n ...window.strapi.features,\n isEnabled: (featureName: string | undefined) =>\n features.some((feature) => feature.name === featureName),\n };\n window.strapi.projectType = getProjectType({ isEE, planPriceId });\n // eslint-disable-next-line\n // @ts-ignore – there's pollution from the global scope of Node. Cannot use @ts-expect-error because of build:code and build:types context collision.\n window.strapi.ai = ai;\n } catch (err) {\n /**\n * If this fails, we simply don't activate any EE features.\n * Should we warn clearer in the UI?\n */\n console.error(err);\n }\n\n const app = new StrapiApp({\n config: customisations?.config,\n appPlugins: plugins,\n });\n\n await app.register(customisations?.register);\n await app.bootstrap(customisations?.bootstrap);\n await app.loadTrads(customisations?.config?.translations);\n\n createRoot(mountNode).render(app.render());\n\n if (\n typeof module !== 'undefined' &&\n module &&\n 'hot' in module &&\n typeof module.hot === 'object' &&\n module.hot !== null &&\n 'accept' in module.hot &&\n typeof module.hot.accept === 'function'\n ) {\n module.hot.accept();\n }\n\n if (typeof import.meta.hot?.accept === 'function') {\n import.meta.hot.accept();\n }\n};\n\nexport { renderAdmin };\nexport type { RenderAdminArgs };\n"],"names":["renderAdmin","mountNode","plugins","customisations","features","Error","window","strapi","backendURL","createAbsoluteUrl","process","env","STRAPI_ADMIN_BACKEND_URL","isEE","isTrial","telemetryDisabled","STRAPI_TELEMETRY_DISABLED","future","isEnabled","name","featureFlags","SSO","AUDIT_LOGS","REVIEW_WORKFLOWS","projectType","flags","nps","promoteEE","docLinks","ai","enabled","get","getFetchClient","data","planPriceId","isTrialLicense","featureName","some","feature","getProjectType","err","console","error","app","StrapiApp","config","appPlugins","register","bootstrap","loadTrads","translations","createRoot","render","module","hot","accept"],"mappings":"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"}
@@ -23,6 +23,11 @@ const renderAdmin = async (mountNode, { plugins, customisations, features })=>{
23
23
  return features?.future?.[name] === true;
24
24
  }
25
25
  },
26
+ featureFlags: {
27
+ isEnabled: (name)=>{
28
+ return features?.[name] === true;
29
+ }
30
+ },
26
31
  // eslint-disable-next-line
27
32
  // @ts-ignore – there's pollution from the global scope of Node. Cannot use @ts-expect-error because of build:code and build:types context collision. Cannot use @ts-expect-error because of build:code and build:types context collision.
28
33
  features: {
@@ -1 +1 @@
1
- {"version":3,"file":"render.mjs","sources":["../../../../admin/src/render.ts"],"sourcesContent":["/* eslint-disable no-undef */\nimport { createRoot } from 'react-dom/client';\n\nimport { StrapiApp, StrapiAppConstructorArgs } from './StrapiApp';\nimport { getFetchClient } from './utils/getFetchClient';\nimport { getProjectType } from './utils/getProjectType';\nimport { createAbsoluteUrl } from './utils/urls';\n\nimport type { Modules } from '@strapi/types';\n\ninterface RenderAdminArgs {\n customisations: {\n register?: (app: StrapiApp) => Promise<void> | void;\n bootstrap?: (app: StrapiApp) => Promise<void> | void;\n config?: StrapiAppConstructorArgs['config'];\n };\n plugins: StrapiAppConstructorArgs['appPlugins'];\n features?: Modules.Features.FeaturesService['config'];\n}\n\nconst renderAdmin = async (\n mountNode: HTMLElement | null,\n { plugins, customisations, features }: RenderAdminArgs\n) => {\n if (!mountNode) {\n throw new Error('[@strapi/admin]: Could not find the root element to mount the admin app');\n }\n\n window.strapi = {\n /**\n * This ENV variable is passed from the strapi instance, by default no url is set\n * in the config and therefore the instance returns you an empty string so URLs are relative.\n *\n * To ensure that the backendURL is always set, we use the window.location.origin as a fallback.\n */\n backendURL: createAbsoluteUrl(process.env.STRAPI_ADMIN_BACKEND_URL),\n isEE: false,\n isTrial: false,\n telemetryDisabled: process.env.STRAPI_TELEMETRY_DISABLED === 'true',\n future: {\n isEnabled: (name: keyof NonNullable<Modules.Features.FeaturesConfig['future']>) => {\n return features?.future?.[name] === true;\n },\n },\n // eslint-disable-next-line\n // @ts-ignore – there's pollution from the global scope of Node. Cannot use @ts-expect-error because of build:code and build:types context collision. Cannot use @ts-expect-error because of build:code and build:types context collision.\n features: {\n SSO: 'sso',\n AUDIT_LOGS: 'audit-logs',\n REVIEW_WORKFLOWS: 'review-workflows',\n /**\n * If we don't get the license then we know it's not EE\n * so no feature is enabled.\n */\n isEnabled: () => false,\n },\n projectType: 'Community',\n flags: {\n nps: false,\n promoteEE: true,\n docLinks: true,\n },\n // eslint-disable-next-line\n // @ts-ignore – there's pollution from the global scope of Node. Cannot use @ts-expect-error because of build:code and build:types context collision.\n ai: {\n enabled: true,\n },\n };\n\n const { get } = getFetchClient();\n\n interface ProjectType extends Pick<Window['strapi'], 'flags'> {\n isEE: boolean;\n isTrial: boolean;\n /**\n * The licensed plan price id, sent by the license registry (EE only).\n * Used to distinguish the Growth plan from other Enterprise plans.\n */\n planPriceId?: string;\n features: {\n name: string;\n }[];\n ai: {\n enabled: boolean;\n };\n }\n\n try {\n const {\n data: {\n data: { isEE, isTrial, features, flags, ai, planPriceId },\n },\n } = await get<{ data: ProjectType }>('/admin/project-type');\n\n window.strapi.isEE = isEE;\n window.strapi.isTrialLicense = isTrial;\n window.strapi.flags = flags;\n window.strapi.features = {\n ...window.strapi.features,\n isEnabled: (featureName: string | undefined) =>\n features.some((feature) => feature.name === featureName),\n };\n window.strapi.projectType = getProjectType({ isEE, planPriceId });\n // eslint-disable-next-line\n // @ts-ignore – there's pollution from the global scope of Node. Cannot use @ts-expect-error because of build:code and build:types context collision.\n window.strapi.ai = ai;\n } catch (err) {\n /**\n * If this fails, we simply don't activate any EE features.\n * Should we warn clearer in the UI?\n */\n console.error(err);\n }\n\n const app = new StrapiApp({\n config: customisations?.config,\n appPlugins: plugins,\n });\n\n await app.register(customisations?.register);\n await app.bootstrap(customisations?.bootstrap);\n await app.loadTrads(customisations?.config?.translations);\n\n createRoot(mountNode).render(app.render());\n\n if (\n typeof module !== 'undefined' &&\n module &&\n 'hot' in module &&\n typeof module.hot === 'object' &&\n module.hot !== null &&\n 'accept' in module.hot &&\n typeof module.hot.accept === 'function'\n ) {\n module.hot.accept();\n }\n\n if (typeof import.meta.hot?.accept === 'function') {\n import.meta.hot.accept();\n }\n};\n\nexport { renderAdmin };\nexport type { RenderAdminArgs };\n"],"names":["renderAdmin","mountNode","plugins","customisations","features","Error","window","strapi","backendURL","createAbsoluteUrl","process","env","STRAPI_ADMIN_BACKEND_URL","isEE","isTrial","telemetryDisabled","STRAPI_TELEMETRY_DISABLED","future","isEnabled","name","SSO","AUDIT_LOGS","REVIEW_WORKFLOWS","projectType","flags","nps","promoteEE","docLinks","ai","enabled","get","getFetchClient","data","planPriceId","isTrialLicense","featureName","some","feature","getProjectType","err","console","error","app","StrapiApp","config","appPlugins","register","bootstrap","loadTrads","translations","createRoot","render","module","hot","accept"],"mappings":"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"}
1
+ {"version":3,"file":"render.mjs","sources":["../../../../admin/src/render.ts"],"sourcesContent":["/* eslint-disable no-undef */\nimport { createRoot } from 'react-dom/client';\n\nimport { StrapiApp, StrapiAppConstructorArgs } from './StrapiApp';\nimport { getFetchClient } from './utils/getFetchClient';\nimport { getProjectType } from './utils/getProjectType';\nimport { createAbsoluteUrl } from './utils/urls';\n\nimport type { Modules } from '@strapi/types';\n\ninterface RenderAdminArgs {\n customisations: {\n register?: (app: StrapiApp) => Promise<void> | void;\n bootstrap?: (app: StrapiApp) => Promise<void> | void;\n config?: StrapiAppConstructorArgs['config'];\n };\n plugins: StrapiAppConstructorArgs['appPlugins'];\n features?: Modules.Features.FeaturesService['config'];\n}\n\nconst renderAdmin = async (\n mountNode: HTMLElement | null,\n { plugins, customisations, features }: RenderAdminArgs\n) => {\n if (!mountNode) {\n throw new Error('[@strapi/admin]: Could not find the root element to mount the admin app');\n }\n\n window.strapi = {\n /**\n * This ENV variable is passed from the strapi instance, by default no url is set\n * in the config and therefore the instance returns you an empty string so URLs are relative.\n *\n * To ensure that the backendURL is always set, we use the window.location.origin as a fallback.\n */\n backendURL: createAbsoluteUrl(process.env.STRAPI_ADMIN_BACKEND_URL),\n isEE: false,\n isTrial: false,\n telemetryDisabled: process.env.STRAPI_TELEMETRY_DISABLED === 'true',\n future: {\n isEnabled: (name: keyof NonNullable<Modules.Features.FeaturesConfig['future']>) => {\n return features?.future?.[name] === true;\n },\n },\n featureFlags: {\n isEnabled: (name: keyof Omit<Modules.Features.FeaturesConfig, 'future'>) => {\n return features?.[name] === true;\n },\n },\n // eslint-disable-next-line\n // @ts-ignore – there's pollution from the global scope of Node. Cannot use @ts-expect-error because of build:code and build:types context collision. Cannot use @ts-expect-error because of build:code and build:types context collision.\n features: {\n SSO: 'sso',\n AUDIT_LOGS: 'audit-logs',\n REVIEW_WORKFLOWS: 'review-workflows',\n /**\n * If we don't get the license then we know it's not EE\n * so no feature is enabled.\n */\n isEnabled: () => false,\n },\n projectType: 'Community',\n flags: {\n nps: false,\n promoteEE: true,\n docLinks: true,\n },\n // eslint-disable-next-line\n // @ts-ignore – there's pollution from the global scope of Node. Cannot use @ts-expect-error because of build:code and build:types context collision.\n ai: {\n enabled: true,\n },\n };\n\n const { get } = getFetchClient();\n\n interface ProjectType extends Pick<Window['strapi'], 'flags'> {\n isEE: boolean;\n isTrial: boolean;\n /**\n * The licensed plan price id, sent by the license registry (EE only).\n * Used to distinguish the Growth plan from other Enterprise plans.\n */\n planPriceId?: string;\n features: {\n name: string;\n }[];\n ai: {\n enabled: boolean;\n };\n }\n\n try {\n const {\n data: {\n data: { isEE, isTrial, features, flags, ai, planPriceId },\n },\n } = await get<{ data: ProjectType }>('/admin/project-type');\n\n window.strapi.isEE = isEE;\n window.strapi.isTrialLicense = isTrial;\n window.strapi.flags = flags;\n window.strapi.features = {\n ...window.strapi.features,\n isEnabled: (featureName: string | undefined) =>\n features.some((feature) => feature.name === featureName),\n };\n window.strapi.projectType = getProjectType({ isEE, planPriceId });\n // eslint-disable-next-line\n // @ts-ignore – there's pollution from the global scope of Node. Cannot use @ts-expect-error because of build:code and build:types context collision.\n window.strapi.ai = ai;\n } catch (err) {\n /**\n * If this fails, we simply don't activate any EE features.\n * Should we warn clearer in the UI?\n */\n console.error(err);\n }\n\n const app = new StrapiApp({\n config: customisations?.config,\n appPlugins: plugins,\n });\n\n await app.register(customisations?.register);\n await app.bootstrap(customisations?.bootstrap);\n await app.loadTrads(customisations?.config?.translations);\n\n createRoot(mountNode).render(app.render());\n\n if (\n typeof module !== 'undefined' &&\n module &&\n 'hot' in module &&\n typeof module.hot === 'object' &&\n module.hot !== null &&\n 'accept' in module.hot &&\n typeof module.hot.accept === 'function'\n ) {\n module.hot.accept();\n }\n\n if (typeof import.meta.hot?.accept === 'function') {\n import.meta.hot.accept();\n }\n};\n\nexport { renderAdmin };\nexport type { RenderAdminArgs };\n"],"names":["renderAdmin","mountNode","plugins","customisations","features","Error","window","strapi","backendURL","createAbsoluteUrl","process","env","STRAPI_ADMIN_BACKEND_URL","isEE","isTrial","telemetryDisabled","STRAPI_TELEMETRY_DISABLED","future","isEnabled","name","featureFlags","SSO","AUDIT_LOGS","REVIEW_WORKFLOWS","projectType","flags","nps","promoteEE","docLinks","ai","enabled","get","getFetchClient","data","planPriceId","isTrialLicense","featureName","some","feature","getProjectType","err","console","error","app","StrapiApp","config","appPlugins","register","bootstrap","loadTrads","translations","createRoot","render","module","hot","accept"],"mappings":"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"}
@@ -184,6 +184,7 @@ var en = {
184
184
  "Settings.permissions.auditLogs.action": "Action",
185
185
  "Settings.permissions.auditLogs.admin.auth.success": "Admin login",
186
186
  "Settings.permissions.auditLogs.admin.logout": "Admin logout",
187
+ "Settings.permissions.auditLogs.audit-log.export": "Export audit logs",
187
188
  "Settings.permissions.auditLogs.component.create": "Create component",
188
189
  "Settings.permissions.auditLogs.component.delete": "Delete component",
189
190
  "Settings.permissions.auditLogs.component.update": "Update component",
@@ -198,14 +199,35 @@ var en = {
198
199
  "Settings.permissions.auditLogs.entry.unpublish": "Unpublish entry{model, select, undefined {} other { ({model})}}",
199
200
  "Settings.permissions.auditLogs.entry.update": "Update entry{model, select, undefined {} other { ({model})}}",
200
201
  "Settings.permissions.auditLogs.filters.combobox.aria-label": "Search and select an option to filter",
202
+ "Settings.permissions.auditLogs.listview.export": "Export as CSV",
203
+ "Settings.permissions.auditLogs.listview.export.error": "The export failed. Please try again.",
204
+ "Settings.permissions.auditLogs.listview.export.error.forbidden": "You don't have the permissions to export audit logs.",
205
+ "Settings.permissions.auditLogs.listview.export.error.tooLarge": "Table too large to export. Please add filters and try again.",
206
+ "Settings.permissions.auditLogs.listview.export.leave": "Are you sure you want to leave? Your ongoing export will be canceled.",
207
+ "Settings.permissions.auditLogs.listview.export.progress.caption": "Preparing your export - {fetched, number} out of {total, plural, one {# event} other {# events}}",
208
+ "Settings.permissions.auditLogs.listview.export.progress.title": "Exporting audit logs",
209
+ "Settings.permissions.auditLogs.listview.export.ready.download": "Download CSV",
210
+ "Settings.permissions.auditLogs.listview.export.ready.title": "Export ready",
201
211
  "Settings.permissions.auditLogs.listview.header.subtitle": "Logs of all the activities that happened in your environment",
202
212
  "Settings.permissions.auditLogs.not-available": "Audit Logs is only available as part of a paid plan. Upgrade to get a searchable and filterable display of all activities.",
213
+ "Settings.permissions.auditLogs.locale.create": "Create locale",
214
+ "Settings.permissions.auditLogs.locale.default.update": "Change default locale",
215
+ "Settings.permissions.auditLogs.locale.delete": "Delete locale",
216
+ "Settings.permissions.auditLogs.locale.update": "Update locale",
203
217
  "Settings.permissions.auditLogs.media.create": "Create media",
204
218
  "Settings.permissions.auditLogs.media.delete": "Delete media",
205
219
  "Settings.permissions.auditLogs.media.update": "Update media",
206
220
  "Settings.permissions.auditLogs.payload": "Payload",
207
221
  "Settings.permissions.auditLogs.permission.create": "Create permission",
208
222
  "Settings.permissions.auditLogs.permission.delete": "Delete permission",
223
+ "Settings.permissions.auditLogs.release.create": "Create release",
224
+ "Settings.permissions.auditLogs.release.update": "Update release",
225
+ "Settings.permissions.auditLogs.release.delete": "Delete release",
226
+ "Settings.permissions.auditLogs.release.trigger": "Trigger release",
227
+ "Settings.permissions.auditLogs.release.entry.add": "Add entry to release",
228
+ "Settings.permissions.auditLogs.release.entry.update": "Change entry on release",
229
+ "Settings.permissions.auditLogs.release.entry.remove": "Remove entry from release",
230
+ "Settings.permissions.auditLogs.release.settings.update": "Update release settings",
209
231
  "Settings.permissions.auditLogs.permission.update": "Update permission",
210
232
  "Settings.permissions.auditLogs.role.create": "Create role",
211
233
  "Settings.permissions.auditLogs.role.delete": "Delete role",
@@ -522,6 +544,12 @@ var en = {
522
544
  "app.components.PluginCard.PopUpWarning.install.impossible.title": "Downloading is impossible",
523
545
  "app.components.PluginCard.compatible": "Compatible with your app",
524
546
  "app.components.PluginCard.compatibleCommunity": "Compatible with the community",
547
+ "app.components.MediaLibraryBanner.button": "Docs",
548
+ "app.components.MediaLibraryBanner.button.enabled": "Read blog post",
549
+ "app.components.MediaLibraryBanner.close": "Close the banner. ",
550
+ "app.components.MediaLibraryBanner.intro": "Introducing the new Media Library ",
551
+ "app.components.MediaLibraryBanner.text": "Check the documentation to learn how to switch to the new one.",
552
+ "app.components.MediaLibraryBanner.text.enabled": "You're now using the revamped version.",
525
553
  "app.components.PluginCard.more-details": "More details",
526
554
  "app.components.Select.placeholder": "Select",
527
555
  "app.components.ToggleCheckbox.off-label": "False",
@@ -561,6 +589,8 @@ var en = {
561
589
  "app.containers.Users.ModalForm.footer.button-success": "Invite user",
562
590
  "app.links.configure-view": "Configure the view",
563
591
  "app.page.not.found": "Oops! We can't seem to find the page you're looking for...",
592
+ "app.session.ended.title": "Session ended",
593
+ "app.session.ended.unsaved": "Your session has ended and can't be resumed. Your unsaved changes will be lost when you log out.",
564
594
  "app.static.links.cheatsheet": "CheatSheet",
565
595
  "app.utils.SelectOption.defaultMessage": " ",
566
596
  "app.utils.add-filter": "Add filter",
@@ -1 +1 @@
1
- {"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -180,6 +180,7 @@ var en = {
180
180
  "Settings.permissions.auditLogs.action": "Action",
181
181
  "Settings.permissions.auditLogs.admin.auth.success": "Admin login",
182
182
  "Settings.permissions.auditLogs.admin.logout": "Admin logout",
183
+ "Settings.permissions.auditLogs.audit-log.export": "Export audit logs",
183
184
  "Settings.permissions.auditLogs.component.create": "Create component",
184
185
  "Settings.permissions.auditLogs.component.delete": "Delete component",
185
186
  "Settings.permissions.auditLogs.component.update": "Update component",
@@ -194,14 +195,35 @@ var en = {
194
195
  "Settings.permissions.auditLogs.entry.unpublish": "Unpublish entry{model, select, undefined {} other { ({model})}}",
195
196
  "Settings.permissions.auditLogs.entry.update": "Update entry{model, select, undefined {} other { ({model})}}",
196
197
  "Settings.permissions.auditLogs.filters.combobox.aria-label": "Search and select an option to filter",
198
+ "Settings.permissions.auditLogs.listview.export": "Export as CSV",
199
+ "Settings.permissions.auditLogs.listview.export.error": "The export failed. Please try again.",
200
+ "Settings.permissions.auditLogs.listview.export.error.forbidden": "You don't have the permissions to export audit logs.",
201
+ "Settings.permissions.auditLogs.listview.export.error.tooLarge": "Table too large to export. Please add filters and try again.",
202
+ "Settings.permissions.auditLogs.listview.export.leave": "Are you sure you want to leave? Your ongoing export will be canceled.",
203
+ "Settings.permissions.auditLogs.listview.export.progress.caption": "Preparing your export - {fetched, number} out of {total, plural, one {# event} other {# events}}",
204
+ "Settings.permissions.auditLogs.listview.export.progress.title": "Exporting audit logs",
205
+ "Settings.permissions.auditLogs.listview.export.ready.download": "Download CSV",
206
+ "Settings.permissions.auditLogs.listview.export.ready.title": "Export ready",
197
207
  "Settings.permissions.auditLogs.listview.header.subtitle": "Logs of all the activities that happened in your environment",
198
208
  "Settings.permissions.auditLogs.not-available": "Audit Logs is only available as part of a paid plan. Upgrade to get a searchable and filterable display of all activities.",
209
+ "Settings.permissions.auditLogs.locale.create": "Create locale",
210
+ "Settings.permissions.auditLogs.locale.default.update": "Change default locale",
211
+ "Settings.permissions.auditLogs.locale.delete": "Delete locale",
212
+ "Settings.permissions.auditLogs.locale.update": "Update locale",
199
213
  "Settings.permissions.auditLogs.media.create": "Create media",
200
214
  "Settings.permissions.auditLogs.media.delete": "Delete media",
201
215
  "Settings.permissions.auditLogs.media.update": "Update media",
202
216
  "Settings.permissions.auditLogs.payload": "Payload",
203
217
  "Settings.permissions.auditLogs.permission.create": "Create permission",
204
218
  "Settings.permissions.auditLogs.permission.delete": "Delete permission",
219
+ "Settings.permissions.auditLogs.release.create": "Create release",
220
+ "Settings.permissions.auditLogs.release.update": "Update release",
221
+ "Settings.permissions.auditLogs.release.delete": "Delete release",
222
+ "Settings.permissions.auditLogs.release.trigger": "Trigger release",
223
+ "Settings.permissions.auditLogs.release.entry.add": "Add entry to release",
224
+ "Settings.permissions.auditLogs.release.entry.update": "Change entry on release",
225
+ "Settings.permissions.auditLogs.release.entry.remove": "Remove entry from release",
226
+ "Settings.permissions.auditLogs.release.settings.update": "Update release settings",
205
227
  "Settings.permissions.auditLogs.permission.update": "Update permission",
206
228
  "Settings.permissions.auditLogs.role.create": "Create role",
207
229
  "Settings.permissions.auditLogs.role.delete": "Delete role",
@@ -518,6 +540,12 @@ var en = {
518
540
  "app.components.PluginCard.PopUpWarning.install.impossible.title": "Downloading is impossible",
519
541
  "app.components.PluginCard.compatible": "Compatible with your app",
520
542
  "app.components.PluginCard.compatibleCommunity": "Compatible with the community",
543
+ "app.components.MediaLibraryBanner.button": "Docs",
544
+ "app.components.MediaLibraryBanner.button.enabled": "Read blog post",
545
+ "app.components.MediaLibraryBanner.close": "Close the banner. ",
546
+ "app.components.MediaLibraryBanner.intro": "Introducing the new Media Library ",
547
+ "app.components.MediaLibraryBanner.text": "Check the documentation to learn how to switch to the new one.",
548
+ "app.components.MediaLibraryBanner.text.enabled": "You're now using the revamped version.",
521
549
  "app.components.PluginCard.more-details": "More details",
522
550
  "app.components.Select.placeholder": "Select",
523
551
  "app.components.ToggleCheckbox.off-label": "False",
@@ -557,6 +585,8 @@ var en = {
557
585
  "app.containers.Users.ModalForm.footer.button-success": "Invite user",
558
586
  "app.links.configure-view": "Configure the view",
559
587
  "app.page.not.found": "Oops! We can't seem to find the page you're looking for...",
588
+ "app.session.ended.title": "Session ended",
589
+ "app.session.ended.unsaved": "Your session has ended and can't be resumed. Your unsaved changes will be lost when you log out.",
560
590
  "app.static.links.cheatsheet": "CheatSheet",
561
591
  "app.utils.SelectOption.defaultMessage": " ",
562
592
  "app.utils.add-filter": "Add filter",
@@ -1 +1 @@
1
- {"version":3,"file":"en.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"en.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,11 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var reducer = require('../reducer.js');
4
3
  var getFetchClient = require('./getFetchClient.js');
5
4
 
6
5
  const isAuthPath = (url)=>/^\/admin\/(login|logout|access-token)\b/.test(url);
7
6
  const simpleQuery = async (query, api)=>{
8
- const { signal, dispatch } = api;
7
+ const { signal } = api;
9
8
  const executeQuery = async (queryToExecute)=>{
10
9
  const { get, post, del, put } = getFetchClient.getFetchClient();
11
10
  if (typeof queryToExecute === 'string') {
@@ -51,17 +50,8 @@ const simpleQuery = async (query, api)=>{
51
50
  if (err.status === 401) {
52
51
  const url = typeof query === 'string' ? query : query.url;
53
52
  if (!isAuthPath(url)) {
54
- try {
55
- const { post } = getFetchClient.getFetchClient();
56
- await post('/admin/logout');
57
- } catch {
58
- // no-op
59
- }
60
- dispatch(reducer.logout());
61
- // Notify the React layer so the active tab redirects to /auth/login.
62
- // Without this, only other tabs (via the storage event) would react;
63
- // the tab that originated the failing request would stay put until
64
- // the user clicked something or refreshed.
53
+ // Defer clearing auth state to AuthProvider so unsaved-change guards
54
+ // can run before token removal (which unmounts edit forms).
65
55
  getFetchClient.triggerSessionExpired();
66
56
  }
67
57
  }
@@ -1 +1 @@
1
- {"version":3,"file":"baseQuery.js","sources":["../../../../../admin/src/utils/baseQuery.ts"],"sourcesContent":["import { SerializedError } from '@reduxjs/toolkit';\nimport { BaseQueryFn } from '@reduxjs/toolkit/query';\n\nimport { logout as logoutAction } from '../reducer';\nimport {\n getFetchClient,\n triggerSessionExpired,\n type FetchOptions,\n ApiError,\n isFetchError,\n} from '../utils/getFetchClient';\n\ninterface QueryArguments {\n url: string;\n method?: 'GET' | 'POST' | 'DELETE' | 'PUT';\n data?: unknown;\n config?: FetchOptions;\n}\n\ninterface UnknownApiError {\n name: 'UnknownError';\n message: string;\n details?: unknown;\n status?: number;\n}\n\ntype BaseQueryError = ApiError | UnknownApiError;\n\nconst isAuthPath = (url: string) => /^\\/admin\\/(login|logout|access-token)\\b/.test(url);\n\nconst simpleQuery: BaseQueryFn<\n string | QueryArguments,\n unknown,\n BaseQueryError | SerializedError\n> = async (query, api) => {\n const { signal, dispatch } = api;\n\n const executeQuery = async (queryToExecute: string | QueryArguments) => {\n const { get, post, del, put } = getFetchClient();\n if (typeof queryToExecute === 'string') {\n const result = await get(queryToExecute, { signal });\n return result;\n }\n\n const { url, method = 'GET', data, config } = queryToExecute;\n if (method === 'POST') {\n return post(url, data, { ...config, signal });\n }\n if (method === 'DELETE') {\n return del(url, { ...config, signal });\n }\n if (method === 'PUT') {\n return put(url, data, { ...config, signal });\n }\n return get(url, { ...config, signal });\n };\n\n try {\n const result = await executeQuery(query);\n return { data: result.data };\n } catch (err) {\n // Handle error of type FetchError\n\n if (isFetchError(err)) {\n // If we receive a 401 here, getFetchClient already tried to refresh and failed.\n // Log the user out since their session is no longer valid.\n if (err.status === 401) {\n const url = typeof query === 'string' ? query : query.url;\n\n if (!isAuthPath(url)) {\n try {\n const { post } = getFetchClient();\n await post('/admin/logout');\n } catch {\n // no-op\n }\n\n dispatch(logoutAction());\n // Notify the React layer so the active tab redirects to /auth/login.\n // Without this, only other tabs (via the storage event) would react;\n // the tab that originated the failing request would stay put until\n // the user clicked something or refreshed.\n triggerSessionExpired();\n }\n }\n\n const responseData = err.response?.data;\n\n if (typeof responseData === 'object' && responseData !== null && 'error' in responseData) {\n /**\n * This will most likely be ApiError\n */\n return { data: undefined, error: responseData.error as BaseQueryError };\n } else {\n return {\n data: undefined,\n error: {\n name: 'UnknownError',\n message: err.message,\n details: err.response,\n status: err.status,\n } as UnknownApiError,\n };\n }\n }\n\n const error = err instanceof Error ? err : new Error('Unknown error');\n return {\n data: undefined,\n error: {\n name: error.name,\n message: error.message,\n stack: error.stack,\n } satisfies SerializedError,\n };\n }\n};\n\nconst fetchBaseQuery = () => simpleQuery;\n\nconst isBaseQueryError = (error: BaseQueryError | SerializedError): error is BaseQueryError => {\n return error.name !== undefined;\n};\n\nexport { fetchBaseQuery, isBaseQueryError };\nexport type { BaseQueryError, UnknownApiError, QueryArguments };\n"],"names":["isAuthPath","url","test","simpleQuery","query","api","signal","dispatch","executeQuery","queryToExecute","get","post","del","put","getFetchClient","result","method","data","config","err","isFetchError","status","logoutAction","triggerSessionExpired","responseData","response","undefined","error","name","message","details","Error","stack","fetchBaseQuery","isBaseQueryError"],"mappings":"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"}
1
+ {"version":3,"file":"baseQuery.js","sources":["../../../../../admin/src/utils/baseQuery.ts"],"sourcesContent":["import { SerializedError } from '@reduxjs/toolkit';\nimport { BaseQueryFn } from '@reduxjs/toolkit/query';\n\nimport {\n getFetchClient,\n triggerSessionExpired,\n type FetchOptions,\n ApiError,\n isFetchError,\n} from '../utils/getFetchClient';\n\ninterface QueryArguments {\n url: string;\n method?: 'GET' | 'POST' | 'DELETE' | 'PUT';\n data?: unknown;\n config?: FetchOptions;\n}\n\ninterface UnknownApiError {\n name: 'UnknownError';\n message: string;\n details?: unknown;\n status?: number;\n}\n\ntype BaseQueryError = ApiError | UnknownApiError;\n\nconst isAuthPath = (url: string) => /^\\/admin\\/(login|logout|access-token)\\b/.test(url);\n\nconst simpleQuery: BaseQueryFn<\n string | QueryArguments,\n unknown,\n BaseQueryError | SerializedError\n> = async (query, api) => {\n const { signal } = api;\n\n const executeQuery = async (queryToExecute: string | QueryArguments) => {\n const { get, post, del, put } = getFetchClient();\n if (typeof queryToExecute === 'string') {\n const result = await get(queryToExecute, { signal });\n return result;\n }\n\n const { url, method = 'GET', data, config } = queryToExecute;\n if (method === 'POST') {\n return post(url, data, { ...config, signal });\n }\n if (method === 'DELETE') {\n return del(url, { ...config, signal });\n }\n if (method === 'PUT') {\n return put(url, data, { ...config, signal });\n }\n return get(url, { ...config, signal });\n };\n\n try {\n const result = await executeQuery(query);\n return { data: result.data };\n } catch (err) {\n // Handle error of type FetchError\n\n if (isFetchError(err)) {\n // If we receive a 401 here, getFetchClient already tried to refresh and failed.\n // Log the user out since their session is no longer valid.\n if (err.status === 401) {\n const url = typeof query === 'string' ? query : query.url;\n\n if (!isAuthPath(url)) {\n // Defer clearing auth state to AuthProvider so unsaved-change guards\n // can run before token removal (which unmounts edit forms).\n triggerSessionExpired();\n }\n }\n\n const responseData = err.response?.data;\n\n if (typeof responseData === 'object' && responseData !== null && 'error' in responseData) {\n /**\n * This will most likely be ApiError\n */\n return { data: undefined, error: responseData.error as BaseQueryError };\n } else {\n return {\n data: undefined,\n error: {\n name: 'UnknownError',\n message: err.message,\n details: err.response,\n status: err.status,\n } as UnknownApiError,\n };\n }\n }\n\n const error = err instanceof Error ? err : new Error('Unknown error');\n return {\n data: undefined,\n error: {\n name: error.name,\n message: error.message,\n stack: error.stack,\n } satisfies SerializedError,\n };\n }\n};\n\nconst fetchBaseQuery = () => simpleQuery;\n\nconst isBaseQueryError = (error: BaseQueryError | SerializedError): error is BaseQueryError => {\n return error.name !== undefined;\n};\n\nexport { fetchBaseQuery, isBaseQueryError };\nexport type { BaseQueryError, UnknownApiError, QueryArguments };\n"],"names":["isAuthPath","url","test","simpleQuery","query","api","signal","executeQuery","queryToExecute","get","post","del","put","getFetchClient","result","method","data","config","err","isFetchError","status","triggerSessionExpired","responseData","response","undefined","error","name","message","details","Error","stack","fetchBaseQuery","isBaseQueryError"],"mappings":";;;;AA2BA,MAAMA,UAAAA,GAAa,CAACC,GAAAA,GAAgB,yCAAA,CAA0CC,IAAI,CAACD,GAAAA,CAAAA;AAEnF,MAAME,WAAAA,GAIF,OAAOC,KAAAA,EAAOC,GAAAA,GAAAA;IAChB,MAAM,EAAEC,MAAM,EAAE,GAAGD,GAAAA;AAEnB,IAAA,MAAME,eAAe,OAAOC,cAAAA,GAAAA;QAC1B,MAAM,EAAEC,GAAG,EAAEC,IAAI,EAAEC,GAAG,EAAEC,GAAG,EAAE,GAAGC,6BAAAA,EAAAA;QAChC,IAAI,OAAOL,mBAAmB,QAAA,EAAU;YACtC,MAAMM,MAAAA,GAAS,MAAML,GAAAA,CAAID,cAAAA,EAAgB;AAAEF,gBAAAA;AAAO,aAAA,CAAA;YAClD,OAAOQ,MAAAA;AACT,QAAA;QAEA,MAAM,EAAEb,GAAG,EAAEc,MAAAA,GAAS,KAAK,EAAEC,IAAI,EAAEC,MAAM,EAAE,GAAGT,cAAAA;AAC9C,QAAA,IAAIO,WAAW,MAAA,EAAQ;YACrB,OAAOL,IAAAA,CAAKT,KAAKe,IAAAA,EAAM;AAAE,gBAAA,GAAGC,MAAM;AAAEX,gBAAAA;AAAO,aAAA,CAAA;AAC7C,QAAA;AACA,QAAA,IAAIS,WAAW,QAAA,EAAU;AACvB,YAAA,OAAOJ,IAAIV,GAAAA,EAAK;AAAE,gBAAA,GAAGgB,MAAM;AAAEX,gBAAAA;AAAO,aAAA,CAAA;AACtC,QAAA;AACA,QAAA,IAAIS,WAAW,KAAA,EAAO;YACpB,OAAOH,GAAAA,CAAIX,KAAKe,IAAAA,EAAM;AAAE,gBAAA,GAAGC,MAAM;AAAEX,gBAAAA;AAAO,aAAA,CAAA;AAC5C,QAAA;AACA,QAAA,OAAOG,IAAIR,GAAAA,EAAK;AAAE,YAAA,GAAGgB,MAAM;AAAEX,YAAAA;AAAO,SAAA,CAAA;AACtC,IAAA,CAAA;IAEA,IAAI;QACF,MAAMQ,MAAAA,GAAS,MAAMP,YAAAA,CAAaH,KAAAA,CAAAA;QAClC,OAAO;AAAEY,YAAAA,IAAAA,EAAMF,OAAOE;AAAK,SAAA;AAC7B,IAAA,CAAA,CAAE,OAAOE,GAAAA,EAAK;;AAGZ,QAAA,IAAIC,4BAAaD,GAAAA,CAAAA,EAAM;;;YAGrB,IAAIA,GAAAA,CAAIE,MAAM,KAAK,GAAA,EAAK;AACtB,gBAAA,MAAMnB,MAAM,OAAOG,KAAAA,KAAU,QAAA,GAAWA,KAAAA,GAAQA,MAAMH,GAAG;gBAEzD,IAAI,CAACD,WAAWC,GAAAA,CAAAA,EAAM;;;AAGpBoB,oBAAAA,oCAAAA,EAAAA;AACF,gBAAA;AACF,YAAA;YAEA,MAAMC,YAAAA,GAAeJ,GAAAA,CAAIK,QAAQ,EAAEP,IAAAA;AAEnC,YAAA,IAAI,OAAOM,YAAAA,KAAiB,QAAA,IAAYA,YAAAA,KAAiB,IAAA,IAAQ,WAAWA,YAAAA,EAAc;AACxF;;AAEC,YACD,OAAO;oBAAEN,IAAAA,EAAMQ,SAAAA;AAAWC,oBAAAA,KAAAA,EAAOH,aAAaG;AAAwB,iBAAA;YACxE,CAAA,MAAO;gBACL,OAAO;oBACLT,IAAAA,EAAMQ,SAAAA;oBACNC,KAAAA,EAAO;wBACLC,IAAAA,EAAM,cAAA;AACNC,wBAAAA,OAAAA,EAAST,IAAIS,OAAO;AACpBC,wBAAAA,OAAAA,EAASV,IAAIK,QAAQ;AACrBH,wBAAAA,MAAAA,EAAQF,IAAIE;AACd;AACF,iBAAA;AACF,YAAA;AACF,QAAA;AAEA,QAAA,MAAMK,KAAAA,GAAQP,GAAAA,YAAeW,KAAAA,GAAQX,GAAAA,GAAM,IAAIW,KAAAA,CAAM,eAAA,CAAA;QACrD,OAAO;YACLb,IAAAA,EAAMQ,SAAAA;YACNC,KAAAA,EAAO;AACLC,gBAAAA,IAAAA,EAAMD,MAAMC,IAAI;AAChBC,gBAAAA,OAAAA,EAASF,MAAME,OAAO;AACtBG,gBAAAA,KAAAA,EAAOL,MAAMK;AACf;AACF,SAAA;AACF,IAAA;AACF,CAAA;AAEA,MAAMC,iBAAiB,IAAM5B;AAE7B,MAAM6B,mBAAmB,CAACP,KAAAA,GAAAA;IACxB,OAAOA,KAAAA,CAAMC,IAAI,KAAKF,SAAAA;AACxB;;;;;"}
@@ -1,9 +1,8 @@
1
- import { logout } from '../reducer.mjs';
2
1
  import { isFetchError, getFetchClient, triggerSessionExpired } from './getFetchClient.mjs';
3
2
 
4
3
  const isAuthPath = (url)=>/^\/admin\/(login|logout|access-token)\b/.test(url);
5
4
  const simpleQuery = async (query, api)=>{
6
- const { signal, dispatch } = api;
5
+ const { signal } = api;
7
6
  const executeQuery = async (queryToExecute)=>{
8
7
  const { get, post, del, put } = getFetchClient();
9
8
  if (typeof queryToExecute === 'string') {
@@ -49,17 +48,8 @@ const simpleQuery = async (query, api)=>{
49
48
  if (err.status === 401) {
50
49
  const url = typeof query === 'string' ? query : query.url;
51
50
  if (!isAuthPath(url)) {
52
- try {
53
- const { post } = getFetchClient();
54
- await post('/admin/logout');
55
- } catch {
56
- // no-op
57
- }
58
- dispatch(logout());
59
- // Notify the React layer so the active tab redirects to /auth/login.
60
- // Without this, only other tabs (via the storage event) would react;
61
- // the tab that originated the failing request would stay put until
62
- // the user clicked something or refreshed.
51
+ // Defer clearing auth state to AuthProvider so unsaved-change guards
52
+ // can run before token removal (which unmounts edit forms).
63
53
  triggerSessionExpired();
64
54
  }
65
55
  }
@@ -1 +1 @@
1
- {"version":3,"file":"baseQuery.mjs","sources":["../../../../../admin/src/utils/baseQuery.ts"],"sourcesContent":["import { SerializedError } from '@reduxjs/toolkit';\nimport { BaseQueryFn } from '@reduxjs/toolkit/query';\n\nimport { logout as logoutAction } from '../reducer';\nimport {\n getFetchClient,\n triggerSessionExpired,\n type FetchOptions,\n ApiError,\n isFetchError,\n} from '../utils/getFetchClient';\n\ninterface QueryArguments {\n url: string;\n method?: 'GET' | 'POST' | 'DELETE' | 'PUT';\n data?: unknown;\n config?: FetchOptions;\n}\n\ninterface UnknownApiError {\n name: 'UnknownError';\n message: string;\n details?: unknown;\n status?: number;\n}\n\ntype BaseQueryError = ApiError | UnknownApiError;\n\nconst isAuthPath = (url: string) => /^\\/admin\\/(login|logout|access-token)\\b/.test(url);\n\nconst simpleQuery: BaseQueryFn<\n string | QueryArguments,\n unknown,\n BaseQueryError | SerializedError\n> = async (query, api) => {\n const { signal, dispatch } = api;\n\n const executeQuery = async (queryToExecute: string | QueryArguments) => {\n const { get, post, del, put } = getFetchClient();\n if (typeof queryToExecute === 'string') {\n const result = await get(queryToExecute, { signal });\n return result;\n }\n\n const { url, method = 'GET', data, config } = queryToExecute;\n if (method === 'POST') {\n return post(url, data, { ...config, signal });\n }\n if (method === 'DELETE') {\n return del(url, { ...config, signal });\n }\n if (method === 'PUT') {\n return put(url, data, { ...config, signal });\n }\n return get(url, { ...config, signal });\n };\n\n try {\n const result = await executeQuery(query);\n return { data: result.data };\n } catch (err) {\n // Handle error of type FetchError\n\n if (isFetchError(err)) {\n // If we receive a 401 here, getFetchClient already tried to refresh and failed.\n // Log the user out since their session is no longer valid.\n if (err.status === 401) {\n const url = typeof query === 'string' ? query : query.url;\n\n if (!isAuthPath(url)) {\n try {\n const { post } = getFetchClient();\n await post('/admin/logout');\n } catch {\n // no-op\n }\n\n dispatch(logoutAction());\n // Notify the React layer so the active tab redirects to /auth/login.\n // Without this, only other tabs (via the storage event) would react;\n // the tab that originated the failing request would stay put until\n // the user clicked something or refreshed.\n triggerSessionExpired();\n }\n }\n\n const responseData = err.response?.data;\n\n if (typeof responseData === 'object' && responseData !== null && 'error' in responseData) {\n /**\n * This will most likely be ApiError\n */\n return { data: undefined, error: responseData.error as BaseQueryError };\n } else {\n return {\n data: undefined,\n error: {\n name: 'UnknownError',\n message: err.message,\n details: err.response,\n status: err.status,\n } as UnknownApiError,\n };\n }\n }\n\n const error = err instanceof Error ? err : new Error('Unknown error');\n return {\n data: undefined,\n error: {\n name: error.name,\n message: error.message,\n stack: error.stack,\n } satisfies SerializedError,\n };\n }\n};\n\nconst fetchBaseQuery = () => simpleQuery;\n\nconst isBaseQueryError = (error: BaseQueryError | SerializedError): error is BaseQueryError => {\n return error.name !== undefined;\n};\n\nexport { fetchBaseQuery, isBaseQueryError };\nexport type { BaseQueryError, UnknownApiError, QueryArguments };\n"],"names":["isAuthPath","url","test","simpleQuery","query","api","signal","dispatch","executeQuery","queryToExecute","get","post","del","put","getFetchClient","result","method","data","config","err","isFetchError","status","logoutAction","triggerSessionExpired","responseData","response","undefined","error","name","message","details","Error","stack","fetchBaseQuery","isBaseQueryError"],"mappings":";;;AA4BA,MAAMA,UAAAA,GAAa,CAACC,GAAAA,GAAgB,yCAAA,CAA0CC,IAAI,CAACD,GAAAA,CAAAA;AAEnF,MAAME,WAAAA,GAIF,OAAOC,KAAAA,EAAOC,GAAAA,GAAAA;AAChB,IAAA,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAE,GAAGF,GAAAA;AAE7B,IAAA,MAAMG,eAAe,OAAOC,cAAAA,GAAAA;QAC1B,MAAM,EAAEC,GAAG,EAAEC,IAAI,EAAEC,GAAG,EAAEC,GAAG,EAAE,GAAGC,cAAAA,EAAAA;QAChC,IAAI,OAAOL,mBAAmB,QAAA,EAAU;YACtC,MAAMM,MAAAA,GAAS,MAAML,GAAAA,CAAID,cAAAA,EAAgB;AAAEH,gBAAAA;AAAO,aAAA,CAAA;YAClD,OAAOS,MAAAA;AACT,QAAA;QAEA,MAAM,EAAEd,GAAG,EAAEe,MAAAA,GAAS,KAAK,EAAEC,IAAI,EAAEC,MAAM,EAAE,GAAGT,cAAAA;AAC9C,QAAA,IAAIO,WAAW,MAAA,EAAQ;YACrB,OAAOL,IAAAA,CAAKV,KAAKgB,IAAAA,EAAM;AAAE,gBAAA,GAAGC,MAAM;AAAEZ,gBAAAA;AAAO,aAAA,CAAA;AAC7C,QAAA;AACA,QAAA,IAAIU,WAAW,QAAA,EAAU;AACvB,YAAA,OAAOJ,IAAIX,GAAAA,EAAK;AAAE,gBAAA,GAAGiB,MAAM;AAAEZ,gBAAAA;AAAO,aAAA,CAAA;AACtC,QAAA;AACA,QAAA,IAAIU,WAAW,KAAA,EAAO;YACpB,OAAOH,GAAAA,CAAIZ,KAAKgB,IAAAA,EAAM;AAAE,gBAAA,GAAGC,MAAM;AAAEZ,gBAAAA;AAAO,aAAA,CAAA;AAC5C,QAAA;AACA,QAAA,OAAOI,IAAIT,GAAAA,EAAK;AAAE,YAAA,GAAGiB,MAAM;AAAEZ,YAAAA;AAAO,SAAA,CAAA;AACtC,IAAA,CAAA;IAEA,IAAI;QACF,MAAMS,MAAAA,GAAS,MAAMP,YAAAA,CAAaJ,KAAAA,CAAAA;QAClC,OAAO;AAAEa,YAAAA,IAAAA,EAAMF,OAAOE;AAAK,SAAA;AAC7B,IAAA,CAAA,CAAE,OAAOE,GAAAA,EAAK;;AAGZ,QAAA,IAAIC,aAAaD,GAAAA,CAAAA,EAAM;;;YAGrB,IAAIA,GAAAA,CAAIE,MAAM,KAAK,GAAA,EAAK;AACtB,gBAAA,MAAMpB,MAAM,OAAOG,KAAAA,KAAU,QAAA,GAAWA,KAAAA,GAAQA,MAAMH,GAAG;gBAEzD,IAAI,CAACD,WAAWC,GAAAA,CAAAA,EAAM;oBACpB,IAAI;wBACF,MAAM,EAAEU,IAAI,EAAE,GAAGG,cAAAA,EAAAA;AACjB,wBAAA,MAAMH,IAAAA,CAAK,eAAA,CAAA;AACb,oBAAA,CAAA,CAAE,OAAM;;AAER,oBAAA;oBAEAJ,QAAAA,CAASe,MAAAA,EAAAA,CAAAA;;;;;AAKTC,oBAAAA,qBAAAA,EAAAA;AACF,gBAAA;AACF,YAAA;YAEA,MAAMC,YAAAA,GAAeL,GAAAA,CAAIM,QAAQ,EAAER,IAAAA;AAEnC,YAAA,IAAI,OAAOO,YAAAA,KAAiB,QAAA,IAAYA,YAAAA,KAAiB,IAAA,IAAQ,WAAWA,YAAAA,EAAc;AACxF;;AAEC,YACD,OAAO;oBAAEP,IAAAA,EAAMS,SAAAA;AAAWC,oBAAAA,KAAAA,EAAOH,aAAaG;AAAwB,iBAAA;YACxE,CAAA,MAAO;gBACL,OAAO;oBACLV,IAAAA,EAAMS,SAAAA;oBACNC,KAAAA,EAAO;wBACLC,IAAAA,EAAM,cAAA;AACNC,wBAAAA,OAAAA,EAASV,IAAIU,OAAO;AACpBC,wBAAAA,OAAAA,EAASX,IAAIM,QAAQ;AACrBJ,wBAAAA,MAAAA,EAAQF,IAAIE;AACd;AACF,iBAAA;AACF,YAAA;AACF,QAAA;AAEA,QAAA,MAAMM,KAAAA,GAAQR,GAAAA,YAAeY,KAAAA,GAAQZ,GAAAA,GAAM,IAAIY,KAAAA,CAAM,eAAA,CAAA;QACrD,OAAO;YACLd,IAAAA,EAAMS,SAAAA;YACNC,KAAAA,EAAO;AACLC,gBAAAA,IAAAA,EAAMD,MAAMC,IAAI;AAChBC,gBAAAA,OAAAA,EAASF,MAAME,OAAO;AACtBG,gBAAAA,KAAAA,EAAOL,MAAMK;AACf;AACF,SAAA;AACF,IAAA;AACF,CAAA;AAEA,MAAMC,iBAAiB,IAAM9B;AAE7B,MAAM+B,mBAAmB,CAACP,KAAAA,GAAAA;IACxB,OAAOA,KAAAA,CAAMC,IAAI,KAAKF,SAAAA;AACxB;;;;"}
1
+ {"version":3,"file":"baseQuery.mjs","sources":["../../../../../admin/src/utils/baseQuery.ts"],"sourcesContent":["import { SerializedError } from '@reduxjs/toolkit';\nimport { BaseQueryFn } from '@reduxjs/toolkit/query';\n\nimport {\n getFetchClient,\n triggerSessionExpired,\n type FetchOptions,\n ApiError,\n isFetchError,\n} from '../utils/getFetchClient';\n\ninterface QueryArguments {\n url: string;\n method?: 'GET' | 'POST' | 'DELETE' | 'PUT';\n data?: unknown;\n config?: FetchOptions;\n}\n\ninterface UnknownApiError {\n name: 'UnknownError';\n message: string;\n details?: unknown;\n status?: number;\n}\n\ntype BaseQueryError = ApiError | UnknownApiError;\n\nconst isAuthPath = (url: string) => /^\\/admin\\/(login|logout|access-token)\\b/.test(url);\n\nconst simpleQuery: BaseQueryFn<\n string | QueryArguments,\n unknown,\n BaseQueryError | SerializedError\n> = async (query, api) => {\n const { signal } = api;\n\n const executeQuery = async (queryToExecute: string | QueryArguments) => {\n const { get, post, del, put } = getFetchClient();\n if (typeof queryToExecute === 'string') {\n const result = await get(queryToExecute, { signal });\n return result;\n }\n\n const { url, method = 'GET', data, config } = queryToExecute;\n if (method === 'POST') {\n return post(url, data, { ...config, signal });\n }\n if (method === 'DELETE') {\n return del(url, { ...config, signal });\n }\n if (method === 'PUT') {\n return put(url, data, { ...config, signal });\n }\n return get(url, { ...config, signal });\n };\n\n try {\n const result = await executeQuery(query);\n return { data: result.data };\n } catch (err) {\n // Handle error of type FetchError\n\n if (isFetchError(err)) {\n // If we receive a 401 here, getFetchClient already tried to refresh and failed.\n // Log the user out since their session is no longer valid.\n if (err.status === 401) {\n const url = typeof query === 'string' ? query : query.url;\n\n if (!isAuthPath(url)) {\n // Defer clearing auth state to AuthProvider so unsaved-change guards\n // can run before token removal (which unmounts edit forms).\n triggerSessionExpired();\n }\n }\n\n const responseData = err.response?.data;\n\n if (typeof responseData === 'object' && responseData !== null && 'error' in responseData) {\n /**\n * This will most likely be ApiError\n */\n return { data: undefined, error: responseData.error as BaseQueryError };\n } else {\n return {\n data: undefined,\n error: {\n name: 'UnknownError',\n message: err.message,\n details: err.response,\n status: err.status,\n } as UnknownApiError,\n };\n }\n }\n\n const error = err instanceof Error ? err : new Error('Unknown error');\n return {\n data: undefined,\n error: {\n name: error.name,\n message: error.message,\n stack: error.stack,\n } satisfies SerializedError,\n };\n }\n};\n\nconst fetchBaseQuery = () => simpleQuery;\n\nconst isBaseQueryError = (error: BaseQueryError | SerializedError): error is BaseQueryError => {\n return error.name !== undefined;\n};\n\nexport { fetchBaseQuery, isBaseQueryError };\nexport type { BaseQueryError, UnknownApiError, QueryArguments };\n"],"names":["isAuthPath","url","test","simpleQuery","query","api","signal","executeQuery","queryToExecute","get","post","del","put","getFetchClient","result","method","data","config","err","isFetchError","status","triggerSessionExpired","responseData","response","undefined","error","name","message","details","Error","stack","fetchBaseQuery","isBaseQueryError"],"mappings":"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"}