feat(umpires): move umpires between 3 lists by drag-and-drop

This commit is contained in:
2026-05-27 16:54:51 +02:00
parent 03bfc8fc16
commit 71c3733363
10 changed files with 508 additions and 11 deletions
+85 -5
View File
@@ -1,17 +1,97 @@
<ion-header [translucent]="true">
<ion-toolbar>
<ion-title>
Tab 1
</ion-title>
<ion-title> Pályák </ion-title>
</ion-toolbar>
</ion-header>
<ion-content [fullscreen]="true">
<ion-header collapse="condense">
<ion-toolbar>
<ion-title size="large">Tab 1</ion-title>
<ion-title size="large">Pályák</ion-title>
</ion-toolbar>
</ion-header>
<app-explore-container name="Tab 1 page"></app-explore-container>
<ion-grid [fixed]="'fixed'">
<ion-row>
<ion-col [size]="1">Pálya</ion-col>
<ion-col>Játékvezető</ion-col>
<ion-col>Adogatásbíró</ion-col>
</ion-row>
@for (item of [].constructor(settings()?.numberOfCourts); track $index) {
<ion-row>
<ion-col [size]="1">{{ $index + 1 }}.</ion-col>
<ion-col>név1</ion-col>
<ion-col>név2</ion-col>
</ion-row>
}
</ion-grid>
<ion-grid [fixed]="'fixed'" class="ion-margin-top">
<ion-row>
<ion-col [size]="4">Játékvezetők</ion-col>
<ion-col [size]="4">Adogatásbírók</ion-col>
<ion-col [size]="4">Pihenők</ion-col>
</ion-row>
<ion-row>
<ion-col>
<ion-list
[lines]="'none'"
cdkDropList
cdkDropListSortingDisabled
id="list-waiting-umpires"
[cdkDropListData]="waitingUmpires"
(cdkDropListDropped)="dropToWaitingUmpire($event)"
[cdkDropListConnectedTo]="['list-on-rest', 'list-waiting-service-judges']">
@for (umpire of waitingUmpires; track umpire.id) {
<ion-item cdkDrag [cdkDragData]="umpire">
<ion-label>{{ umpire|fullname }}</ion-label>
</ion-item>
} @empty {
<ion-item>
<ion-label class="ion-text-center">
<ion-icon [color]="'primary'" name="add"></ion-icon>
</ion-label>
</ion-item>
}
</ion-list>
</ion-col>
<ion-col>
<ion-list
[lines]="'none'"
cdkDropList
cdkDropListSortingDisabled
id="list-waiting-service-judges"
[cdkDropListData]="waitingServiceJudges"
(cdkDropListDropped)="dropToWaitingServiceJudge($event)"
[cdkDropListConnectedTo]="['list-on-rest', 'list-waiting-umpires']">
@for (umpire of waitingServiceJudges; track umpire.id) {
<ion-item cdkDrag [cdkDragData]="umpire">
<ion-label>{{ umpire|fullname }}</ion-label>
</ion-item>
} @empty {
<ion-item>
<ion-label class="ion-text-center">
<ion-icon [color]="'primary'" name="add"></ion-icon>
</ion-label>
</ion-item>
}
</ion-list>
</ion-col>
<ion-col>
<ion-list
[lines]="'none'"
cdkDropList
cdkDropListSortingDisabled
id="list-on-rest"
(cdkDropListDropped)="dropToRest($event)"
[cdkDropListData]="onRest"
[cdkDropListConnectedTo]="['list-waiting-service-judges', 'list-waiting-umpires']">
@for (umpire of onRest; track umpire.id) {
<ion-item cdkDrag [cdkDragData]="umpire">
<ion-label>{{ umpire|fullname }}</ion-label>
</ion-item>
}
</ion-list>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>
+158 -5
View File
@@ -1,13 +1,166 @@
import { Component } from '@angular/core';
import { IonHeader, IonToolbar, IonTitle, IonContent } from '@ionic/angular/standalone';
import { ExploreContainerComponent } from '../explore-container/explore-container.component';
import { Component, effect, inject } from '@angular/core';
import {
IonHeader,
IonToolbar,
IonTitle,
IonContent,
IonGrid,
IonCol,
IonRow,
IonList,
IonItem,
IonLabel,
IonIcon
} from '@ionic/angular/standalone';
import { SettingsService } from '../services/settings-service';
import { UmpireService } from '../services/umpire.service';
import { Umpire, WaitingAsServiceJudge, WaitingAsUmpire } from 'db';
import { WaitingUmpiresService } from '../services/waiting-umpires.service';
import { WaitingServiceJudgesService } from '../services/waiting-service-judges.service';
import { FullnamePipe } from '../fullname-pipe';
import {
CdkDrag,
CdkDragDrop,
CdkDropList,
DragDropModule
} from '@angular/cdk/drag-drop';
import { CommonModule } from '@angular/common';
import { addIcons } from 'ionicons';
import { add } from 'ionicons/icons';
@Component({
selector: 'app-tab1',
templateUrl: 'tab1.page.html',
styleUrls: ['tab1.page.scss'],
imports: [IonHeader, IonToolbar, IonTitle, IonContent, ExploreContainerComponent],
imports: [
IonIcon,
IonLabel,
IonItem,
IonList,
IonRow,
IonCol,
IonGrid,
IonHeader,
IonToolbar,
IonTitle,
IonContent,
FullnamePipe,
CdkDropList,
CdkDrag,
CommonModule,
DragDropModule
]
})
export class Tab1Page {
constructor() {}
readonly settingsService = inject(SettingsService);
readonly umpireService = inject(UmpireService);
readonly waitingUmpireService = inject(WaitingUmpiresService);
readonly waitingServiceJudgeService = inject(WaitingServiceJudgesService);
public readonly settings = this.settingsService.settings;
public readonly _umpires = this.umpireService.umpires;
public readonly _waitingUmpires = this.waitingUmpireService.waitingUmpires;
public readonly _waitingServiceJudges =
this.waitingServiceJudgeService.waitingServiceJudges;
public onRest: Umpire[] = [];
public waitingUmpires: Umpire[] = [];
public waitingServiceJudges: Umpire[] = [];
constructor() {
addIcons({ add });
effect(() => {
this.onRest = this._umpires().filter((umpire) => {
return (
!this.isUmpireOnCourt(umpire) &&
!this.isWaitingUmpire(umpire) &&
!this.isWaitingServiceJudge(umpire)
);
});
this.waitingUmpires = this._waitingUmpires()
.map((_wa) => {
return this._umpires().find((u) => u.id === _wa.umpireId);
})
.filter((u) => typeof u !== 'undefined');
this.waitingServiceJudges = this._waitingServiceJudges()
.map((_wsj) => {
return this._umpires().find((u) => u.id === _wsj.serviceJudgeId);
})
.filter((u) => typeof u !== 'undefined');
});
}
private isUmpireOnCourt(umpire: Umpire): boolean {
return false;
}
private isWaitingUmpire(umpire: Umpire): boolean {
return (
typeof this._waitingUmpires().find((wu) => wu.umpireId === umpire.id) !==
'undefined'
);
}
private isWaitingServiceJudge(umpire: Umpire): boolean {
return (
typeof this._waitingServiceJudges().find(
(wsj) => wsj.serviceJudgeId === umpire.id
) !== 'undefined'
);
}
dropToRest(event: CdkDragDrop<Umpire[]>) {
if (event.previousContainer === event.container) {
return;
} else {
const comingFrom = event.previousContainer.id;
const umpireToMove = event.item.data;
if ('list-waiting-service-judges' === comingFrom) {
// Remove from waiting service judges
this.waitingServiceJudgeService.removeByUmpireId(umpireToMove.id);
}
if ('list-waiting-umpires' === comingFrom) {
this.waitingUmpireService.removeByUmpireId(umpireToMove.id);
}
}
}
dropToWaitingServiceJudge(event: CdkDragDrop<Umpire[]>) {
if (event.previousContainer === event.container) {
// TODO
} else {
const comingFrom = event.previousContainer.id;
const umpireToMove = event.item.data;
this.waitingServiceJudgeService.add(umpireToMove.id);
if ('list-waiting-umpires' === comingFrom) {
this.waitingUmpireService.removeByUmpireId(umpireToMove.id);
}
}
}
dropToWaitingUmpire(event: CdkDragDrop<Umpire[]>) {
console.log(
event.container.data,
event.previousContainer.data,
event.previousContainer.id,
event.container.id
);
if (event.previousContainer === event.container) {
// TODO
} else {
const comingFrom = event.previousContainer.id;
const umpireToMove = event.item.data;
this.waitingUmpireService.add(umpireToMove.id);
if ('list-waiting-service-judges' === comingFrom) {
// Remove from waiting service judges
this.waitingServiceJudgeService.removeByUmpireId(umpireToMove.id);
}
}
}
}