From 95fe01ad868200f613a7f52fc28483a0cd3e125c Mon Sep 17 00:00:00 2001 From: "m.ilhan" Date: Wed, 27 Nov 2024 11:40:43 +0100 Subject: [PATCH] v1 --- .gitignore | 1 + .vscode/launch.json | 39 + MIGRATED_PROJECT - Backup.esproj | 11 + PROJECT_MIGRATION_LOG.txt | 10 + VeragTVAppFrontend.sln | 36 + VeragTvApp.client.esproj | 9 + VeragTvApp.client.esproj.user | 4 + nuget.config | 10 + ...TED_PROJECT.esproj.CoreCompileInputs.cache | 0 ...GRATED_PROJECT.esproj.FileListAbsolute.txt | 1 + ...vApp.client.esproj.CoreCompileInputs.cache | 0 ...agTvApp.client.esproj.FileListAbsolute.txt | 1 + package-lock.json | 21 +- package.json | 3 +- src/app/app-routing.module.ts | 10 +- src/app/app.module.ts | 13 +- .../directives/auto-resize-text.directive.ts | 128 ++ src/app/home/home.page.html | 25 - src/app/home/home.page.ts | 25 - src/app/message/message.component.html | 16 - src/app/message/message.component.scss | 69 - src/app/message/message.component.spec.ts | 25 - src/app/message/message.component.ts | 17 - src/app/message/message.module.ts | 15 - .../aviso/aviso-routing.module.ts} | 6 +- src/app/pages/aviso/aviso.module.ts | 23 + src/app/pages/aviso/aviso.page.html | 96 ++ src/app/pages/aviso/aviso.page.scss | 149 ++ src/app/pages/aviso/aviso.page.spec.ts | 17 + src/app/pages/aviso/aviso.page.ts | 484 ++++++ .../{ => pages}/home/home-routing.module.ts | 0 src/app/{ => pages}/home/home.module.ts | 3 +- src/app/pages/home/home.page.html | 0 src/app/pages/home/home.page.scss | 0 src/app/{ => pages}/home/home.page.spec.ts | 0 src/app/pages/home/home.page.ts | 15 + src/app/services/aviso-tv-settings.dto.ts | 24 + src/app/services/aviso.dto.ts | 13 + src/app/services/aviso.service.ts | 88 + src/app/services/data.service.spec.ts | 12 - src/app/services/data.service.ts | 83 - src/app/view-message/view-message.module.ts | 19 - src/app/view-message/view-message.page.html | 29 - src/app/view-message/view-message.page.scss | 50 - .../view-message/view-message.page.spec.ts | 26 - src/app/view-message/view-message.page.ts | 29 - verag.njsproj | 1480 ++++++++++++++++ verag.njsproj.user | 6 + verag.sln | 0 verage.njsproj | 1481 +++++++++++++++++ verage.njsproj.user | 9 + 51 files changed, 4175 insertions(+), 456 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 MIGRATED_PROJECT - Backup.esproj create mode 100644 PROJECT_MIGRATION_LOG.txt create mode 100644 VeragTVAppFrontend.sln create mode 100644 VeragTvApp.client.esproj create mode 100644 VeragTvApp.client.esproj.user create mode 100644 nuget.config rename src/app/home/home.page.scss => obj/Debug/MIGRATED_PROJECT.esproj.CoreCompileInputs.cache (100%) create mode 100644 obj/Debug/MIGRATED_PROJECT.esproj.FileListAbsolute.txt create mode 100644 obj/Debug/VeragTvApp.client.esproj.CoreCompileInputs.cache create mode 100644 obj/Debug/VeragTvApp.client.esproj.FileListAbsolute.txt create mode 100644 src/app/directives/auto-resize-text.directive.ts delete mode 100644 src/app/home/home.page.html delete mode 100644 src/app/home/home.page.ts delete mode 100644 src/app/message/message.component.html delete mode 100644 src/app/message/message.component.scss delete mode 100644 src/app/message/message.component.spec.ts delete mode 100644 src/app/message/message.component.ts delete mode 100644 src/app/message/message.module.ts rename src/app/{view-message/view-message-routing.module.ts => pages/aviso/aviso-routing.module.ts} (64%) create mode 100644 src/app/pages/aviso/aviso.module.ts create mode 100644 src/app/pages/aviso/aviso.page.html create mode 100644 src/app/pages/aviso/aviso.page.scss create mode 100644 src/app/pages/aviso/aviso.page.spec.ts create mode 100644 src/app/pages/aviso/aviso.page.ts rename src/app/{ => pages}/home/home-routing.module.ts (100%) rename src/app/{ => pages}/home/home.module.ts (82%) create mode 100644 src/app/pages/home/home.page.html create mode 100644 src/app/pages/home/home.page.scss rename src/app/{ => pages}/home/home.page.spec.ts (100%) create mode 100644 src/app/pages/home/home.page.ts create mode 100644 src/app/services/aviso-tv-settings.dto.ts create mode 100644 src/app/services/aviso.dto.ts create mode 100644 src/app/services/aviso.service.ts delete mode 100644 src/app/services/data.service.spec.ts delete mode 100644 src/app/services/data.service.ts delete mode 100644 src/app/view-message/view-message.module.ts delete mode 100644 src/app/view-message/view-message.page.html delete mode 100644 src/app/view-message/view-message.page.scss delete mode 100644 src/app/view-message/view-message.page.spec.ts delete mode 100644 src/app/view-message/view-message.page.ts create mode 100644 verag.njsproj create mode 100644 verag.njsproj.user create mode 100644 verag.sln create mode 100644 verage.njsproj create mode 100644 verage.njsproj.user diff --git a/.gitignore b/.gitignore index 5b669df..900fc2d 100644 --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,7 @@ yarn-error.log *.sublime-workspace # Visual Studio Code +.vs/* .vscode/* !.vscode/settings.json !.vscode/tasks.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..316fb6e --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,39 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "localhost (Chrome)", + "type": "chrome", + "request": "launch", + "url": "http://localhost:8100", + "webRoot": "${workspaceFolder}/www", + "preLaunchTask": "ng serve", + "sourceMaps": true, + "trace": true + }, + { + "name": "Debug node process", + "type": "node", + "request": "launch", + "cwd": "${workspaceFolder}", + "program": "${workspaceFolder}/capacitor.config.ts", + "skipFiles": [ + " + + + ionic build + + + + + + + \ No newline at end of file diff --git a/PROJECT_MIGRATION_LOG.txt b/PROJECT_MIGRATION_LOG.txt new file mode 100644 index 0000000..b6b6cae --- /dev/null +++ b/PROJECT_MIGRATION_LOG.txt @@ -0,0 +1,10 @@ +Hello! Thank you for trying out our new JavaScript and TypeScript project experience. We've added the below list of files to your project directory in order to enable the new experience: + +C:\Users\m.ilhan\source\repos\verag\.vscode\launch.json +C:\Users\m.ilhan\source\repos\verag\nuget.config +C:\Users\m.ilhan\source\repos\verag\MIGRATED_PROJECT.esproj +C:\Users\m.ilhan\source\repos\verag\PROJECT_MIGRATION_LOG.txt + +We'd love to get your feedback! Please submit any bugs or improvements that need to be made by going to Help -> Send Feedback. + +If you'd like to revert to your original project, you can right-click on the project and click on 'Revert Project To Old Experience'. diff --git a/VeragTVAppFrontend.sln b/VeragTVAppFrontend.sln new file mode 100644 index 0000000..80baab9 --- /dev/null +++ b/VeragTVAppFrontend.sln @@ -0,0 +1,36 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35327.3 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{54A90642-561A-4BB1-A94E-469ADEE60C69}") = "VeragTvApp.client", "VeragTvApp.client.esproj", "{1650CC57-EA5F-4ACF-BD98-B8A5DED15956}" + ProjectSection(ProjectDependencies) = postProject + {C085CCA8-3E7E-4AA3-A0C5-D41DDAF8192C} = {C085CCA8-3E7E-4AA3-A0C5-D41DDAF8192C} + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VeragTvApp.server", "..\VeragTvApp\VeragTvApp.server.csproj", "{C085CCA8-3E7E-4AA3-A0C5-D41DDAF8192C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1650CC57-EA5F-4ACF-BD98-B8A5DED15956}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1650CC57-EA5F-4ACF-BD98-B8A5DED15956}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1650CC57-EA5F-4ACF-BD98-B8A5DED15956}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {1650CC57-EA5F-4ACF-BD98-B8A5DED15956}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1650CC57-EA5F-4ACF-BD98-B8A5DED15956}.Release|Any CPU.Build.0 = Release|Any CPU + {1650CC57-EA5F-4ACF-BD98-B8A5DED15956}.Release|Any CPU.Deploy.0 = Release|Any CPU + {C085CCA8-3E7E-4AA3-A0C5-D41DDAF8192C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C085CCA8-3E7E-4AA3-A0C5-D41DDAF8192C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C085CCA8-3E7E-4AA3-A0C5-D41DDAF8192C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C085CCA8-3E7E-4AA3-A0C5-D41DDAF8192C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9B2DABB1-ADAB-46C3-B82D-B9BB96C00E15} + EndGlobalSection +EndGlobal diff --git a/VeragTvApp.client.esproj b/VeragTvApp.client.esproj new file mode 100644 index 0000000..7545b0f --- /dev/null +++ b/VeragTvApp.client.esproj @@ -0,0 +1,9 @@ + + + + + + + ionic serve + + \ No newline at end of file diff --git a/VeragTvApp.client.esproj.user b/VeragTvApp.client.esproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/VeragTvApp.client.esproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/nuget.config b/nuget.config new file mode 100644 index 0000000..6548586 --- /dev/null +++ b/nuget.config @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/app/home/home.page.scss b/obj/Debug/MIGRATED_PROJECT.esproj.CoreCompileInputs.cache similarity index 100% rename from src/app/home/home.page.scss rename to obj/Debug/MIGRATED_PROJECT.esproj.CoreCompileInputs.cache diff --git a/obj/Debug/MIGRATED_PROJECT.esproj.FileListAbsolute.txt b/obj/Debug/MIGRATED_PROJECT.esproj.FileListAbsolute.txt new file mode 100644 index 0000000..733233a --- /dev/null +++ b/obj/Debug/MIGRATED_PROJECT.esproj.FileListAbsolute.txt @@ -0,0 +1 @@ +C:\Users\m.ilhan\source\repos\verag\obj\Debug\MIGRATED_PROJECT.esproj.CoreCompileInputs.cache diff --git a/obj/Debug/VeragTvApp.client.esproj.CoreCompileInputs.cache b/obj/Debug/VeragTvApp.client.esproj.CoreCompileInputs.cache new file mode 100644 index 0000000..e69de29 diff --git a/obj/Debug/VeragTvApp.client.esproj.FileListAbsolute.txt b/obj/Debug/VeragTvApp.client.esproj.FileListAbsolute.txt new file mode 100644 index 0000000..f1b0e75 --- /dev/null +++ b/obj/Debug/VeragTvApp.client.esproj.FileListAbsolute.txt @@ -0,0 +1 @@ +C:\Users\m.ilhan\source\repos\verag\obj\Debug\VeragTvApp.client.esproj.CoreCompileInputs.cache diff --git a/package-lock.json b/package-lock.json index 4fd9330..2867036 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,9 +21,10 @@ "@capacitor/haptics": "6.0.1", "@capacitor/keyboard": "6.0.2", "@capacitor/status-bar": "6.0.1", - "@ionic/angular": "^8.0.0", + "@ionic/angular": "^8.4.0", "ionicons": "^7.0.0", "rxjs": "~7.8.0", + "swiper": "^11.1.15", "tslib": "^2.3.0", "zone.js": "~0.14.2" }, @@ -14801,6 +14802,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swiper": { + "version": "11.1.15", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.1.15.tgz", + "integrity": "sha512-IzWeU34WwC7gbhjKsjkImTuCRf+lRbO6cnxMGs88iVNKDwV+xQpBCJxZ4bNH6gSrIbbyVJ1kuGzo3JTtz//CBw==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/swiperjs" + }, + { + "type": "open_collective", + "url": "http://opencollective.com/swiper" + } + ], + "engines": { + "node": ">= 4.7.0" + } + }, "node_modules/symbol-observable": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", diff --git a/package.json b/package.json index 77d34cf..35678d8 100644 --- a/package.json +++ b/package.json @@ -26,9 +26,10 @@ "@capacitor/haptics": "6.0.1", "@capacitor/keyboard": "6.0.2", "@capacitor/status-bar": "6.0.1", - "@ionic/angular": "^8.0.0", + "@ionic/angular": "^8.4.0", "ionicons": "^7.0.0", "rxjs": "~7.8.0", + "swiper": "^11.1.15", "tslib": "^2.3.0", "zone.js": "~0.14.2" }, diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index a2b2e0f..a477ecd 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -4,17 +4,17 @@ import { PreloadAllModules, RouterModule, Routes } from '@angular/router'; const routes: Routes = [ { path: 'home', - loadChildren: () => import('./home/home.module').then( m => m.HomePageModule) + loadChildren: () => import('./pages/home/home.module').then( m => m.HomePageModule) }, { - path: 'message/:id', - loadChildren: () => import('./view-message/view-message.module').then( m => m.ViewMessagePageModule) + path: 'aviso', + loadChildren: () => import('./pages/aviso/aviso.module').then( m => m.AvisoPageModule) }, { path: '', - redirectTo: 'home', + redirectTo: 'aviso', pathMatch: 'full' - }, + } ]; @NgModule({ diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 34b715b..11989fe 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,16 +1,21 @@ -import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { RouteReuseStrategy } from '@angular/router'; +import { HttpClientModule } from '@angular/common/http'; import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; - +import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { AppRoutingModule } from './app-routing.module'; @NgModule({ declarations: [AppComponent], - imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule], + imports: [ + BrowserModule, + IonicModule.forRoot(), + AppRoutingModule, + HttpClientModule // Hinzufügen + ], providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }], bootstrap: [AppComponent], }) -export class AppModule {} +export class AppModule { } diff --git a/src/app/directives/auto-resize-text.directive.ts b/src/app/directives/auto-resize-text.directive.ts new file mode 100644 index 0000000..f4cd84f --- /dev/null +++ b/src/app/directives/auto-resize-text.directive.ts @@ -0,0 +1,128 @@ +import { Directive, ElementRef, AfterViewInit, OnDestroy } from '@angular/core'; +import { Subject } from 'rxjs'; +import { debounceTime, takeUntil } from 'rxjs/operators'; + +@Directive({ + selector: '[autoResizeText]' +}) +export class AutoResizeTextDirective implements AfterViewInit, OnDestroy { + private resizeObserver!: ResizeObserver; + private resize$ = new Subject(); + private destroy$ = new Subject(); + + constructor(private el: ElementRef) { } + + ngAfterViewInit() { + this.adjustFontSizes(); + this.resizeObserver = new ResizeObserver(() => { + this.resize$.next(); + }); + this.resizeObserver.observe(this.el.nativeElement); + + // Debounce der Resize-Events + this.resize$.pipe( + debounceTime(100), // Warte 100ms nach dem letzten Resize-Event + takeUntil(this.destroy$) + ).subscribe(() => { + this.adjustFontSizes(); + }); + } + + ngOnDestroy() { + if (this.resizeObserver) { + this.resizeObserver.disconnect(); + } + this.destroy$.next(); + this.destroy$.complete(); + } + + /** + * Passt die Schriftgrößen der einzelnen Spans individuell an. + */ + private adjustFontSizes() { + const container: HTMLElement = this.el.nativeElement; + const spans: HTMLElement[] = Array.from(container.querySelectorAll('div.dynamic-font-size')); + + // Store the original font sizes + spans.forEach(span => { + if (!span.dataset['originalFontSizePx']) { + const computedStyle = window.getComputedStyle(span); + const originalFontSizePx = parseFloat(computedStyle.fontSize); + span.dataset['originalFontSizePx'] = originalFontSizePx.toString(); + } + }); + + // Reset font sizes to original + spans.forEach(span => { + const originalFontSizePx = parseFloat(span.dataset['originalFontSizePx'] || '16'); + span.style.fontSize = `${originalFontSizePx}px`; + }); + + // If content overflows, adjust font sizes + if (this.isOverflowing(container)) { + // Find the scaling factor needed to fit the content + let scalingFactor = this.calculateScalingFactor(container, spans); + + // Apply the scaling factor to all spans + spans.forEach(span => { + const originalFontSizePx = parseFloat(span.dataset['originalFontSizePx'] || '16'); + let newFontSizePx = originalFontSizePx * scalingFactor; + + // Ensure the font size doesn't go below a minimum value + const minFontSizePx = 12; + if (newFontSizePx < minFontSizePx) { + newFontSizePx = minFontSizePx; + } + + span.style.fontSize = `${newFontSizePx}px`; + }); + } + } + + /** + * Calculates the scaling factor needed to fit all content within the container. + * @param container The container element. + * @param spans The list of span elements. + * @returns The scaling factor as a decimal. + */ + private calculateScalingFactor(container: HTMLElement, spans: HTMLElement[]): number { + const minFontSizePx = 12; // Minimum font size + let low = 0.1; // 10% scaling + let high = 1; // 100% scaling + let mid = 1; + + // Binary search to find the optimal scaling factor + while (high - low > 0.01) { + mid = (low + high) / 2; + + // Apply scaling factor + spans.forEach(span => { + const originalFontSizePx = parseFloat(span.dataset['originalFontSizePx'] || '16'); + let newFontSizePx = originalFontSizePx * mid; + if (newFontSizePx < minFontSizePx) { + newFontSizePx = minFontSizePx; + } + span.style.fontSize = `${newFontSizePx}px`; + }); + + // Check if content overflows + if (this.isOverflowing(container)) { + high = mid; + } else { + low = mid; + } + } + + return low; + } + + + /** + * Überprüft, ob der Inhalt des Containers überläuft. + * @param container Das zu überprüfende HTMLElement. + * @returns Wahr, wenn ein Überlauf vorliegt, sonst falsch. + */ + private isOverflowing(container: HTMLElement): boolean { + return container.scrollWidth > container.clientWidth || container.scrollHeight > container.clientHeight; + } +} diff --git a/src/app/home/home.page.html b/src/app/home/home.page.html deleted file mode 100644 index 0f7b249..0000000 --- a/src/app/home/home.page.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - Inbox - - - - - - - - - - - - - Inbox - - - - - - - - \ No newline at end of file diff --git a/src/app/home/home.page.ts b/src/app/home/home.page.ts deleted file mode 100644 index 4815425..0000000 --- a/src/app/home/home.page.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Component, inject } from '@angular/core'; -import { RefresherCustomEvent } from '@ionic/angular'; -import { MessageComponent } from '../message/message.component'; - -import { DataService, Message } from '../services/data.service'; - -@Component({ - selector: 'app-home', - templateUrl: 'home.page.html', - styleUrls: ['home.page.scss'], -}) -export class HomePage { - private data = inject(DataService); - constructor() {} - - refresh(ev: any) { - setTimeout(() => { - (ev as RefresherCustomEvent).detail.complete(); - }, 3000); - } - - getMessages(): Message[] { - return this.data.getMessages(); - } -} diff --git a/src/app/message/message.component.html b/src/app/message/message.component.html deleted file mode 100644 index cde642f..0000000 --- a/src/app/message/message.component.html +++ /dev/null @@ -1,16 +0,0 @@ - -
- -

- {{ message.fromName }} - - {{ message.date }} - - -

-

{{ message.subject }}

-

- Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -

-
-
\ No newline at end of file diff --git a/src/app/message/message.component.scss b/src/app/message/message.component.scss deleted file mode 100644 index 82d140e..0000000 --- a/src/app/message/message.component.scss +++ /dev/null @@ -1,69 +0,0 @@ -ion-item { - --padding-start: 0; - --inner-padding-end: 0; -} - -ion-label { - margin-top: 12px; - margin-bottom: 12px; -} - -ion-item h2 { - font-weight: 600; - margin: 0; - - /** - * With larger font scales - * the date/time should wrap to the next - * line. However, there should be - * space between the name and the date/time - * if they can appear on the same line. - */ - display: flex; - flex-wrap: wrap; - justify-content: space-between; -} - -ion-item p { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - width: 95%; -} - -ion-item .date { - align-items: center; - display: flex; -} - -ion-item ion-icon { - color: #c9c9ca; -} - -ion-item ion-note { - font-size: 0.9375rem; - margin-right: 8px; - font-weight: normal; -} - -ion-item ion-note.md { - margin-right: 14px; -} - -.dot { - display: block; - height: 12px; - width: 12px; - border-radius: 50%; - align-self: start; - margin: 16px 10px 16px 16px; -} - -.dot-unread { - background: var(--ion-color-primary); -} - -ion-footer ion-title { - font-size: 11px; - font-weight: normal; -} \ No newline at end of file diff --git a/src/app/message/message.component.spec.ts b/src/app/message/message.component.spec.ts deleted file mode 100644 index ba40d5b..0000000 --- a/src/app/message/message.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { RouterModule } from '@angular/router'; -import { IonicModule } from '@ionic/angular'; - -import { MessageComponent } from './message.component'; - -describe('MessageComponent', () => { - let component: MessageComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [MessageComponent], - imports: [IonicModule.forRoot(), RouterModule.forRoot([])] - }).compileComponents(); - - fixture = TestBed.createComponent(MessageComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/message/message.component.ts b/src/app/message/message.component.ts deleted file mode 100644 index 9fdac3f..0000000 --- a/src/app/message/message.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { ChangeDetectionStrategy, Component, inject, Input } from '@angular/core'; -import { Platform } from '@ionic/angular'; -import { Message } from '../services/data.service'; - -@Component({ - selector: 'app-message', - templateUrl: './message.component.html', - styleUrls: ['./message.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class MessageComponent { - private platform = inject(Platform); - @Input() message?: Message; - isIos() { - return this.platform.is('ios') - } -} diff --git a/src/app/message/message.module.ts b/src/app/message/message.module.ts deleted file mode 100644 index 3299ebf..0000000 --- a/src/app/message/message.module.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; -import { RouterModule } from '@angular/router'; - -import { IonicModule } from '@ionic/angular'; - -import { MessageComponent } from './message.component'; - -@NgModule({ - imports: [ CommonModule, FormsModule, IonicModule, RouterModule], - declarations: [MessageComponent], - exports: [MessageComponent] -}) -export class MessageComponentModule {} diff --git a/src/app/view-message/view-message-routing.module.ts b/src/app/pages/aviso/aviso-routing.module.ts similarity index 64% rename from src/app/view-message/view-message-routing.module.ts rename to src/app/pages/aviso/aviso-routing.module.ts index 3a829f7..1a39cee 100644 --- a/src/app/view-message/view-message-routing.module.ts +++ b/src/app/pages/aviso/aviso-routing.module.ts @@ -1,12 +1,12 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; -import { ViewMessagePage } from './view-message.page'; +import { AvisoPage } from './aviso.page'; const routes: Routes = [ { path: '', - component: ViewMessagePage + component: AvisoPage } ]; @@ -14,4 +14,4 @@ const routes: Routes = [ imports: [RouterModule.forChild(routes)], exports: [RouterModule], }) -export class ViewMessagePageRoutingModule {} +export class AvisoPageRoutingModule {} diff --git a/src/app/pages/aviso/aviso.module.ts b/src/app/pages/aviso/aviso.module.ts new file mode 100644 index 0000000..9df1bf6 --- /dev/null +++ b/src/app/pages/aviso/aviso.module.ts @@ -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 {} diff --git a/src/app/pages/aviso/aviso.page.html b/src/app/pages/aviso/aviso.page.html new file mode 100644 index 0000000..2b1a311 --- /dev/null +++ b/src/app/pages/aviso/aviso.page.html @@ -0,0 +1,96 @@ + + + + + + + + Ankünfte ({{ totalArrivals }}) Seite {{ currentPageIndex + 1 }} von {{ pages.length }} + + + + + + + + +

{{ errorMessage }}

+
+
+
+ + + + + + + +
+ + +
+ + + + {{ aviso.lkW_Nr }} + + + + +
+

+ + {{ aviso.ankunft }} + + {{ aviso.dauer }} +

+

+ + {{ aviso.letzterMitarbeiter }} +

+
+
+
+
+ + + + + + +

Keine Ankünfte gefunden.

+
+
+
+
+ + + +
+ + + + + + +
+
+ + +
+
+
+
+
+
diff --git a/src/app/pages/aviso/aviso.page.scss b/src/app/pages/aviso/aviso.page.scss new file mode 100644 index 0000000..8098bba --- /dev/null +++ b/src/app/pages/aviso/aviso.page.scss @@ -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; + } +} + + + + diff --git a/src/app/pages/aviso/aviso.page.spec.ts b/src/app/pages/aviso/aviso.page.spec.ts new file mode 100644 index 0000000..ff1262f --- /dev/null +++ b/src/app/pages/aviso/aviso.page.spec.ts @@ -0,0 +1,17 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { AvisoPage } from './aviso.page'; + +describe('AvisoPage', () => { + let component: AvisoPage; + let fixture: ComponentFixture; + + beforeEach(() => { + fixture = TestBed.createComponent(AvisoPage); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/aviso/aviso.page.ts b/src/app/pages/aviso/aviso.page.ts new file mode 100644 index 0000000..525274e --- /dev/null +++ b/src/app/pages/aviso/aviso.page.ts @@ -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(); + private pageRotation$ = new Subject(); // 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(); + } +} diff --git a/src/app/home/home-routing.module.ts b/src/app/pages/home/home-routing.module.ts similarity index 100% rename from src/app/home/home-routing.module.ts rename to src/app/pages/home/home-routing.module.ts diff --git a/src/app/home/home.module.ts b/src/app/pages/home/home.module.ts similarity index 82% rename from src/app/home/home.module.ts rename to src/app/pages/home/home.module.ts index 53aa867..1bf1818 100644 --- a/src/app/home/home.module.ts +++ b/src/app/pages/home/home.module.ts @@ -5,14 +5,13 @@ import { FormsModule } from '@angular/forms'; import { HomePage } from './home.page'; import { HomePageRoutingModule } from './home-routing.module'; -import { MessageComponentModule } from '../message/message.module'; + @NgModule({ imports: [ CommonModule, FormsModule, IonicModule, - MessageComponentModule, HomePageRoutingModule ], declarations: [HomePage] diff --git a/src/app/pages/home/home.page.html b/src/app/pages/home/home.page.html new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/home/home.page.scss b/src/app/pages/home/home.page.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/home/home.page.spec.ts b/src/app/pages/home/home.page.spec.ts similarity index 100% rename from src/app/home/home.page.spec.ts rename to src/app/pages/home/home.page.spec.ts diff --git a/src/app/pages/home/home.page.ts b/src/app/pages/home/home.page.ts new file mode 100644 index 0000000..588576e --- /dev/null +++ b/src/app/pages/home/home.page.ts @@ -0,0 +1,15 @@ +import { Component, inject } from '@angular/core'; +import { RefresherCustomEvent } from '@ionic/angular'; + + + +@Component({ + selector: 'app-home', + templateUrl: 'home.page.html', + styleUrls: ['home.page.scss'], +}) +export class HomePage { + constructor() {} + + +} diff --git a/src/app/services/aviso-tv-settings.dto.ts b/src/app/services/aviso-tv-settings.dto.ts new file mode 100644 index 0000000..cc1e17f --- /dev/null +++ b/src/app/services/aviso-tv-settings.dto.ts @@ -0,0 +1,24 @@ +export interface AvisoTvSettingsDto { + tvTextBezeichnungID: number; + standortID: number; + tvTextBezeichnung: string; + standort: string; + position: string; + fixeZeile1?: string; + fixeZeile2?: string; + fixeZeile3?: string; + art?: string; + startDate?: string | null; + endDate?: string | null; + startTime?: string | null; + endTime?: string | null; + isRecurring: boolean; + isMonday: boolean; + isTuesday: boolean; + isWednesday: boolean; + isThursday: boolean; + isFriday: boolean; + isSaturday: boolean; + isSunday: boolean; + isActive: boolean; +} diff --git a/src/app/services/aviso.dto.ts b/src/app/services/aviso.dto.ts new file mode 100644 index 0000000..c3212b4 --- /dev/null +++ b/src/app/services/aviso.dto.ts @@ -0,0 +1,13 @@ +export interface AvisoDto { + avisoID: number; + status: number; + lkW_Nr: string; + ankunft: string | null; + dauer: string; + letzterMitarbeiter: string; + weiterleitungTextTV: string; + imEx: string; + zollDigitalEingereicht: boolean; + buero: string; + avisoTVHinweis: string; +} diff --git a/src/app/services/aviso.service.ts b/src/app/services/aviso.service.ts new file mode 100644 index 0000000..f26e3d9 --- /dev/null +++ b/src/app/services/aviso.service.ts @@ -0,0 +1,88 @@ +import { Injectable } from '@angular/core'; +import { HttpClient, HttpParams, HttpErrorResponse } from '@angular/common/http'; +import { Observable, throwError } from 'rxjs'; +import { catchError, tap } from 'rxjs/operators'; +import { AvisoDto } from './aviso.dto'; // Importiere das Interface +import { AvisoTvSettingsDto } from './aviso-tv-settings.dto'; // Importiere das neue Interface + +// Definiere die Response Interfaces +export interface AvisoArrivalsResponse { + avisos: AvisoDto[]; + totalCount: number; +} + + + +@Injectable({ + providedIn: 'root' +}) +export class AvisoService { + + private baseUrl = 'https://localhost:7063/api/Aviso'; + + constructor(private http: HttpClient) { } + + /** + * Holt die Ankünfte (Arrivals) basierend auf den übergebenen Parametern. + * @param standort Standort zur Filterung der Ankünfte. + * @param seiten Gibt an, ob nur Seiten zurückgegeben werden sollen. + * @param onlyOK Gibt an, ob nur gültige Ankünfte zurückgegeben werden sollen. + * @returns Ein Observable von AvisoArrivalsResponse. + */ + getArrivals(standort: string, seiten: boolean = false, onlyOK: boolean = false): Observable { + let params = new HttpParams() + .set('standort', standort) + .set('seiten', seiten.toString()) + .set('onlyOK', onlyOK.toString()); + + return this.http.get(`${this.baseUrl}/arrivals`, { params }) + .pipe( + tap(data => console.log('AvisoService received arrivals data:', data)), // Logge die empfangenen Daten + catchError(this.handleError) + ); + } + + /** + * Holt die Aviso TV Einstellungen basierend auf dem übergebenen Standort. + * @param standort Standort zur Filterung der Einstellungen. + * @returns Ein Observable von AvisoTvSettingsDto[]. + */ + getAvisoTvSettings(standort: string): Observable { + return this.http.get(`${this.baseUrl}/${standort}`) + .pipe( + tap(data => console.log('AvisoService received TV settings data:', data)), // Logge die empfangenen Daten + catchError(this.handleError) + ); + } + + /** + * Holt die bereitstehenden Avisos basierend auf dem übergebenen Standort. + * @param standort Standort zur Filterung der bereitstehenden Avisos. + * @returns Ein Observable von AvisoDto[]. + */ + getReadyAvisos(standort: string = ''): Observable { + let params = new HttpParams().set('standort', standort); + return this.http.get(`${this.baseUrl}/ready`, { params }) + .pipe( + tap(data => console.log('AvisoService received ready avisos:', data)), // Logge die empfangenen Daten + catchError(this.handleError) + ); + } + + /** + * Behandelt Fehler, die während HTTP-Anfragen auftreten. + * @param error Das aufgetretene HttpErrorResponse-Objekt. + * @returns Ein Observable, das einen Fehler auswirft. + */ + private handleError(error: HttpErrorResponse) { + let errorMessage = 'Unbekannter Fehler!'; + if (error.error instanceof ErrorEvent) { + // Client-seitiger Fehler + errorMessage = `Fehler: ${error.error.message}`; + } else { + // Server-seitiger Fehler + errorMessage = `Server returned code: ${error.status}, error message is: ${error.message}`; + } + return throwError(errorMessage); + } +} diff --git a/src/app/services/data.service.spec.ts b/src/app/services/data.service.spec.ts deleted file mode 100644 index a5283fc..0000000 --- a/src/app/services/data.service.spec.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { DataService } from './data.service'; - -describe('DataService', () => { - beforeEach(() => TestBed.configureTestingModule({})); - - it('should be created', () => { - const service: DataService = TestBed.get(DataService); - expect(service).toBeTruthy(); - }); -}); diff --git a/src/app/services/data.service.ts b/src/app/services/data.service.ts deleted file mode 100644 index 2fb24a2..0000000 --- a/src/app/services/data.service.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { Injectable } from '@angular/core'; - -export interface Message { - fromName: string; - subject: string; - date: string; - id: number; - read: boolean; -} - -@Injectable({ - providedIn: 'root' -}) -export class DataService { - public messages: Message[] = [ - { - fromName: 'Matt Chorsey', - subject: 'New event: Trip to Vegas', - date: '9:32 AM', - id: 0, - read: false - }, - { - fromName: 'Lauren Ruthford', - subject: 'Long time no chat', - date: '6:12 AM', - id: 1, - read: false - }, - { - fromName: 'Jordan Firth', - subject: 'Report Results', - date: '4:55 AM', - id: 2, - read: false - }, - { - fromName: 'Bill Thomas', - subject: 'The situation', - date: 'Yesterday', - id: 3, - read: false - }, - { - fromName: 'Joanne Pollan', - subject: 'Updated invitation: Swim lessons', - date: 'Yesterday', - id: 4, - read: false - }, - { - fromName: 'Andrea Cornerston', - subject: 'Last minute ask', - date: 'Yesterday', - id: 5, - read: false - }, - { - fromName: 'Moe Chamont', - subject: 'Family Calendar - Version 1', - date: 'Last Week', - id: 6, - read: false - }, - { - fromName: 'Kelly Richardson', - subject: 'Placeholder Headhots', - date: 'Last Week', - id: 7, - read: false - } - ]; - - constructor() { } - - public getMessages(): Message[] { - return this.messages; - } - - public getMessageById(id: number): Message { - return this.messages[id]; - } -} diff --git a/src/app/view-message/view-message.module.ts b/src/app/view-message/view-message.module.ts deleted file mode 100644 index 6e00f88..0000000 --- a/src/app/view-message/view-message.module.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; -import { ViewMessagePage } from './view-message.page'; - -import { IonicModule } from '@ionic/angular'; - -import { ViewMessagePageRoutingModule } from './view-message-routing.module'; - -@NgModule({ - imports: [ - CommonModule, - FormsModule, - IonicModule, - ViewMessagePageRoutingModule - ], - declarations: [ViewMessagePage] -}) -export class ViewMessagePageModule {} diff --git a/src/app/view-message/view-message.page.html b/src/app/view-message/view-message.page.html deleted file mode 100644 index a35ec27..0000000 --- a/src/app/view-message/view-message.page.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - -

- {{ message.fromName }} - - {{ message.date }} - -

-

To: Me

-
-
- -
-

{{ message.subject }}

-

- Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -

-
-
diff --git a/src/app/view-message/view-message.page.scss b/src/app/view-message/view-message.page.scss deleted file mode 100644 index 729b5d6..0000000 --- a/src/app/view-message/view-message.page.scss +++ /dev/null @@ -1,50 +0,0 @@ -ion-item { - --inner-padding-end: 0; - --background: transparent; -} - -ion-label { - margin-top: 12px; - margin-bottom: 12px; -} - -ion-item h2 { - font-weight: 600; - - /** - * With larger font scales - * the date/time should wrap to the next - * line. However, there should be - * space between the name and the date/time - * if they can appear on the same line. - */ - display: flex; - flex-wrap: wrap; - justify-content: space-between; -} - -ion-item .date { - align-items: center; - display: flex; -} - -ion-item ion-icon { - font-size: 42px; - margin-right: 8px; -} - -ion-item ion-note { - font-size: 0.9375rem; - margin-right: 12px; - font-weight: normal; -} - -h1 { - margin: 0; - font-weight: bold; - font-size: 1.4rem; -} - -p { - line-height: 1.4; -} \ No newline at end of file diff --git a/src/app/view-message/view-message.page.spec.ts b/src/app/view-message/view-message.page.spec.ts deleted file mode 100644 index 0e99d66..0000000 --- a/src/app/view-message/view-message.page.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { IonicModule } from '@ionic/angular'; -import { RouterModule } from '@angular/router'; - -import { ViewMessagePageRoutingModule } from './view-message-routing.module'; -import { ViewMessagePage } from './view-message.page'; - -describe('ViewMessagePage', () => { - let component: ViewMessagePage; - let fixture: ComponentFixture; - - beforeEach(async () => { - TestBed.configureTestingModule({ - declarations: [ViewMessagePage], - imports: [IonicModule.forRoot(), ViewMessagePageRoutingModule, RouterModule.forRoot([])] - }).compileComponents(); - - fixture = TestBed.createComponent(ViewMessagePage); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/view-message/view-message.page.ts b/src/app/view-message/view-message.page.ts deleted file mode 100644 index a720c70..0000000 --- a/src/app/view-message/view-message.page.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { Component, inject, OnInit } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { IonicModule, Platform } from '@ionic/angular'; -import { DataService, Message } from '../services/data.service'; - -@Component({ - selector: 'app-view-message', - templateUrl: './view-message.page.html', - styleUrls: ['./view-message.page.scss'], -}) -export class ViewMessagePage implements OnInit { - public message!: Message; - private data = inject(DataService); - private activatedRoute = inject(ActivatedRoute); - private platform = inject(Platform); - - constructor() {} - - ngOnInit() { - const id = this.activatedRoute.snapshot.paramMap.get('id') as string; - this.message = this.data.getMessageById(parseInt(id, 10)); - } - - getBackButtonText() { - const isIos = this.platform.is('ios') - return isIos ? 'Inbox' : ''; - } -} diff --git a/verag.njsproj b/verag.njsproj new file mode 100644 index 0000000..b8477ee --- /dev/null +++ b/verag.njsproj @@ -0,0 +1,1480 @@ + + + + Debug + 2.0 + {9f7038b1-f317-4f61-aa11-1a3bfb65e29e} + . + ShowAllFiles + capacitor.config.ts + . + . + {3AF33F2E-1136-4D97-BBB7-1795711AC8B8};{349c5851-65df-11da-9384-00065b846f21};{9092AA53-FB77-4645-B42D-1CCCA6BD08BD} + true + 17.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + True + 0 + / + http://localhost:48022/ + False + True + http://localhost:1337 + False + + + + + + + CurrentPage + True + False + False + False + + + + + + + + + False + False + + + + + \ No newline at end of file diff --git a/verag.njsproj.user b/verag.njsproj.user new file mode 100644 index 0000000..db86229 --- /dev/null +++ b/verag.njsproj.user @@ -0,0 +1,6 @@ + + + + Debug|Any CPU + + \ No newline at end of file diff --git a/verag.sln b/verag.sln new file mode 100644 index 0000000..e69de29 diff --git a/verage.njsproj b/verage.njsproj new file mode 100644 index 0000000..c9c4235 --- /dev/null +++ b/verage.njsproj @@ -0,0 +1,1481 @@ + + + + Debug + 2.0 + {1d4bd177-e7c5-4cff-8e06-5fa200e6f887} + . + ShowAllFiles + capacitor.config.ts + . + . + {3AF33F2E-1136-4D97-BBB7-1795711AC8B8};{349c5851-65df-11da-9384-00065b846f21};{9092AA53-FB77-4645-B42D-1CCCA6BD08BD} + true + 17.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + True + 0 + / + http://localhost:48022/ + False + True + http://localhost:1337 + False + + + + + + + CurrentPage + True + False + False + False + + + + + + + + + False + False + + + + + \ No newline at end of file diff --git a/verage.njsproj.user b/verage.njsproj.user new file mode 100644 index 0000000..3fb2ba8 --- /dev/null +++ b/verage.njsproj.user @@ -0,0 +1,9 @@ + + + + Debug|Any CPU + + + + + \ No newline at end of file