This commit is contained in:
Andras Schmelczer 2026-05-30 14:33:39 +01:00
parent e2a60e71a3
commit 003f38ea60
36 changed files with 1543 additions and 1287 deletions

View file

@ -7,7 +7,7 @@
@for (tower of page().towers; track tower.id) {
<lt-tower
cdkDrag
[cdkDragDisabled]="modalOpen()"
[cdkDragDisabled]="modalOpen() || mobileDragDisabled()"
[tower]="tower"
[dateRange]="dateRange()"
[keepTasksOpen]="page().keep_tasks_open"
@ -48,7 +48,7 @@
@if (showAddTower()) {
<lt-modal title="New Tower" (close)="showAddTower.set(false)">
<lt-tower-settings [tower]="null" (save)="onAddTower($event)" />
<lt-tower-settings [tower]="null" (save)="onAddTower($event)" (close)="showAddTower.set(false)" />
</lt-modal>
}

View file

@ -5,6 +5,7 @@
flex-direction: column;
height: 100%;
min-height: 0;
position: relative; // anchor for absolute-positioned .trash
@include inner-spacing(var(--large-padding));
@ -18,10 +19,12 @@
justify-content: center;
width: 100%;
box-sizing: border-box;
margin-left: auto;
margin-right: auto;
flex: 1 0 auto;
flex: 1 1 auto;
min-height: 0;
transition: box-shadow $short-animation-time;
@ -55,6 +58,7 @@
max-width: 200px;
box-sizing: content-box;
flex: 0 0 auto;
min-height: 0;
&:not(:nth-last-child(1)) {
margin-right: var(--medium-padding);
@ -84,15 +88,22 @@
// without needing !important on every property only the width triples need it
// to beat the per-child-count selectors generated above.
@media (max-width: $mobile-width) {
--mobile-tower-width: calc(66vw - var(--small-padding));
--mobile-tower-side-padding: max(
var(--medium-padding),
calc((100% - var(--mobile-tower-width)) / 2)
);
overflow-x: auto;
overflow-y: visible;
-webkit-overflow-scrolling: touch;
scroll-snap-type: x mandatory;
scroll-padding-inline: var(--mobile-tower-side-padding);
flex-wrap: nowrap;
justify-content: flex-start;
// Side padding lets the first and last tower scroll fully into view.
padding: 0 var(--medium-padding);
padding: 0 var(--mobile-tower-side-padding);
max-width: 100%;
gap: var(--medium-padding);
&::-webkit-scrollbar {
display: none;
@ -100,12 +111,16 @@
// Override the @for width-calc rules above.
& > * {
width: calc(66vw - var(--small-padding)) !important;
max-width: calc(66vw - var(--small-padding)) !important;
min-width: calc(66vw - var(--small-padding)) !important;
scroll-snap-align: start;
width: var(--mobile-tower-width) !important;
max-width: var(--mobile-tower-width) !important;
min-width: var(--mobile-tower-width) !important;
scroll-snap-align: center;
flex-shrink: 0;
}
& > *:not(:nth-last-child(1)) {
margin-right: 0;
}
}
}

View file

@ -5,6 +5,7 @@ import {
output,
signal,
inject,
HostListener,
} from '@angular/core';
import { Page } from '../../models';
import { StoreService } from '../../services/store.service';
@ -66,6 +67,7 @@ export class PageComponent {
private readonly modalState = inject(ModalStateService);
/** True while any lt-modal is mounted — used to lock tower drag. */
readonly modalOpen = this.modalState.anyOpen;
readonly mobileDragDisabled = signal(this.isMobileViewport());
readonly showAddTower = signal(false);
readonly isDragging = signal(false);
@ -116,6 +118,18 @@ export class PageComponent {
this.dateRange.set({ from: range.from as number, to: range.to as number });
}
@HostListener('window:resize')
onResize(): void {
this.mobileDragDisabled.set(this.isMobileViewport());
}
private isMobileViewport(): boolean {
return (
typeof window !== 'undefined' &&
window.matchMedia('(max-width: 520px), (pointer: coarse)').matches
);
}
// ── Tower mutations ────────────────────────────────────────────────────────
onAddTower(result: TowerSettingsResult): void {