diff --git a/app/app-upgraded-providers.ts b/app/app-upgraded-providers.ts index 6f8866bac..40ba48f24 100644 --- a/app/app-upgraded-providers.ts +++ b/app/app-upgraded-providers.ts @@ -14,6 +14,7 @@ import {kommonitorScriptHelperService} from'util/genericServices/kommonitorScrip import {kommonitorShareHelperService} from 'util/genericServices/kommonitorShareHelperService/kommonitor-share-helper-service.module' import {kommonitorSingleFeatureMapHelperService} from 'util/genericServices/kommonitorSingleFeatureMapHelperService/kommonitor-single-feature-map-helper-service.module' import {kommonitorVisualStyleHelperService} from 'util/genericServices/kommonitorVisualStyleHelperService/kommonitor-visual-style-helper-service.module' +import { kommonitorToastHelperService } from 'util/genericServices/kommonitorToastHelperService/kommonitor-toast-helper-service.module'; export function kommonitorCacheHelperServiceFactory(injector:any){ return injector.get('kommonitorCacheHelperService'); @@ -168,6 +169,17 @@ export const ajskommonitorElementVisibilityHelperServiceProvider: any = { useFactory:kommonitorElementVisibilityHelperServiceFactory, }; +// Toast Helper Service +export function kommonitorToastHelperServiceFactory(injector: any) { + return injector.get('kommonitorToastHelperService') +} + +export const ajskommonitorToastHelperServiceProvider: any = { + deps: ['$injector'], + provide: 'kommonitorToastHelperService', + useFactory: kommonitorToastHelperServiceFactory, +}; + export const serviceProviders: any[] = [ ajskommonitorCacheHelperServiceProvider, @@ -183,5 +195,6 @@ export const ajskommonitorElementVisibilityHelperServiceProvider: any = { ajskommonitorShareHelperServiceProvider, ajskommonitorSingleFeatureMapServiceProvider, ajskommonitorVisualStyleHelperServiceProvider, - ajskommonitorElementVisibilityHelperServiceProvider + ajskommonitorElementVisibilityHelperServiceProvider, + ajskommonitorToastHelperServiceProvider ]; diff --git a/app/app.css b/app/app.css index c830a1760..971a2153d 100644 --- a/app/app.css +++ b/app/app.css @@ -1766,6 +1766,22 @@ aside{ width: 0; opacity: 0; } +#sidebarNotifier { + /* min-width: 35%; */ + max-width: 35%; + width:100%; + height: 100%; + /* min-height: 100vh; */ + background: rgb(236,240,245); + transition: opacity 0.3s; + overflow-y: auto; + overflow-x: hidden; +} + +#sidebarNotifier.disappear { + width: 0; + opacity: 0; +} #sidebarFilter { /* min-width: 35%; */ @@ -1942,6 +1958,17 @@ transition: opacity 0.3s; overflow: auto; } +#kommonitorNotifier{ + margin-left: 1%; + margin-right: 1%; + font-size: 12px; + /* margin-top: 1%x; */ + z-index: 1000; + height: 99%; + max-height: 99%; + overflow: auto; +} + #kommonitorFilter{ margin-left: 1%; margin-right: 1%; diff --git a/app/app.module.ts b/app/app.module.ts index bcc9e6521..373b49328 100644 --- a/app/app.module.ts +++ b/app/app.module.ts @@ -11,7 +11,7 @@ import angular from "angular"; import { RouterModule, Routes } from '@angular/router'; import { HashLocationStrategy, LocationStrategy } from '@angular/common'; -import { +import { ajskommonitorCacheHelperServiceProvider, ajskommonitorBatchUpdateHelperServiceProvider, ajskommonitorConfigStorageServiceProvider, @@ -20,13 +20,16 @@ import { ajskommonitorDiagramHelperServiceProvider, ajskommonitorFilterHelperServiceProvider, ajskommonitorKeycloackHelperServiceProvider, - ajskommonitorMultiStepFormHelperServiceProvider, + ajskommonitorMultiStepFormHelperServiceProvider, ajskommonitorSingleFeatureMapServiceProvider, ajskommonitorElementVisibilityHelperServiceProvider, ajskommonitorShareHelperServiceProvider, - ajskommonitorVisualStyleHelperServiceProvider } from 'app-upgraded-providers'; + ajskommonitorVisualStyleHelperServiceProvider, + ajskommonitorToastHelperServiceProvider +} from 'app-upgraded-providers'; import { InfoModalComponent } from 'components/ngComponents/userInterface/infoModal/info-modal.component'; import { KommonitorLegendComponent } from 'components/ngComponents/userInterface/kommonitorLegend/kommonitor-legend.component'; +import { GsocDemoComponent } from 'components/gsoc-demo/gsoc-demo.component'; import { NgbCalendar, NgbDatepickerModule, NgbDateStruct, NgbAccordionModule, NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { FormsModule } from '@angular/forms'; import { JsonPipe } from '@angular/common'; @@ -43,9 +46,9 @@ declare var MathJax; BrowserModule, UpgradeModule, RouterModule.forRoot(routes , { useHash: true }), - NgbDatepickerModule, + NgbDatepickerModule, NgbAccordionModule, - FormsModule, + FormsModule, JsonPipe ], providers:[ @@ -56,13 +59,14 @@ declare var MathJax; ajskommonitorDataGridHelperServiceProvider,ajskommonitorSingleFeatureMapServiceProvider, ajskommonitorDiagramHelperServiceProvider,ajskommonitorFilterHelperServiceProvider, ajskommonitorElementVisibilityHelperServiceProvider, ajskommonitorShareHelperServiceProvider, - ajskommonitorVisualStyleHelperServiceProvider, + ajskommonitorVisualStyleHelperServiceProvider, ajskommonitorToastHelperServiceProvider, NgbModule ], declarations: [ InfoModalComponent, KommonitorLegendComponent, - KommonitorClassificationComponent + KommonitorClassificationComponent, + GsocDemoComponent ] }) @@ -88,13 +92,13 @@ export class AppModule implements DoBootstrap { // init keycloak authentication await this.initKeycloak(); - + this.upgrade.bootstrap(document.documentElement, ['kommonitorClient']); // setUpLocationSync(this.upgrade); } - private downgradeDependencies(): void { + private downgradeDependencies(): void { // to inject already upgraded KomMonitor Angular components into "old" AngluarJS components, we must do 2 things // 1. downgrade the new Angular component and register it as directive within each requiring AngularJS module/component @@ -111,9 +115,11 @@ export class AppModule implements DoBootstrap { angular.module('kommonitorUserInterface') .directive('kommonitorLegendNew', downgradeComponent({ component: KommonitorLegendComponent }) as angular.IDirectiveFactory); - /* angular.module('kommonitorUserInterface') - .directive('versionInfo', downgradeComponent({ component: VersionInfoComponent }) as angular.IDirectiveFactory); - */ + angular.module('kommonitorUserInterface') + .directive('appGsocDemo', downgradeComponent({ component: GsocDemoComponent }) as angular.IDirectiveFactory); + /* angular.module('kommonitorUserInterface') + .directive('versionInfo', downgradeComponent({ component: VersionInfoComponent }) as angular.IDirectiveFactory); + */ console.log("registered downgraded Angular components for AngularJS usage"); } @@ -327,27 +333,27 @@ export class AppModule implements DoBootstrap { // custom unique filter angular.module('kommonitorClient').filter('unique', function () { - return function (collection, primaryKey) { //no need for secondary key + return function (collection, primaryKey) { //no need for secondary key var output :string[] = [], keys :string[] = []; - var splitKeys = primaryKey.split('.'); //split by period + var splitKeys = primaryKey.split('.'); //split by period - angular.forEach(collection, function (item: string) { + angular.forEach(collection, function (item: string) { let key :string = ""; - angular.copy(item, key); - for (var i = 0; i < splitKeys.length; i++) { - key = key[splitKeys[i]]; - } + angular.copy(item, key); + for (var i = 0; i < splitKeys.length; i++) { + key = key[splitKeys[i]]; + } - if (keys.indexOf(key) === -1) { - keys.push(key); - output.push(item); - } - }); + if (keys.indexOf(key) === -1) { + keys.push(key); + output.push(item); + } + }); - return output; - }; + return output; + }; }); angular.module('kommonitorClient').service("ControlsConfigService", ['$http', function ($http) { diff --git a/app/components/gsoc-demo/gsoc-demo.component.html b/app/components/gsoc-demo/gsoc-demo.component.html new file mode 100644 index 000000000..587de6100 --- /dev/null +++ b/app/components/gsoc-demo/gsoc-demo.component.html @@ -0,0 +1,64 @@ +
+ +

+ + +
+
+

Configure Toast Notifications

+ +
+ +
+
+
+ + + + +
+ + + +
+ + + + + + +
+ + + + + + + +
+ + + + + + + + +
+
+ +
\ No newline at end of file diff --git a/app/components/gsoc-demo/gsoc-demo.component.spec.ts b/app/components/gsoc-demo/gsoc-demo.component.spec.ts new file mode 100644 index 000000000..f00dcc3a3 --- /dev/null +++ b/app/components/gsoc-demo/gsoc-demo.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { GsocDemoComponent } from './gsoc-demo.component'; + +describe('GsocDemoComponent', () => { + let component: GsocDemoComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [GsocDemoComponent] + }); + fixture = TestBed.createComponent(GsocDemoComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/app/components/gsoc-demo/gsoc-demo.component.ts b/app/components/gsoc-demo/gsoc-demo.component.ts new file mode 100644 index 000000000..5e770db4d --- /dev/null +++ b/app/components/gsoc-demo/gsoc-demo.component.ts @@ -0,0 +1,80 @@ +import { Component, Input, Output, EventEmitter } from '@angular/core'; +import { KommonitorToastHelperService } from 'services/kommonitor-toast-helper-service/kommonitor-toast-helper.service'; + +interface ToastConfig { + title: string; + message: string; + type: 'info' | 'success' | 'warning' | 'error'; + position: 'default' | 'upperLeft' | 'upperRight'; +} + +@Component({ + selector: 'app-gsoc-demo', + templateUrl: './gsoc-demo.component.html', +}) +export class GsocDemoComponent { + @Input() isVisible: boolean = false; + @Output() closeRequest = new EventEmitter(); + + toastConfig: ToastConfig = { + title: '', + message: '', + type: 'info', + position: 'default', + }; + + constructor( + private toastService: KommonitorToastHelperService + ) { } + + closeModal() { + console.log('Close modal called'); + this.closeRequest.emit(); + } + + showToast(): void { + console.log('Attempting to show toast', this.toastConfig); + + if (!this.toastConfig.message.trim()) { + console.warn('Toast message is empty'); + return; + } + + try { + // Directly call the appropriate toast method + const methodMap = { + default: { + success: this.toastService.displaySuccessToast.bind(this.toastService), + info: this.toastService.displayInfoToast.bind(this.toastService), + warning: this.toastService.displayWarningToast.bind(this.toastService), + error: this.toastService.displayErrorToast.bind(this.toastService) + }, + upperLeft: { + success: this.toastService.displaySuccessToast_upperLeft.bind(this.toastService), + info: this.toastService.displayInfoToast_upperLeft.bind(this.toastService), + warning: this.toastService.displayWarningToast_upperLeft.bind(this.toastService), + error: this.toastService.displayErrorToast_upperLeft.bind(this.toastService) + }, + upperRight: { + success: this.toastService.displaySuccessToast_upperRight.bind(this.toastService), + info: this.toastService.displayInfoToast_upperRight.bind(this.toastService), + warning: this.toastService.displayWarningToast_upperRight.bind(this.toastService), + error: this.toastService.displayErrorToast_upperRight.bind(this.toastService) + } + }; + + // Get the correct method based on position and type + const toastMethod = methodMap[this.toastConfig.position][this.toastConfig.type]; + + // Call the method with title and message + toastMethod(this.toastConfig.title, this.toastConfig.message); + + console.log('Toast displayed successfully'); + } catch (error) { + console.error('Error displaying toast:', error); + + // Fallback alert + alert(`${this.toastConfig.type.toUpperCase()}: ${this.toastConfig.title}\n${this.toastConfig.message}`); + } + } +} \ No newline at end of file diff --git a/app/components/kommonitorUserInterface/kommonitor-user-interface.component.js b/app/components/kommonitorUserInterface/kommonitor-user-interface.component.js index 38ca6cee2..fd0b0cead 100644 --- a/app/components/kommonitorUserInterface/kommonitor-user-interface.component.js +++ b/app/components/kommonitorUserInterface/kommonitor-user-interface.component.js @@ -95,6 +95,7 @@ angular.module('kommonitorUserInterface').component('kommonitorUserInterface', { $scope.sidebarReachabilityClass = "disappear"; $scope.sidebarPoiClass = "disappear"; $scope.sidebarDataImportClass = "disappear"; + $scope.sidebarNotifierClass = "disappear"; $scope.sidebarLegendClass = ""; @@ -108,6 +109,7 @@ angular.module('kommonitorUserInterface').component('kommonitorUserInterface', { $scope.buttonReachabilityClass = "btn btn-custom btn-circle"; $scope.buttonPoiClass = "btn btn-custom btn-circle"; $scope.buttonDataImportClass = "btn btn-custom btn-circle"; + $scope.buttonNotifierClass = "btn btn-custom btn-circle"; $scope.buttonLegendClass = "btn btn-custom-docked-right btn-docked-right"; @@ -195,6 +197,7 @@ angular.module('kommonitorUserInterface').component('kommonitorUserInterface', { $scope.buttonReachabilityClass = "btn btn-custom btn-circle"; $scope.buttonPoiClass = "btn btn-custom btn-circle"; $scope.buttonDataImportClass = "btn btn-custom btn-circle"; + $scope.buttonNotifierClass = "btn btn-custom btn-circle"; // in addition check if balance menue and button are allowed for current indicator // it is not allowed if indicator is of type "DYNAMIC" @@ -212,6 +215,7 @@ angular.module('kommonitorUserInterface').component('kommonitorUserInterface', { $scope.sidebarReachabilityClass = "disappear"; $scope.sidebarPoiClass = "disappear"; $scope.sidebarDataImportClass = "disappear"; + $scope.sidebarNotifierClass = "disappear"; }; $scope.checkBalanceButtonAndMenueState = function(){ @@ -229,6 +233,30 @@ angular.module('kommonitorUserInterface').component('kommonitorUserInterface', { $scope.checkBalanceButtonAndMenueState(); }); + $scope.onSidebarNotifierButtonClick = function () { + $scope.undockButtons(); + + if ($scope.sidebarNotifierClass == "disappear") { + console.log("Hiding Sidebar..."); + $scope.hideSidebars(); + $scope.sidebarNotifierClass = ""; // Remove class to show sidebar + $scope.buttonNotifierClass = "btn btn-custom-docked btn-docked"; + + if (!kommonitorDataExchangeService.anySideBarIsShown) { + $rootScope.$broadcast("recenterMapOnShowSideBar"); + } + kommonitorDataExchangeService.anySideBarIsShown = true; + } else { + + $scope.sidebarNotifierClass = "disappear"; // Add class to hide sidebar + $rootScope.$broadcast("recenterMapOnHideSideBar"); + kommonitorDataExchangeService.anySideBarIsShown = false; + } + + $rootScope.$broadcast("refreshIndicatorValueRangeSlider"); + $rootScope.$broadcast("redrawGuidedTourElement"); + }; + $scope.onSidebarIndicatorButtonClick = function(){ $scope.undockButtons(); diff --git a/app/components/kommonitorUserInterface/kommonitor-user-interface.component.ts b/app/components/kommonitorUserInterface/kommonitor-user-interface.component.ts index 4c8a2733f..94465f9d8 100644 --- a/app/components/kommonitorUserInterface/kommonitor-user-interface.component.ts +++ b/app/components/kommonitorUserInterface/kommonitor-user-interface.component.ts @@ -43,6 +43,7 @@ angular.module('kommonitorUserInterface').component('kommonitorUserInterface', { $scope.sidebarReachabilityClass = "disappear"; $scope.sidebarPoiClass = "disappear"; $scope.sidebarDataImportClass = "disappear"; + $scope.sidebarNotifierClass = "disappear"; $scope.sidebarLegendClass = ""; @@ -56,6 +57,7 @@ angular.module('kommonitorUserInterface').component('kommonitorUserInterface', { $scope.buttonReachabilityClass = "btn btn-custom btn-circle"; $scope.buttonPoiClass = "btn btn-custom btn-circle"; $scope.buttonDataImportClass = "btn btn-custom btn-circle"; + $scope.buttonNotifierClass = "btn btn-custom btn-circle"; $scope.buttonLegendClass = "btn btn-custom-docked-right btn-docked-right"; @@ -138,7 +140,7 @@ angular.module('kommonitorUserInterface').component('kommonitorUserInterface', { $scope.buttonReachabilityClass = "btn btn-custom btn-circle"; $scope.buttonPoiClass = "btn btn-custom btn-circle"; $scope.buttonDataImportClass = "btn btn-custom btn-circle"; - + $scope.buttonNotifierClass = "btn btn-custom btn-circle"; // in addition check if balance menue and button are allowed for current indicator // it is not allowed if indicator is of type "DYNAMIC" $scope.checkBalanceButtonAndMenueState(); @@ -155,6 +157,7 @@ angular.module('kommonitorUserInterface').component('kommonitorUserInterface', { $scope.sidebarReachabilityClass = "disappear"; $scope.sidebarPoiClass = "disappear"; $scope.sidebarDataImportClass = "disappear"; + $scope.sidebarNotifierClass = "disappear"; }; $scope.checkBalanceButtonAndMenueState = function(){ @@ -172,6 +175,30 @@ angular.module('kommonitorUserInterface').component('kommonitorUserInterface', { $scope.checkBalanceButtonAndMenueState(); }); + $scope.onSidebarNotifierButtonClick = function () { + $scope.undockButtons(); + + if ($scope.sidebarNotifierClass === "disappear") { + $scope.hideSidebars(); + $scope.sidebarNotifierClass = ""; + $scope.buttonNotifierClass = "btn btn-custom-docked btn-docked"; + + if (kommonitorDataExchangeService.anySideBarIsShown === false) { + $rootScope.$broadcast("recenterMapOnShowSideBar"); + } + kommonitorDataExchangeService.anySideBarIsShown = true; + } + else { + $scope.sidebarNotifierClass = "disappear"; + $rootScope.$broadcast("recenterMapOnHideSideBar"); + kommonitorDataExchangeService.anySideBarIsShown = false; + } + + $rootScope.$broadcast("refreshIndicatorValueRangeSlider"); + $rootScope.$broadcast("redrawGuidedTourElement"); + + } + $scope.onSidebarIndicatorButtonClick = function(){ $scope.undockButtons(); diff --git a/app/components/kommonitorUserInterface/kommonitor-user-interface.template.html b/app/components/kommonitorUserInterface/kommonitor-user-interface.template.html index d8b5e175d..61cf27d74 100644 --- a/app/components/kommonitorUserInterface/kommonitor-user-interface.template.html +++ b/app/components/kommonitorUserInterface/kommonitor-user-interface.template.html @@ -149,6 +149,10 @@

Gruppen (Hierarchie)

+ + @@ -208,6 +212,10 @@

Gruppen (Hierarchie)

+