feat: Quickstart, Benutzerverwaltung und Orion-Ergebnisbox
This commit is contained in:
parent
4f669a3426
commit
e9e46f2cb4
404 changed files with 1032 additions and 600 deletions
Binary file not shown.
Binary file not shown.
|
|
@ -8,6 +8,7 @@ from app.modules.orion.assets import schubamed_logo_uri
|
|||
from app.modules.orion.components.base import ReportComponent
|
||||
from app.modules.orion.context import ReportContext
|
||||
from app.modules.orion.html import definition_list, paragraph, section, table, text, yes_no
|
||||
from app.modules.orion.result import validation_result_box, validation_result_label
|
||||
|
||||
|
||||
def render_template_text(content: str, context: ReportContext) -> str:
|
||||
|
|
@ -63,7 +64,6 @@ class CoverComponent(ReportComponent):
|
|||
("Pruefdatum", validation.performed_on),
|
||||
("Pruefungsort", validation.test_location),
|
||||
("Pruefer", validation.examiner_name),
|
||||
("Gesamtergebnis", validation.result),
|
||||
("Status", validation.status),
|
||||
(
|
||||
"Ansprechpartner",
|
||||
|
|
@ -83,6 +83,7 @@ class CoverComponent(ReportComponent):
|
|||
'<p class="cover-subtitle">Funktions- und Leistungsqualifikation Klein-Sterilisator</p>'
|
||||
f'<p class="cover-subtitle">{text(context.customer.name)}</p>'
|
||||
f"{rows}"
|
||||
f"{validation_result_box(validation.result)}"
|
||||
'<div class="signature-grid"><div>Unterschrift technische Validierung</div><div>Unterschrift Auftraggeber</div></div>'
|
||||
"</section>"
|
||||
)
|
||||
|
|
@ -121,7 +122,8 @@ class SummaryComponent(ReportComponent):
|
|||
def render(self, context: ReportContext) -> str:
|
||||
validation = context.validation
|
||||
block = context.text_blocks.get("summary")
|
||||
body = f"<p>{paragraph(render_template_text(block.content, context) if block else 'nicht erfasst')}</p>"
|
||||
body = validation_result_box(validation.result, compact=True)
|
||||
body += f"<p>{paragraph(render_template_text(block.content, context) if block else 'nicht erfasst')}</p>"
|
||||
body += definition_list(
|
||||
[
|
||||
("Kunde", context.customer.name),
|
||||
|
|
@ -135,7 +137,7 @@ class SummaryComponent(ReportComponent):
|
|||
),
|
||||
),
|
||||
("Pruefmittel", len(context.equipment)),
|
||||
("Ergebnis", validation.result),
|
||||
("Ergebnis", validation_result_label(validation.result)),
|
||||
("Mitwirkende Personen", validation.participants),
|
||||
(
|
||||
"Hinweis auf naechste Leistungsbeurteilung",
|
||||
|
|
@ -166,6 +168,10 @@ class StaticTextComponent(ReportComponent):
|
|||
return f"{self.number} {self.title}" if self.number else self.title
|
||||
|
||||
def render(self, context: ReportContext) -> str:
|
||||
if self.anchor == "results":
|
||||
body = validation_result_box(context.validation.result, compact=True)
|
||||
body += f"<p>{paragraph(self.body)}</p>"
|
||||
return section(self.anchor, self.title, body, self.bookmark_label)
|
||||
if self.block_key and self.block_key in context.text_blocks:
|
||||
content = render_template_text(context.text_blocks[self.block_key].content, context)
|
||||
return section(self.anchor, self.title, f"<p>{paragraph(content)}</p>", self.bookmark_label)
|
||||
|
|
|
|||
66
validation-suite/backend/mercury/app/modules/orion/result.py
Normal file
66
validation-suite/backend/mercury/app/modules/orion/result.py
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from app.modules.orion.html import text
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ResultPresentation:
|
||||
key: str
|
||||
label: str
|
||||
css_class: str
|
||||
color: str
|
||||
|
||||
|
||||
RESULT_PRESENTATIONS: dict[str, ResultPresentation] = {
|
||||
"BESTANDEN": ResultPresentation("BESTANDEN", "Bestanden", "result-box--passed", "#245C36"),
|
||||
"BESTANDEN_MIT_AUFLAGEN": ResultPresentation(
|
||||
"BESTANDEN_MIT_AUFLAGEN",
|
||||
"Bestanden mit Auflagen",
|
||||
"result-box--conditional",
|
||||
"#7A5A00",
|
||||
),
|
||||
"NICHT_BESTANDEN": ResultPresentation(
|
||||
"NICHT_BESTANDEN",
|
||||
"Nicht bestanden",
|
||||
"result-box--failed",
|
||||
"#7A1F26",
|
||||
),
|
||||
"OFFEN": ResultPresentation("OFFEN", "Noch nicht bewertet", "result-box--open", "#2E3B40"),
|
||||
}
|
||||
|
||||
RESULT_ALIASES = {
|
||||
"": "OFFEN",
|
||||
"OFFEN": "OFFEN",
|
||||
"BESTANDEN": "BESTANDEN",
|
||||
"BESTANDEN_MIT_AUFLAGEN": "BESTANDEN_MIT_AUFLAGEN",
|
||||
"NICHT_BESTANDEN": "NICHT_BESTANDEN",
|
||||
"offen": "OFFEN",
|
||||
"bestanden": "BESTANDEN",
|
||||
"bestanden_mit_auflagen": "BESTANDEN_MIT_AUFLAGEN",
|
||||
"mit_auflagen": "BESTANDEN_MIT_AUFLAGEN",
|
||||
"bestanden mit Auflagen": "BESTANDEN_MIT_AUFLAGEN",
|
||||
"nicht_bestanden": "NICHT_BESTANDEN",
|
||||
"nicht bestanden": "NICHT_BESTANDEN",
|
||||
}
|
||||
|
||||
|
||||
def validation_result_presentation(value: str | None) -> ResultPresentation:
|
||||
key = RESULT_ALIASES.get(str(value or "").strip(), "OFFEN")
|
||||
return RESULT_PRESENTATIONS[key]
|
||||
|
||||
|
||||
def validation_result_label(value: str | None) -> str:
|
||||
return validation_result_presentation(value).label
|
||||
|
||||
|
||||
def validation_result_box(value: str | None, *, compact: bool = False) -> str:
|
||||
presentation = validation_result_presentation(value)
|
||||
size_class = "result-box--compact" if compact else "result-box--cover"
|
||||
return (
|
||||
f'<div class="result-box {size_class} {presentation.css_class}">'
|
||||
'<div class="result-box__label">VALIDIERUNGSERGEBNIS</div>'
|
||||
f'<div class="result-box__value">{text(presentation.label.upper() if not compact else presentation.label)}</div>'
|
||||
"</div>"
|
||||
)
|
||||
|
|
@ -151,7 +151,7 @@ body {
|
|||
display: grid;
|
||||
gap: 18mm;
|
||||
grid-template-columns: 1fr 55mm;
|
||||
margin-bottom: 32mm;
|
||||
margin-bottom: 18mm;
|
||||
}
|
||||
|
||||
.cover-logo {
|
||||
|
|
@ -178,22 +178,94 @@ body {
|
|||
|
||||
h1 {
|
||||
color: #2E3B40;
|
||||
font-size: 34pt;
|
||||
font-size: 30pt;
|
||||
line-height: 1.05;
|
||||
margin: 0 0 8mm 0;
|
||||
margin: 0 0 5mm 0;
|
||||
}
|
||||
|
||||
.cover-subtitle {
|
||||
color: #4F6A74;
|
||||
font-size: 14pt;
|
||||
margin: 0 0 9mm 0;
|
||||
}
|
||||
|
||||
.cover-page .definition-row {
|
||||
grid-template-columns: 36mm 1fr;
|
||||
padding: 1.4mm 0;
|
||||
}
|
||||
|
||||
.result-box {
|
||||
border: 1.2mm solid #8A9498;
|
||||
border-radius: 2mm;
|
||||
break-inside: avoid;
|
||||
margin: 8mm 0;
|
||||
padding: 7mm 8mm;
|
||||
page-break-inside: avoid;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.result-box__label {
|
||||
color: #4F5E63;
|
||||
font-size: 9.5pt;
|
||||
font-weight: 700;
|
||||
letter-spacing: .06em;
|
||||
margin-bottom: 4mm;
|
||||
}
|
||||
|
||||
.result-box__value {
|
||||
font-weight: 800;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
.result-box--cover {
|
||||
margin-top: 7mm;
|
||||
padding: 6mm 8mm;
|
||||
}
|
||||
|
||||
.result-box--cover .result-box__value {
|
||||
font-size: 24pt;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.result-box--compact {
|
||||
margin: 0 0 6mm 0;
|
||||
padding: 5mm 6mm;
|
||||
}
|
||||
|
||||
.result-box--compact .result-box__value {
|
||||
font-size: 16pt;
|
||||
margin: 0 0 18mm 0;
|
||||
}
|
||||
|
||||
.result-box--passed {
|
||||
background: #EAF5EE;
|
||||
border-color: #6FA37D;
|
||||
color: #245C36;
|
||||
}
|
||||
|
||||
.result-box--conditional {
|
||||
background: #FFF7DD;
|
||||
border-color: #C9A64A;
|
||||
color: #7A5A00;
|
||||
}
|
||||
|
||||
.result-box--failed {
|
||||
background: #FCEBEC;
|
||||
border-color: #C96A70;
|
||||
color: #7A1F26;
|
||||
}
|
||||
|
||||
.result-box--open {
|
||||
background: #F1F3F3;
|
||||
border-color: #9AA6AA;
|
||||
color: #2E3B40;
|
||||
}
|
||||
|
||||
.signature-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 16mm;
|
||||
margin-top: 18mm;
|
||||
margin-top: 11mm;
|
||||
}
|
||||
|
||||
.signature-grid div {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue