From 5c6d300c4ea38bfde7c5723a45bfaad9bffe10a1 Mon Sep 17 00:00:00 2001 From: Md Bayazid Bostame Date: Tue, 24 Mar 2026 17:43:01 +0100 Subject: [PATCH] snapshot: preserve shared base shell foundation --- backend/locale/en/LC_MESSAGES/django.po | 47 ++-- .../static/workflows/css/app_chrome.css | 101 ++++++++ .../static/workflows/css/offboarding_form.css | 4 +- .../static/workflows/css/onboarding_form.css | 224 +++++++++++++++++- .../templates/registration/login.html | 11 +- .../templates/workflows/base_shell.html | 22 ++ .../workflows/developer_handbook.html | 28 +-- .../templates/workflows/form_builder.html | 6 +- .../templates/workflows/handbook.html | 26 +- .../workflows/templates/workflows/home.html | 3 +- .../workflows/includes/app_header.html | 23 ++ .../workflows/integrations_setup.html | 6 +- .../templates/workflows/intro_builder.html | 6 +- .../templates/workflows/offboarding_form.html | 14 +- .../workflows/offboarding_success.html | 44 ++-- .../templates/workflows/onboarding_form.html | 108 +++++++-- .../workflows/onboarding_intro_session.html | 16 +- .../workflows/onboarding_success.html | 42 ++-- .../templates/workflows/project_wiki.html | 26 +- .../workflows/release_checklist.html | 25 +- .../workflows/requests_dashboard.html | 3 +- .../templates/workflows/welcome_emails.html | 6 +- 22 files changed, 615 insertions(+), 176 deletions(-) create mode 100644 backend/workflows/static/workflows/css/app_chrome.css create mode 100644 backend/workflows/templates/workflows/base_shell.html create mode 100644 backend/workflows/templates/workflows/includes/app_header.html diff --git a/backend/locale/en/LC_MESSAGES/django.po b/backend/locale/en/LC_MESSAGES/django.po index 4c55457..eb6e042 100644 --- a/backend/locale/en/LC_MESSAGES/django.po +++ b/backend/locale/en/LC_MESSAGES/django.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: tubco-portal\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-03-24 13:05+0000\n" +"POT-Creation-Date: 2026-03-24 15:40+0000\n" "PO-Revision-Date: 2026-03-24 00:00+0000\n" "Language: en\n" "MIME-Version: 1.0\n" @@ -262,40 +262,40 @@ msgstr "deployment, security, and maintenance notes" msgid "Open Developer Handbook" msgstr "Open Developer Handbook" -#: workflows/templates/workflows/handbook.html:67 +#: workflows/templates/workflows/handbook.html:68 #: workflows/templates/workflows/release_checklist.html:36 msgid "Release" msgstr "" -#: workflows/templates/workflows/handbook.html:68 +#: workflows/templates/workflows/handbook.html:69 #: workflows/templates/workflows/release_checklist.html:7 #: workflows/templates/workflows/release_checklist.html:38 msgid "Release Checklist" msgstr "" -#: workflows/templates/workflows/handbook.html:69 +#: workflows/templates/workflows/handbook.html:70 msgid "" "Step-by-step release runbook for rebuilds, migrations, translations, static " "assets, smoke checks, and rollout verification." msgstr "" -#: workflows/templates/workflows/handbook.html:71 +#: workflows/templates/workflows/handbook.html:72 msgid "pre-release validation commands" msgstr "" -#: workflows/templates/workflows/handbook.html:72 +#: workflows/templates/workflows/handbook.html:73 msgid "translation, static, and migration steps" msgstr "" -#: workflows/templates/workflows/handbook.html:73 +#: workflows/templates/workflows/handbook.html:74 msgid "post-release smoke checks" msgstr "" -#: workflows/templates/workflows/handbook.html:74 +#: workflows/templates/workflows/handbook.html:75 msgid "rollback and evidence checklist" msgstr "" -#: workflows/templates/workflows/handbook.html:77 +#: workflows/templates/workflows/handbook.html:78 msgid "Open Release Checklist" msgstr "" @@ -823,23 +823,38 @@ msgid "" "Bitte prüfen Sie die markierten Felder. Ungültige Eingaben wurden erkannt." msgstr "Please check the highlighted fields. Invalid input was detected." -#: workflows/templates/workflows/onboarding_form.html:113 +#: workflows/templates/workflows/onboarding_form.html:86 +#: workflows/templates/workflows/onboarding_form.html:88 +#: workflows/templates/workflows/onboarding_form.html:125 +#: workflows/templates/workflows/onboarding_form.html:127 +#: workflows/templates/workflows/welcome_emails.html:105 +msgid "Alle auswählen" +msgstr "Select all" + +#: workflows/templates/workflows/onboarding_form.html:87 +#: workflows/templates/workflows/onboarding_form.html:126 +#, fuzzy +#| msgid "Auswahl löschen" +msgid "Auswahl aufheben" +msgstr "Delete selection" + +#: workflows/templates/workflows/onboarding_form.html:149 msgid "Keine konfigurierten Felder in diesem Schritt." msgstr "No configured fields in this step." -#: workflows/templates/workflows/onboarding_form.html:118 +#: workflows/templates/workflows/onboarding_form.html:154 msgid "Fast geschafft. Bitte Abschlussdaten prüfen und die Anfrage absenden." msgstr "Almost done. Please review the final details and submit the request." -#: workflows/templates/workflows/onboarding_form.html:130 +#: workflows/templates/workflows/onboarding_form.html:166 msgid "Zurück" msgstr "Back" -#: workflows/templates/workflows/onboarding_form.html:131 +#: workflows/templates/workflows/onboarding_form.html:167 msgid "Weiter" msgstr "Next" -#: workflows/templates/workflows/onboarding_form.html:132 +#: workflows/templates/workflows/onboarding_form.html:168 msgid "Onboarding-Anfrage absenden" msgstr "Submit onboarding request" @@ -1318,10 +1333,6 @@ msgstr "Available keywords:" msgid "Welcome-Einstellungen speichern" msgstr "Save welcome settings" -#: workflows/templates/workflows/welcome_emails.html:105 -msgid "Alle auswählen" -msgstr "Select all" - #: workflows/templates/workflows/welcome_emails.html:108 #: workflows/templates/workflows/welcome_emails.html:163 msgid "Pausieren" diff --git a/backend/workflows/static/workflows/css/app_chrome.css b/backend/workflows/static/workflows/css/app_chrome.css new file mode 100644 index 0000000..fe96482 --- /dev/null +++ b/backend/workflows/static/workflows/css/app_chrome.css @@ -0,0 +1,101 @@ +:root { + --app-shell-width: 1380px; + --app-line: #d9e3ee; + --app-brand-blue: #000078; + --app-panel: rgba(255, 255, 255, 0.9); + --app-shadow: 0 22px 48px rgba(18, 34, 56, 0.14); +} + +.app-header { + box-sizing: border-box; + width: min(var(--app-shell-width), 100%); + margin: 0 auto 12px; + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 18px; + padding: 22px 24px 18px; + border: 1px solid rgba(217, 227, 238, 0.9); + border-radius: 28px; + background: linear-gradient(180deg, rgba(255,255,255,0.95), rgba(248,251,255,0.84)); + box-shadow: var(--app-shadow); +} + +.app-header-in-shell { + box-sizing: border-box; + width: 100%; + margin: 0; + padding: 22px 24px 18px; + border: 0; + border-bottom: 1px solid rgba(217, 227, 238, 0.9); + border-radius: 0; + background: linear-gradient(180deg, rgba(255,255,255,0.95), rgba(248,251,255,0.84)); + box-shadow: none; +} + +.app-brand { + display: inline-flex; + min-width: 0; + align-items: center; + text-decoration: none; +} + +.app-brand-logo { + width: 186px; + max-width: 100%; + height: auto; + display: block; +} + +.app-header-actions { + display: flex; + margin-left: auto; + flex: 0 0 auto; + gap: 8px; + flex-wrap: wrap; + justify-content: flex-end; + align-items: center; +} + +.app-lang-switch { + display: flex; + gap: 6px; +} + +.app-lang-btn { + border: 1px solid var(--app-line); + background: #f8fbff; + color: #1f3a5f; + border-radius: 999px; + padding: 6px 10px; + font-size: 12px; + font-weight: 700; + cursor: pointer; +} + +.app-lang-btn.active { + background: var(--app-brand-blue); + border-color: var(--app-brand-blue); + color: #fff; +} + +.shell, +.wrap, +.top-wrap { + width: min(var(--app-shell-width), 100%) !important; + max-width: none !important; + margin-left: auto !important; + margin-right: auto !important; +} + +@media (max-width: 900px) { + .app-header, + .app-header-in-shell { + flex-direction: column; + align-items: stretch; + } + + .app-header-actions { + justify-content: flex-start; + } +} diff --git a/backend/workflows/static/workflows/css/offboarding_form.css b/backend/workflows/static/workflows/css/offboarding_form.css index 56fded5..34a1a12 100644 --- a/backend/workflows/static/workflows/css/offboarding_form.css +++ b/backend/workflows/static/workflows/css/offboarding_form.css @@ -7,10 +7,12 @@ body { radial-gradient(900px 520px at 92% 0%, #eef4ff, transparent), #edf2fb; } -.wrap { max-width: 920px; margin: 0 auto; } +.wrap { width: min(var(--app-shell-width), 100%); margin: 0 auto; background: #ffffff; border: 1px solid #d8e1ee; border-radius: 20px; box-shadow: 0 20px 44px rgba(16, 32, 57, 0.13); overflow: hidden; } +.wrap-body { padding: 18px; } .brand-logo { width: 180px; max-width: 100%; height: auto; margin: 0 0 10px; display: block; } .top-link { margin-bottom: 10px; } .card { background: linear-gradient(180deg, #ffffff, #fbfcff); border: 1px solid #d9dcf3; border-radius: 14px; padding: 18px; margin-bottom: 14px; box-shadow: 0 10px 24px rgba(0, 0, 120, 0.08); } +.wrap-body .card:last-child { margin-bottom: 0; } h1 { margin-top: 0; color: #000078; } .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; } .field { margin-bottom: 12px; } diff --git a/backend/workflows/static/workflows/css/onboarding_form.css b/backend/workflows/static/workflows/css/onboarding_form.css index b095902..a787442 100644 --- a/backend/workflows/static/workflows/css/onboarding_form.css +++ b/backend/workflows/static/workflows/css/onboarding_form.css @@ -25,15 +25,24 @@ body { } .shell { - max-width: 1120px; + width: min(var(--app-shell-width), 100%); margin: 0 auto; + background: var(--card); + border: 1px solid var(--line); + border-radius: 20px; + box-shadow: 0 20px 44px rgba(16, 32, 57, 0.13); + overflow: hidden; +} + +.shell-body { display: grid; grid-template-columns: 290px 1fr; gap: 16px; + padding: 18px; } .top-wrap { - max-width: 1120px; + width: min(var(--app-shell-width), 100%); margin: 0 auto 10px; } @@ -172,7 +181,9 @@ h1 { } .section-itsetup { - background: linear-gradient(160deg, #ffffff, #f7faff); + background: linear-gradient(180deg, #ffffff 0%, #f9fbff 100%); + border-color: #d5e2f9; + box-shadow: 0 10px 24px rgba(15, 42, 84, 0.08); } .section-abschluss { @@ -198,6 +209,23 @@ h1 { font-size: 13px; } +.section-itsetup .section-head { + margin: -14px -14px 16px; + padding: 12px 14px; + border-bottom: 1px solid #d5e2f9; + background: #eef4ff; + border-top-left-radius: 14px; + border-top-right-radius: 14px; +} + +.section-itsetup .section-head h2 { + color: #1f376b; +} + +.section-itsetup .section-head p { + color: #5e7088; +} + .grid-2 { display: grid; grid-template-columns: 1fr 1fr; @@ -224,6 +252,107 @@ h1 { margin-bottom: 0; } +.section-itsetup .field-group { + border: 1px solid #d7e0ea; + border-radius: 14px; + background: #ffffff; + padding: 14px; +} + +.section-itsetup .field-group.hidden { + display: none; +} + +.section-itsetup .field:not(.field-full) { + border: 1px solid #d7e0ea; + border-radius: 14px; + background: #ffffff; + padding: 12px; + min-height: 118px; + display: flex; + flex-direction: column; + box-shadow: 0 4px 14px rgba(17, 52, 95, 0.04); +} + +.section-itsetup .field:not(.field-full) input, +.section-itsetup .field:not(.field-full) select, +.section-itsetup .field:not(.field-full) textarea { + margin-top: auto; +} + +.section-itsetup .field.field-full:not(.checkbox-list):not(.inline-check) { + border: 1px solid #d7e0ea; + border-radius: 14px; + background: #ffffff; + padding: 12px; + box-shadow: 0 4px 14px rgba(17, 52, 95, 0.04); +} + +.itsetup-checklist-panel { + border: 1px solid #d7e0ea; + border-radius: 12px; + overflow: hidden; + background: #ffffff; + padding: 0; + box-shadow: 0 4px 10px rgba(17, 52, 95, 0.04); +} + +.itsetup-checklist-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + padding: 12px 14px; + background: linear-gradient(180deg, #edf3ff, #e5eeff); + border-bottom: 1px solid #cad8f3; +} + +.itsetup-checklist-head h3 { + margin: 0; + font-size: 21px; + line-height: 1.2; + font-weight: 700; + color: #1f376b; +} + +.checklist-toggle-btn { + appearance: none; + border: 1px solid #6d86ca; + background: linear-gradient(180deg, #ffffff, #e9f0ff); + color: #14315f; + border-radius: 10px; + padding: 8px 12px; + font: inherit; + font-size: 12px; + font-weight: 700; + cursor: pointer; + line-height: 1; + min-height: 36px; + white-space: nowrap; + box-shadow: 0 4px 10px rgba(23, 54, 109, 0.10); + transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, transform 0.08s ease; +} + +.checklist-toggle-btn:hover { + background: linear-gradient(180deg, #ffffff, #dfe9ff); + border-color: #5d79c3; + box-shadow: 0 6px 14px rgba(23, 54, 109, 0.14); +} + +.checklist-toggle-btn:focus-visible { + outline: 3px solid rgba(0, 0, 120, 0.16); + outline-offset: 2px; +} + +.checklist-toggle-btn:active { + transform: translateY(1px); +} + +.itsetup-checklist-body { + padding: 0; + background: #ffffff; +} + label { display: block; font-weight: 600; @@ -305,6 +434,95 @@ select:focus { break-inside: avoid; } +.itsetup-checklist-body > div { + margin: 0; + padding: 0; + border: 0; + border-radius: 0; + background: #ffffff; + display: grid; + grid-template-columns: 1fr 1fr; + column-gap: 0; + row-gap: 0; +} + +.itsetup-checklist-body > [id^="id_"] { + display: grid !important; + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) !important; + column-gap: 0 !important; + row-gap: 0 !important; +} + +.itsetup-checklist-body > [id^="id_"].cols-3 { + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) !important; +} + +.itsetup-checklist-body > div > div { + margin: 0; + border-bottom: 1px solid #e6edf7; + min-width: 0; +} + +.itsetup-checklist-body > div > div label { + display: flex; + align-items: flex-start; + gap: 10px; + margin: 0; + padding: 8px 10px; + border: 0; + border-radius: 0; + background: #ffffff; + font-weight: 500; + font-size: 14px; + line-height: 1.25; + min-height: 100%; + min-width: 0; + overflow-wrap: anywhere; +} + +.itsetup-checklist-body > div > div:nth-child(odd) { + border-right: 1px solid #e6edf7; +} + +.itsetup-checklist-body > [id^="id_"].cols-3 > div:nth-child(odd) { + border-right: 0; +} + +.itsetup-checklist-body > [id^="id_"].cols-3 > div:not(:nth-child(3n)) { + border-right: 1px solid #e6edf7; +} + +.itsetup-checklist-body > div > div:last-child, +.itsetup-checklist-body > div > div:nth-last-child(2):nth-child(odd) { + border-bottom: 0; +} + +.itsetup-checklist-body > [id^="id_"].cols-3 > div:last-child, +.itsetup-checklist-body > [id^="id_"].cols-3 > div:nth-last-child(2):nth-child(3n-1), +.itsetup-checklist-body > [id^="id_"].cols-3 > div:nth-last-child(3):nth-child(3n-2) { + border-bottom: 0; +} + +.itsetup-checklist-body > div > div input[type="checkbox"] { + width: 16px; + height: 16px; + min-height: auto; + margin: 1px 0 0; + padding: 0; + accent-color: var(--brand); + box-shadow: none; +} + +.itsetup-checklist-panel .hint, +.itsetup-checklist-panel .errorlist { + margin: 0; + padding: 10px 14px 12px; +} + +.field-group .grid-2 > .field:only-child { + grid-column: 1 / -1; +} + .hint { color: var(--muted); font-size: 12px; diff --git a/backend/workflows/templates/registration/login.html b/backend/workflows/templates/registration/login.html index e59e84c..8ed8f39 100644 --- a/backend/workflows/templates/registration/login.html +++ b/backend/workflows/templates/registration/login.html @@ -6,10 +6,10 @@ {% trans "Anmeldung" %} + + {% include 'workflows/includes/app_header.html' with header_show_home=0 %}
-
- -

{% trans "Anmeldung" %}

{% trans "Bitte melden Sie sich mit Ihrem Benutzerkonto an." %}

diff --git a/backend/workflows/templates/workflows/base_shell.html b/backend/workflows/templates/workflows/base_shell.html new file mode 100644 index 0000000..96cf3b7 --- /dev/null +++ b/backend/workflows/templates/workflows/base_shell.html @@ -0,0 +1,22 @@ +{% load static i18n %} +{% get_current_language as CURRENT_LANGUAGE %} + + + + + + {% block title %}{% endblock %} + + + {% block extra_css %}{% endblock %} + {% block extra_head %}{% endblock %} + + + {% block pre_shell %}{% endblock %} +
+ {% block shell_header %}{% endblock %} + {% block shell_body %}{% endblock %} +
+ {% block extra_scripts %}{% endblock %} + + diff --git a/backend/workflows/templates/workflows/developer_handbook.html b/backend/workflows/templates/workflows/developer_handbook.html index 4c6431d..ac99da5 100644 --- a/backend/workflows/templates/workflows/developer_handbook.html +++ b/backend/workflows/templates/workflows/developer_handbook.html @@ -1,11 +1,9 @@ +{% extends 'workflows/base_shell.html' %} {% load static %} - - - - - - Developer Handbook - + +{% block title %}Developer Handbook{% endblock %} + +{% block extra_head %} - - -
- +{% endblock %} + +{% block shell_body %} + {% include 'workflows/includes/app_header.html' with header_show_home=1 header_inside_shell=1 %}

Developer Handbook

Engineering runbook for development, deployment, maintenance, and extension of the TUBCO Onboarding & Offboarding Portal.

@@ -68,6 +65,7 @@
  • /backend/config/: Django settings, WSGI, URL config
  • /backend/workflows/: application logic, views, models, tasks, templates, static assets
  • +
  • /backend/workflows/templates/workflows/base_shell.html: standard page shell for new staff-facing pages
  • /backend/media/templates/: PDF HTML templates and letterhead source files
  • /backend/media/pdfs/: generated PDF outputs on host volume
  • /backend/locale/: translation catalogs
  • @@ -193,6 +191,7 @@ docker compose exec -T web python manage.py run_staging_e2e_check
    • Use check after model/view/template changes.
    • Use targeted shell checks for render validation when changing templates or routes.
    • +
    • New pages should extend base_shell.html and keep header/frame logic out of page-local templates.
    • Use real PDF generation tests when changing PDF templates or intro/offboarding document logic.
    • Use the dedicated Release Checklist page as the final go/no-go runbook before shipping changes.
    • The automated bilingual smoke tests now cover DE/EN request language capture and English email-template rendering.
    • @@ -230,6 +229,5 @@ docker compose exec -T web python manage.py run_staging_e2e_check
    • Prefer standard framework workflows over custom one-off maintenance scripts.
    • When adding new features, document them in both the Project Wiki and this handbook if they change engineering workflow.
    -
- - + +{% endblock %} diff --git a/backend/workflows/templates/workflows/form_builder.html b/backend/workflows/templates/workflows/form_builder.html index 783a17d..7a2497f 100644 --- a/backend/workflows/templates/workflows/form_builder.html +++ b/backend/workflows/templates/workflows/form_builder.html @@ -6,14 +6,12 @@ {% trans "Form Builder" %} +
- + {% include 'workflows/includes/app_header.html' with header_show_home=1 header_inside_shell=1 %}

{% trans "Form Builder" %}

diff --git a/backend/workflows/templates/workflows/handbook.html b/backend/workflows/templates/workflows/handbook.html index 1b9a407..69b28b0 100644 --- a/backend/workflows/templates/workflows/handbook.html +++ b/backend/workflows/templates/workflows/handbook.html @@ -1,11 +1,9 @@ +{% extends 'workflows/base_shell.html' %} {% load static i18n %} - - - - - - {% trans "Handbook" %} - + +{% block title %}{% trans "Handbook" %}{% endblock %} + +{% block extra_head %} - - -
- +{% endblock %} + +{% block shell_body %} + {% include 'workflows/includes/app_header.html' with header_show_home=1 header_inside_shell=1 %}

{% trans "Handbook" %}

- {% trans "Back to Home" %}

{% trans "Single documentation entry point for both operational knowledge and long-term engineering knowledge." %}

@@ -79,6 +76,5 @@
-
- - + +{% endblock %} diff --git a/backend/workflows/templates/workflows/home.html b/backend/workflows/templates/workflows/home.html index 44d0984..fe4b887 100644 --- a/backend/workflows/templates/workflows/home.html +++ b/backend/workflows/templates/workflows/home.html @@ -7,6 +7,7 @@ {% trans "TUBCO Onboarding & Offboarding Portal" %} + -

Offboarding gespeichert

-

Vorgangs-ID: {{ obj.id }}

-

Name: {{ obj.full_name }}

-

E-Mail: {{ obj.work_email }}

-

Letzter Arbeitstag: {{ obj.last_working_day }}

- {% if pdf_url %} -

PDF: PDF öffnen

-

Datei: {{ obj.generated_pdf_path }}

- {% else %} -

PDF wird im Hintergrund erstellt.

- {% endif %} -

Zur Startseite

-

Neue Offboarding-Anfrage erfassen

+ {% include 'workflows/includes/app_header.html' with header_show_home=1 %} +
+

{% trans "Offboarding gespeichert" %}

+

{% trans "Vorgangs-ID:" %} {{ obj.id }}

+

{% trans "Name:" %} {{ obj.full_name }}

+

{% trans "E-Mail:" %} {{ obj.work_email }}

+

{% trans "Letzter Arbeitstag:" %} {{ obj.last_working_day }}

+ {% if pdf_url %} +

{% trans "PDF:" %} {% trans "PDF öffnen" %}

+

{% trans "Datei:" %} {{ obj.generated_pdf_path }}

+ {% else %} +

{% trans "PDF wird im Hintergrund erstellt." %}

+ {% endif %} + +
diff --git a/backend/workflows/templates/workflows/onboarding_form.html b/backend/workflows/templates/workflows/onboarding_form.html index 2f8bb07..b124e18 100644 --- a/backend/workflows/templates/workflows/onboarding_form.html +++ b/backend/workflows/templates/workflows/onboarding_form.html @@ -7,6 +7,7 @@ {% trans "Onboarding-Anfrage" %} + @@ -18,21 +19,11 @@ -
- - -
-
-