diff --git a/app/controllers/api/v1/admin/database_controller.rb b/app/controllers/api/v1/admin/database_controller.rb index b601cd7..d270bbd 100644 --- a/app/controllers/api/v1/admin/database_controller.rb +++ b/app/controllers/api/v1/admin/database_controller.rb @@ -30,7 +30,7 @@ module Api File.binwrite(uploaded_path, upload.read) sql_path = extract_sql(uploaded_path, directory) restore_path = build_atomic_restore_file(sql_path, directory) - Rails.logger.info("Atomic database restore v2026.08.16.8 using #{File.basename(restore_path)}") + Rails.logger.info("Atomic database restore v2026.08.18.1 using #{File.basename(restore_path)}") run_database_command!(psql_command(restore_path)) # The restored schema invalidates prepared statements and the schema # cache of already open Rails connections. Reconnect cleanly before diff --git a/config/initializers/build_version.rb b/config/initializers/build_version.rb index fc4f820..0b1e326 100644 --- a/config/initializers/build_version.rb +++ b/config/initializers/build_version.rb @@ -1,2 +1,2 @@ -Rails.application.config.x.build_version = "2026.08.16.8" -Rails.logger.info("Praktikum API build 2026.08.16.8 loaded") +Rails.application.config.x.build_version = "2026.08.18.1" +Rails.logger.info("Praktikum API build 2026.08.18.1 loaded") diff --git a/docker-compose.yml b/docker-compose.yml index a2c092d..408c52d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,5 @@ version: "2.4" + services: db: image: postgres:17 diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts index f42dd84..b3d0cae 100644 --- a/frontend/src/app/app.component.ts +++ b/frontend/src/app/app.component.ts @@ -77,7 +77,7 @@ import { ApiService } from "./core/api.service"; - Build 2026.08.16.8 + Build 2026.08.18.1 }
+ > @for (e of forDay(day.key); track e.id) { - {{ e.entry_art }}{{ e.hours }}h {{ e.minutes }}min @@ -75,6 +75,7 @@ import { Entry } from "../core/models"; ` .calendar { overflow: hidden; + min-width: 0; } .calendar-filters { margin-bottom:18px; } .calendar-filters mat-card-content { display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding-bottom:0; } @@ -83,7 +84,8 @@ import { Entry } from "../core/models"; .weekdays, .days { display: grid; - grid-template-columns: repeat(7, 1fr); + grid-template-columns: repeat(7, minmax(0, 1fr)); + min-width: 0; } .weekdays { padding: 14px; @@ -93,9 +95,11 @@ import { Entry } from "../core/models"; } .day { min-height: 145px; + min-width: 0; padding: 8px; border-top: 1px solid #e1e6ef; border-right: 1px solid #e1e6ef; + overflow: hidden; } .day-head { display: flex; @@ -123,6 +127,10 @@ import { Entry } from "../core/models"; .event { display: flex; flex-direction: column; + width: 100%; + min-width: 0; + max-width: 100%; + overflow: hidden; text-decoration: none; color: inherit; background: #dce9ff; @@ -136,10 +144,29 @@ import { Entry } from "../core/models"; opacity: 0.75; margin-top: 2px; } + .event strong, + .event span { + display: block; + min-width: 0; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } .event.type-propaedeutikum { background:rgba(13,110,253,.14);border-left-color:#0d6efd; } .event.type-fachspezifikum { background:rgba(25,135,84,.14);border-left-color:#198754; } .event.type-mediation { background:rgba(253,126,20,.16);border-left-color:#fd7e14; } @media (max-width: 700px) { + .calendar-filters mat-card-content { + gap: 8px; + padding: 12px 12px 0; + } + .calendar-filters mat-form-field { + width: 100%; + min-width: 0; + } + .weekdays { + padding: 9px 0; + } .weekdays strong { font-size: 0; } @@ -147,17 +174,63 @@ import { Entry } from "../core/models"; font-size: 13px; } .day { - min-height: 90px; - padding: 4px; + min-height: 92px; + padding: 4px 3px; + } + .day-head a { + width: 30px; + height: 30px; + padding: 3px; + transform: none; + } + .day-head mat-icon { + width: 20px; + height: 20px; + font-size: 20px; + line-height: 20px; } - .event strong { - overflow: hidden; - text-overflow: ellipsis; + .event { + padding: 4px; + border-left-width: 2px; + font-size: 11px; } .event span { display: none; } } + @media (max-width: 480px) { + .weekdays strong:first-letter { + font-size: 11px; + } + .day { + min-height: 78px; + padding: 3px 2px; + } + .day-head { + font-size: 12px; + } + .day-head a { + width: 24px; + height: 24px; + padding: 2px; + } + .day-head mat-icon { + width: 18px; + height: 18px; + font-size: 18px; + line-height: 18px; + } + .today .day-head > span { + width: 24px; + height: 24px; + } + .event { + margin: 3px 0; + padding: 3px 2px; + border-radius: 4px; + font-size: 10px; + } + } `, ], }) diff --git a/frontend/src/app/pages/entries.component.ts b/frontend/src/app/pages/entries.component.ts index 2d12268..8a366fd 100644 --- a/frontend/src/app/pages/entries.component.ts +++ b/frontend/src/app/pages/entries.component.ts @@ -125,7 +125,7 @@ import { Dashboard, Entry } from "../core/models"; margin-bottom: 20px; } .entries-page { - max-width: 1680px; + max-width: 1720px; } .timer-card { margin-bottom: 20px; } .timer-card mat-card-content { display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap; } diff --git a/frontend/src/styles.scss b/frontend/src/styles.scss index 805de3b..9778662 100644 --- a/frontend/src/styles.scss +++ b/frontend/src/styles.scss @@ -43,7 +43,7 @@ h1,h2,h3,h4,h5,h6 { color:var(--app-text); letter-spacing:-.025em; } .mat-mdc-option,.mat-mdc-table,.mat-mdc-dialog-container,.mat-mdc-card,.mat-mdc-menu-panel, .mat-toolbar,.mat-mdc-checkbox,.mat-mdc-snack-bar-container,.cdk-overlay-container { font-family:$font !important; } .page { - max-width:1480px; + max-width:1720px; min-height:0 !important; height:auto !important; margin:0 auto; @@ -77,4 +77,4 @@ body.dark .cost-year { background:var(--app-surface-soft) !important; } .shell.mat-drawer-container { height:100dvh; min-height:0; overflow:hidden; } .shell .mat-drawer-inner-container { overflow:hidden; } .shell .mat-drawer-content { height:100%; min-height:0; overflow-y:auto; overflow-x:hidden; } -@media(max-width:700px){.page{padding:20px 12px 36px}.page-head{align-items:flex-start;flex-direction:column}.hide-mobile{display:none!important}} +@media(max-width:700px){.page{padding:20px 10px 36px}.page-head{align-items:flex-start;flex-direction:column}.hide-mobile{display:none!important}}