v1
This commit is contained in:
17
src/app/pages/aviso/aviso-routing.module.ts
Normal file
17
src/app/pages/aviso/aviso-routing.module.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
import { AvisoPage } from './aviso.page';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: AvisoPage
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class AvisoPageRoutingModule {}
|
||||
23
src/app/pages/aviso/aviso.module.ts
Normal file
23
src/app/pages/aviso/aviso.module.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
|
||||
import { AvisoPageRoutingModule } from './aviso-routing.module';
|
||||
import { AutoResizeTextDirective } from '../../directives/auto-resize-text.directive';
|
||||
|
||||
import { AvisoPage } from './aviso.page';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
IonicModule,
|
||||
AvisoPageRoutingModule
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
declarations: [AvisoPage, AutoResizeTextDirective]
|
||||
})
|
||||
export class AvisoPageModule {}
|
||||
96
src/app/pages/aviso/aviso.page.html
Normal file
96
src/app/pages/aviso/aviso.page.html
Normal file
@@ -0,0 +1,96 @@
|
||||
|
||||
<ion-content fullscreen>
|
||||
<!-- Titel für Arrivals -->
|
||||
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title class="ion-text-center">
|
||||
Ankünfte ({{ totalArrivals }}) Seite {{ currentPageIndex + 1 }} von {{ pages.length }}
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<!-- Fehlernachricht anzeigen -->
|
||||
<ion-grid>
|
||||
<ion-row *ngIf="errorMessage">
|
||||
<ion-col size="12" class="ion-text-center">
|
||||
<ion-text color="danger">
|
||||
<p>{{ errorMessage }}</p>
|
||||
</ion-text>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
|
||||
<!-- Ladeindikator -->
|
||||
<ion-row *ngIf="loadingArrivals && arrivals.length === 0">
|
||||
<ion-col size="12" class="ion-text-center">
|
||||
<ion-spinner name="crescent"></ion-spinner>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
|
||||
<!-- Grid-Container für Arrivals Kacheln -->
|
||||
<div class="grid-container" *ngIf="!loadingArrivals && pages.length > 0">
|
||||
<ion-card *ngFor="let aviso of pages[currentPageIndex]"
|
||||
class="arrival-card"
|
||||
[ngClass]="getStatusClass(aviso.status)">
|
||||
<ion-card-header>
|
||||
<ion-card-title class="ion-text-center">
|
||||
<strong>{{ aviso.lkW_Nr }}</strong>
|
||||
</ion-card-title>
|
||||
</ion-card-header>
|
||||
<ion-card-content>
|
||||
<!-- Zentrierter Absatz für Ankunft und Dauer -->
|
||||
<div class="centered-content">
|
||||
<p class="ion-text-center">
|
||||
<ion-icon [name]="getStatusIcon(aviso.status)"
|
||||
[color]="getStatusColor(aviso.status)"></ion-icon>
|
||||
{{ aviso.ankunft }}
|
||||
<ion-icon name="hourglass-outline"></ion-icon>
|
||||
{{ aviso.dauer }}
|
||||
</p>
|
||||
<p class="ion-text-center">
|
||||
<ion-icon name="person-outline"></ion-icon>
|
||||
{{ aviso.letzterMitarbeiter }}
|
||||
</p>
|
||||
</div>
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</div>
|
||||
|
||||
<!-- Nachricht, wenn keine Arrivals vorhanden sind -->
|
||||
<ion-grid>
|
||||
<ion-row *ngIf="!loadingArrivals && arrivals.length === 0 && !errorMessage">
|
||||
<ion-col size="12" class="ion-text-center">
|
||||
<ion-text>
|
||||
<p>Keine Ankünfte gefunden.</p>
|
||||
</ion-text>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
|
||||
<!-- Bedingtes Textfeld für TV-Einstellungen -->
|
||||
|
||||
</ion-content>
|
||||
|
||||
<ion-footer>
|
||||
<ng-container *ngFor="let setting of avisoTvSettings; let i = index">
|
||||
<ng-container *ngIf="setting.isActive && setting.fixeZeile1">
|
||||
<ion-item>
|
||||
<!-- Erstes Div, wird angezeigt, wenn showFirstDiv true ist -->
|
||||
<div *ngIf="showFirstDiv"
|
||||
[innerHTML]="sanitizeHtml(setting.fixeZeile1 || '',i)"
|
||||
autoResizeText
|
||||
[style.text-align]="getTextAlign(i)"
|
||||
class="htmltext">
|
||||
</div>
|
||||
|
||||
<!-- Zweites Div, wird angezeigt, wenn showFirstDiv false ist -->
|
||||
<div *ngIf="!showFirstDiv"
|
||||
[innerHTML]="sanitizeHtml(setting.fixeZeile2 || '',i)"
|
||||
autoResizeText
|
||||
[style.text-align]="getTextAlign(i)"
|
||||
class="htmltext">
|
||||
</div>
|
||||
</ion-item>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</ion-footer>
|
||||
149
src/app/pages/aviso/aviso.page.scss
Normal file
149
src/app/pages/aviso/aviso.page.scss
Normal file
@@ -0,0 +1,149 @@
|
||||
|
||||
|
||||
ion-content {
|
||||
--background: #f0f0f0; /* Heller Hintergrund für besseren Kontrast */
|
||||
}
|
||||
|
||||
.title-card {
|
||||
background-color: #3880ff; /* Beispiel: Blaue Hintergrundfarbe */
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
ion-card-content p {
|
||||
font-size: 1.8em; /* Größere Schriftgröße für die Inhalte */
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.grid-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(15%, 1fr)); /* Feste Mindestbreite */
|
||||
gap: 1%; /* Abstand zwischen den Kacheln */
|
||||
padding: 0px; /* Optional: Innenabstand */
|
||||
justify-content: center; /* Zentriert die Kacheln */
|
||||
}
|
||||
|
||||
.arrival-card {
|
||||
width: 95%; /* Feste Breite */
|
||||
height: 24vh; /* Feste Höhe */
|
||||
border-radius: 15px; /* Abgerundete Ecken für ein moderneres Aussehen */
|
||||
transition: box-shadow 0.3s, transform 0.3s;
|
||||
}
|
||||
|
||||
.htmltext {
|
||||
height: 30vh;
|
||||
width: 100%;
|
||||
white-space: pre-line;
|
||||
transition: box-shadow 0.3s, transform 0.3s;
|
||||
}
|
||||
ion-content {
|
||||
ion-grid.htmltext {
|
||||
height: 30vh;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ion-icon {
|
||||
vertical-align: middle;
|
||||
font-size: 1.2em; /* Größere Icons für bessere Sichtbarkeit */
|
||||
}
|
||||
|
||||
/* Statusklassen */
|
||||
.statusLKW_Erfasst {
|
||||
border-left: 10px solid #2dd36f; /* Grün */
|
||||
}
|
||||
|
||||
.statusLKW_Freigegeben {
|
||||
border-left: 10px solid #3880ff; /* Blau */
|
||||
}
|
||||
|
||||
.statusLKW_LKW_neu {
|
||||
border-left: 10px solid #f78c40; /* Orange */
|
||||
}
|
||||
|
||||
.statusLKW_Ankunft {
|
||||
border-left: 10px solid #f78c40; /* Orange */
|
||||
}
|
||||
|
||||
.statusLKW_Vorbereitet {
|
||||
border-left: 10px solid #c8c8c8; /* Grau */
|
||||
}
|
||||
|
||||
.statusLKW_Vorgeschrieben {
|
||||
border-left: 10px solid #a259ff; /* Violett */
|
||||
}
|
||||
|
||||
.status-default {
|
||||
border-left: 10px solid #c8c8c8; /* Grau */
|
||||
}
|
||||
|
||||
/* Animationen für Ankunftskarten */
|
||||
.arrival-card {
|
||||
animation: fadeIn 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
ion-card-title {
|
||||
font-size: 3.5em;
|
||||
}
|
||||
|
||||
ion-card-content p {
|
||||
font-size: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
ion-text p {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 2.5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.card-title ion-icon {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
ion-footer {
|
||||
background-color: #ffffff;
|
||||
border-top: 1px solid #c8c8c8;
|
||||
}
|
||||
|
||||
ion-toolbar {
|
||||
--padding-start: 0;
|
||||
--padding-end: 0;
|
||||
}
|
||||
|
||||
ion-title {
|
||||
font-size: 1.6em;
|
||||
font-weight: bold;
|
||||
color: #3880ff;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
ion-title {
|
||||
font-size: 1.4em;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
17
src/app/pages/aviso/aviso.page.spec.ts
Normal file
17
src/app/pages/aviso/aviso.page.spec.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { AvisoPage } from './aviso.page';
|
||||
|
||||
describe('AvisoPage', () => {
|
||||
let component: AvisoPage;
|
||||
let fixture: ComponentFixture<AvisoPage>;
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AvisoPage);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
484
src/app/pages/aviso/aviso.page.ts
Normal file
484
src/app/pages/aviso/aviso.page.ts
Normal file
@@ -0,0 +1,484 @@
|
||||
import {
|
||||
Component,OnInit,OnDestroy,HostListener,ChangeDetectorRef
|
||||
} from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { AvisoService, AvisoArrivalsResponse } from '../../services/aviso.service';
|
||||
import { AvisoDto } from '../../services/aviso.dto';
|
||||
import { AvisoTvSettingsDto } from '../../services/aviso-tv-settings.dto';
|
||||
import { ToastController } from '@ionic/angular';
|
||||
import { interval, Subject } from 'rxjs';
|
||||
import { switchMap, takeUntil, startWith } from 'rxjs/operators';
|
||||
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||
|
||||
@Component({
|
||||
selector: 'app-aviso',
|
||||
templateUrl: './aviso.page.html',
|
||||
styleUrls: ['./aviso.page.scss'],
|
||||
})
|
||||
export class AvisoPage implements OnInit, OnDestroy {
|
||||
|
||||
|
||||
standort: string = '';
|
||||
seiten: boolean = false;
|
||||
onlyOK: boolean = false;
|
||||
|
||||
// Datenmodelle
|
||||
arrivals: AvisoDto[] = [];
|
||||
avisoTvSettings: AvisoTvSettingsDto[] = []; // Neues Datenmodell
|
||||
|
||||
// Paginierung
|
||||
pages: AvisoDto[][] = [];
|
||||
currentPageIndex: number = 0;
|
||||
tilesPerPage: number = 0;
|
||||
|
||||
// Ladezustand
|
||||
loadingArrivals: boolean = false;
|
||||
loadingSettings: boolean = false; // Ladezustand für Einstellungen
|
||||
|
||||
// Gesamtanzahl
|
||||
totalArrivals: number = 0;
|
||||
totalSettings: number = 0; // Gesamtanzahl für Einstellungen
|
||||
|
||||
// Fehlernachricht
|
||||
errorMessage: string = '';
|
||||
settingsErrorMessage: string = ''; // Fehlernachricht für Einstellungen
|
||||
|
||||
// Subjects zum Beenden der Subscriptions
|
||||
private destroy$ = new Subject<void>();
|
||||
private pageRotation$ = new Subject<void>(); // Optional, für separate Page Rotation
|
||||
|
||||
// Feste Kachelgrößen (entsprechend den CSS-Einstellungen)
|
||||
private readonly tileWidth: number = 450; // in px
|
||||
private readonly tileHeight: number = 100; // in px
|
||||
private readonly gutter: number = 0; // Abstand zwischen den Kacheln in px
|
||||
private readonly containerPadding: number = 0; // Innenabstand des Grid-Containers in px
|
||||
public fontSettings: {textAlign: string}[] = [];
|
||||
private toggleDivInterval: any;
|
||||
showFirstDiv: boolean = true;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private avisoService: AvisoService,
|
||||
private toastController: ToastController,
|
||||
private cdr: ChangeDetectorRef,
|
||||
private sanitizer: DomSanitizer
|
||||
) { }
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Sanitizes HTML, extracts font size and text align from span elements,
|
||||
* and stores them in dataset attributes and the fontSettings array.
|
||||
* @param html Das zu sanitizende HTML
|
||||
* @param index Index der Einstellung zur Zuordnung der Stilinformationen
|
||||
* @returns Sanitized HTML als SafeHtml
|
||||
*/
|
||||
sanitizeHtml(html: string, index: number): SafeHtml {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(html, 'text/html');
|
||||
const spans = doc.querySelectorAll('div');
|
||||
|
||||
spans.forEach(span => {
|
||||
const fontSize = span.style.fontSize;
|
||||
|
||||
if (fontSize) {
|
||||
|
||||
let fontSizePx: number;
|
||||
if (fontSize.endsWith('pt')) {
|
||||
fontSizePx = parseFloat(fontSize) * 1.333; // Umrechnung von pt zu px
|
||||
} else if (fontSize.endsWith('px')) {
|
||||
fontSizePx = parseFloat(fontSize);
|
||||
} else {
|
||||
// Andere Einheiten oder Standardfall
|
||||
fontSizePx = parseFloat(fontSize);
|
||||
}
|
||||
|
||||
const textAlign = span.style.textAlign || 'left';
|
||||
|
||||
// Speichern der ursprünglichen Schriftgröße und Textausrichtung
|
||||
this.fontSettings[index] = {
|
||||
textAlign: textAlign
|
||||
};
|
||||
|
||||
// Speichern in dataset
|
||||
span.dataset['originalFontSizePx'] = fontSizePx.toString();
|
||||
span.dataset['originalTextAlign'] = textAlign;
|
||||
|
||||
// Debugging: Loggen der ursprünglichen Schriftgröße
|
||||
console.log(`Original Font Size for span: "${span.textContent}" = ${fontSizePx}px`);
|
||||
} else {
|
||||
// Falls keine Schriftgröße definiert ist
|
||||
console.log(`No inline font size found for span: "${span.textContent}"`);
|
||||
}
|
||||
|
||||
// Entfernen der Inline-Schriftgröße
|
||||
span.style.fontSize = '';
|
||||
|
||||
// Hinzufügen der Klasse für die dynamische Anpassung
|
||||
span.classList.add('dynamic-font-size');
|
||||
});
|
||||
|
||||
// Debugging: Loggen des bearbeiteten HTML
|
||||
console.log('Processed HTML:', doc.body.innerHTML);
|
||||
|
||||
return this.sanitizer.bypassSecurityTrustHtml(doc.body.innerHTML);
|
||||
}
|
||||
|
||||
getTextAlign(index: number): string {
|
||||
const settings = this.fontSettings[index];
|
||||
return settings ? settings.textAlign : 'left';
|
||||
}
|
||||
|
||||
|
||||
ngOnInit() {
|
||||
this.route.queryParams.pipe(takeUntil(this.destroy$)).subscribe((params) => {
|
||||
this.standort = params['standort'] || 'SUB';
|
||||
this.seiten = params['seiten'] === 'true' || false;
|
||||
this.onlyOK = params['onlyOK'] === 'true' || false;
|
||||
|
||||
// Initiales Laden der Daten
|
||||
this.loadArrivals();
|
||||
this.loadAvisoTvSettings();
|
||||
this.startDivToggle();
|
||||
|
||||
});
|
||||
|
||||
interval(1000000) // 10000 Millisekunden = 10 Sekunden
|
||||
.pipe(
|
||||
startWith(0), // Sofortiger Start ohne Warten
|
||||
switchMap(() => {
|
||||
// Nur den Ladeindikator anzeigen, wenn keine Daten vorhanden sind
|
||||
this.loadingArrivals = this.arrivals.length === 0;
|
||||
this.errorMessage = '';
|
||||
return this.avisoService.getArrivals(this.standort, this.seiten, this.onlyOK);
|
||||
}),
|
||||
takeUntil(this.destroy$)
|
||||
)
|
||||
.subscribe(
|
||||
(data: AvisoArrivalsResponse) => { // Typisierung der empfangenen Daten
|
||||
console.log('Received arrivals data:', data); // Zum Debuggen
|
||||
this.arrivals = data.avisos;
|
||||
this.totalArrivals = data.totalCount;
|
||||
this.loadingArrivals = false;
|
||||
this.paginateArrivals();
|
||||
this.cdr.detectChanges(); // Manuelle Change Detection
|
||||
},
|
||||
(error) => {
|
||||
console.error('Fehler beim Laden der Arrivals:', error);
|
||||
this.presentToast(`Fehler beim Laden der Arrivals: ${error}`);
|
||||
this.errorMessage = 'Fehler beim Laden der Arrivals. Bitte versuche es später erneut.';
|
||||
this.loadingArrivals = false;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// Automatisches Aktualisieren der TV-Einstellungen alle 10 Sekunden
|
||||
interval(1000000) // 10000 Millisekunden = 10 Sekunden
|
||||
.pipe(
|
||||
startWith(0),
|
||||
switchMap(() => {
|
||||
this.loadingSettings = this.avisoTvSettings.length === 0;
|
||||
this.settingsErrorMessage = '';
|
||||
return this.avisoService.getAvisoTvSettings(this.standort);
|
||||
}),
|
||||
takeUntil(this.destroy$)
|
||||
)
|
||||
.subscribe(
|
||||
(data: AvisoTvSettingsDto[]) => { // Typisierung als Array
|
||||
console.log('Received TV settings data:', data);
|
||||
this.avisoTvSettings = data;
|
||||
this.totalSettings = data.length; // Setze totalSettings auf die Länge des Arrays
|
||||
this.loadingSettings = false;
|
||||
this.cdr.detectChanges(); // Manuelle Change Detection
|
||||
|
||||
// Debugging: Überprüfe jede Einstellung
|
||||
this.avisoTvSettings.forEach(setting => {
|
||||
console.log(`Setting ID: ${setting.tvTextBezeichnungID}, isActive: ${setting.isActive}, position: ${setting.position}, fixeZeile1: ${setting.fixeZeile1}`);
|
||||
});
|
||||
},
|
||||
(error) => {
|
||||
console.error('Fehler beim Laden der TV Settings:', error);
|
||||
this.presentToast(`Fehler beim Laden der TV Settings: ${error}`);
|
||||
this.settingsErrorMessage = 'Fehler beim Laden der TV Settings. Bitte versuche es später erneut.';
|
||||
this.loadingSettings = false;
|
||||
}
|
||||
);
|
||||
|
||||
// Starte die Page Rotation einmal nach dem Initialen Laden
|
||||
// Optional: Falls du separate Subjects für Page Rotation verwendest
|
||||
// this.startPageRotation();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
// Beenden aller Subscriptions, um Speicherlecks zu vermeiden
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
|
||||
// Beende auch die Page Rotation Subscription, falls du separate Subjects verwendest
|
||||
// this.pageRotation$.next();
|
||||
// this.pageRotation$.complete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt die Ankünfte (Arrivals) von der API.
|
||||
*/
|
||||
loadArrivals() {
|
||||
this.loadingArrivals = true;
|
||||
this.avisoService
|
||||
.getArrivals(this.standort, this.seiten, this.onlyOK)
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe(
|
||||
(data: AvisoArrivalsResponse) => {
|
||||
console.log('Received arrivals data:', data);
|
||||
this.arrivals = data.avisos;
|
||||
this.totalArrivals = data.totalCount;
|
||||
this.loadingArrivals = false;
|
||||
this.paginateArrivals();
|
||||
this.cdr.detectChanges();
|
||||
},
|
||||
(error) => {
|
||||
console.error('Fehler beim Laden der Arrivals:', error);
|
||||
this.presentToast(`Fehler beim Laden der Arrivals: ${error}`);
|
||||
this.errorMessage = 'Fehler beim Laden der Arrivals. Bitte versuche es später erneut.';
|
||||
this.loadingArrivals = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt die Aviso TV Einstellungen von der API.
|
||||
*/
|
||||
loadAvisoTvSettings() {
|
||||
this.loadingSettings = true;
|
||||
this.avisoService
|
||||
.getAvisoTvSettings(this.standort)
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe(
|
||||
(data: AvisoTvSettingsDto[]) => { // Typisierung als Array
|
||||
console.log('Received TV settings data:', data); // Zum Debuggen
|
||||
this.avisoTvSettings = data;
|
||||
this.totalSettings = data.length; // Setze totalSettings auf die Länge des Arrays
|
||||
this.loadingSettings = false;
|
||||
this.cdr.detectChanges(); // Manuelle Change Detection
|
||||
showFirstDiv: true // Initialisiere alle auf true
|
||||
|
||||
// Debugging: Überprüfe jede Einstellung
|
||||
this.avisoTvSettings.forEach(setting => {
|
||||
console.log(`Setting ID: ${setting.tvTextBezeichnungID}, isActive: ${setting.isActive}, position: ${setting.position}, fixeZeile1: ${setting.fixeZeile1}`);
|
||||
});
|
||||
},
|
||||
(error) => {
|
||||
console.error('Fehler beim Laden der TV Settings:', error);
|
||||
this.presentToast(`Fehler beim Laden der TV Settings: ${error}`);
|
||||
this.settingsErrorMessage = 'Fehler beim Laden der TV Settings. Bitte versuche es später erneut.';
|
||||
this.loadingSettings = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
startDivToggle() {
|
||||
this.toggleDivInterval = setInterval(() => {
|
||||
this.showFirstDiv = !this.showFirstDiv;
|
||||
this.cdr.detectChanges(); // Manuelle Change Detection, falls nötig
|
||||
}, 5000); // 5000 Millisekunden = 5 Sekunden
|
||||
}
|
||||
/**
|
||||
* Lädt Arrivals und TV-Einstellungen basierend auf aktuellen Filtern.
|
||||
*/
|
||||
applyFilters() {
|
||||
this.loadArrivals();
|
||||
this.loadAvisoTvSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeigt eine Toast-Nachricht an.
|
||||
* @param message Die Nachricht, die angezeigt werden soll.
|
||||
*/
|
||||
async presentToast(message: string) {
|
||||
const toast = await this.toastController.create({
|
||||
message: message,
|
||||
duration: 3000,
|
||||
position: 'bottom',
|
||||
});
|
||||
toast.present();
|
||||
}
|
||||
|
||||
// Methoden zur Bestimmung von Statusklassen und -farben
|
||||
getStatusClass(status: number): string {
|
||||
switch (status) {
|
||||
case 0:
|
||||
return 'statusLKW_Erfasst';
|
||||
case 1:
|
||||
return 'statusLKW_Freigegeben';
|
||||
case 2:
|
||||
return 'statusLKW_LKW_neu';
|
||||
case 3:
|
||||
return 'statusLKW_Ankunft';
|
||||
case 4:
|
||||
return 'statusLKW_Vorbereitet';
|
||||
case 5:
|
||||
return 'statusLKW_Vorgeschrieben';
|
||||
default:
|
||||
return 'status-default';
|
||||
}
|
||||
}
|
||||
|
||||
getStatusIcon(status: number): string {
|
||||
switch (status) {
|
||||
case 0:
|
||||
return 'checkmark-circle'; // Erfasst
|
||||
case 1:
|
||||
return 'checkmark-circle'; // Freigegeben
|
||||
case 2:
|
||||
return 'help-circle'; // LKW n.e.
|
||||
case 3:
|
||||
return 'time'; // Ankunft
|
||||
case 4:
|
||||
return 'construct'; // Vorbereitet
|
||||
case 5:
|
||||
return 'bookmarks'; // Vorgeschrieben
|
||||
default:
|
||||
return 'help-circle'; // Unbekannt
|
||||
}
|
||||
}
|
||||
|
||||
getStatusColor(status: number): string {
|
||||
switch (status) {
|
||||
case 0:
|
||||
return 'success'; // Erfasst - Grün
|
||||
case 1:
|
||||
return 'primary'; // Freigegeben - Blau
|
||||
case 2:
|
||||
return 'warning'; // LKW n.e. - Gelb/Orange
|
||||
case 3:
|
||||
return 'warning'; // Ankunft - Gelb/Orange
|
||||
case 4:
|
||||
return 'secondary'; // Vorbereitet - Grau
|
||||
case 5:
|
||||
return 'tertiary'; // Vorgeschrieben - Violett
|
||||
default:
|
||||
return 'medium'; // Unbekannt - Grau
|
||||
}
|
||||
}
|
||||
|
||||
getStatusText(status: number): string {
|
||||
switch (status) {
|
||||
case 0:
|
||||
return 'Erfasst';
|
||||
case 1:
|
||||
return 'Freigegeben';
|
||||
case 2:
|
||||
return 'LKW n.e.';
|
||||
case 3:
|
||||
return 'Ankunft';
|
||||
case 4:
|
||||
return 'Vorbereitet';
|
||||
case 5:
|
||||
return 'Vorgeschrieben';
|
||||
default:
|
||||
return 'Unbekannt';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt die CSS-Klasse basierend auf dem Position-Wert zurück.
|
||||
* @param position Die Position (Top, Middle, Left, Right)
|
||||
* @returns Eine CSS-Klassen-String
|
||||
*/
|
||||
getPositionClass(position: string): string {
|
||||
const pos = position.toLowerCase(); // Konvertiere zu Kleinbuchstaben
|
||||
switch (pos) {
|
||||
case 'top':
|
||||
return 'position-top';
|
||||
case 'middle':
|
||||
return 'position-middle';
|
||||
case 'left':
|
||||
return 'position-left';
|
||||
case 'right':
|
||||
return 'position-right';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
// Paginierung der Arrivals
|
||||
paginateArrivals() {
|
||||
// Berechnung der verfügbaren Breite und Höhe
|
||||
const windowWidth = window.innerWidth;
|
||||
const windowHeight = window.innerHeight;
|
||||
// Definiere die Prozentsätze für Layout-Parameter
|
||||
const titleHeightPercent = 5; // z.B. 10% der Fensterhöhe
|
||||
const htmltextPercent = this.totalArrivals > 0 ? 30 : 0;
|
||||
|
||||
const containerPaddingPercent = 0; // z.B. 5% der Fensterbreite
|
||||
const gutterPercent = 1;
|
||||
const tileWidthPercent = 15; // z.B. 20% der Fensterbreite
|
||||
const tileHeightPercent = 23; // z.B. 25% der Fensterhöhe
|
||||
|
||||
|
||||
|
||||
const containerPadding = (containerPaddingPercent / 100) * windowWidth;
|
||||
const gutter = (gutterPercent / 100) * windowWidth;
|
||||
const tileWidth = (tileWidthPercent / 100) * windowWidth;
|
||||
const tileHeight = (tileHeightPercent / 100) * windowHeight;
|
||||
|
||||
// Berechnung der verfügbaren Breite für die Kacheln
|
||||
const containerPaddingTotal = containerPadding * 2; // Links und rechts
|
||||
const columns = Math.floor((windowWidth - containerPaddingTotal + gutter) / (tileWidth + gutter));
|
||||
|
||||
// Berechnung der verfügbaren Höhe für die Kacheln
|
||||
const titleHeight = (titleHeightPercent / 100) * windowHeight;
|
||||
let htmltext = 0;
|
||||
if (this.totalArrivals > 0) {
|
||||
htmltext = (htmltextPercent / 100) * windowHeight;
|
||||
}
|
||||
|
||||
const availableHeightForTiles = windowHeight - htmltext - titleHeight - containerPadding * 2 - gutter * (columns > 1 ? columns : 0);
|
||||
|
||||
// Berechnung der maximal möglichen Kacheln pro Spalte
|
||||
const rows = Math.floor((availableHeightForTiles + gutter) / (tileHeight + gutter));
|
||||
|
||||
// Berechnung der Kacheln pro Seite
|
||||
this.tilesPerPage = columns * rows;
|
||||
|
||||
// Sicherstellen, dass mindestens eine Kachel pro Seite angezeigt wird
|
||||
this.tilesPerPage = this.tilesPerPage > 0 ? this.tilesPerPage : 1;
|
||||
|
||||
console.log('Columns:', columns);
|
||||
console.log('Rows:', rows);
|
||||
console.log('Tiles per Page:', this.tilesPerPage);
|
||||
|
||||
// Aufteilung der Arrivals in Seiten
|
||||
this.pages = [];
|
||||
for (let i = 0; i < this.arrivals.length; i += this.tilesPerPage) {
|
||||
this.pages.push(this.arrivals.slice(i, i + this.tilesPerPage));
|
||||
}
|
||||
|
||||
// Reset der aktuellen Seite, wenn nötig
|
||||
if (this.currentPageIndex >= this.pages.length) {
|
||||
this.currentPageIndex = 0;
|
||||
}
|
||||
|
||||
console.log('Total Pages:', this.pages.length);
|
||||
}
|
||||
|
||||
// Automatisches Wechseln der Seiten alle 10 Sekunden
|
||||
startPageRotation() {
|
||||
interval(10000) // 10000 Millisekunden = 10 Sekunden
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe(() => {
|
||||
if (this.pages.length > 0) {
|
||||
this.currentPageIndex = (this.currentPageIndex + 1) % this.pages.length;
|
||||
console.log('Wechsel zu Seite:', this.currentPageIndex + 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Event Listener für Fenstergrößenänderungen, um die Paginierung anzupassen
|
||||
*/
|
||||
@HostListener('window:resize', ['$event'])
|
||||
onResize(event: Event) {
|
||||
this.paginateArrivals();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user