@strapi/i18n 0.0.0-next.e21fe90bf2ab9906267ea6e6ca620bdcc729906c → 0.0.0-next.e2e3ca14971ee768e1a227a209362264fd0132d4

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 (203) hide show
  1. package/dist/admin/components/BulkLocaleActionModal.js +2 -2
  2. package/dist/admin/components/BulkLocaleActionModal.js.map +1 -1
  3. package/dist/admin/components/BulkLocaleActionModal.mjs +2 -2
  4. package/dist/admin/components/BulkLocaleActionModal.mjs.map +1 -1
  5. package/dist/admin/components/CMHeaderActions.js +294 -20
  6. package/dist/admin/components/CMHeaderActions.js.map +1 -1
  7. package/dist/admin/components/CMHeaderActions.mjs +298 -25
  8. package/dist/admin/components/CMHeaderActions.mjs.map +1 -1
  9. package/dist/admin/components/CreateLocale.js +12 -6
  10. package/dist/admin/components/CreateLocale.js.map +1 -1
  11. package/dist/admin/components/CreateLocale.mjs +13 -7
  12. package/dist/admin/components/CreateLocale.mjs.map +1 -1
  13. package/dist/admin/components/EditLocale.js +1 -1
  14. package/dist/admin/components/EditLocale.js.map +1 -1
  15. package/dist/admin/components/EditLocale.mjs +1 -1
  16. package/dist/admin/components/EditLocale.mjs.map +1 -1
  17. package/dist/admin/components/LocaleListCell.js +65 -45
  18. package/dist/admin/components/LocaleListCell.js.map +1 -1
  19. package/dist/admin/components/LocaleListCell.mjs +66 -46
  20. package/dist/admin/components/LocaleListCell.mjs.map +1 -1
  21. package/dist/admin/components/LocalePicker.js +18 -11
  22. package/dist/admin/components/LocalePicker.js.map +1 -1
  23. package/dist/admin/components/LocalePicker.mjs +19 -12
  24. package/dist/admin/components/LocalePicker.mjs.map +1 -1
  25. package/dist/admin/contentManagerHooks/editView.js +6 -3
  26. package/dist/admin/contentManagerHooks/editView.js.map +1 -1
  27. package/dist/admin/contentManagerHooks/editView.mjs +7 -4
  28. package/dist/admin/contentManagerHooks/editView.mjs.map +1 -1
  29. package/dist/admin/contentManagerHooks/listView.js +2 -1
  30. package/dist/admin/contentManagerHooks/listView.js.map +1 -1
  31. package/dist/admin/contentManagerHooks/listView.mjs +2 -1
  32. package/dist/admin/contentManagerHooks/listView.mjs.map +1 -1
  33. package/dist/admin/hooks/useAILocalizationJobsPolling.js +110 -0
  34. package/dist/admin/hooks/useAILocalizationJobsPolling.js.map +1 -0
  35. package/dist/admin/hooks/useAILocalizationJobsPolling.mjs +89 -0
  36. package/dist/admin/hooks/useAILocalizationJobsPolling.mjs.map +1 -0
  37. package/dist/admin/hooks/useI18n.js +4 -4
  38. package/dist/admin/hooks/useI18n.js.map +1 -1
  39. package/dist/admin/hooks/useI18n.mjs +4 -4
  40. package/dist/admin/hooks/useI18n.mjs.map +1 -1
  41. package/dist/admin/index.js +1 -1
  42. package/dist/admin/index.js.map +1 -1
  43. package/dist/admin/index.mjs +2 -2
  44. package/dist/admin/index.mjs.map +1 -1
  45. package/dist/admin/middlewares/extendCTBAttributeInitialData.js +34 -24
  46. package/dist/admin/middlewares/extendCTBAttributeInitialData.js.map +1 -1
  47. package/dist/admin/middlewares/extendCTBAttributeInitialData.mjs +34 -24
  48. package/dist/admin/middlewares/extendCTBAttributeInitialData.mjs.map +1 -1
  49. package/dist/admin/pages/SettingsPage.js +121 -46
  50. package/dist/admin/pages/SettingsPage.js.map +1 -1
  51. package/dist/admin/pages/SettingsPage.mjs +124 -30
  52. package/dist/admin/pages/SettingsPage.mjs.map +1 -1
  53. package/dist/admin/services/aiLocalizationJobs.js +26 -0
  54. package/dist/admin/services/aiLocalizationJobs.js.map +1 -0
  55. package/dist/admin/services/aiLocalizationJobs.mjs +24 -0
  56. package/dist/admin/services/aiLocalizationJobs.mjs.map +1 -0
  57. package/dist/admin/services/api.js +4 -1
  58. package/dist/admin/services/api.js.map +1 -1
  59. package/dist/admin/services/api.mjs +4 -1
  60. package/dist/admin/services/api.mjs.map +1 -1
  61. package/dist/admin/services/locales.js +4 -2
  62. package/dist/admin/services/locales.js.map +1 -1
  63. package/dist/admin/services/locales.mjs +4 -2
  64. package/dist/admin/services/locales.mjs.map +1 -1
  65. package/dist/admin/services/settings.js +30 -0
  66. package/dist/admin/services/settings.js.map +1 -0
  67. package/dist/admin/services/settings.mjs +27 -0
  68. package/dist/admin/services/settings.mjs.map +1 -0
  69. package/dist/admin/src/components/CMHeaderActions.d.ts +17 -4
  70. package/dist/admin/src/components/LocaleListCell.d.ts +2 -1
  71. package/dist/admin/src/hooks/useAILocalizationJobsPolling.d.ts +9 -0
  72. package/dist/admin/src/services/aiLocalizationJobs.d.ts +6 -0
  73. package/dist/admin/src/services/api.d.ts +1 -1
  74. package/dist/admin/src/services/locales.d.ts +1 -1
  75. package/dist/admin/src/services/relations.d.ts +1 -1
  76. package/dist/admin/src/services/settings.d.ts +5 -0
  77. package/dist/admin/src/utils/schemas.d.ts +642 -16
  78. package/dist/admin/translations/en.json.js +10 -0
  79. package/dist/admin/translations/en.json.js.map +1 -1
  80. package/dist/admin/translations/en.json.mjs +10 -0
  81. package/dist/admin/translations/en.json.mjs.map +1 -1
  82. package/dist/admin/utils/clean.js +2 -2
  83. package/dist/admin/utils/clean.js.map +1 -1
  84. package/dist/admin/utils/clean.mjs +2 -2
  85. package/dist/admin/utils/clean.mjs.map +1 -1
  86. package/dist/admin/utils/fields.js +6 -1
  87. package/dist/admin/utils/fields.js.map +1 -1
  88. package/dist/admin/utils/fields.mjs +6 -1
  89. package/dist/admin/utils/fields.mjs.map +1 -1
  90. package/dist/admin/utils/getTranslation.js.map +1 -1
  91. package/dist/admin/utils/getTranslation.mjs.map +1 -1
  92. package/dist/admin/utils/prefixPluginTranslations.js.map +1 -1
  93. package/dist/admin/utils/prefixPluginTranslations.mjs.map +1 -1
  94. package/dist/admin/utils/schemas.js +19 -13
  95. package/dist/admin/utils/schemas.js.map +1 -1
  96. package/dist/admin/utils/schemas.mjs +19 -13
  97. package/dist/admin/utils/schemas.mjs.map +1 -1
  98. package/dist/server/bootstrap.js +24 -8
  99. package/dist/server/bootstrap.js.map +1 -1
  100. package/dist/server/bootstrap.mjs +24 -8
  101. package/dist/server/bootstrap.mjs.map +1 -1
  102. package/dist/server/constants/iso-locales.json.js +4 -0
  103. package/dist/server/constants/iso-locales.json.js.map +1 -1
  104. package/dist/server/constants/iso-locales.json.mjs +4 -0
  105. package/dist/server/constants/iso-locales.json.mjs.map +1 -1
  106. package/dist/server/controllers/ai-localization-jobs.js +47 -0
  107. package/dist/server/controllers/ai-localization-jobs.js.map +1 -0
  108. package/dist/server/controllers/ai-localization-jobs.mjs +45 -0
  109. package/dist/server/controllers/ai-localization-jobs.mjs.map +1 -0
  110. package/dist/server/controllers/index.js +5 -1
  111. package/dist/server/controllers/index.js.map +1 -1
  112. package/dist/server/controllers/index.mjs +5 -1
  113. package/dist/server/controllers/index.mjs.map +1 -1
  114. package/dist/server/controllers/settings.js +24 -0
  115. package/dist/server/controllers/settings.js.map +1 -0
  116. package/dist/server/controllers/settings.mjs +22 -0
  117. package/dist/server/controllers/settings.mjs.map +1 -0
  118. package/dist/server/models/ai-localization-job.js +60 -0
  119. package/dist/server/models/ai-localization-job.js.map +1 -0
  120. package/dist/server/models/ai-localization-job.mjs +57 -0
  121. package/dist/server/models/ai-localization-job.mjs.map +1 -0
  122. package/dist/server/register.js +3 -1
  123. package/dist/server/register.js.map +1 -1
  124. package/dist/server/register.mjs +3 -1
  125. package/dist/server/register.mjs.map +1 -1
  126. package/dist/server/routes/admin.js +40 -0
  127. package/dist/server/routes/admin.js.map +1 -1
  128. package/dist/server/routes/admin.mjs +40 -0
  129. package/dist/server/routes/admin.mjs.map +1 -1
  130. package/dist/server/routes/content-api.js +11 -7
  131. package/dist/server/routes/content-api.js.map +1 -1
  132. package/dist/server/routes/content-api.mjs +11 -7
  133. package/dist/server/routes/content-api.mjs.map +1 -1
  134. package/dist/server/routes/index.mjs +2 -2
  135. package/dist/server/routes/validation/locale.js +57 -0
  136. package/dist/server/routes/validation/locale.js.map +1 -0
  137. package/dist/server/routes/validation/locale.mjs +36 -0
  138. package/dist/server/routes/validation/locale.mjs.map +1 -0
  139. package/dist/server/services/ai-localization-jobs.js +64 -0
  140. package/dist/server/services/ai-localization-jobs.js.map +1 -0
  141. package/dist/server/services/ai-localization-jobs.mjs +62 -0
  142. package/dist/server/services/ai-localization-jobs.mjs.map +1 -0
  143. package/dist/server/services/ai-localizations.js +268 -0
  144. package/dist/server/services/ai-localizations.js.map +1 -0
  145. package/dist/server/services/ai-localizations.mjs +266 -0
  146. package/dist/server/services/ai-localizations.mjs.map +1 -0
  147. package/dist/server/services/content-types.js.map +1 -1
  148. package/dist/server/services/content-types.mjs.map +1 -1
  149. package/dist/server/services/index.js +7 -1
  150. package/dist/server/services/index.js.map +1 -1
  151. package/dist/server/services/index.mjs +7 -1
  152. package/dist/server/services/index.mjs.map +1 -1
  153. package/dist/server/services/settings.js +25 -0
  154. package/dist/server/services/settings.js.map +1 -0
  155. package/dist/server/services/settings.mjs +23 -0
  156. package/dist/server/services/settings.mjs.map +1 -0
  157. package/dist/server/src/bootstrap.d.ts.map +1 -1
  158. package/dist/server/src/controllers/ai-localization-jobs.d.ts +17 -0
  159. package/dist/server/src/controllers/ai-localization-jobs.d.ts.map +1 -0
  160. package/dist/server/src/controllers/index.d.ts +10 -0
  161. package/dist/server/src/controllers/index.d.ts.map +1 -1
  162. package/dist/server/src/controllers/settings.d.ts +7 -0
  163. package/dist/server/src/controllers/settings.d.ts.map +1 -0
  164. package/dist/server/src/index.d.ts +47 -8
  165. package/dist/server/src/index.d.ts.map +1 -1
  166. package/dist/server/src/models/ai-localization-job.d.ts +5 -0
  167. package/dist/server/src/models/ai-localization-job.d.ts.map +1 -0
  168. package/dist/server/src/models/index.d.ts +5 -0
  169. package/dist/server/src/models/index.d.ts.map +1 -0
  170. package/dist/server/src/register.d.ts +1 -1
  171. package/dist/server/src/register.d.ts.map +1 -1
  172. package/dist/server/src/routes/admin.d.ts.map +1 -1
  173. package/dist/server/src/routes/content-api.d.ts +5 -8
  174. package/dist/server/src/routes/content-api.d.ts.map +1 -1
  175. package/dist/server/src/routes/index.d.ts +3 -7
  176. package/dist/server/src/routes/index.d.ts.map +1 -1
  177. package/dist/server/src/routes/validation/index.d.ts +2 -0
  178. package/dist/server/src/routes/validation/index.d.ts.map +1 -0
  179. package/dist/server/src/routes/validation/locale.d.ts +41 -0
  180. package/dist/server/src/routes/validation/locale.d.ts.map +1 -0
  181. package/dist/server/src/services/ai-localization-jobs.d.ts +26 -0
  182. package/dist/server/src/services/ai-localization-jobs.d.ts.map +1 -0
  183. package/dist/server/src/services/ai-localizations.d.ts +18 -0
  184. package/dist/server/src/services/ai-localizations.d.ts.map +1 -0
  185. package/dist/server/src/services/index.d.ts +33 -0
  186. package/dist/server/src/services/index.d.ts.map +1 -1
  187. package/dist/server/src/services/settings.d.ts +13 -0
  188. package/dist/server/src/services/settings.d.ts.map +1 -0
  189. package/dist/server/src/utils/index.d.ts +7 -1
  190. package/dist/server/src/utils/index.d.ts.map +1 -1
  191. package/dist/server/src/validation/settings.d.ts +12 -0
  192. package/dist/server/src/validation/settings.d.ts.map +1 -0
  193. package/dist/server/utils/index.js.map +1 -1
  194. package/dist/server/utils/index.mjs.map +1 -1
  195. package/dist/server/validation/settings.js +11 -0
  196. package/dist/server/validation/settings.js.map +1 -0
  197. package/dist/server/validation/settings.mjs +9 -0
  198. package/dist/server/validation/settings.mjs.map +1 -0
  199. package/dist/shared/contracts/ai-localization-jobs.d.ts +27 -0
  200. package/dist/shared/contracts/ai-localization-jobs.d.ts.map +1 -0
  201. package/dist/shared/contracts/settings.d.ts +40 -0
  202. package/dist/shared/contracts/shared.d.ts.map +1 -0
  203. package/package.json +13 -10
@@ -4,15 +4,19 @@ var jsxRuntime = require('react/jsx-runtime');
4
4
  var React = require('react');
5
5
  var query = require('@reduxjs/toolkit/query');
6
6
  var strapiAdmin = require('@strapi/admin/strapi-admin');
7
+ var ee = require('@strapi/admin/strapi-admin/ee');
7
8
  var strapiAdmin$1 = require('@strapi/content-manager/strapi-admin');
8
9
  var designSystem = require('@strapi/design-system');
9
10
  var icons = require('@strapi/icons');
10
11
  var reactIntl = require('react-intl');
11
12
  var reactRouterDom = require('react-router-dom');
12
13
  var styledComponents = require('styled-components');
14
+ var useAILocalizationJobsPolling = require('../hooks/useAILocalizationJobsPolling.js');
13
15
  var useI18n = require('../hooks/useI18n.js');
16
+ var aiLocalizationJobs = require('../services/aiLocalizationJobs.js');
14
17
  var locales = require('../services/locales.js');
15
18
  var relations = require('../services/relations.js');
19
+ var settings = require('../services/settings.js');
16
20
  var clean = require('../utils/clean.js');
17
21
  var getTranslation = require('../utils/getTranslation.js');
18
22
  var strings = require('../utils/strings.js');
@@ -81,6 +85,18 @@ const LocaleOption = ({ isDraftAndPublishEnabled, locale, status, entryExists })
81
85
  ]
82
86
  });
83
87
  };
88
+ const LocaleOptionStartIcon = ({ entryWithLocaleExists, translationStatus, index })=>{
89
+ const isAiAvailable = ee.useAIAvailability();
90
+ if (!entryWithLocaleExists) {
91
+ return /*#__PURE__*/ jsxRuntime.jsx(icons.Plus, {});
92
+ }
93
+ if (isAiAvailable && index !== 0 && translationStatus === 'failed') {
94
+ return /*#__PURE__*/ jsxRuntime.jsx(icons.WarningCircle, {
95
+ fill: "warning600"
96
+ });
97
+ }
98
+ return null;
99
+ };
84
100
  const LocalePickerAction = ({ document, meta, model, collectionType, documentId })=>{
85
101
  const { formatMessage } = reactIntl.useIntl();
86
102
  const [{ query }, setQuery] = strapiAdmin.useQueryParams();
@@ -95,6 +111,14 @@ const LocalePickerAction = ({ document, meta, model, collectionType, documentId
95
111
  locale: currentDesiredLocale
96
112
  }
97
113
  });
114
+ const { data: jobData } = aiLocalizationJobs.useGetAILocalizationJobsByDocumentQuery({
115
+ documentId: documentId,
116
+ model: model,
117
+ collectionType: collectionType
118
+ });
119
+ const { data: settings$1 } = settings.useGetSettingsQuery();
120
+ const isAiAvailable = ee.useAIAvailability();
121
+ const setValues = strapiAdmin.useForm('LocalePickerAction', (state)=>state.setValues);
98
122
  const handleSelect = React__namespace.useCallback((value)=>{
99
123
  setQuery({
100
124
  plugins: {
@@ -103,11 +127,56 @@ const LocalePickerAction = ({ document, meta, model, collectionType, documentId
103
127
  locale: value
104
128
  }
105
129
  }
106
- });
130
+ }, 'push', true);
107
131
  }, [
108
132
  query.plugins,
109
133
  setQuery
110
134
  ]);
135
+ const nonTranslatedFields = React__namespace.useMemo(()=>{
136
+ if (!schema?.attributes) return [];
137
+ return Object.keys(schema.attributes).filter((field)=>{
138
+ const attribute = schema.attributes[field];
139
+ return attribute?.pluginOptions?.i18n?.localized === false;
140
+ });
141
+ }, [
142
+ schema?.attributes
143
+ ]);
144
+ const sourceLocaleData = React__namespace.useMemo(()=>{
145
+ if (!Array.isArray(locales$1) || !meta?.availableLocales) return null;
146
+ const defaultLocale = locales$1.find((locale)=>locale.isDefault);
147
+ const existingLocales = meta.availableLocales.map((loc)=>loc.locale);
148
+ const sourceLocaleCode = defaultLocale && existingLocales.includes(defaultLocale.code) && defaultLocale.code !== currentDesiredLocale ? defaultLocale.code : existingLocales.find((locale)=>locale !== currentDesiredLocale);
149
+ if (!sourceLocaleCode) return null;
150
+ // Find the document data from availableLocales (now includes non-translatable fields)
151
+ const sourceLocaleDoc = meta.availableLocales.find((loc)=>loc.locale === sourceLocaleCode);
152
+ return sourceLocaleDoc ? {
153
+ locale: sourceLocaleCode,
154
+ data: sourceLocaleDoc
155
+ } : null;
156
+ }, [
157
+ locales$1,
158
+ meta?.availableLocales,
159
+ currentDesiredLocale
160
+ ]);
161
+ /**
162
+ * Prefilling form with non-translatable fields from already existing locale
163
+ */ React__namespace.useEffect(()=>{
164
+ // Only run when creating a new locale (no document ID yet) and when we have non-translatable fields
165
+ if (!document?.id && nonTranslatedFields.length > 0 && sourceLocaleData?.data) {
166
+ const dataToSet = nonTranslatedFields.reduce((acc, field)=>{
167
+ acc[field] = sourceLocaleData.data[field];
168
+ return acc;
169
+ }, {});
170
+ if (Object.keys(dataToSet).length > 0) {
171
+ setValues(dataToSet);
172
+ }
173
+ }
174
+ }, [
175
+ document?.id,
176
+ nonTranslatedFields,
177
+ sourceLocaleData?.data,
178
+ setValues
179
+ ]);
111
180
  React__namespace.useEffect(()=>{
112
181
  if (!Array.isArray(locales$1) || !hasI18n) {
113
182
  return;
@@ -127,12 +196,18 @@ const LocalePickerAction = ({ document, meta, model, collectionType, documentId
127
196
  currentDesiredLocale
128
197
  ]);
129
198
  const currentLocale = Array.isArray(locales$1) ? locales$1.find((locale)=>locale.code === currentDesiredLocale) : undefined;
199
+ // Use meta.availableLocales instead of document.localizations
200
+ // meta.availableLocales contains all locales for the document, even when creating new locales
201
+ const availableLocales = meta?.availableLocales ?? [];
202
+ const documentLocalizations = document?.localizations ?? [];
203
+ // Prefer meta.availableLocales as it's more reliable, fallback to document.localizations
204
+ const allLocalizations = availableLocales.length > 0 ? availableLocales : documentLocalizations;
130
205
  const allCurrentLocales = [
131
206
  {
132
207
  status: getDocumentStatus(document, meta),
133
208
  locale: currentLocale?.code
134
209
  },
135
- ...document?.localizations ?? []
210
+ ...allLocalizations
136
211
  ];
137
212
  if (!hasI18n || !Array.isArray(locales$1) || locales$1.length === 0) {
138
213
  return null;
@@ -143,15 +218,52 @@ const LocalePickerAction = ({ document, meta, model, collectionType, documentId
143
218
  * otherwise the locale is hidden.
144
219
  */ return canRead.includes(locale.code);
145
220
  });
221
+ const localesSortingDefaultFirst = displayedLocales.sort((a, b)=>a.isDefault ? -1 : b.isDefault ? 1 : 0);
146
222
  return {
147
223
  label: formatMessage({
148
224
  id: getTranslation.getTranslation('Settings.locales.modal.locales.label'),
149
225
  defaultMessage: 'Locales'
150
226
  }),
151
- options: displayedLocales.map((locale)=>{
227
+ options: localesSortingDefaultFirst.map((locale, index)=>{
152
228
  const entryWithLocaleExists = allCurrentLocales.some((doc)=>doc.locale === locale.code);
153
229
  const currentLocaleDoc = allCurrentLocales.find((doc)=>'locale' in doc ? doc.locale === locale.code : false);
154
230
  const permissionsToCheck = currentLocaleDoc ? canRead : canCreate;
231
+ if (isAiAvailable && settings$1?.data?.aiLocalizations) {
232
+ return {
233
+ _render: ()=>/*#__PURE__*/ jsxRuntime.jsxs(React__namespace.Fragment, {
234
+ children: [
235
+ /*#__PURE__*/ jsxRuntime.jsx(designSystem.SingleSelectOption, {
236
+ disabled: !permissionsToCheck.includes(locale.code),
237
+ startIcon: /*#__PURE__*/ jsxRuntime.jsx(LocaleOptionStartIcon, {
238
+ entryWithLocaleExists: entryWithLocaleExists,
239
+ translationStatus: jobData?.data?.status,
240
+ index: index
241
+ }),
242
+ value: locale.code,
243
+ children: /*#__PURE__*/ jsxRuntime.jsx(LocaleOption, {
244
+ isDraftAndPublishEnabled: !!schema?.options?.draftAndPublish,
245
+ locale: locale,
246
+ status: currentLocaleDoc?.status,
247
+ entryExists: entryWithLocaleExists
248
+ })
249
+ }, locale.code),
250
+ localesSortingDefaultFirst.length > 1 && index === 0 && /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
251
+ paddingRight: 4,
252
+ paddingLeft: 4,
253
+ paddingTop: 2,
254
+ paddingBottom: 2,
255
+ children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
256
+ variant: "sigma",
257
+ children: formatMessage({
258
+ id: getTranslation.getTranslation('CMEditViewLocalePicker.locale.ai-translations'),
259
+ defaultMessage: 'AI Translations'
260
+ })
261
+ })
262
+ })
263
+ ]
264
+ }, index)
265
+ };
266
+ }
155
267
  return {
156
268
  disabled: !permissionsToCheck.includes(locale.code),
157
269
  value: locale.code,
@@ -159,9 +271,12 @@ const LocalePickerAction = ({ document, meta, model, collectionType, documentId
159
271
  isDraftAndPublishEnabled: !!schema?.options?.draftAndPublish,
160
272
  locale: locale,
161
273
  status: currentLocaleDoc?.status,
162
- entryExists: entryWithLocaleExists
274
+ entryExists: entryWithLocaleExists,
275
+ translationStatus: jobData?.data?.status
163
276
  }),
164
- startIcon: !entryWithLocaleExists ? /*#__PURE__*/ jsxRuntime.jsx(icons.Plus, {}) : null
277
+ startIcon: /*#__PURE__*/ jsxRuntime.jsx(LocaleOptionStartIcon, {
278
+ entryWithLocaleExists: entryWithLocaleExists
279
+ })
165
280
  };
166
281
  }),
167
282
  customizeContent: ()=>currentLocale?.name,
@@ -184,6 +299,130 @@ const getDocumentStatus = (document, meta)=>{
184
299
  }
185
300
  return docStatus;
186
301
  };
302
+ /* -------------------------------------------------------------------------------------------------
303
+ * AISettingsStatusAction
304
+ * -----------------------------------------------------------------------------------------------*/ const AITranslationStatusIcon = styledComponents.styled(designSystem.Status)`
305
+ display: flex;
306
+ gap: ${({ theme })=>theme.spaces[1]};
307
+ justify-content: center;
308
+ align-items: center;
309
+ height: 100%;
310
+
311
+ // Disabled state
312
+ ${({ $isAISettingEnabled, theme })=>!$isAISettingEnabled && `
313
+ background-color: ${theme.colors.neutral150};
314
+ `}
315
+
316
+ svg {
317
+ ${({ $isAISettingEnabled, theme })=>!$isAISettingEnabled && `
318
+ fill: ${theme.colors.neutral300};
319
+ `}
320
+ }
321
+ `;
322
+ const SpinningLoader = styledComponents.styled(icons.Loader)`
323
+ @keyframes spin {
324
+ from {
325
+ transform: rotate(0deg);
326
+ }
327
+ to {
328
+ transform: rotate(360deg);
329
+ }
330
+ }
331
+
332
+ animation: spin 2s linear infinite;
333
+ `;
334
+ const AITranslationStatusAction = ({ documentId, model, collectionType })=>{
335
+ const { formatMessage } = reactIntl.useIntl();
336
+ const isAIAvailable = ee.useAIAvailability();
337
+ const { data: settings$1 } = settings.useGetSettingsQuery();
338
+ const isAISettingEnabled = settings$1?.data?.aiLocalizations;
339
+ const { hasI18n } = useI18n.useI18n();
340
+ // Poll for AI localizations jobs when AI is enabled and we have a documentId
341
+ const { status } = useAILocalizationJobsPolling.useAILocalizationJobsPolling({
342
+ documentId,
343
+ model,
344
+ collectionType
345
+ });
346
+ const statusVariant = (()=>{
347
+ if (status === 'failed') {
348
+ return 'warning';
349
+ }
350
+ if (isAISettingEnabled) {
351
+ return 'alternative';
352
+ }
353
+ return 'neutral';
354
+ })();
355
+ // Do not display this action when i18n is not available
356
+ if (!hasI18n) {
357
+ return null;
358
+ }
359
+ // Do not display this action when AI is not available
360
+ if (!isAIAvailable) {
361
+ return null;
362
+ }
363
+ return {
364
+ _status: {
365
+ message: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
366
+ height: "100%",
367
+ "aria-label": formatMessage({
368
+ id: getTranslation.getTranslation('CMEditViewAITranslation.status-aria-label'),
369
+ defaultMessage: 'AI Translation Status'
370
+ }),
371
+ children: /*#__PURE__*/ jsxRuntime.jsx(AITranslationStatusIcon, {
372
+ $isAISettingEnabled: Boolean(isAISettingEnabled),
373
+ variant: statusVariant,
374
+ size: "S",
375
+ children: status === 'processing' ? /*#__PURE__*/ jsxRuntime.jsx(SpinningLoader, {}) : /*#__PURE__*/ jsxRuntime.jsx(icons.Sparkle, {})
376
+ })
377
+ }),
378
+ tooltip: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
379
+ direction: "column",
380
+ padding: 4,
381
+ alignItems: "flex-start",
382
+ width: "25rem",
383
+ children: [
384
+ /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
385
+ variant: "pi",
386
+ fontWeight: "600",
387
+ children: formatMessage({
388
+ id: getTranslation.getTranslation('CMEditViewAITranslation.status-title'),
389
+ defaultMessage: '{enabled, select, true {AI translation enabled} false {AI translation disabled} other {AI translation disabled}}'
390
+ }, {
391
+ enabled: isAISettingEnabled
392
+ })
393
+ }),
394
+ /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
395
+ variant: "pi",
396
+ paddingTop: 1,
397
+ paddingBottom: 3,
398
+ children: formatMessage({
399
+ id: getTranslation.getTranslation('CMEditViewAITranslation.status-description'),
400
+ defaultMessage: 'Our AI translates content in all locales each time you save a modification in the default locale.'
401
+ })
402
+ }),
403
+ /*#__PURE__*/ jsxRuntime.jsx(designSystem.Link, {
404
+ fontSize: "inherit",
405
+ tag: reactRouterDom.NavLink,
406
+ to: "/settings/internationalization",
407
+ style: {
408
+ alignSelf: 'flex-end'
409
+ },
410
+ children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
411
+ variant: "pi",
412
+ textAlign: "right",
413
+ children: formatMessage({
414
+ id: getTranslation.getTranslation('CMEditViewAITranslation.settings-link'),
415
+ defaultMessage: '{enabled, select, true {Disable it in settings} false {Enable it in settings} other {Enable it in settings}}'
416
+ }, {
417
+ enabled: isAISettingEnabled
418
+ })
419
+ })
420
+ })
421
+ ]
422
+ })
423
+ }
424
+ };
425
+ };
187
426
  /* -------------------------------------------------------------------------------------------------
188
427
  * FillFromAnotherLocaleAction
189
428
  * -----------------------------------------------------------------------------------------------*/ const FillFromAnotherLocaleAction = ({ documentId, meta, model, collectionType })=>{
@@ -203,6 +442,9 @@ const getDocumentStatus = (document, meta)=>{
203
442
  }
204
443
  });
205
444
  const { data: locales$1 = [] } = locales.useGetLocalesQuery();
445
+ const isAIAvailable = ee.useAIAvailability();
446
+ const { data: settings$1 } = settings.useGetSettingsQuery();
447
+ const isAISettingEnabled = settings$1?.data?.aiLocalizations;
206
448
  const availableLocales = Array.isArray(locales$1) ? locales$1.filter((locale)=>meta?.availableLocales.some((l)=>l.locale === locale.code)) : [];
207
449
  const fillFromLocale = (onClose)=>async ()=>{
208
450
  const response = await getDocument({
@@ -224,6 +466,10 @@ const getDocumentStatus = (document, meta)=>{
224
466
  if (!hasI18n) {
225
467
  return null;
226
468
  }
469
+ // Do not display this action when AI is available and AI translations are enabled
470
+ if (isAIAvailable && isAISettingEnabled) {
471
+ return null;
472
+ }
227
473
  return {
228
474
  type: 'icon',
229
475
  icon: /*#__PURE__*/ jsxRuntime.jsx(icons.Earth, {}),
@@ -410,7 +656,7 @@ const getDocumentStatus = (document, meta)=>{
410
656
  * BulkLocaleAction
411
657
  *
412
658
  * This component is used to handle bulk publish and unpublish actions on locales.
413
- * -----------------------------------------------------------------------------------------------*/ const BulkLocaleAction = ({ document, documentId, model, collectionType, action })=>{
659
+ * -----------------------------------------------------------------------------------------------*/ const BulkLocaleAction = ({ document, documentId, model, collectionType, action, meta })=>{
414
660
  const locale = document?.locale ?? null;
415
661
  const [{ query: query$1 }] = strapiAdmin.useQueryParams();
416
662
  const params = React__namespace.useMemo(()=>strapiAdmin$1.buildValidParams(query$1), [
@@ -468,25 +714,51 @@ const getDocumentStatus = (document, meta)=>{
468
714
  {}
469
715
  ];
470
716
  }
471
- const localizations = document.localizations ?? [];
472
- // Build the rows for the bulk locale publish modal by combining the current
473
- // document with all the available locales from the document meta
474
- const locales = localizations.map((doc)=>{
475
- const { locale, status } = doc;
476
- return {
477
- locale,
478
- status
479
- };
717
+ const metaLocalizations = (meta?.availableLocales ?? []).map((locale)=>({
718
+ locale: locale.locale,
719
+ status: locale.status ?? 'draft'
720
+ }));
721
+ const documentLocalizations = (document.localizations ?? []).map((doc)=>({
722
+ locale: doc.locale ?? undefined,
723
+ status: doc.status ?? 'draft'
724
+ }));
725
+ const localesMap = new Map();
726
+ metaLocalizations.forEach(({ locale, status })=>{
727
+ if (locale) {
728
+ localesMap.set(locale, {
729
+ locale,
730
+ status
731
+ });
732
+ }
480
733
  });
481
- // Add the current document locale
482
- locales.unshift({
483
- locale: document.locale,
484
- status: document.status
734
+ documentLocalizations.forEach(({ locale, status })=>{
735
+ if (locale) {
736
+ localesMap.set(locale, {
737
+ locale,
738
+ status
739
+ });
740
+ }
485
741
  });
742
+ // Build the rows for the bulk locale publish modal by combining the current
743
+ // document with all the available locales from the document meta
744
+ const locales = [];
745
+ if (document?.locale) {
746
+ locales.push({
747
+ locale: document.locale,
748
+ status: document.status ?? 'draft'
749
+ });
750
+ }
751
+ locales.push(...Array.from(localesMap.entries()).filter(([locale])=>locale !== document?.locale).map(([, value])=>value));
752
+ if (locales.length === 0 && document?.locale) {
753
+ locales.push({
754
+ locale: document.locale,
755
+ status: document.status ?? 'draft'
756
+ });
757
+ }
486
758
  // Build the validation errors for each locale.
487
759
  const allDocuments = [
488
760
  document,
489
- ...localizations
761
+ ...document.localizations ?? []
490
762
  ];
491
763
  const errors = allDocuments.reduce((errs, document)=>{
492
764
  if (!document) {
@@ -505,6 +777,7 @@ const getDocumentStatus = (document, meta)=>{
505
777
  ];
506
778
  }, [
507
779
  document,
780
+ meta?.availableLocales,
508
781
  validate
509
782
  ]);
510
783
  const isBulkPublish = action === 'bulk-publish';
@@ -713,6 +986,7 @@ const getDocumentStatus = (document, meta)=>{
713
986
  }
714
987
  `;
715
988
 
989
+ exports.AITranslationStatusAction = AITranslationStatusAction;
716
990
  exports.BulkLocalePublishAction = BulkLocalePublishAction;
717
991
  exports.BulkLocaleUnpublishAction = BulkLocaleUnpublishAction;
718
992
  exports.DeleteLocaleAction = DeleteLocaleAction;