Redesign and translate grid controls
This commit is contained in:
@@ -290,6 +290,9 @@ Implemented layout foundation:
|
||||
- active sorts and filters are summarized above the grid and can be removed individually or reset together
|
||||
- column filter buttons show their selected-value count
|
||||
- filter menus provide value search, select-all/select-none controls and explicit cancel/apply actions
|
||||
- filter values and visible columns use full-width selectable rows instead of permanent checkbox controls
|
||||
- column settings use the same searchable panel pattern as column filters
|
||||
- column headings are visually plain text while remaining keyboard-accessible sort controls
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
|
||||
+131
-13
@@ -115,24 +115,62 @@ body {
|
||||
margin-top: 2rem;
|
||||
border: 1px solid #cfd7e5;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
|
||||
padding: 0.45rem;
|
||||
width: 300px;
|
||||
padding: 0.55rem;
|
||||
width: 340px;
|
||||
color: #1f2937;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.column-settings-actions {
|
||||
.column-settings-title-row,
|
||||
.column-settings-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-bottom: 0.35rem;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
.column-settings-title-row {
|
||||
margin-bottom: 0.25rem;
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.column-settings-close {
|
||||
border: 0 !important;
|
||||
background: transparent !important;
|
||||
color: #4b5563;
|
||||
padding: 0.05rem 0.2rem !important;
|
||||
font-size: 1rem !important;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.column-settings-explanation {
|
||||
margin-bottom: 0.4rem;
|
||||
color: #4b5563;
|
||||
font-size: 0.72rem;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.column-settings-search {
|
||||
width: 100%;
|
||||
margin-bottom: 0.4rem;
|
||||
border: 1px solid #c4cddc;
|
||||
border-radius: 4px;
|
||||
padding: 0.3rem 0.4rem;
|
||||
font-size: 0.76rem;
|
||||
}
|
||||
|
||||
.column-settings-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
max-height: 340px;
|
||||
gap: 0.15rem;
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
border: 1px solid #e1e6ef;
|
||||
border-radius: 4px;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
.column-settings-item {
|
||||
@@ -142,7 +180,12 @@ body {
|
||||
gap: 0.4rem;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
padding: 0.2rem 0.25rem;
|
||||
padding: 0.1rem;
|
||||
}
|
||||
|
||||
.column-settings-item.selected {
|
||||
border-color: #bfdbfe;
|
||||
background: #eff6ff;
|
||||
}
|
||||
|
||||
.column-settings-item.dragging {
|
||||
@@ -158,11 +201,32 @@ body {
|
||||
background: #f7fafc;
|
||||
}
|
||||
|
||||
.column-settings-item label {
|
||||
.column-visibility-button {
|
||||
display: flex;
|
||||
gap: 0.3rem;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
border: 0 !important;
|
||||
background: transparent !important;
|
||||
padding: 0.2rem 0.25rem !important;
|
||||
color: inherit;
|
||||
text-align: left;
|
||||
font-size: 0.8rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.column-visibility-button:disabled {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.selection-marker {
|
||||
display: inline-flex;
|
||||
flex: 0 0 1rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #1d4ed8;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.column-settings-order {
|
||||
@@ -189,6 +253,23 @@ body {
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
.column-settings-empty {
|
||||
padding: 0.55rem 0.35rem;
|
||||
color: #6b7280;
|
||||
font-size: 0.76rem;
|
||||
}
|
||||
|
||||
.column-settings-footer {
|
||||
justify-content: flex-end;
|
||||
margin-top: 0.45rem;
|
||||
}
|
||||
|
||||
.column-settings-footer button.primary {
|
||||
border-color: #2563eb;
|
||||
background: #2563eb;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.tree-editor-layout {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(240px, 320px) minmax(0, 1fr);
|
||||
@@ -300,7 +381,6 @@ body {
|
||||
gap: 0.3rem;
|
||||
}
|
||||
|
||||
.tree-grid .header-sort-btn,
|
||||
.tree-grid .header-filter-btn {
|
||||
border: 1px solid #c4cddc;
|
||||
background: #fff;
|
||||
@@ -310,7 +390,28 @@ body {
|
||||
}
|
||||
|
||||
.tree-grid .header-sort-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
color: #1f2937;
|
||||
font: inherit;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 600;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tree-grid .header-sort-btn:hover span:first-child,
|
||||
.tree-grid .header-sort-btn:focus-visible span:first-child {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.tree-grid .sort-indicator {
|
||||
color: #2563eb;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.tree-grid .header-filter-btn.active {
|
||||
@@ -407,9 +508,26 @@ body {
|
||||
.tree-grid .header-filter-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
gap: 0.35rem;
|
||||
width: 100%;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 3px;
|
||||
background: transparent;
|
||||
padding: 0.25rem 0.3rem;
|
||||
color: #1f2937;
|
||||
font-weight: 400;
|
||||
font-size: 0.75rem;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tree-grid .header-filter-item:hover {
|
||||
background: #f3f4f6;
|
||||
}
|
||||
|
||||
.tree-grid .header-filter-item.selected {
|
||||
border-color: #bfdbfe;
|
||||
background: #eff6ff;
|
||||
}
|
||||
|
||||
.tree-grid .header-filter-empty {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -55,36 +55,36 @@ export interface ColumnDef {
|
||||
// BMK stays locked as the first column because circuit identity and circuit drag
|
||||
// handles depend on an always-visible equipment identifier.
|
||||
export const allColumns: ColumnDef[] = [
|
||||
{ key: "equipmentIdentifier", label: "Equipment identifier", defaultVisible: true, locked: true },
|
||||
{ key: "displayName", label: "Display name", defaultVisible: true },
|
||||
{ key: "quantity", label: "Quantity", numeric: true, defaultVisible: true },
|
||||
{ key: "powerPerUnit", label: "Power / unit", numeric: true, defaultVisible: true },
|
||||
{ key: "simultaneityFactor", label: "Simultaneity", numeric: true, defaultVisible: true },
|
||||
{ key: "rowTotalPower", label: "Row total", numeric: true, defaultVisible: true },
|
||||
{ key: "circuitTotalPower", label: "Circuit total", numeric: true, defaultVisible: true },
|
||||
{ key: "protectionSummary", label: "Protection summary", defaultVisible: true },
|
||||
{ key: "cableSummary", label: "Cable summary", defaultVisible: true },
|
||||
{ key: "roomSummary", label: "Room", defaultVisible: true },
|
||||
{ key: "remark", label: "Remark", defaultVisible: true },
|
||||
{ key: "technicalName", label: "Technical name" },
|
||||
{ key: "connectionKind", label: "Connection kind" },
|
||||
{ key: "phaseType", label: "Phase type" },
|
||||
{ key: "costGroup", label: "Cost group" },
|
||||
{ key: "category", label: "Category" },
|
||||
{ key: "level", label: "Level" },
|
||||
{ key: "roomNumberSnapshot", label: "Room number" },
|
||||
{ key: "roomNameSnapshot", label: "Room name" },
|
||||
{ key: "cosPhi", label: "cosPhi", numeric: true },
|
||||
{ key: "protectionType", label: "Protection type" },
|
||||
{ key: "protectionRatedCurrent", label: "Protection rated current", numeric: true },
|
||||
{ key: "protectionCharacteristic", label: "Protection characteristic" },
|
||||
{ key: "cableType", label: "Cable type" },
|
||||
{ key: "cableCrossSection", label: "Cable cross-section" },
|
||||
{ key: "cableLength", label: "Cable length", numeric: true },
|
||||
{ key: "rcdAssignment", label: "RCD assignment" },
|
||||
{ key: "terminalDesignation", label: "Terminal designation" },
|
||||
{ key: "voltage", label: "Voltage", numeric: true },
|
||||
{ key: "controlRequirement", label: "Control requirement" },
|
||||
{ key: "equipmentIdentifier", label: "Betriebsmittelkennzeichen", defaultVisible: true, locked: true },
|
||||
{ key: "displayName", label: "Anzeigename", defaultVisible: true },
|
||||
{ key: "quantity", label: "Anzahl", numeric: true, defaultVisible: true },
|
||||
{ key: "powerPerUnit", label: "Leistung / Gerät", numeric: true, defaultVisible: true },
|
||||
{ key: "simultaneityFactor", label: "Gleichzeitigkeit", numeric: true, defaultVisible: true },
|
||||
{ key: "rowTotalPower", label: "Zeilensumme", numeric: true, defaultVisible: true },
|
||||
{ key: "circuitTotalPower", label: "Stromkreissumme", numeric: true, defaultVisible: true },
|
||||
{ key: "protectionSummary", label: "Schutz", defaultVisible: true },
|
||||
{ key: "cableSummary", label: "Kabel", defaultVisible: true },
|
||||
{ key: "roomSummary", label: "Raum", defaultVisible: true },
|
||||
{ key: "remark", label: "Bemerkung", defaultVisible: true },
|
||||
{ key: "technicalName", label: "Technischer Name" },
|
||||
{ key: "connectionKind", label: "Anschlussart" },
|
||||
{ key: "phaseType", label: "Phasenart" },
|
||||
{ key: "costGroup", label: "Kostengruppe" },
|
||||
{ key: "category", label: "Kategorie" },
|
||||
{ key: "level", label: "Ebene" },
|
||||
{ key: "roomNumberSnapshot", label: "Raumnummer" },
|
||||
{ key: "roomNameSnapshot", label: "Raumname" },
|
||||
{ key: "cosPhi", label: "cos φ", numeric: true },
|
||||
{ key: "protectionType", label: "Schutzart" },
|
||||
{ key: "protectionRatedCurrent", label: "Bemessungsstrom", numeric: true },
|
||||
{ key: "protectionCharacteristic", label: "Charakteristik" },
|
||||
{ key: "cableType", label: "Kabeltyp" },
|
||||
{ key: "cableCrossSection", label: "Kabelquerschnitt" },
|
||||
{ key: "cableLength", label: "Kabellänge", numeric: true },
|
||||
{ key: "rcdAssignment", label: "RCD-Zuordnung" },
|
||||
{ key: "terminalDesignation", label: "Klemmenbezeichnung" },
|
||||
{ key: "voltage", label: "Spannung", numeric: true },
|
||||
{ key: "controlRequirement", label: "Steuerungsanforderung" },
|
||||
{ key: "status", label: "Status" },
|
||||
{ key: "isReserve", label: "Reserve" },
|
||||
];
|
||||
@@ -172,7 +172,7 @@ export function formatValue(value: GridValue): string {
|
||||
return "-";
|
||||
}
|
||||
if (typeof value === "boolean") {
|
||||
return value ? "Yes" : "No";
|
||||
return value ? "Ja" : "Nein";
|
||||
}
|
||||
return String(value);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user