Browse Source

minor UI fixes

main
Christoph Marzell 1 month ago
parent
commit
f0be914caa
  1. 2
      app/controllers/api/v1/admin/database_controller.rb
  2. 4
      config/initializers/build_version.rb
  3. 1
      docker-compose.yml
  4. 2
      frontend/src/app/app.component.ts
  5. 89
      frontend/src/app/pages/calendar.component.ts
  6. 2
      frontend/src/app/pages/entries.component.ts
  7. 4
      frontend/src/styles.scss

2
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

4
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")

1
docker-compose.yml

@ -1,4 +1,5 @@
version: "2.4"
services:
db:
image: postgres:17

2
frontend/src/app/app.component.ts

@ -77,7 +77,7 @@ import { ApiService } from "./core/api.service";
<button mat-button (click)="logout()">
<mat-icon>logout</mat-icon> Abmelden
</button>
<small class="build-version">Build 2026.08.16.8</small>
<small class="build-version">Build 2026.08.18.1</small>
</div>
</div>
</mat-sidenav

89
frontend/src/app/pages/calendar.component.ts

@ -39,7 +39,7 @@ import { Entry } from "../core/models";
<mat-progress-bar mode="indeterminate" />
}
<mat-card class="calendar"
><div class="weekdays">
><div class="weekdays" aria-hidden="true">
@for (d of weekdays; track d) {
<strong>{{ d }}</strong>
}
@ -61,7 +61,7 @@ import { Entry } from "../core/models";
>
</div>
@for (e of forDay(day.key); track e.id) {
<a class="event" [class]="'event ' + typeClass(e.praktikums_typ)" [routerLink]="['/entries', e.id, 'edit']"
<a class="event" [class]="'event ' + typeClass(e.praktikums_typ)" [routerLink]="['/entries', e.id, 'edit']" [attr.aria-label]="e.entry_art + ', ' + e.hours + ' Stunden ' + e.minutes + ' Minuten'"
><strong>{{ e.entry_art }}</strong
><span>{{ e.hours }}h {{ e.minutes }}min</span></a
>
@ -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;
}
}
`,
],
})

2
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; }

4
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}}
Loading…
Cancel
Save