diff --git a/assets/controllers/elements/part_search_controller.js b/assets/controllers/elements/part_search_controller.js
index aeeb701d..78d947b9 100644
--- a/assets/controllers/elements/part_search_controller.js
+++ b/assets/controllers/elements/part_search_controller.js
@@ -227,7 +227,7 @@ export default class extends Controller {
},
templates: {
header({ html }) {
- return html`
+ return html`
`;
},
item({ item, components, html }) {
@@ -273,7 +273,7 @@ export default class extends Controller {
},
templates: {
header({ html }) {
- return html`
+ return html`
`;
},
item({ item, components, html }) {
diff --git a/assets/controllers/pages/statistics_assembly_controller.js b/assets/controllers/pages/statistics_assembly_controller.js
index b20ef3b3..248fe29d 100644
--- a/assets/controllers/pages/statistics_assembly_controller.js
+++ b/assets/controllers/pages/statistics_assembly_controller.js
@@ -2,44 +2,154 @@ import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static values = {
- url: String,
- confirmMsg: String,
- successMsg: String,
- errorMsg: String
+ cleanupBomUrl: String,
+ cleanupPreviewUrl: String
}
- static targets = ["count"]
+ static targets = ["bomCount", "previewCount", "bomButton", "previewButton"]
async cleanup(event) {
- event.preventDefault();
-
- if (!confirm(this.confirmMsgValue)) {
- return;
+ if (event) {
+ event.preventDefault();
+ event.stopImmediatePropagation();
}
+ const button = event ? event.currentTarget : null;
+ if (button) button.disabled = true;
+
try {
- const response = await fetch(this.urlValue, {
- method: 'POST',
- headers: {
- 'X-Requested-With': 'XMLHttpRequest'
- }
- });
+ const data = await this.fetchWithErrorHandling(this.cleanupBomUrlValue, { method: 'POST' });
- if (response.ok) {
- const data = await response.json();
- alert(this.successMsgValue.replace('%count%', data.count));
- // Update the count displayed in the UI
- if (this.hasCountTarget) {
- this.countTarget.innerText = '0';
+ if (data.success) {
+ this.showSuccessMessage(data.message);
+ if (this.hasBomCountTarget) {
+ this.bomCountTarget.textContent = data.new_count;
+ }
+ if (data.new_count === 0 && this.hasBomButtonTarget) {
+ this.bomButtonTarget.remove();
}
- // Reload page to reflect changes if needed, or just let the user see 0
- window.location.reload();
} else {
- alert(this.errorMsgValue);
+ this.showErrorMessage(data.message || 'BOM cleanup failed');
}
} catch (error) {
- console.error('Cleanup failed:', error);
- alert(this.errorMsgValue);
+ this.showErrorMessage(error.message || 'An unexpected error occurred during BOM cleanup');
+ } finally {
+ if (button) button.disabled = false;
}
}
+
+ async cleanupPreview(event) {
+ if (event) {
+ event.preventDefault();
+ event.stopImmediatePropagation();
+ }
+
+ const button = event ? event.currentTarget : null;
+ if (button) button.disabled = true;
+
+ try {
+ const data = await this.fetchWithErrorHandling(this.cleanupPreviewUrlValue, { method: 'POST' });
+
+ if (data.success) {
+ this.showSuccessMessage(data.message);
+ if (this.hasPreviewCountTarget) {
+ this.previewCountTarget.textContent = data.new_count;
+ }
+ if (data.new_count === 0 && this.hasPreviewButtonTarget) {
+ this.previewButtonTarget.remove();
+ }
+ } else {
+ this.showErrorMessage(data.message || 'Preview cleanup failed');
+ }
+ } catch (error) {
+ this.showErrorMessage(error.message || 'An unexpected error occurred during Preview cleanup');
+ } finally {
+ if (button) button.disabled = false;
+ }
+ }
+
+ getHeaders() {
+ return {
+ 'X-Requested-With': 'XMLHttpRequest',
+ 'Accept': 'application/json',
+ }
+ }
+
+ async fetchWithErrorHandling(url, options = {}, timeout = 30000) {
+ const controller = new AbortController()
+ const timeoutId = setTimeout(() => controller.abort(), timeout)
+
+ try {
+ const response = await fetch(url, {
+ ...options,
+ headers: { ...this.getHeaders(), ...options.headers },
+ signal: controller.signal
+ })
+
+ clearTimeout(timeoutId)
+
+ if (!response.ok) {
+ const errorText = await response.text()
+ let errorMessage = `Server error (${response.status})`;
+ try {
+ const errorJson = JSON.parse(errorText);
+ if (errorJson && errorJson.message) {
+ errorMessage = errorJson.message;
+ }
+ } catch (e) {
+ // Not a JSON response, use status text
+ errorMessage = `${errorMessage}: ${errorText}`;
+ }
+ throw new Error(errorMessage)
+ }
+
+ return await response.json()
+ } catch (error) {
+ clearTimeout(timeoutId)
+
+ if (error.name === 'AbortError') {
+ throw new Error('Request timed out. Please try again.')
+ } else if (error.message.includes('Failed to fetch')) {
+ throw new Error('Network error. Please check your connection and try again.')
+ } else {
+ throw error
+ }
+ }
+ }
+
+ showSuccessMessage(message) {
+ this.showToast('success', message)
+ }
+
+ showErrorMessage(message) {
+ this.showToast('error', message)
+ }
+
+ showToast(type, message) {
+ // Create a simple alert that doesn't disrupt layout
+ const alertId = 'alert-' + Date.now();
+ const iconClass = type === 'success' ? 'fa-check-circle' : 'fa-exclamation-triangle';
+ const alertClass = type === 'success' ? 'alert-success' : 'alert-danger';
+
+ const alertHTML = `
+
+
+ ${message}
+
+
+ `;
+
+ // Add alert to body
+ document.body.insertAdjacentHTML('beforeend', alertHTML);
+
+ // Auto-remove after 5 seconds if not closed manually
+ setTimeout(() => {
+ const elementToRemove = document.getElementById(alertId);
+ if (elementToRemove) {
+ elementToRemove.remove();
+ }
+ }, 5000);
+ }
}
diff --git a/src/Controller/StatisticsController.php b/src/Controller/StatisticsController.php
index e3b378f1..baec7467 100644
--- a/src/Controller/StatisticsController.php
+++ b/src/Controller/StatisticsController.php
@@ -43,11 +43,13 @@ namespace App\Controller;
use App\Services\Tools\StatisticsHelper;
use App\Entity\AssemblySystem\AssemblyBOMEntry;
+use App\Entity\AssemblySystem\Assembly;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
+use Symfony\Contracts\Translation\TranslatorInterface;
class StatisticsController extends AbstractController
{
@@ -62,31 +64,95 @@ class StatisticsController extends AbstractController
}
#[Route(path: '/statistics/cleanup-assembly-bom-entries', name: 'statistics_cleanup_assembly_bom_entries', methods: ['POST'])]
- public function cleanupAssemblyBOMEntries(EntityManagerInterface $em): JsonResponse
- {
+ public function cleanupAssemblyBOMEntries(
+ EntityManagerInterface $em,
+ StatisticsHelper $helper,
+ TranslatorInterface $translator
+ ): JsonResponse {
$this->denyAccessUnlessGranted('@tools.statistics');
- $qb = $em->createQueryBuilder();
- $qb->select('be', 'IDENTITY(be.part) AS part_id')
- ->from(AssemblyBOMEntry::class, 'be')
- ->leftJoin('be.part', 'p')
- ->where('be.part IS NOT NULL')
- ->andWhere('p.id IS NULL');
+ try {
+ // We fetch the IDs of the entries that have a non-existent part.
+ // We use a raw SQL approach or a more robust DQL to avoid proxy initialization issues.
+ $qb = $em->createQueryBuilder();
+ $qb->select('be.id', 'IDENTITY(be.part) AS part_id')
+ ->from(AssemblyBOMEntry::class, 'be')
+ ->leftJoin('be.part', 'p')
+ ->where('be.part IS NOT NULL')
+ ->andWhere('p.id IS NULL');
- $results = $qb->getQuery()->getResult();
- $count = count($results);
+ $results = $qb->getQuery()->getResult();
+ $count = count($results);
- foreach ($results as $result) {
- /** @var AssemblyBOMEntry $entry */
- $entry = $result[0];
- $part_id = $result['part_id'] ?? 'unknown';
+ foreach ($results as $result) {
+ $entryId = $result['id'];
+ $partId = $result['part_id'] ?? 'unknown';
- $entry->setPart(null);
- $entry->setName(sprintf('part-id=%s not found', $part_id));
+ $entry = $em->find(AssemblyBOMEntry::class, $entryId);
+ if ($entry instanceof AssemblyBOMEntry) {
+ $entry->setPart(null);
+ $entry->setName(sprintf('part-id=%s not found', $partId));
+ }
+ }
+
+ $em->flush();
+
+ return new JsonResponse([
+ 'success' => true,
+ 'count' => $count,
+ 'message' => $translator->trans('statistics.cleanup_assembly_bom_entries.success', [
+ '%count%' => $count,
+ ]),
+ 'new_count' => $helper->getInvalidPartBOMEntriesCount(),
+ ]);
+ } catch (\Exception $e) {
+ return new JsonResponse([
+ 'success' => false,
+ 'message' => $translator->trans('statistics.cleanup_assembly_bom_entries.error') . ' ' . $e->getMessage(),
+ ], Response::HTTP_INTERNAL_SERVER_ERROR);
}
+ }
- $em->flush();
+ #[Route(path: '/statistics/cleanup-assembly-preview-attachments', name: 'statistics_cleanup_assembly_preview_attachments', methods: ['POST'])]
+ public function cleanupAssemblyPreviewAttachments(
+ EntityManagerInterface $em,
+ StatisticsHelper $helper,
+ TranslatorInterface $translator
+ ): JsonResponse {
+ $this->denyAccessUnlessGranted('@tools.statistics');
- return new JsonResponse(['success' => true, 'count' => $count]);
+ try {
+ $qb = $em->createQueryBuilder();
+ $qb->select('a')
+ ->from(Assembly::class, 'a')
+ ->leftJoin('a.master_picture_attachment', 'm')
+ ->where('a.master_picture_attachment IS NOT NULL')
+ ->andWhere('m.id IS NULL');
+
+ $assemblies = $qb->getQuery()->getResult();
+ $count = count($assemblies);
+
+ foreach ($assemblies as $assembly) {
+ if ($assembly instanceof Assembly) {
+ $assembly->setMasterPictureAttachment(null);
+ }
+ }
+
+ $em->flush();
+
+ return new JsonResponse([
+ 'success' => true,
+ 'count' => $count,
+ 'message' => $translator->trans('statistics.cleanup_assembly_preview_attachments.success', [
+ '%count%' => $count,
+ ]),
+ 'new_count' => $helper->getInvalidAssemblyPreviewAttachmentsCount(),
+ ]);
+ } catch (\Exception $e) {
+ return new JsonResponse([
+ 'success' => false,
+ 'message' => $translator->trans('statistics.cleanup_assembly_preview_attachments.error') . ' ' . $e->getMessage(),
+ ], Response::HTTP_INTERNAL_SERVER_ERROR);
+ }
}
}
diff --git a/src/Entity/Attachments/AssemblyAttachment.php b/src/Entity/Attachments/AssemblyAttachment.php
index bb9a11c8..c0c75c18 100644
--- a/src/Entity/Attachments/AssemblyAttachment.php
+++ b/src/Entity/Attachments/AssemblyAttachment.php
@@ -33,7 +33,6 @@ use Symfony\Component\Serializer\Attribute\Context;
* @extends Attachment
*/
#[UniqueEntity(['name', 'attachment_type', 'element'])]
-#[UniqueEntity(['name', 'attachment_type', 'element'])]
#[ORM\Entity]
class AssemblyAttachment extends Attachment
{
diff --git a/src/Services/Tools/StatisticsHelper.php b/src/Services/Tools/StatisticsHelper.php
index a3da3fde..653d9635 100644
--- a/src/Services/Tools/StatisticsHelper.php
+++ b/src/Services/Tools/StatisticsHelper.php
@@ -190,4 +190,19 @@ class StatisticsHelper
return (int) $qb->getQuery()->getSingleScalarResult();
}
+
+ /**
+ * Returns the number of assemblies that have a master_picture_attachment that does not exist anymore.
+ */
+ public function getInvalidAssemblyPreviewAttachmentsCount(): int
+ {
+ $qb = $this->em->createQueryBuilder();
+ $qb->select('COUNT(a.id)')
+ ->from(Assembly::class, 'a')
+ ->leftJoin('a.master_picture_attachment', 'at')
+ ->where('a.master_picture_attachment IS NOT NULL')
+ ->andWhere('at.id IS NULL');
+
+ return (int) $qb->getQuery()->getSingleScalarResult();
+ }
}
diff --git a/templates/tools/statistics/statistics.html.twig b/templates/tools/statistics/statistics.html.twig
index ed817cbe..ed787270 100644
--- a/templates/tools/statistics/statistics.html.twig
+++ b/templates/tools/statistics/statistics.html.twig
@@ -64,10 +64,8 @@
@@ -85,14 +83,25 @@
| {% trans %}statistics.invalid_part_bom_entries_count{% endtrans %} |
- {{ helper.invalidPartBOMEntriesCount }}
+ {{ helper.invalidPartBOMEntriesCount }}
{% if helper.invalidPartBOMEntriesCount > 0 %}
- |
+
+ | {% trans %}statistics.invalid_assembly_preview_attachments_count{% endtrans %} |
+
+ {{ helper.invalidAssemblyPreviewAttachmentsCount }}
+ {% if helper.invalidAssemblyPreviewAttachmentsCount > 0 %}
+
+ {% trans %}statistics.cleanup_assembly_preview_attachments.button{% endtrans %}
+
+ {% endif %}
+ |
+
diff --git a/translations/frontend.cs.xlf b/translations/frontend.cs.xlf
index 4ba1f913..6c9011f8 100644
--- a/translations/frontend.cs.xlf
+++ b/translations/frontend.cs.xlf
@@ -49,6 +49,18 @@
Velmi silné
+
+
+ assembly.labelp
+ Sestavy
+
+
+
+
+ project.labelp
+ Projekty
+
+
search.submit
diff --git a/translations/frontend.da.xlf b/translations/frontend.da.xlf
index 4b6a15b9..2e3807fa 100644
--- a/translations/frontend.da.xlf
+++ b/translations/frontend.da.xlf
@@ -49,6 +49,18 @@
Meget stærk
+
+
+ assembly.labelp
+ Samlinger
+
+
+
+
+ project.labelp
+ Projekter
+
+
search.submit
diff --git a/translations/frontend.de.xlf b/translations/frontend.de.xlf
index 9ebd0d32..9479cc48 100644
--- a/translations/frontend.de.xlf
+++ b/translations/frontend.de.xlf
@@ -49,6 +49,18 @@
Sehr stark
+
+
+ assembly.labelp
+ Baugruppen
+
+
+
+
+ project.labelp
+ Projekte
+
+
search.submit
diff --git a/translations/frontend.el.xlf b/translations/frontend.el.xlf
index bab41358..f8e55b3e 100644
--- a/translations/frontend.el.xlf
+++ b/translations/frontend.el.xlf
@@ -2,10 +2,22 @@
-
- search.placeholder
- Αναζήτηση
-
-
+
+ search.placeholder
+ Αναζήτηση
+
+
+
+
+ assembly.labelp
+ Συναρμολογήσεις
+
+
+
+
+ project.labelp
+ Έργα
+
+
-
\ No newline at end of file
+
diff --git a/translations/frontend.en.xlf b/translations/frontend.en.xlf
index 91617f79..55712493 100644
--- a/translations/frontend.en.xlf
+++ b/translations/frontend.en.xlf
@@ -49,6 +49,18 @@
Very strong
+
+
+ assembly.labelp
+ Assemblies
+
+
+
+
+ project.labelp
+ Projects
+
+
search.submit
diff --git a/translations/frontend.es.xlf b/translations/frontend.es.xlf
index 7d339959..3093e719 100644
--- a/translations/frontend.es.xlf
+++ b/translations/frontend.es.xlf
@@ -49,6 +49,18 @@
Muy fuerte
+
+
+ assembly.labelp
+ Ensamblajes
+
+
+
+
+ project.labelp
+ Proyectos
+
+
search.submit
diff --git a/translations/frontend.fr.xlf b/translations/frontend.fr.xlf
index 5ebfca51..49660bd4 100644
--- a/translations/frontend.fr.xlf
+++ b/translations/frontend.fr.xlf
@@ -49,6 +49,18 @@
Très fort
+
+
+ assembly.labelp
+ Assemblages
+
+
+
+
+ project.labelp
+ Projets
+
+
search.submit
diff --git a/translations/frontend.hu.xlf b/translations/frontend.hu.xlf
index c303dedc..c1d1c393 100644
--- a/translations/frontend.hu.xlf
+++ b/translations/frontend.hu.xlf
@@ -49,6 +49,18 @@
Nagyon erős
+
+
+ assembly.labelp
+ Összeállítások
+
+
+
+
+ project.labelp
+ Projektek
+
+
search.submit
diff --git a/translations/frontend.it.xlf b/translations/frontend.it.xlf
index f163e3e2..02bcfb09 100644
--- a/translations/frontend.it.xlf
+++ b/translations/frontend.it.xlf
@@ -49,6 +49,18 @@
Molto forte
+
+
+ assembly.labelp
+ Assemblaggi
+
+
+
+
+ project.labelp
+ Progetti
+
+
search.submit
diff --git a/translations/frontend.ja.xlf b/translations/frontend.ja.xlf
index 90ffdf5f..327c4778 100644
--- a/translations/frontend.ja.xlf
+++ b/translations/frontend.ja.xlf
@@ -2,22 +2,34 @@
-
- search.placeholder
- 検索
-
-
+
+ search.placeholder
+ 検索
+
+
-
- part.labelp
- 部品
-
-
+
+ part.labelp
+ 部品
+
+
-
- search.submit
- 検索
-
-
+
+ search.submit
+ 検索
+
+
+
+
+ assembly.labelp
+ アセンブリ一覧
+
+
+
+
+ project.labelp
+ プロジェクト
+
+
-
\ No newline at end of file
+
diff --git a/translations/frontend.nl.xlf b/translations/frontend.nl.xlf
index 13187f62..c3b30ed9 100644
--- a/translations/frontend.nl.xlf
+++ b/translations/frontend.nl.xlf
@@ -2,10 +2,22 @@
-
- search.placeholder
- Zoeken
-
-
+
+ search.placeholder
+ Zoeken
+
+
+
+
+ assembly.labelp
+ Assemblages
+
+
+
+
+ project.labelp
+ Projecten
+
+
-
\ No newline at end of file
+
diff --git a/translations/frontend.pl.xlf b/translations/frontend.pl.xlf
index fface684..2e50305e 100644
--- a/translations/frontend.pl.xlf
+++ b/translations/frontend.pl.xlf
@@ -49,6 +49,18 @@
Bardzo mocne
+
+
+ assembly.labelp
+ Zespoły
+
+
+
+
+ project.labelp
+ Projekty
+
+
search.submit
diff --git a/translations/frontend.ru.xlf b/translations/frontend.ru.xlf
index f4665a74..f84e1a61 100644
--- a/translations/frontend.ru.xlf
+++ b/translations/frontend.ru.xlf
@@ -49,6 +49,18 @@
Очень сильный
+
+
+ assembly.labelp
+ Сборки
+
+
+
+
+ project.labelp
+ Проекты
+
+
search.submit
diff --git a/translations/frontend.uk.xlf b/translations/frontend.uk.xlf
index fee1b03e..748bac5c 100644
--- a/translations/frontend.uk.xlf
+++ b/translations/frontend.uk.xlf
@@ -49,6 +49,18 @@
Дуже надійний
+
+
+ assembly.labelp
+ Збірки
+
+
+
+
+ project.labelp
+ Проєкти
+
+
search.submit
diff --git a/translations/frontend.zh.xlf b/translations/frontend.zh.xlf
index 8bb063b8..0159f8f2 100644
--- a/translations/frontend.zh.xlf
+++ b/translations/frontend.zh.xlf
@@ -49,6 +49,18 @@
非常强
+
+
+ assembly.labelp
+ 装配列表
+
+
+
+
+ project.labelp
+ 项目
+
+
search.submit
diff --git a/translations/messages.cs.xlf b/translations/messages.cs.xlf
index 9dff3038..8e398a65 100644
--- a/translations/messages.cs.xlf
+++ b/translations/messages.cs.xlf
@@ -1845,25 +1845,19 @@ Související prvky budou přesunuty nahoru.
Projekty
-
+
statistics.cleanup_assembly_bom_entries.error
Při čištění došlo k chybě.
-
+
statistics.cleanup_assembly_bom_entries.success
%count% položek bylo úspěšně vyčištěno.
-
-
- statistics.cleanup_assembly_bom_entries.confirm
- Chcete vyčistit všechny neplatné položky kusovníku? Odkaz na díl bude odstraněn a název nastaven na "part-id=id not found".
-
-
-
+
statistics.cleanup_assembly_bom_entries.button
Vyčistit
@@ -12320,14 +12314,38 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
Uživatelé
-
-
- Do not remove! Used for datatables rendering.
-
-
- datatable.datatable.lengthMenu
- _MENU_
-
-
+
+
+ Do not remove! Used for datatables rendering.
+
+
+ datatable.datatable.lengthMenu
+ _MENU_
+
+
+
+
+ statistics.invalid_assembly_preview_attachments_count
+ Invalid assembly preview attachments (attachment not found)
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.button
+ Cleanup
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.success
+ %count% entries were successfully cleaned up.
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.error
+ An error occurred during cleanup.
+
+
-
\ No newline at end of file
+
diff --git a/translations/messages.da.xlf b/translations/messages.da.xlf
index a125c32f..4e186e35 100644
--- a/translations/messages.da.xlf
+++ b/translations/messages.da.xlf
@@ -1803,25 +1803,19 @@ Underelementer vil blive flyttet opad.
Projekter
-
+
statistics.cleanup_assembly_bom_entries.error
Der opstod en fejl under oprydningen.
-
+
statistics.cleanup_assembly_bom_entries.success
%count% poster blev ryddet op.
-
-
- statistics.cleanup_assembly_bom_entries.confirm
- Vil du rydde op i alle ugyldige stykliste-poster? Forbindelsen til delen vil blive slettet, og navnet sat til "part-id=id not found".
-
-
-
+
statistics.cleanup_assembly_bom_entries.button
Ryd op
@@ -13748,5 +13742,29 @@ Buerklin API-godkendelsesserver: 10 anmodninger/minut pr. IP-adresse
Opdatér til
+
+
+ statistics.invalid_assembly_preview_attachments_count
+ Invalid assembly preview attachments (attachment not found)
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.button
+ Cleanup
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.success
+ %count% entries were successfully cleaned up.
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.error
+ An error occurred during cleanup.
+
+
diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf
index 5c7986dc..f8dff6f7 100644
--- a/translations/messages.de.xlf
+++ b/translations/messages.de.xlf
@@ -1826,25 +1826,19 @@ Subelemente werden beim Löschen nach oben verschoben.
Ungültige Stücklisteneinträge (Teil nicht gefunden)
-
+
statistics.cleanup_assembly_bom_entries.button
Bereinigen
-
-
- statistics.cleanup_assembly_bom_entries.confirm
- Möchten Sie alle ungültigen Stücklisteneinträge bereinigen? Die Verknüpfung zum Teil wird gelöscht und der Name auf "part-id=id not found" gesetzt.
-
-
-
+
statistics.cleanup_assembly_bom_entries.success
%count% Einträge wurden erfolgreich bereinigt.
-
+
statistics.cleanup_assembly_bom_entries.error
Bei der Bereinigung ist ein Fehler aufgetreten.
@@ -13121,7 +13115,7 @@ Bitte beachten Sie, dass dieses System derzeit experimentell ist und die hier de
settings.ips.buerklin.help
Buerklin-API-Zugriffsbeschränkungen: 100 Requests/Minute pro IP-Adresse
-Buerklin-API-Authentication-Server:
+Buerklin-API-Authentication-Server:
10 Requests/Minute pro IP-Adresse
@@ -13887,5 +13881,29 @@ Buerklin-API-Authentication-Server:
Letzte Inventur
+
+
+ statistics.invalid_assembly_preview_attachments_count
+ Ungültige Baugruppen-Vorschaubilder (Anhang nicht gefunden)
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.button
+ Bereinigen
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.success
+ %count% Einträge wurden erfolgreich bereinigt.
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.error
+ Bei der Bereinigung ist ein Fehler aufgetreten.
+
+
diff --git a/translations/messages.el.xlf b/translations/messages.el.xlf
index 9995d942..f9cf770f 100644
--- a/translations/messages.el.xlf
+++ b/translations/messages.el.xlf
@@ -1883,25 +1883,19 @@
Έργα
-
+
statistics.cleanup_assembly_bom_entries.error
Παρουσιάστηκε σφάλμα κατά την εκκαθάριση.
-
+
statistics.cleanup_assembly_bom_entries.success
%count% εγγραφές εκκαθαρίστηκαν με επιτυχία.
-
-
- statistics.cleanup_assembly_bom_entries.confirm
- Θέλετε να εκκαθαρίσετε όλες τις μη έγκυρες εγγραφές BOM; Ο σύνδεσμος προς το εξάρτημα θα διαγραφεί και το όνομα θα οριστεί σε "part-id=id not found".
-
-
-
+
statistics.cleanup_assembly_bom_entries.button
Εκκαθάριση
@@ -1925,5 +1919,29 @@
Αριθμός [[Assembly]]
+
+
+ statistics.invalid_assembly_preview_attachments_count
+ Invalid assembly preview attachments (attachment not found)
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.button
+ Cleanup
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.success
+ %count% entries were successfully cleaned up.
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.error
+ An error occurred during cleanup.
+
+
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index 47896b4e..b7757644 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -1827,25 +1827,19 @@ Sub elements will be moved upwards.
Invalid BOM entries (part not found)
-
+
statistics.cleanup_assembly_bom_entries.button
Cleanup
-
-
- statistics.cleanup_assembly_bom_entries.confirm
- Do you want to cleanup all invalid BOM entries? The link to the part will be removed and the name set to "part-id=id not found".
-
-
-
+
statistics.cleanup_assembly_bom_entries.success
%count% entries were successfully cleaned up.
-
+
statistics.cleanup_assembly_bom_entries.error
An error occurred during cleanup.
@@ -13781,6 +13775,30 @@ Buerklin-API Authentication server:
Update to
+
+
+ statistics.invalid_assembly_preview_attachments_count
+ Invalid assembly preview attachments (attachment not found)
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.button
+ Cleanup
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.success
+ %count% entries were successfully cleaned up.
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.error
+ An error occurred during cleanup.
+
+
part.gtin
diff --git a/translations/messages.es.xlf b/translations/messages.es.xlf
index b03886bb..a29fe277 100644
--- a/translations/messages.es.xlf
+++ b/translations/messages.es.xlf
@@ -1845,25 +1845,19 @@ Subelementos serán desplazados hacia arriba.
Proyectos
-
+
statistics.cleanup_assembly_bom_entries.error
Ocurrió un error durante la limpieza.
-
+
statistics.cleanup_assembly_bom_entries.success
%count% entradas se limpiaron con éxito.
-
-
- statistics.cleanup_assembly_bom_entries.confirm
- ¿Desea limpiar todas las entradas de lista de materiales no válidas? El enlace a la pieza se eliminará y el nombre se establecerá en "part-id=id not found".
-
-
-
+
statistics.cleanup_assembly_bom_entries.button
Limpiar
@@ -11098,5 +11092,29 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
_MENU_
+
+
+ statistics.invalid_assembly_preview_attachments_count
+ Invalid assembly preview attachments (attachment not found)
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.button
+ Cleanup
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.success
+ %count% entries were successfully cleaned up.
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.error
+ An error occurred during cleanup.
+
+
-
\ No newline at end of file
+
diff --git a/translations/messages.fr.xlf b/translations/messages.fr.xlf
index 63159e5a..68a45b3f 100644
--- a/translations/messages.fr.xlf
+++ b/translations/messages.fr.xlf
@@ -1828,25 +1828,19 @@ Show/Hide sidebar
Projets
-
+
statistics.cleanup_assembly_bom_entries.error
Une erreur est survenue lors du nettoyage.
-
+
statistics.cleanup_assembly_bom_entries.success
%count% entrées ont été nettoyées avec succès.
-
-
- statistics.cleanup_assembly_bom_entries.confirm
- Voulez-vous nettoyer toutes les entrées de nomenclature non valides ? Le lien vers la pièce sera supprimé et le nom sera défini sur "part-id=id not found".
-
-
-
+
statistics.cleanup_assembly_bom_entries.button
Nettoyer
@@ -7554,7 +7548,31 @@ exemple de ville
datatable.datatable.lengthMenu
_MENU_
-
+
+
+
+
+ statistics.invalid_assembly_preview_attachments_count
+ Invalid assembly preview attachments (attachment not found)
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.button
+ Cleanup
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.success
+ %count% entries were successfully cleaned up.
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.error
+ An error occurred during cleanup.
+
-
\ No newline at end of file
+
diff --git a/translations/messages.hu.xlf b/translations/messages.hu.xlf
index b754bb4a..2cc63004 100644
--- a/translations/messages.hu.xlf
+++ b/translations/messages.hu.xlf
@@ -1756,25 +1756,19 @@
Projektek
-
+
statistics.cleanup_assembly_bom_entries.error
Hiba történt a tisztítás során.
-
+
statistics.cleanup_assembly_bom_entries.success
%count% tétel sikeresen törölve.
-
-
- statistics.cleanup_assembly_bom_entries.confirm
- Szeretné törölni az összes érvénytelen darabjegyzék tételt? Az alkatrészre mutató hivatkozás törlődik, a név pedig "part-id=id not found" lesz.
-
-
-
+
statistics.cleanup_assembly_bom_entries.button
Tisztítás
@@ -11525,7 +11519,31 @@
datatable.datatable.lengthMenu
_MENU_
-
+
+
+
+
+ statistics.invalid_assembly_preview_attachments_count
+ Invalid assembly preview attachments (attachment not found)
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.button
+ Cleanup
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.success
+ %count% entries were successfully cleaned up.
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.error
+ An error occurred during cleanup.
+
-
\ No newline at end of file
+
diff --git a/translations/messages.it.xlf b/translations/messages.it.xlf
index b2de4468..96121a4d 100644
--- a/translations/messages.it.xlf
+++ b/translations/messages.it.xlf
@@ -1845,25 +1845,19 @@ I sub elementi saranno spostati verso l'alto.
Progetti
-
+
statistics.cleanup_assembly_bom_entries.error
Si è verificato un errore durante la pulizia.
-
+
statistics.cleanup_assembly_bom_entries.success
%count% voci sono state pulite con successo.
-
-
- statistics.cleanup_assembly_bom_entries.confirm
- Vuoi pulire tutte le voci della distinta base non valide? Il collegamento alla parte verrà rimosso e il nome impostato su "part-id=id not found".
-
-
-
+
statistics.cleanup_assembly_bom_entries.button
Pulisci
@@ -11098,7 +11092,31 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
datatable.datatable.lengthMenu
_MENU_
-
+
+
+
+
+ statistics.invalid_assembly_preview_attachments_count
+ Invalid assembly preview attachments (attachment not found)
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.button
+ Cleanup
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.success
+ %count% entries were successfully cleaned up.
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.error
+ An error occurred during cleanup.
+
-
\ No newline at end of file
+
diff --git a/translations/messages.ja.xlf b/translations/messages.ja.xlf
index bd7119ab..c98355db 100644
--- a/translations/messages.ja.xlf
+++ b/translations/messages.ja.xlf
@@ -1828,25 +1828,19 @@
プロジェクト
-
+
statistics.cleanup_assembly_bom_entries.error
クリーンアップ中にエラーが発生しました。
-
+
statistics.cleanup_assembly_bom_entries.success
%count% 個のエントリが正常にクリーンアップされました。
-
-
- statistics.cleanup_assembly_bom_entries.confirm
- すべての無効な部品表エントリをクリーンアップしますか?部品へのリンクは削除され、名前は "part-id=id not found" に設定されます。
-
-
-
+
statistics.cleanup_assembly_bom_entries.button
クリーンアップ
@@ -7273,7 +7267,31 @@ Exampletown
datatable.datatable.lengthMenu
_MENU_
-
+
+
+
+
+ statistics.invalid_assembly_preview_attachments_count
+ Invalid assembly preview attachments (attachment not found)
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.button
+ Cleanup
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.success
+ %count% entries were successfully cleaned up.
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.error
+ An error occurred during cleanup.
+
-
\ No newline at end of file
+
diff --git a/translations/messages.nl.xlf b/translations/messages.nl.xlf
index cf022030..650b1cec 100644
--- a/translations/messages.nl.xlf
+++ b/translations/messages.nl.xlf
@@ -1560,25 +1560,19 @@
Projecten
-
+
statistics.cleanup_assembly_bom_entries.error
Er is een fout opgetreden tijdens het opschonen.
-
+
statistics.cleanup_assembly_bom_entries.success
%count% regels zijn succesvol opgeschoond.
-
-
- statistics.cleanup_assembly_bom_entries.confirm
- Wilt u alle ongeldige stuklijstregels opschonen? De koppeling naar het onderdeel wordt verwijderd en de naam wordt ingesteld op "part-id=id not found".
-
-
-
+
statistics.cleanup_assembly_bom_entries.button
Opschonen
@@ -1602,5 +1596,29 @@
Aantal [[Assembly]]
+
+
+ statistics.invalid_assembly_preview_attachments_count
+ Invalid assembly preview attachments (attachment not found)
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.button
+ Cleanup
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.success
+ %count% entries were successfully cleaned up.
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.error
+ An error occurred during cleanup.
+
+
diff --git a/translations/messages.pl.xlf b/translations/messages.pl.xlf
index f253417e..4b981e2c 100644
--- a/translations/messages.pl.xlf
+++ b/translations/messages.pl.xlf
@@ -1842,25 +1842,19 @@ Po usunięciu pod elementy zostaną przeniesione na górę.
Projekty
-
+
statistics.cleanup_assembly_bom_entries.error
Wystąpił błąd podczas czyszczenia.
-
+
statistics.cleanup_assembly_bom_entries.success
Pomyślnie wyczyszczono %count% wpisów.
-
-
- statistics.cleanup_assembly_bom_entries.confirm
- Czy chcesz wyczyścić wszystkie nieprawidłowe wpisy w zestawieniu? Link do części zostanie usunięty, a nazwa ustawiona na "part-id=id not found".
-
-
-
+
statistics.cleanup_assembly_bom_entries.button
Wyczyść
@@ -10943,7 +10937,31 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
datatable.datatable.lengthMenu
_MENU_
-
+
+
+
+
+ statistics.invalid_assembly_preview_attachments_count
+ Invalid assembly preview attachments (attachment not found)
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.button
+ Cleanup
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.success
+ %count% entries were successfully cleaned up.
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.error
+ An error occurred during cleanup.
+
-
\ No newline at end of file
+
diff --git a/translations/messages.ru.xlf b/translations/messages.ru.xlf
index bf0ec4f5..45cedc02 100644
--- a/translations/messages.ru.xlf
+++ b/translations/messages.ru.xlf
@@ -1846,25 +1846,19 @@
Проекты
-
+
statistics.cleanup_assembly_bom_entries.error
Произошла ошибка при очистке.
-
+
statistics.cleanup_assembly_bom_entries.success
%count% записей успешно очищено.
-
-
- statistics.cleanup_assembly_bom_entries.confirm
- Вы хотите очистить все неверные записи в спецификации? Ссылка на деталь будет удалена, а имя установлено в "part-id=id not found".
-
-
-
+
statistics.cleanup_assembly_bom_entries.button
Очистить
@@ -11043,7 +11037,31 @@
datatable.datatable.lengthMenu
_MENU_
-
+
+
+
+
+ statistics.invalid_assembly_preview_attachments_count
+ Invalid assembly preview attachments (attachment not found)
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.button
+ Cleanup
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.success
+ %count% entries were successfully cleaned up.
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.error
+ An error occurred during cleanup.
+
-
\ No newline at end of file
+
diff --git a/translations/messages.zh.xlf b/translations/messages.zh.xlf
index 6b319f8b..e3ed318b 100644
--- a/translations/messages.zh.xlf
+++ b/translations/messages.zh.xlf
@@ -1845,25 +1845,19 @@
项目
-
+
statistics.cleanup_assembly_bom_entries.error
清理过程中发生错误。
-
+
statistics.cleanup_assembly_bom_entries.success
成功清理了 %count% 条条目。
-
-
- statistics.cleanup_assembly_bom_entries.confirm
- 您想清理所有无效的物料清单条目吗?部件链接将被删除,名称将设置为 "part-id=id not found"。
-
-
-
+
statistics.cleanup_assembly_bom_entries.button
清理
@@ -10928,7 +10922,31 @@ Element 3
datatable.datatable.lengthMenu
_MENU_
-
+
+
+
+
+ statistics.invalid_assembly_preview_attachments_count
+ Invalid assembly preview attachments (attachment not found)
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.button
+ Cleanup
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.success
+ %count% entries were successfully cleaned up.
+
+
+
+
+ statistics.cleanup_assembly_preview_attachments.error
+ An error occurred during cleanup.
+
-
\ No newline at end of file
+