Add part number chips feature to CalculationMassEdit modal

- Display selected part numbers as chips with a count summary.
- Add logic to extract and display unique part numbers from edit IDs.
- Update modal and style components to support the new feature.
This commit is contained in:
Jan 2026-01-28 22:07:16 +01:00
parent 417221eca8
commit 15854e1076

View file

@ -107,6 +107,27 @@
<modal :z-index="2000" :state="modalShow">
<div class="modal-content-container">
<h3 class="sub-header">{{ modalTitle }}</h3>
<!-- Part Number Chips -->
<div v-if="shouldShowPartNumbers" class="parts-selection-container">
<div class="parts-chips">
<basic-badge
v-for="partNumber in selectedPartNumbers.slice(0, 5)"
:key="partNumber"
variant="primary"
size="compact"
class="part-chip"
>
{{ partNumber }}
</basic-badge>
<span v-if="selectedPartNumbers.length > 5" class="parts-ellipsis">...</span>
</div>
<div v-if="partNumberCountText" class="parts-count">
{{ partNumberCountText }}
</div>
</div>
<!-- END: Part Number Chips -->
<component
:is="modalComponentType"
ref="modalComponent"
@ -176,6 +197,7 @@ import Modal from "@/components/UI/Modal.vue";
import PriceEdit from "@/components/layout/edit/PriceEdit.vue";
import MaterialEdit from "@/components/layout/edit/MaterialEdit.vue";
import PackagingEdit from "@/components/layout/edit/PackagingEdit.vue";
import BasicBadge from "@/components/UI/BasicBadge.vue";
import {useNotificationStore} from "@/store/notification.js";
import {useDestinationEditStore} from "@/store/destinationEdit.js";
@ -211,7 +233,8 @@ export default {
CalculationListItem,
Checkbox,
BulkEditRow,
BasicButton
BasicButton,
BasicBadge
},
data() {
return {
@ -286,6 +309,55 @@ export default {
return "Please wait. Prepare calculation ..."
return this.processingMessage;
},
/**
* Extrahiert eindeutige Teilenummern aus ausgewählten Premises
* @returns {Array<string>} Array eindeutiger Teilenummern, sortiert
*/
selectedPartNumbers() {
// Guard: Keine editIds oder nicht relevant
if (!this.editIds || this.editIds.length === 0) {
return [];
}
// Nur für Material/Price/Packaging Modals anzeigen
const relevantTypes = ['material', 'price', 'packaging'];
if (!relevantTypes.includes(this.modalType)) {
return [];
}
try {
// Teilenummern extrahieren
const partNumbers = this.editIds
.map(id => {
const premise = this.premiseEditStore.getById(id);
return premise?.material?.part_number;
})
.filter(partNumber => partNumber != null && partNumber !== '');
// Duplikate entfernen und sortieren
return [...new Set(partNumbers)].sort();
} catch (error) {
logger.log('Error extracting part numbers:', error);
return [];
}
},
/**
* Prüft ob Part Numbers angezeigt werden sollen
*/
shouldShowPartNumbers() {
return this.selectedPartNumbers.length > 0;
},
/**
* Anzahl-Text für viele Teile (> 5)
*/
partNumberCountText() {
const count = this.selectedPartNumbers.length;
return count > 5 ? `${count} part numbers` : null;
}
},
watch: {
@ -630,6 +702,38 @@ export default {
margin-bottom: 1.6rem;
}
/* Part Number Chips Styling */
.parts-selection-container {
display: flex;
flex-direction: column;
gap: 0.4rem;
margin-bottom: 1.6rem;
padding-bottom: 1.6rem;
border-bottom: 0.1rem solid rgba(107, 134, 156, 0.1);
}
.parts-chips {
display: flex;
flex-wrap: wrap;
gap: 0.6rem;
}
.part-chip {
flex-shrink: 0;
}
.parts-ellipsis {
font-size: 1.4rem;
color: #6B869C;
align-self: center;
padding: 0 0.4rem;
}
.parts-count {
font-size: 1.2rem;
color: #9CA3AF;
}
/* Global style für copy-mode cursor */
.edit-calculation-container.has-selection :deep(.edit-calculation-list-header-cell--copyable:hover) {
cursor: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDEyOC41MSAxMzQuMDUiPjxkZWZzPjxzdHlsZT4uY3tmaWxsOm5vbmU7fS5jLC5ke3N0cm9rZTojMDEwMTAxO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6NXB4O30uZHtmaWxsOiNmZmY7fTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJhIj48cGF0aCBjbGFzcz0iYyIgZD0ibTU0Ljg5LDExMi41MWgtMi4yNGMtMS4yNCwwLTIuMjQtMS0yLjI0LTIuMjR2LTIuMjQiLz48bGluZSBjbGFzcz0iYyIgeDE9IjcwLjU3IiB5MT0iNzYuNjciIHgyPSI2My44NSIgeTI9Ijc2LjY3Ii8+PGxpbmUgY2xhc3M9ImMiIHgxPSI3MC41NyIgeTE9IjExMi41MSIgeDI9IjY2LjA5IiB5Mj0iMTEyLjUxIi8+PGxpbmUgY2xhc3M9ImMiIHgxPSI4Ni4yNSIgeTE9Ijk5LjA3IiB4Mj0iODYuMjUiIHkyPSI5Mi4zNSIvPjxsaW5lIGNsYXNzPSJjIiB4MT0iNTAuNDEiIHkxPSI5Ni44MyIgeDI9IjUwLjQxIiB5Mj0iOTIuMzUiLz48cGF0aCBjbGFzcz0iYyIgZD0ibTgxLjc3LDExMi41MWgyLjI0YzEuMjQsMCwyLjI0LTEsMi4yNC0yLjI0di0yLjI0Ii8+PHBhdGggY2xhc3M9ImMiIGQ9Im04MS43Nyw3Ni42N2gyLjI0YzEuMjQsMCwyLjI0LDEsMi4yNCwyLjI0djIuMjQiLz48cGF0aCBjbGFzcz0iYyIgZD0ibTU0Ljg5LDc2LjY3aC0yLjI0Yy0xLjI0LDAtMi4yNCwxLTIuMjQsMi4yNHYyLjI0Ii8+PHBhdGggY2xhc3M9ImMiIGQ9Im04Ni4yNSw5OS4wN2gxMS4yYzEuMjQsMCwyLjI0LTEsMi4yNC0yLjI0di0zMS4zNmMwLTEuMjQtMS0yLjI0LTIuMjQtMi4yNGgtMzEuMzZjLTEuMjQsMC0yLjI0LDEtMi4yNCwyLjI0djExLjIiLz48L2c+PGcgaWQ9ImIiPjxwYXRoIGNsYXNzPSJkIiBkPSJtNDQuMDgsNDQuMDdsMzIuOTQtOS4yYzEuNjktLjUyLDIuNjQtMi4zMSwyLjEyLTQtLjMtLjk4LTEuMDUtMS43NS0yLjAxLTIuMDlMNi43MywyLjY3Yy0xLjY3LS41Ny0zLjQ5LjMzLTQuMDYsMi0uMjMuNjYtLjIzLDEuMzgsMCwyLjA1bDI2LjExLDcwLjRjLjU4LDEuNjcsMi40LDIuNTYsNC4wNywxLjk4Ljk3LS4zMywxLjcxLTEuMTEsMi4wMS0yLjA5bDkuMjItMzIuOTRaIi8+PC9nPjwvc3ZnPg==") 12 12, pointer;