From e1ae0a36d75c4d4c37e585f27c8aacd60dd8cd90 Mon Sep 17 00:00:00 2001 From: Schneider Roland Date: Thu, 27 Nov 2025 06:50:39 +0100 Subject: [PATCH] implement edit event --- .../components/detail-view/detail-view.css | 0 .../components/detail-view/detail-view.html | 28 ++++++++ .../detail-view/detail-view.spec.ts | 23 ++++++ .../app/components/detail-view/detail-view.ts | 70 +++++++++++++++++++ .../calendar-view/calendar-view.html | 17 +++-- .../components/calendar-view/calendar-view.ts | 56 +++++---------- .../single-event-dashboard.css | 0 .../single-event-dashboard.html | 3 + .../single-event-dashboard.ts | 28 ++++++++ 9 files changed, 180 insertions(+), 45 deletions(-) create mode 100644 admin/src/app/components/detail-view/detail-view.css create mode 100644 admin/src/app/components/detail-view/detail-view.html create mode 100644 admin/src/app/components/detail-view/detail-view.spec.ts create mode 100644 admin/src/app/components/detail-view/detail-view.ts create mode 100644 admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.css create mode 100644 admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.html create mode 100644 admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.ts diff --git a/admin/src/app/components/detail-view/detail-view.css b/admin/src/app/components/detail-view/detail-view.css new file mode 100644 index 0000000..e69de29 diff --git a/admin/src/app/components/detail-view/detail-view.html b/admin/src/app/components/detail-view/detail-view.html new file mode 100644 index 0000000..586fe53 --- /dev/null +++ b/admin/src/app/components/detail-view/detail-view.html @@ -0,0 +1,28 @@ +{{config().data}} +@if (config().data){ +
+ + + @for (row of config().rows; track row.attribute) { + + + + + } + +
+ @if (row.titleComponent) { + + } @else { + {{ getTitle(row, config().data) }} + } + + @if (row.component) { + + } @else { + {{ getFormattedValue(row, config().data) }} + } +
+
+ +} diff --git a/admin/src/app/components/detail-view/detail-view.spec.ts b/admin/src/app/components/detail-view/detail-view.spec.ts new file mode 100644 index 0000000..bd5e1bc --- /dev/null +++ b/admin/src/app/components/detail-view/detail-view.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DetailView } from './detail-view'; + +describe('DetailView', () => { + let component: DetailView; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [DetailView] + }) + .compileComponents(); + + fixture = TestBed.createComponent(DetailView); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/admin/src/app/components/detail-view/detail-view.ts b/admin/src/app/components/detail-view/detail-view.ts new file mode 100644 index 0000000..7c45859 --- /dev/null +++ b/admin/src/app/components/detail-view/detail-view.ts @@ -0,0 +1,70 @@ +import { Component, input, Type } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +export interface CellComponent { + component?: Type; + componentInputs?: (obj: T) => { [key: string]: any }; +} + +export interface DetailViewRow extends CellComponent { + attribute: keyof T; + getValue?: (obj: T) => any; + format?: 'date' | 'datetime' | 'number' | 'raw' | ((value: any) => string); + getTitle?: string | ((obj: T) => string); + getDetailClass?: (obj: T) => string; + getTitleStyleClass?: (obj: T) => string; + getValueStyleClass?: (obj: T) => string; + titleComponent?: Type; + titleComponentInputs?: (obj: T) => { [key: string]: any }; +} + +export interface DetailViewConfig { + data: T; + rows: DetailViewRow[]; + styleClass?: string; +} + +@Component({ + selector: 'app-detail-view', + imports: [CommonModule], + templateUrl: './detail-view.html', + styleUrl: './detail-view.css', +}) +export class DetailView { + config = input.required>(); + + getFormattedValue(row: DetailViewRow, data: T): string { + const value = row.getValue ? row.getValue(data) : data[row.attribute]; + + if (row.component) { + return ''; + } + + if (typeof row.format === 'function') { + return row.format(value); + } + + switch (row.format) { + case 'date': + return new Date(value).toLocaleDateString(); + case 'datetime': + return new Date(value).toLocaleString(); + case 'number': + return Number(value).toString(); + case 'raw': + default: + return value; + } + } + + getTitle(row: DetailViewRow, data: T): string { + if (row.titleComponent) { + return ''; + } + + if (typeof row.getTitle === 'function') { + return row.getTitle(data); + } + return row.getTitle || String(row.attribute); + } +} diff --git a/admin/src/app/features/calendar/components/calendar-view/calendar-view.html b/admin/src/app/features/calendar/components/calendar-view/calendar-view.html index 81b9330..3daf11d 100644 --- a/admin/src/app/features/calendar/components/calendar-view/calendar-view.html +++ b/admin/src/app/features/calendar/components/calendar-view/calendar-view.html @@ -6,11 +6,18 @@ - - - @if (isOpen()){ - +{{"workflow:"+workflow()}} + + @if (workflow() == 'create') { + } - + + +@if (workflow() == 'event-dashboard' && selectedEvent()) { + + + +} diff --git a/admin/src/app/features/calendar/components/calendar-view/calendar-view.ts b/admin/src/app/features/calendar/components/calendar-view/calendar-view.ts index 8f5fc24..907590f 100644 --- a/admin/src/app/features/calendar/components/calendar-view/calendar-view.ts +++ b/admin/src/app/features/calendar/components/calendar-view/calendar-view.ts @@ -9,13 +9,13 @@ import interactionPlugin from '@fullcalendar/interaction'; import { Modal } from '@rschneider/ng-daisyui'; import { CreateEventForm } from '../create-event-form/create-event-form'; import { CalendarService } from '../../services/calendar.service'; -import { addDays, subDays } from 'date-fns'; -import { EventsInRangeDTO } from '../../models/events-in-range-dto.model'; +import { CalendarEventDto, EventsInRangeDTO } from '../../models/events-in-range-dto.model'; import { map } from 'rxjs'; +import { SingleEventDashboard } from './single-event-dashboard/single-event-dashboard'; @Component({ selector: 'app-calendar-view', - imports: [FullCalendarModule, Modal, CreateEventForm], + imports: [FullCalendarModule, Modal, CreateEventForm, SingleEventDashboard], templateUrl: './calendar-view.html', styleUrl: './calendar-view.css', }) @@ -27,67 +27,40 @@ export class CalendarView implements OnInit, AfterViewInit { calendarService = inject(CalendarService); workflow = signal(''); - isOpen = signal(false); selectedDate = signal(undefined); - selectedEventId = signal(undefined) - - events = signal([]); + selectedEvent = signal(undefined) calendarOptions: CalendarOptions; constructor() { - const start = new Date(); - start.setHours(10, 0, 0); - const end = new Date(); - end.setHours(11, 0, 0); - this.calendarOptions = { plugins: [dayGridPlugin, timeGridPlugin, listPlugin, interactionPlugin], initialView: 'dayGridMonth', weekends: true, + firstDay: 1, headerToolbar: { left: 'prev,next,today', center: 'title', - // right: 'dayGridMonth,dayGridWeek,dayGridDay' // user can switch between the two right: 'dayGridMonth,dayGridWeek,dayGridDay,timeGridWeek,timeGridDay,listWeek', }, events: this.fetchEvents.bind(this), // Bind the context - eventClick: function(info) { - console.info('Event info: ', info); - - // change the border color just for fun - info.el.style.borderColor = 'red'; + eventClick: (info) => { + this.selectedEvent.set(info.event.extendedProps['event']); + this.workflow.set('event-dashboard'); }, dateClick: (info) => { - console.info('setting day ',info); - this.workflow.set('day'); + console.info('create new evet for day ',info); + this.workflow.set('create'); this.selectedDate.set(info.date); - this.selectedEventId.set(undefined); - console.info("date click with", this.selectedDate()) - this.isOpen.set(true); - // console.info('Date click on: ' , info); - // const calendarApi = info.view.calendar; - // const start = new Date(info.date.getTime()) - // start.setHours(2,0,0) - // const end = new Date(info.date.getTime()) - // end.setHours(3,0,0) - // calendarApi.addEvent({ - // title: 'New Event', - // start, - // end, - // }); + this.selectedEvent.set(undefined); }, }; - effect(() => { - // this.calendarOptions.events = this.events - - }); } fetchEvents(fetchInfo: any, successCallback: (events: EventInput[]) => void, failureCallback: (error: any) => void): void { @@ -111,7 +84,10 @@ export class CalendarView implements OnInit, AfterViewInit { const calendarEvent: EventInput = { start: new Date(model.startTime), // end: model.end_time, - title: model.title + title: model.title, + extendedProps: { + event: value + } }; if ( model.eventType){ calendarEvent.borderColor = model.eventType.color; @@ -160,6 +136,6 @@ export class CalendarView implements OnInit, AfterViewInit { } closeDialog() { - this.isOpen.set(false); + this.workflow.set(''); } } diff --git a/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.css b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.css new file mode 100644 index 0000000..e69de29 diff --git a/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.html b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.html new file mode 100644 index 0000000..fce4be3 --- /dev/null +++ b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.html @@ -0,0 +1,3 @@ + diff --git a/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.ts b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.ts new file mode 100644 index 0000000..5f3b128 --- /dev/null +++ b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard/single-event-dashboard.ts @@ -0,0 +1,28 @@ +import { Component, input, signal } from '@angular/core'; +import { CalendarEventDto, EventsInRangeDTO } from '../../../models/events-in-range-dto.model'; +import { DetailView, DetailViewConfig } from '../../../../../components/detail-view/detail-view'; + +@Component({ + selector: 'app-single-event-dashboard', + imports: [ + DetailView, + ], + templateUrl: './single-event-dashboard.html', + styleUrl: './single-event-dashboard.css', +}) +export class SingleEventDashboard { + + event = input(); + + config: DetailViewConfig; + constructor() { + this.config = { + data: this.event()!, + + rows: [{ + attribute: 'title', + getTitle: 'title', + }] + } + } +}