add calendar dashboard edit
This commit is contained in:
parent
a043d64229
commit
fa098f4a1b
@ -1,18 +1,18 @@
|
|||||||
<div>
|
<div>
|
||||||
<h1>Naptár</h1>
|
<h1>Naptár</h1>
|
||||||
<div>
|
<!-- <div>-->
|
||||||
<input type="text" name="startHour" id="starthour" #startHour>
|
<!-- <input type="text" name="startHour" id="starthour" #startHour>-->
|
||||||
<a class="btn" (click)="addEvent($event)">add</a>
|
<!-- <a class="btn" (click)="addEvent($event)">add</a>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
<full-calendar #calendar [options]="calendarOptions"></full-calendar>
|
<full-calendar #calendar [options]="calendarOptions"></full-calendar>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<rs-daisy-modal [isOpen]="workflow() == 'create'" (closeClick)="closeDialog()">
|
@if (workflow() == 'event-create') {
|
||||||
@if (workflow() == 'create') {
|
<rs-daisy-modal [isOpen]="true" (closeClick)="closeDialog()" [modalBoxStyleClass]="'max-w-none w-2xl'">
|
||||||
<app-create-event-form (ready)="closeDialog()" [date]="selectedDate()"
|
<app-create-event-form (ready)="closeDialog()" [date]="selectedDate()"
|
||||||
[id]="undefined"></app-create-event-form>
|
[id]="undefined"></app-create-event-form>
|
||||||
}
|
|
||||||
</rs-daisy-modal>
|
</rs-daisy-modal>
|
||||||
|
}
|
||||||
|
|
||||||
@if (workflow() == 'event-dashboard' && selectedEvent()) {
|
@if (workflow() == 'event-dashboard' && selectedEvent()) {
|
||||||
<rs-daisy-modal [isOpen]="true" (closeClick)="closeDialog()" [modalBoxStyleClass]="'max-w-none w-2xl'">
|
<rs-daisy-modal [isOpen]="true" (closeClick)="closeDialog()" [modalBoxStyleClass]="'max-w-none w-2xl'">
|
||||||
@ -27,7 +27,7 @@
|
|||||||
@if (dialogDefinition.isRendered()) {
|
@if (dialogDefinition.isRendered()) {
|
||||||
<rs-daisy-modal [isOpen]="true" (closeClick)="closeDialog()" [modalBoxStyleClass]="'max-w-none w-2xl'">
|
<rs-daisy-modal [isOpen]="true" (closeClick)="closeDialog()" [modalBoxStyleClass]="'max-w-none w-2xl'">
|
||||||
<ng-container
|
<ng-container
|
||||||
*ngComponentOutlet="dialogDefinition.component; inputs: dialogDefinition.componentInputs ? dialogDefinition.componentInputs() : {}; injector: dialogDefinition.componentOutputs()"
|
*ngComponentOutlet="dialogDefinition.component; inputs: dialogDefinition.componentInputs ? dialogDefinition.componentInputs() : {}; "
|
||||||
></ng-container>
|
></ng-container>
|
||||||
</rs-daisy-modal>
|
</rs-daisy-modal>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
AfterViewInit,
|
|
||||||
Component,
|
Component,
|
||||||
effect,
|
|
||||||
ElementRef,
|
ElementRef,
|
||||||
inject,
|
inject,
|
||||||
Injector,
|
|
||||||
OnInit,
|
|
||||||
signal,
|
signal,
|
||||||
Type,
|
Type,
|
||||||
ViewChild,
|
ViewChild,
|
||||||
@ -17,27 +13,28 @@ import dayGridPlugin from '@fullcalendar/daygrid';
|
|||||||
import timeGridPlugin from '@fullcalendar/timegrid';
|
import timeGridPlugin from '@fullcalendar/timegrid';
|
||||||
import listPlugin from '@fullcalendar/list';
|
import listPlugin from '@fullcalendar/list';
|
||||||
import interactionPlugin from '@fullcalendar/interaction';
|
import interactionPlugin from '@fullcalendar/interaction';
|
||||||
import { Button, Modal } from '@rschneider/ng-daisyui';
|
import { Modal } from '@rschneider/ng-daisyui';
|
||||||
import { CreateEventForm } from '../create-event-form/create-event-form';
|
import { CreateEventForm } from '../create-event-form/create-event-form';
|
||||||
import { CalendarService } from '../../services/calendar.service';
|
import { CalendarService } from '../../services/calendar.service';
|
||||||
import { CalendarEventDto, EventsInRangeDTO } from '../../models/events-in-range-dto.model';
|
import { CalendarEventDto } from '../../models/events-in-range-dto.model';
|
||||||
import { map } from 'rxjs';
|
import { map } from 'rxjs';
|
||||||
import { SingleEventDashboard } from './single-event-dashboard/single-event-dashboard';
|
import { SingleEventDashboard } from './single-event-dashboard/single-event-dashboard';
|
||||||
import { CommonModule, JsonPipe, NgComponentOutlet } from '@angular/common';
|
import { CommonModule, NgComponentOutlet } from '@angular/common';
|
||||||
import {
|
import {
|
||||||
SingleEventDashboardEventDelete
|
SingleEventDashboardEventDelete,
|
||||||
} from './single-event-dashboard-event-delete/single-event-dashboard-event-delete';
|
} from './single-event-dashboard-event-delete/single-event-dashboard-event-delete';
|
||||||
import {
|
import {
|
||||||
SingleEventDashboardEventCancel
|
SingleEventDashboardEventCancel,
|
||||||
} from './single-event-dashboard-event-cancel/single-event-dashboard-event-cancel';
|
} from './single-event-dashboard-event-cancel/single-event-dashboard-event-cancel';
|
||||||
|
import { SingleEventDashboardEventEdit } from './single-event-dashboard-event-edit/single-event-dashboard-event-edit';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-calendar-view',
|
selector: 'app-calendar-view',
|
||||||
imports: [FullCalendarModule, CommonModule, Modal,NgComponentOutlet, CreateEventForm, SingleEventDashboard, JsonPipe],
|
imports: [FullCalendarModule, CommonModule, Modal, NgComponentOutlet, CreateEventForm, SingleEventDashboard],
|
||||||
templateUrl: './calendar-view.html',
|
templateUrl: './calendar-view.html',
|
||||||
styleUrl: './calendar-view.css',
|
styleUrl: './calendar-view.css',
|
||||||
})
|
})
|
||||||
export class CalendarView implements OnInit, AfterViewInit {
|
export class CalendarView {
|
||||||
|
|
||||||
@ViewChild('startHour') startHour!: ElementRef;
|
@ViewChild('startHour') startHour!: ElementRef;
|
||||||
@ViewChild('calendar') calendarComponent: FullCalendarComponent | undefined;
|
@ViewChild('calendar') calendarComponent: FullCalendarComponent | undefined;
|
||||||
@ -45,8 +42,8 @@ export class CalendarView implements OnInit, AfterViewInit {
|
|||||||
calendarService = inject(CalendarService);
|
calendarService = inject(CalendarService);
|
||||||
|
|
||||||
workflow = signal<string>('');
|
workflow = signal<string>('');
|
||||||
selectedDate = signal<Date|undefined>(undefined);
|
selectedDate = signal<Date | undefined>(undefined);
|
||||||
selectedEvent = signal<CalendarEventDto|undefined>(undefined)
|
selectedEvent = signal<CalendarEventDto | undefined>(undefined);
|
||||||
|
|
||||||
calendarOptions: CalendarOptions;
|
calendarOptions: CalendarOptions;
|
||||||
dialogs: DialogConfig[] = [];
|
dialogs: DialogConfig[] = [];
|
||||||
@ -69,26 +66,17 @@ export class CalendarView implements OnInit, AfterViewInit {
|
|||||||
eventClick: (info) => {
|
eventClick: (info) => {
|
||||||
this.selectedEvent.set(info.event.extendedProps['event']);
|
this.selectedEvent.set(info.event.extendedProps['event']);
|
||||||
this.workflow.set('event-dashboard');
|
this.workflow.set('event-dashboard');
|
||||||
|
this.selectedDate.set(undefined);
|
||||||
},
|
},
|
||||||
|
|
||||||
dateClick: (info) => {
|
dateClick: (info) => {
|
||||||
console.info('create new evet for day ',info);
|
this.workflow.set('event-create');
|
||||||
this.workflow.set('create');
|
|
||||||
this.selectedDate.set(info.date);
|
this.selectedDate.set(info.date);
|
||||||
this.selectedEvent.set(undefined);
|
this.selectedEvent.set(undefined);
|
||||||
},
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const injector = Injector.create({
|
|
||||||
providers: [
|
|
||||||
{
|
|
||||||
provide: 'closeDialog',
|
|
||||||
useValue: () => this.closeDialog()
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
this.dialogs = [
|
this.dialogs = [
|
||||||
{
|
{
|
||||||
component: SingleEventDashboardEventDelete,
|
component: SingleEventDashboardEventDelete,
|
||||||
@ -99,10 +87,9 @@ export class CalendarView implements OnInit, AfterViewInit {
|
|||||||
componentInputs: () => {
|
componentInputs: () => {
|
||||||
return {
|
return {
|
||||||
'event': this.selectedEvent(),
|
'event': this.selectedEvent(),
|
||||||
'onAction': this.handleAction
|
'onAction': this.handleAction,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
componentOutputs: () => injector
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -115,13 +102,24 @@ export class CalendarView implements OnInit, AfterViewInit {
|
|||||||
componentInputs: () => {
|
componentInputs: () => {
|
||||||
return {
|
return {
|
||||||
'event': this.selectedEvent(),
|
'event': this.selectedEvent(),
|
||||||
'onAction': this.handleAction
|
'onAction': this.handleAction,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
componentOutputs: () => injector
|
},
|
||||||
|
{
|
||||||
}
|
component: SingleEventDashboardEventEdit,
|
||||||
]
|
isRendered: () => this.workflow() == 'event-edit',
|
||||||
|
// isRendered: () => true,
|
||||||
|
closeClick: () => this.closeDialog(),
|
||||||
|
modalBoxStyleClass: 'max-w-none w-2xl',
|
||||||
|
componentInputs: () => {
|
||||||
|
return {
|
||||||
|
'event': this.selectedEvent(),
|
||||||
|
'onAction': this.handleAction,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchEvents(fetchInfo: any, successCallback: (events: EventInput[]) => void, failureCallback: (error: any) => void): void {
|
fetchEvents(fetchInfo: any, successCallback: (events: EventInput[]) => void, failureCallback: (error: any) => void): void {
|
||||||
@ -129,39 +127,33 @@ export class CalendarView implements OnInit, AfterViewInit {
|
|||||||
console.info('fetching events', fetchInfo);
|
console.info('fetching events', fetchInfo);
|
||||||
const start = fetchInfo.start;
|
const start = fetchInfo.start;
|
||||||
const end = fetchInfo.end;
|
const end = fetchInfo.end;
|
||||||
// if ( fetchInfo ){
|
|
||||||
// console.info("fetchinfo", fetchInfo);
|
|
||||||
// successCallback([]);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
this.calendarService.getEventsInRange({
|
this.calendarService.getEventsInRange({
|
||||||
startTime: start,
|
startTime: start,
|
||||||
endTime: end,
|
endTime: end,
|
||||||
})
|
})
|
||||||
.pipe(
|
.pipe(
|
||||||
map(value => {
|
map(value => {
|
||||||
console.info("vent got" , value );
|
const events: EventInput[] = value.map((model) => {
|
||||||
const events: EventInput[] = value.map( (model) => {
|
|
||||||
const calendarEvent: EventInput = {
|
const calendarEvent: EventInput = {
|
||||||
start: new Date(model.startTime),
|
start: new Date(model.startTime),
|
||||||
// end: model.end_time,
|
// end: model.end_time,
|
||||||
title: model.title,
|
title: model.title,
|
||||||
extendedProps: {
|
extendedProps: {
|
||||||
event: model
|
event: model,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
if ( model.eventType){
|
if (model.eventType) {
|
||||||
calendarEvent.borderColor = model.eventType.color;
|
calendarEvent.borderColor = model.eventType.color;
|
||||||
}
|
}
|
||||||
// calendarEvent.backgroundColor = "#00ff00"
|
// calendarEvent.backgroundColor = "#00ff00"
|
||||||
return calendarEvent;
|
return calendarEvent;
|
||||||
})
|
});
|
||||||
return events;
|
return events;
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (events) => {
|
next: (events) => {
|
||||||
console.info("calendar events", events);
|
console.info('calendar events', events);
|
||||||
successCallback(events);
|
successCallback(events);
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
@ -173,44 +165,38 @@ export class CalendarView implements OnInit, AfterViewInit {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit(): void {
|
// protected addEvent($event: PointerEvent) {
|
||||||
|
// let hourStr = this.startHour.nativeElement.value;
|
||||||
}
|
// const hour = parseInt(hourStr, 10);
|
||||||
|
// const date = new Date();
|
||||||
ngOnInit(): void {
|
// const start = new Date(date.getTime());
|
||||||
|
// start.setHours(hour, 0, 0);
|
||||||
}
|
// const end = new Date(date.getTime());
|
||||||
|
// // end.setHours(3,0,0)
|
||||||
protected addEvent($event: PointerEvent) {
|
//
|
||||||
let hourStr = this.startHour.nativeElement.value;
|
// this.calendarComponent?.getApi().addEvent({
|
||||||
const hour = parseInt(hourStr, 10);
|
// title: 'Event at ' + hour,
|
||||||
const date = new Date();
|
// start,
|
||||||
const start = new Date(date.getTime());
|
// });
|
||||||
start.setHours(hour, 0, 0);
|
// }
|
||||||
const end = new Date(date.getTime());
|
|
||||||
// end.setHours(3,0,0)
|
|
||||||
|
|
||||||
this.calendarComponent?.getApi().addEvent({
|
|
||||||
title: 'Event at ' + hour,
|
|
||||||
start,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
closeDialog() {
|
closeDialog() {
|
||||||
this.workflow.set('');
|
this.workflow.set('');
|
||||||
}
|
}
|
||||||
|
|
||||||
onDashboardAction(action: string){
|
onDashboardAction(action: string) {
|
||||||
console.info("dashboard event", action);
|
console.info('dashboard event', action);
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case 'event_delete':
|
case 'event_delete':
|
||||||
this.workflow.set('event-delete');
|
this.workflow.set('event-delete');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'event_cancel':
|
case 'event_cancel':
|
||||||
console.info("event cancel clicked");
|
|
||||||
this.workflow.set('event-cancel');
|
this.workflow.set('event-cancel');
|
||||||
break;
|
break;
|
||||||
|
case 'event_edit':
|
||||||
|
this.workflow.set('event-edit');
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +204,7 @@ export class CalendarView implements OnInit, AfterViewInit {
|
|||||||
// This function is passed into the child
|
// This function is passed into the child
|
||||||
handleAction = (msg: string) => {
|
handleAction = (msg: string) => {
|
||||||
console.log('Parent received:', msg);
|
console.log('Parent received:', msg);
|
||||||
if ( msg == 'close'){
|
if (msg == 'close') {
|
||||||
this.closeDialog();
|
this.closeDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,11 +212,10 @@ export class CalendarView implements OnInit, AfterViewInit {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DialogConfig{
|
export interface DialogConfig {
|
||||||
component: Type<any>;
|
component: Type<any>;
|
||||||
componentInputs?: () => { [key: string]: any };
|
componentInputs?: () => { [key: string]: any };
|
||||||
closeClick: () => void,
|
closeClick: () => void,
|
||||||
modalBoxStyleClass: string
|
modalBoxStyleClass: string
|
||||||
isRendered: () => boolean;
|
isRendered: () => boolean;
|
||||||
componentOutputs: () => Injector
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
<app-create-event-form (ready)="onAction()" [date]="selectedDate()"
|
||||||
|
|
||||||
|
[id]="event()?.id"></app-create-event-form>
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
import { Component, input, signal } from '@angular/core';
|
||||||
|
import { CalendarEventDto } from '../../../models/events-in-range-dto.model';
|
||||||
|
import { SvgIcons } from '../../../../../svg-icons';
|
||||||
|
import { CreateEventForm } from '../../create-event-form/create-event-form';
|
||||||
|
import { Modal } from '@rschneider/ng-daisyui';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-single-event-dashboard-event-edit',
|
||||||
|
imports: [
|
||||||
|
CreateEventForm,
|
||||||
|
Modal,
|
||||||
|
],
|
||||||
|
templateUrl: './single-event-dashboard-event-edit.html',
|
||||||
|
styleUrl: './single-event-dashboard-event-edit.css',
|
||||||
|
})
|
||||||
|
export class SingleEventDashboardEventEdit {
|
||||||
|
|
||||||
|
selectedDate = signal<Date | undefined>(undefined);
|
||||||
|
event = input<CalendarEventDto>();
|
||||||
|
onAction = input.required<(msg: string) => void>();
|
||||||
|
|
||||||
|
protected readonly SvgIcons = SvgIcons;
|
||||||
|
|
||||||
|
protected triggerAction() {
|
||||||
|
|
||||||
|
this.onAction()('close')
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,5 @@
|
|||||||
<!-- Generated by the CLI -->
|
<!-- Generated by the CLI -->
|
||||||
<div class="p-4 md:p-8">
|
<div class="">
|
||||||
<div class="card bg-base-100 shadow-xl mx-auto">
|
|
||||||
<div class="card-body">
|
|
||||||
<h2 class="card-title text-3xl">
|
<h2 class="card-title text-3xl">
|
||||||
Esemény {{ isEditMode ? 'szerkesztése' : 'létrehozása' }}
|
Esemény {{ isEditMode ? 'szerkesztése' : 'létrehozása' }}
|
||||||
</h2>
|
</h2>
|
||||||
@ -38,7 +36,7 @@
|
|||||||
<input type="checkbox" formControlName="is_recurring" class="checkbox" />
|
<input type="checkbox" formControlName="is_recurring" class="checkbox" />
|
||||||
</label></div>
|
</label></div>
|
||||||
|
|
||||||
@if (isRecurring?.value) {
|
@if (isRecurring?.value === true) {
|
||||||
<div formGroupName="recurrenceRule" class="space-y-4 p-4 border border-base-300 rounded-lg">
|
<div formGroupName="recurrenceRule" class="space-y-4 p-4 border border-base-300 rounded-lg">
|
||||||
<h3 class="text-lg font-semibold">Ismétlődés</h3>
|
<h3 class="text-lg font-semibold">Ismétlődés</h3>
|
||||||
|
|
||||||
@ -114,6 +112,4 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Component, effect, input, OnInit, output, signal } from '@angular/core';
|
import { Component, input, OnInit, output, signal } from '@angular/core';
|
||||||
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { EventService } from '../../../events/services/event.service';
|
import { EventService } from '../../../events/services/event.service';
|
||||||
@ -9,6 +9,7 @@ import { EventType } from '../../../event-type/models/event-type.model';
|
|||||||
import { EventTypeService } from '../../../event-type/services/event-type.service';
|
import { EventTypeService } from '../../../event-type/services/event-type.service';
|
||||||
import { CalendarService } from '../../services/calendar.service';
|
import { CalendarService } from '../../services/calendar.service';
|
||||||
import { EventFormDTO } from '../../models/event-form-dto.model';
|
import { EventFormDTO } from '../../models/event-form-dto.model';
|
||||||
|
import { format } from 'date-fns';
|
||||||
|
|
||||||
export type Frequency = 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'YEARLY';
|
export type Frequency = 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'YEARLY';
|
||||||
export type FrequencyOption = {
|
export type FrequencyOption = {
|
||||||
@ -16,11 +17,10 @@ export type FrequencyOption = {
|
|||||||
label: string;
|
label: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-create-event-form',
|
selector: 'app-create-event-form',
|
||||||
imports: [
|
imports: [
|
||||||
ReactiveFormsModule
|
ReactiveFormsModule,
|
||||||
],
|
],
|
||||||
templateUrl: './create-event-form.html',
|
templateUrl: './create-event-form.html',
|
||||||
styleUrl: './create-event-form.css',
|
styleUrl: './create-event-form.css',
|
||||||
@ -29,27 +29,27 @@ export class CreateEventForm implements OnInit {
|
|||||||
form: FormGroup;
|
form: FormGroup;
|
||||||
isEditMode = false;
|
isEditMode = false;
|
||||||
ready = output<void>();
|
ready = output<void>();
|
||||||
id= input<number | undefined>() ;
|
id = input<number | undefined>();
|
||||||
date = input<Date|undefined>();
|
date = input<Date | undefined>();
|
||||||
eventTypes = signal<EventType[]>([])
|
eventTypes = signal<EventType[]>([]);
|
||||||
|
|
||||||
private numericFields: (keyof EventFormDTO)[] = ["event_type_id"];
|
private numericFields: (keyof EventFormDTO)[] = ['event_type_id'];
|
||||||
|
|
||||||
frequencyOptions: FrequencyOption[] = [
|
frequencyOptions: FrequencyOption[] = [
|
||||||
{
|
{
|
||||||
frequency: 'DAILY',
|
frequency: 'DAILY',
|
||||||
label: 'Napi'
|
label: 'Napi',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
frequency: 'WEEKLY',
|
frequency: 'WEEKLY',
|
||||||
label: 'Heti'
|
label: 'Heti',
|
||||||
}, {
|
}, {
|
||||||
frequency: 'MONTHLY',
|
frequency: 'MONTHLY',
|
||||||
label: 'Havi'
|
label: 'Havi',
|
||||||
},{
|
}, {
|
||||||
frequency: 'YEARLY',
|
frequency: 'YEARLY',
|
||||||
label: 'Éves'
|
label: 'Éves',
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
weekDayOptions = [
|
weekDayOptions = [
|
||||||
@ -68,36 +68,29 @@ export class CreateEventForm implements OnInit {
|
|||||||
private router: Router,
|
private router: Router,
|
||||||
private eventService: EventService,
|
private eventService: EventService,
|
||||||
private calendarService: CalendarService,
|
private calendarService: CalendarService,
|
||||||
private eventTypeService: EventTypeService
|
private eventTypeService: EventTypeService,
|
||||||
) {
|
) {
|
||||||
this.form = this.fb.group({
|
this.form = this.fb.group({
|
||||||
eventTypeId: [null,Validators.required],
|
eventTypeId: [null, Validators.required],
|
||||||
title: [null,Validators.required],
|
title: [null, Validators.required],
|
||||||
description: [null],
|
description: [null],
|
||||||
startTime: [null,Validators.required],
|
startTime: [null, Validators.required],
|
||||||
endTime: [null,Validators.required],
|
endTime: [null, Validators.required],
|
||||||
is_recurring: [false],
|
is_recurring: [false],
|
||||||
recurrenceRule: this.fb.group({
|
recurrenceRule: this.fb.group({
|
||||||
frequency: ['DAILY'] ,//'DAILY' | 'WEEKLY' | 'MONTHLY' | 'YEARLY';
|
frequency: ['DAILY'],//'DAILY' | 'WEEKLY' | 'MONTHLY' | 'YEARLY';
|
||||||
interval: [1] ,//number
|
interval: [1],//number
|
||||||
endDate: [null], // Date
|
endDate: [null], // Date
|
||||||
count: [null], // number
|
count: [null], // number
|
||||||
byDay: [null], // string
|
byDay: [null], // string
|
||||||
byMonthDay: [null], // string
|
byMonthDay: [null], // string
|
||||||
byMonth: [null], // string
|
byMonth: [null], // string
|
||||||
|
|
||||||
})
|
}),
|
||||||
});
|
|
||||||
|
|
||||||
effect(() => {
|
|
||||||
console.info("effect run")
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
console.info("oninit run")
|
|
||||||
this.isRecurring?.valueChanges.subscribe(isRecurring => {
|
this.isRecurring?.valueChanges.subscribe(isRecurring => {
|
||||||
const recurringRule = this.form.get('recurrenceRule');
|
const recurringRule = this.form.get('recurrenceRule');
|
||||||
const frequency = recurringRule?.get('frequency');
|
const frequency = recurringRule?.get('frequency');
|
||||||
@ -118,51 +111,83 @@ export class CreateEventForm implements OnInit {
|
|||||||
of(this.id()).pipe(
|
of(this.id()).pipe(
|
||||||
tap(id => {
|
tap(id => {
|
||||||
if (id) {
|
if (id) {
|
||||||
console.info("edit mode", 'edit')
|
|
||||||
this.isEditMode = true;
|
this.isEditMode = true;
|
||||||
}else{
|
|
||||||
|
|
||||||
const start = this.date() || new Date();
|
|
||||||
const end = this.date() || new Date();
|
|
||||||
|
|
||||||
console.info("staring form with date", start,end);
|
|
||||||
start.setMinutes(0,0);
|
|
||||||
end.setHours(start.getHours()+1,0,0);
|
|
||||||
start.setMinutes(start.getMinutes() - start.getTimezoneOffset());
|
|
||||||
const startString = start.toISOString().slice(0,16);
|
|
||||||
|
|
||||||
end.setMinutes(end.getMinutes() - end.getTimezoneOffset());
|
|
||||||
const endTime = end.toISOString().slice(0,16);
|
|
||||||
|
|
||||||
console.info("Date start",start.toLocaleString("hu-HU", {timeStyle: 'short', dateStyle: 'short'}));
|
|
||||||
this.form.patchValue({
|
|
||||||
// start_time: new Date().getTime().toString(),
|
|
||||||
startTime: startString,
|
|
||||||
endTime: endTime
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
mergeMap(() => {
|
mergeMap(() => {
|
||||||
return this.eventTypeService.find({});
|
return this.eventTypeService.find({});
|
||||||
}
|
},
|
||||||
),
|
),
|
||||||
tap(eventTypes => {
|
tap(eventTypes => {
|
||||||
this.eventTypes.set(eventTypes.data);
|
this.eventTypes.set(eventTypes.data);
|
||||||
}),
|
}),
|
||||||
switchMap(() => {
|
switchMap(() => {
|
||||||
if (this.isEditMode && this.id()) {
|
if (this.isEditMode && this.id()) {
|
||||||
|
console.info('edit mode', 'edit', this.id());
|
||||||
return this.eventService.findOne(this.id()!);
|
return this.eventService.findOne(this.id()!);
|
||||||
}
|
}
|
||||||
return of(null);
|
return of(null);
|
||||||
}),
|
}),
|
||||||
).subscribe(event => {
|
).subscribe(event => {
|
||||||
console.info("subscribe form done")
|
|
||||||
if (event) {
|
if (event) {
|
||||||
this.form.patchValue(event);
|
const startTime = this.formatIsoStringForInput(event.startTime);
|
||||||
|
const endTime = this.formatIsoStringForInput(event.endTime);
|
||||||
|
this.form.patchValue(
|
||||||
|
{
|
||||||
|
title: event.title,
|
||||||
|
description: event.description,
|
||||||
|
startTime,
|
||||||
|
endTime,
|
||||||
|
eventTypeId: event?.eventType?.id,
|
||||||
|
is_recurring: event.isRecurring ,
|
||||||
|
recurrenceRule: {
|
||||||
|
frequency: event.recurrenceRule?.frequency,
|
||||||
|
interval: event.recurrenceRule?.interval,
|
||||||
|
endDate: event.recurrenceRule?.endDate,
|
||||||
|
count: event.recurrenceRule?.count,
|
||||||
|
byDay: event.recurrenceRule?.byDay,
|
||||||
|
byMonthDay: event.recurrenceRule?.byMonthDay,
|
||||||
|
byMonth: event.recurrenceRule?.byMonth,
|
||||||
|
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
const start = this.createDate(this.date());
|
||||||
|
const end = this.createDate(this.date(), start.getHours() + 1);
|
||||||
|
|
||||||
|
const startTime = this.formatDateForInput(start);
|
||||||
|
const endTime = this.formatDateForInput(end);
|
||||||
|
|
||||||
|
this.form.patchValue({
|
||||||
|
startTime,
|
||||||
|
endTime,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
createDate(date?: Date, hours?: number) {
|
||||||
|
const start = date ? new Date(date?.getTime()) : new Date();
|
||||||
|
if (hours != undefined) {
|
||||||
|
start.setHours(start.getHours() + hours, 0, 0);
|
||||||
|
} else {
|
||||||
|
start.setMinutes(0, 0);
|
||||||
|
}
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
formatDateForInput(dateObject: Date) {
|
||||||
|
return format(dateObject, 'yyyy-MM-dd\'T\'HH:mm');
|
||||||
|
}
|
||||||
|
|
||||||
|
formatIsoStringForInput(dateString: string) {
|
||||||
|
const date = new Date(dateString);
|
||||||
|
return this.formatDateForInput(date);
|
||||||
|
}
|
||||||
|
|
||||||
onByDayChange(event: any) {
|
onByDayChange(event: any) {
|
||||||
const target = event.target as HTMLInputElement;
|
const target = event.target as HTMLInputElement;
|
||||||
const day = target.value;
|
const day = target.value;
|
||||||
@ -197,13 +222,13 @@ export class CreateEventForm implements OnInit {
|
|||||||
|
|
||||||
for (const field of this.numericFields) {
|
for (const field of this.numericFields) {
|
||||||
if (payload[field] != null && payload[field] !== '') {
|
if (payload[field] != null && payload[field] !== '') {
|
||||||
if ( typeof payload[field] !== 'number'){
|
if (typeof payload[field] !== 'number') {
|
||||||
payload[field] = parseFloat(payload[field] as string) as never;
|
payload[field] = parseFloat(payload[field] as string) as never;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let action$: Observable<Event|undefined>;
|
let action$: Observable<Event | undefined>;
|
||||||
|
|
||||||
if (this.isEditMode && this.id()) {
|
if (this.isEditMode && this.id()) {
|
||||||
action$ = this.calendarService.update(this.id()!, payload);
|
action$ = this.calendarService.update(this.id()!, payload);
|
||||||
@ -213,45 +238,48 @@ export class CreateEventForm implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
action$.subscribe({
|
action$.subscribe({
|
||||||
next: () => this.router.navigate(['/events']),
|
next: () => this.router.navigate(['/calendar']),
|
||||||
error: (err) => console.error('Failed to save event', err)
|
error: (err) => console.error('Failed to save event', err),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get eventType(){
|
get eventType() {
|
||||||
return this.form.get('eventTypeId');
|
return this.form.get('eventTypeId');
|
||||||
}
|
}
|
||||||
|
|
||||||
get title(){
|
get title() {
|
||||||
return this.form.get('title');
|
return this.form.get('title');
|
||||||
}
|
}
|
||||||
get description(){
|
|
||||||
|
get description() {
|
||||||
return this.form.get('description');
|
return this.form.get('description');
|
||||||
}
|
}
|
||||||
get startTime(){
|
|
||||||
|
get startTime() {
|
||||||
return this.form.get('startTime');
|
return this.form.get('startTime');
|
||||||
}
|
}
|
||||||
get endTime(){
|
|
||||||
|
get endTime() {
|
||||||
return this.form.get('endTime');
|
return this.form.get('endTime');
|
||||||
}
|
}
|
||||||
|
|
||||||
get isRecurring(){
|
get isRecurring() {
|
||||||
return this.form.get('is_recurring');
|
return this.form.get('is_recurring');
|
||||||
}
|
}
|
||||||
|
|
||||||
get recurringRule(){
|
get recurringRule() {
|
||||||
return this.form.get('recurrenceRule');
|
return this.form.get('recurrenceRule');
|
||||||
}
|
}
|
||||||
|
|
||||||
get frequency(){
|
get frequency() {
|
||||||
return this.form.get('recurrenceRule')?.get('frequency');
|
return this.form.get('recurrenceRule')?.get('frequency');
|
||||||
}
|
}
|
||||||
|
|
||||||
get interval(){
|
get interval() {
|
||||||
return this.form.get('recurrenceRule')?.get('interval');
|
return this.form.get('recurrenceRule')?.get('interval');
|
||||||
}
|
}
|
||||||
|
|
||||||
get endDate(){
|
get endDate() {
|
||||||
return this.form.get('recurrenceRule')?.get('endDate');
|
return this.form.get('recurrenceRule')?.get('endDate');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +295,7 @@ export class CreateEventForm implements OnInit {
|
|||||||
return this.form.get('recurrenceRule')?.get('byMonth');
|
return this.form.get('recurrenceRule')?.get('byMonth');
|
||||||
}
|
}
|
||||||
|
|
||||||
doReady(){
|
doReady() {
|
||||||
this.ready.emit();
|
this.ready.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,7 +37,7 @@ export class CalendarService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public update(id: number,data: UpdateEventFormDTO): Observable<Event> {
|
public update(id: number,data: UpdateEventFormDTO): Observable<Event> {
|
||||||
return this.http.put<Event>(this.apiUrl+'/events', data);
|
return this.http.patch<Event>(this.apiUrl+'/events/'+id, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,35 @@
|
|||||||
// dvbooking-cli/src/templates/angular/model.ts.tpl
|
// dvbooking-cli/src/templates/angular/model.ts.tpl
|
||||||
|
|
||||||
// Generated by the CLI
|
// Generated by the CLI
|
||||||
|
|
||||||
export interface Event {
|
export interface Event {
|
||||||
id: number;
|
id: number;
|
||||||
event_type_id: number;
|
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
start_time: Date;
|
startTime: string;
|
||||||
end_time: Date;
|
endTime: string;
|
||||||
timezone: string;
|
timezone: string;
|
||||||
is_recurring: boolean;
|
isRecurring: boolean;
|
||||||
created_at: Date;
|
created_at: string;
|
||||||
updated_at: Date;
|
updated_at: string;
|
||||||
|
eventType: EventType;
|
||||||
|
recurrenceRule: RecurrenceRule
|
||||||
|
}
|
||||||
|
export interface EventType{
|
||||||
|
id: number;
|
||||||
|
description:string;
|
||||||
|
name: string;
|
||||||
|
color: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface RecurrenceRule{
|
||||||
|
|
||||||
|
frequency?: string,
|
||||||
|
interval?: number,
|
||||||
|
endDate?: string,
|
||||||
|
count?: number,
|
||||||
|
byDay?: string,
|
||||||
|
byMonthDay?: string,
|
||||||
|
byMonth?: string,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -59,7 +59,8 @@ export class EventService {
|
|||||||
* Find a single record by its ID.
|
* Find a single record by its ID.
|
||||||
*/
|
*/
|
||||||
public findOne(id: number): Observable<Event> {
|
public findOne(id: number): Observable<Event> {
|
||||||
return this.http.get<Event>(`${this.apiUrl}/${id}`);
|
return this.http.get<Event>(`${this.apiUrl}/${id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -27,24 +27,6 @@ import { CancelBookingDto } from './dto/cancel-booking.dto';
|
|||||||
export class CalendarController {
|
export class CalendarController {
|
||||||
constructor(private readonly calendarService: CalendarService) {}
|
constructor(private readonly calendarService: CalendarService) {}
|
||||||
|
|
||||||
@Get('test')
|
|
||||||
getCalendarTest(
|
|
||||||
@Query('startDate') startDate: string,
|
|
||||||
@Query('endDate') endDate: string,
|
|
||||||
) {
|
|
||||||
console.log('--- TEST ENDPOINT ---');
|
|
||||||
console.log('startDate received:', startDate, '| Type:', typeof startDate);
|
|
||||||
console.log('endDate received:', endDate, '| Type:', typeof endDate);
|
|
||||||
return {
|
|
||||||
message: 'Test successful. Check your server console logs.',
|
|
||||||
received: {
|
|
||||||
startDate,
|
|
||||||
endDate,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// The primary endpoint to get event occurrences
|
|
||||||
@Get()
|
@Get()
|
||||||
getCalendarEvents(@Query() getCalendarDto: GetCalendarDto) {
|
getCalendarEvents(@Query() getCalendarDto: GetCalendarDto) {
|
||||||
return this.calendarService.getEventsInRange(
|
return this.calendarService.getEventsInRange(
|
||||||
|
|||||||
@ -148,7 +148,7 @@ export class CalendarService {
|
|||||||
|
|
||||||
if (!freq) continue;
|
if (!freq) continue;
|
||||||
|
|
||||||
let untilDate: Date|undefined = undefined;
|
let untilDate: Date | undefined = undefined;
|
||||||
// typeorm does not convert postgres type 'date' to javascript date object
|
// typeorm does not convert postgres type 'date' to javascript date object
|
||||||
if (event?.recurrenceRule?.endDate) {
|
if (event?.recurrenceRule?.endDate) {
|
||||||
untilDate = new Date(event.recurrenceRule.endDate);
|
untilDate = new Date(event.recurrenceRule.endDate);
|
||||||
@ -204,9 +204,6 @@ export class CalendarService {
|
|||||||
// --- Other service methods (createEvent, etc.) remain unchanged ---
|
// --- Other service methods (createEvent, etc.) remain unchanged ---
|
||||||
|
|
||||||
async createEvent(createEventDto: CreateEventDto): Promise<Event> {
|
async createEvent(createEventDto: CreateEventDto): Promise<Event> {
|
||||||
console.log('[CalendarService] Entering createEvent method.');
|
|
||||||
console.log('[CalendarService] Received DTO:', JSON.stringify(createEventDto, null, 2));
|
|
||||||
|
|
||||||
const { recurrenceRule, ...eventData } = createEventDto;
|
const { recurrenceRule, ...eventData } = createEventDto;
|
||||||
|
|
||||||
const newEvent: Omit<
|
const newEvent: Omit<
|
||||||
@ -224,19 +221,26 @@ export class CalendarService {
|
|||||||
|
|
||||||
// check if event type exists
|
// check if event type exists
|
||||||
if (eventData.eventTypeId) {
|
if (eventData.eventTypeId) {
|
||||||
console.log(`[CalendarService] Event has eventTypeId: ${eventData.eventTypeId}. Fetching event type...`);
|
console.log(
|
||||||
|
`[CalendarService] Event has eventTypeId: ${eventData.eventTypeId}. Fetching event type...`,
|
||||||
|
);
|
||||||
const eventType = await this.eventTypeRepository.findOneBy({
|
const eventType = await this.eventTypeRepository.findOneBy({
|
||||||
id: eventData.eventTypeId,
|
id: eventData.eventTypeId,
|
||||||
});
|
});
|
||||||
if (!eventType) {
|
if (!eventType) {
|
||||||
console.error(`[CalendarService] Event type with ID ${eventData.eventTypeId} not found.`);
|
console.error(
|
||||||
|
`[CalendarService] Event type with ID ${eventData.eventTypeId} not found.`,
|
||||||
|
);
|
||||||
throw new BadRequestException(
|
throw new BadRequestException(
|
||||||
{},
|
{},
|
||||||
'Event type not found ' + eventData.eventTypeId,
|
'Event type not found ' + eventData.eventTypeId,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
newEvent.eventType = eventType;
|
newEvent.eventType = eventType;
|
||||||
console.log('[CalendarService] Successfully attached event type:', eventType);
|
console.log(
|
||||||
|
'[CalendarService] Successfully attached event type:',
|
||||||
|
eventType,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
console.log('[CalendarService] No eventTypeId provided.');
|
console.log('[CalendarService] No eventTypeId provided.');
|
||||||
}
|
}
|
||||||
@ -246,10 +250,15 @@ export class CalendarService {
|
|||||||
|
|
||||||
console.log('[CalendarService] Saving event entity to the database...');
|
console.log('[CalendarService] Saving event entity to the database...');
|
||||||
const savedEvent = await this.eventRepository.save(event);
|
const savedEvent = await this.eventRepository.save(event);
|
||||||
console.log('[CalendarService] Event saved successfully. Saved event ID:', savedEvent.id);
|
console.log(
|
||||||
|
'[CalendarService] Event saved successfully. Saved event ID:',
|
||||||
|
savedEvent.id,
|
||||||
|
);
|
||||||
|
|
||||||
if (savedEvent.isRecurring && recurrenceRule) {
|
if (savedEvent.isRecurring && recurrenceRule) {
|
||||||
console.log(`[CalendarService] Event is recurring. Creating recurrence rule...`);
|
console.log(
|
||||||
|
`[CalendarService] Event is recurring. Creating recurrence rule...`,
|
||||||
|
);
|
||||||
const rule = this.recurrenceRuleRepository.create({
|
const rule = this.recurrenceRuleRepository.create({
|
||||||
...recurrenceRule,
|
...recurrenceRule,
|
||||||
event: savedEvent,
|
event: savedEvent,
|
||||||
@ -257,10 +266,14 @@ export class CalendarService {
|
|||||||
await this.recurrenceRuleRepository.save(rule);
|
await this.recurrenceRuleRepository.save(rule);
|
||||||
console.log('[CalendarService] Recurrence rule saved successfully.');
|
console.log('[CalendarService] Recurrence rule saved successfully.');
|
||||||
} else {
|
} else {
|
||||||
console.log('[CalendarService] Event is not recurring or no recurrence rule provided.');
|
console.log(
|
||||||
|
'[CalendarService] Event is not recurring or no recurrence rule provided.',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`[CalendarService] Fetching final event by ID ${savedEvent.id} to return.`);
|
console.log(
|
||||||
|
`[CalendarService] Fetching final event by ID ${savedEvent.id} to return.`,
|
||||||
|
);
|
||||||
const finalEvent = await this.getEventById(savedEvent.id);
|
const finalEvent = await this.getEventById(savedEvent.id);
|
||||||
console.log('[CalendarService] Exiting createEvent method.');
|
console.log('[CalendarService] Exiting createEvent method.');
|
||||||
return finalEvent;
|
return finalEvent;
|
||||||
@ -333,7 +346,59 @@ export class CalendarService {
|
|||||||
id: number,
|
id: number,
|
||||||
updateEventDto: CreateEventDto,
|
updateEventDto: CreateEventDto,
|
||||||
): Promise<Event> {
|
): Promise<Event> {
|
||||||
await this.eventRepository.update(id, updateEventDto);
|
// 1. Fetch the existing event (ensure relations are loaded if needed)
|
||||||
|
const event = await this.getEventById(id);
|
||||||
|
|
||||||
|
// 2. Update basic fields
|
||||||
|
event.updatedAt = new Date();
|
||||||
|
event.title = updateEventDto.title;
|
||||||
|
event.description = updateEventDto.description;
|
||||||
|
event.startTime = updateEventDto.startTime;
|
||||||
|
event.endTime = updateEventDto.endTime;
|
||||||
|
event.isRecurring = !!updateEventDto.isRecurring;
|
||||||
|
|
||||||
|
// 3. Handle Event Type Relationship
|
||||||
|
if (updateEventDto.eventTypeId) {
|
||||||
|
const eventType = await this.eventTypeRepository.findOneBy({
|
||||||
|
id: updateEventDto.eventTypeId,
|
||||||
|
});
|
||||||
|
if (!eventType) {
|
||||||
|
throw new NotFoundException(
|
||||||
|
`EventType with ID ${updateEventDto.eventTypeId} not found`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// FIX: You forgot to assign this in your original code
|
||||||
|
event.eventType = eventType;
|
||||||
|
} else {
|
||||||
|
// Handle case where event type is removed/null
|
||||||
|
event.eventType = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Handle Recurrence Rule
|
||||||
|
// Because your entity has @OneToOne(..., { cascade: true }),
|
||||||
|
// modifying event.recurrenceRule and calling eventRepository.save(event)
|
||||||
|
// will automatically save/update the rule.
|
||||||
|
if (event.isRecurring && updateEventDto.recurrenceRule) {
|
||||||
|
const updateRRule = updateEventDto.recurrenceRule;
|
||||||
|
|
||||||
|
// If no rule exists yet, initialize a new one
|
||||||
|
if (!event.recurrenceRule) {
|
||||||
|
event.recurrenceRule = this.recurrenceRuleRepository.create({});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the properties on the relation object
|
||||||
|
event.recurrenceRule.frequency = updateRRule.frequency;
|
||||||
|
event.recurrenceRule.interval = updateRRule.interval;
|
||||||
|
event.recurrenceRule.byDay = updateRRule.byDay as string;
|
||||||
|
event.recurrenceRule.endDate = updateRRule.endDate as Date;
|
||||||
|
event.recurrenceRule.count = updateRRule.count as number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Use SAVE instead of UPDATE
|
||||||
|
// This handles the relations correctly and prevents the "one-to-many" error.
|
||||||
|
await this.eventRepository.save(event);
|
||||||
|
|
||||||
|
// 6. Return the updated event
|
||||||
return this.getEventById(id);
|
return this.getEventById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -80,7 +80,10 @@ export class EventsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async findOne(id: number) {
|
async findOne(id: number) {
|
||||||
const record = await this.eventRepository.findOneBy({ id: id as any });
|
const record = await this.eventRepository.findOne({
|
||||||
|
where: { id: id },
|
||||||
|
relations: ['eventType', 'recurrenceRule', 'exceptions'],
|
||||||
|
});
|
||||||
if (!record) {
|
if (!record) {
|
||||||
throw new NotFoundException(`Event with ID ${id} not found`);
|
throw new NotFoundException(`Event with ID ${id} not found`);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user