diff --git a/assets/locales/en_US.json b/assets/locales/en_US.json index caecdee8b1f..3cd8a5ad1fd 100644 --- a/assets/locales/en_US.json +++ b/assets/locales/en_US.json @@ -4612,5 +4612,15 @@ "Evidence could not be downloaded.": "Evidence could not be downloaded.", "Delete message": "Delete message", "Message Sent": "Message Sent", - "Are you sure you want to delete the selected message?": "Are you sure you want to delete the selected message?" + "Are you sure you want to delete the selected message?": "Are you sure you want to delete the selected message?", + "Delete CMS pages": "Delete CMS pages", + "The following page will be deleted:": "The following page will be deleted:", + "Pages in different languages are not automatically linked. Select only related pages.": "Pages in different languages are not automatically linked. Select only related pages.", + "Select additional pages from other languages": "Select additional pages from other languages", + "No other language pages were found in this category.": "No other language pages were found in this category.", + "Other language pages could not be loaded. You can still delete only the current page.": "Other language pages could not be loaded. You can still delete only the current page.", + "Selected pages to delete:": "Selected pages to delete:", + "Delete selected pages": "Delete selected pages", + "The following pages will be deleted:": "The following pages will be deleted:", + "A maximum of 100 pages can be deleted at once.": "A maximum of 100 pages can be deleted at once." } diff --git a/assets/locales/es.json b/assets/locales/es.json index 19e431bde27..7c34b4e3e3c 100644 --- a/assets/locales/es.json +++ b/assets/locales/es.json @@ -4610,5 +4610,15 @@ "Evidence could not be downloaded.": "No se pudo descargar la evidencia.", "Delete message": " Borrar mensaje", "Message Sent": "Mensaje enviado", - "Are you sure you want to delete the selected message?": "\u00bfEsta seguro de que desea borrar este mensaje?" + "Are you sure you want to delete the selected message?": "\u00bfEsta seguro de que desea borrar este mensaje?", + "Delete CMS pages": "Eliminar páginas del CMS", + "The following page will be deleted:": "Se eliminará la siguiente página:", + "Pages in different languages are not automatically linked. Select only related pages.": "Las páginas en distintos idiomas no se vinculan automáticamente. Seleccione solo las páginas relacionadas.", + "Select additional pages from other languages": "Seleccionar páginas adicionales en otros idiomas", + "No other language pages were found in this category.": "No se encontraron otras páginas en distintos idiomas dentro de esta categoría.", + "Other language pages could not be loaded. You can still delete only the current page.": "No se pudieron cargar las páginas de otros idiomas. Aun así, puede eliminar únicamente la página actual.", + "Selected pages to delete:": "Páginas seleccionadas para eliminar:", + "Delete selected pages": "Eliminar páginas seleccionadas", + "The following pages will be deleted:": "Se eliminarán las siguientes páginas:", + "A maximum of 100 pages can be deleted at once.": "Puede eliminar un máximo de 100 páginas a la vez." } \ No newline at end of file diff --git a/assets/locales/fr_FR.json b/assets/locales/fr_FR.json index 989d8c25c62..485345e4c30 100644 --- a/assets/locales/fr_FR.json +++ b/assets/locales/fr_FR.json @@ -4612,5 +4612,15 @@ "Evidence could not be downloaded.": "Les preuves n\u2019ont pas pu \u00eatre t\u00e9l\u00e9charg\u00e9es.", "Delete message": "Supprimer le message", "Message Sent": "Message envoy\u00e9", - "Are you sure you want to delete the selected message?": "\u00cates-vous certain de vouloir supprimer le message s\u00e9lectionn\u00e9\u202f?" + "Are you sure you want to delete the selected message?": "\u00cates-vous certain de vouloir supprimer le message s\u00e9lectionn\u00e9\u202f?", + "Delete CMS pages": "Supprimer des pages CMS", + "The following page will be deleted:": "La page suivante sera supprimée :", + "Pages in different languages are not automatically linked. Select only related pages.": "Les pages dans différentes langues ne sont pas liées automatiquement. Sélectionnez uniquement les pages correspondantes.", + "Select additional pages from other languages": "Sélectionner d’autres pages dans d’autres langues", + "No other language pages were found in this category.": "Aucune autre page dans une langue différente n’a été trouvée dans cette catégorie.", + "Other language pages could not be loaded. You can still delete only the current page.": "Impossible de charger les pages des autres langues. Vous pouvez tout de même supprimer uniquement la page actuelle.", + "Selected pages to delete:": "Pages sélectionnées pour suppression :", + "Delete selected pages": "Supprimer les pages sélectionnées", + "The following pages will be deleted:": "Les pages suivantes seront supprimées :", + "A maximum of 100 pages can be deleted at once.": "Vous pouvez supprimer au maximum 100 pages à la fois." } \ No newline at end of file diff --git a/assets/vue/services/pageService.js b/assets/vue/services/pageService.js index 42a28462ecf..885896c52a1 100644 --- a/assets/vue/services/pageService.js +++ b/assets/vue/services/pageService.js @@ -58,6 +58,46 @@ async function deletePage(iri) { await api.delete(iri) } +/** + * Load CMS pages in the same category, across languages, for explicit selection. + * The collection is already scoped to the current access URL by PageExtension. + */ +async function getPagesForLanguageDeletion(category) { + const pages = [] + let page = 1 + const limit = 500 + + while (true) { + const result = await baseService.getCollection("/api/pages", { category, page, itemsPerPage: 100 }) + pages.push(...(result.items || [])) + + if (pages.length > limit) { + throw new Error("Too many pages in this category to review safely. Narrow the category first.") + } + if (!result.nextPageParams) { + if (Number(result.totalItems || 0) > pages.length) { + throw new Error("Not all pages could be loaded. No pages were deleted.") + } + return pages + } + const nextPage = Number(result.nextPageParams.page) + if (!Number.isInteger(nextPage) || nextPage <= page) { + throw new Error("Page pagination failed. No pages were deleted.") + } + page = nextPage + } +} + +/** Delete exactly the page IDs selected by the administrator, atomically. */ +async function deleteLanguagePages(sourcePageId, pageIds) { + return await baseService.post(`/api/pages/${sourcePageId}/delete-languages`, { pageIds }) +} + +/** Delete explicitly selected CMS pages, including across categories. */ +async function deleteBulkPages(pageIds) { + return await baseService.post("/api/pages/actions/bulk-delete", { pageIds }) +} + /** * --------------------------- * Page Layouts Service @@ -171,6 +211,9 @@ export default { getTopbarVisibility, // Pages getPublicPageBySlug, + getPagesForLanguageDeletion, + deleteLanguagePages, + deleteBulkPages, postPage, updatePage, deletePage, diff --git a/assets/vue/views/page/List.vue b/assets/vue/views/page/List.vue index 299a23bbf23..0811acc789c 100644 --- a/assets/vue/views/page/List.vue +++ b/assets/vue/views/page/List.vue @@ -78,6 +78,7 @@ :label="t('Delete')" icon="delete" only-icon + name="cms-page-delete-open" size="small" type="danger-text" @click="confirmDeleteItem(slotProps.data)" @@ -97,6 +98,20 @@ +
+ {{ t("Selected pages to delete:") }} {{ selectedItems.length }} + +
+ -
- {{ t("The following page will be deleted:") }}

+

{{ item.title }} ({{ ensureLanguageName(item.locale) }})

+ +

+ {{ t("Pages in different languages are not automatically linked. Select only related pages.") }} +

+ +

{{ t("Select additional pages from other languages") }}

+

{{ t("Loading") }}

+

+ {{ t("Other language pages could not be loaded. You can still delete only the current page.") }} +

+
+ - {{ t("Are you sure you want to delete {0}?", [item.title]) }}
+

{{ t("No other language pages were found in this category.") }}

+ +

{{ t("Selected pages to delete:") }} {{ selectedLanguagePageIds.length }}

+
-
- - -
+

{{ t("The following pages will be deleted:") }}

+
    +
  • + {{ page.title }} ({{ ensureLanguageName(page.locale) }} · {{ page.category?.title || "-" }}) +
  • +
+

{{ t("Selected pages to delete:") }} {{ bulkDeletePages.length }}

@@ -242,6 +296,8 @@