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 7b7690b..3bd0d38 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
@@ -24,8 +24,8 @@ import {
SingleEventDashboardEventDelete,
} from './single-event-dashboard-event-delete/single-event-dashboard-event-delete';
import {
- SingleEventDashboardEventCancel,
-} from './single-event-dashboard-event-cancel/single-event-dashboard-event-cancel';
+ SingleEventDashboardEventActivation,
+} from './single-event-dashboard-event-activation/single-event-dashboard-event-activation.component';
import { SingleEventDashboardEventEdit } from './single-event-dashboard-event-edit/single-event-dashboard-event-edit';
@Component({
@@ -81,7 +81,6 @@ export class CalendarView {
{
component: SingleEventDashboardEventDelete,
isRendered: () => this.workflow() == 'event-delete',
- // isRendered: () => true,
closeClick: () => this.closeDialog(),
modalBoxStyleClass: 'max-w-none w-2xl',
componentInputs: () => {
@@ -94,13 +93,26 @@ export class CalendarView {
},
{
- component: SingleEventDashboardEventCancel,
+ component: SingleEventDashboardEventActivation,
isRendered: () => this.workflow() == 'event-cancel',
- // isRendered: () => true,
closeClick: () => this.closeDialog(),
modalBoxStyleClass: 'max-w-none w-2xl',
componentInputs: () => {
return {
+ 'mode': 'cancel',
+ 'event': this.selectedEvent(),
+ 'onAction': this.handleAction,
+ };
+ },
+ },
+ {
+ component: SingleEventDashboardEventActivation,
+ isRendered: () => this.workflow() == 'event_activate',
+ closeClick: () => this.closeDialog(),
+ modalBoxStyleClass: 'max-w-none w-2xl',
+ componentInputs: () => {
+ return {
+ 'mode': 'activate',
'event': this.selectedEvent(),
'onAction': this.handleAction,
};
@@ -141,6 +153,12 @@ export class CalendarView {
extendedProps: {
event: model,
},
+ editable: !model.isCancelled,
+ // 2. Add a class for styling
+ classNames: model.isCancelled ? ['disabled-event'] : [],
+ // Optional: Force a gray color here if not using CSS
+ backgroundColor: '#d3d3d3',
+ borderColor: '#d3d3d3'
};
if (model.eventType) {
calendarEvent.borderColor = model.eventType.color;
@@ -197,6 +215,9 @@ export class CalendarView {
case 'event_edit':
this.workflow.set('event-edit');
break;
+ default:
+ this.workflow.set(action);
+ break;
}
}
@@ -209,6 +230,7 @@ export class CalendarView {
} else if ( msg == 'save-event-success'){
this.closeDialog();
this.calendarComponent?.getApi().refetchEvents();
+ }else{
}
};
diff --git a/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-cancel/single-event-dashboard-event-cancel.css b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-activation/single-event-dashboard-event-activation.component.css
similarity index 100%
rename from admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-cancel/single-event-dashboard-event-cancel.css
rename to admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-activation/single-event-dashboard-event-activation.component.css
diff --git a/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-activation/single-event-dashboard-event-activation.component.html b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-activation/single-event-dashboard-event-activation.component.html
new file mode 100644
index 0000000..f128b86
--- /dev/null
+++ b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-activation/single-event-dashboard-event-activation.component.html
@@ -0,0 +1,27 @@
+
+ @if (mode() == 'cancel') {
+ Esemény lemondása
+ } @else {
+ Esemény aktiválása
+ }
+
+
+
+
+ @if (mode() == 'cancel') {
+
+
+ Lemondás
+
+ }
+ @if (mode() == 'activate') {
+
+
+ Aktiválás
+
+ }
+
+
+ Mégsem
+
+
diff --git a/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-cancel/single-event-dashboard-event-cancel.spec.ts b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-activation/single-event-dashboard-event-activation.component.spec.ts
similarity index 51%
rename from admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-cancel/single-event-dashboard-event-cancel.spec.ts
rename to admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-activation/single-event-dashboard-event-activation.component.spec.ts
index 4c35e21..6a7ce00 100644
--- a/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-cancel/single-event-dashboard-event-cancel.spec.ts
+++ b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-activation/single-event-dashboard-event-activation.component.spec.ts
@@ -1,18 +1,18 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
-import { SingleEventDashboardEventCancel } from './single-event-dashboard-event-cancel';
+import { SingleEventDashboardEventActivation } from './single-event-dashboard-event-activation.component';
describe('SingleEventDashboardEventCancel', () => {
- let component: SingleEventDashboardEventCancel;
- let fixture: ComponentFixture;
+ let component: SingleEventDashboardEventActivation;
+ let fixture: ComponentFixture;
beforeEach(async () => {
await TestBed.configureTestingModule({
- imports: [SingleEventDashboardEventCancel]
+ imports: [SingleEventDashboardEventActivation]
})
.compileComponents();
- fixture = TestBed.createComponent(SingleEventDashboardEventCancel);
+ fixture = TestBed.createComponent(SingleEventDashboardEventActivation);
component = fixture.componentInstance;
fixture.detectChanges();
});
diff --git a/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-activation/single-event-dashboard-event-activation.component.ts b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-activation/single-event-dashboard-event-activation.component.ts
new file mode 100644
index 0000000..be42096
--- /dev/null
+++ b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-activation/single-event-dashboard-event-activation.component.ts
@@ -0,0 +1,63 @@
+import { Component, inject, input } from '@angular/core';
+import { CalendarEventDto } from '../../../models/events-in-range-dto.model';
+import {
+ SingleEventDashboardEventDetailsView
+} from '../single-event-dashboard-event-details-view/single-event-dashboard-event-details-view';
+import { Button } from '@rschneider/ng-daisyui';
+import { SvgIcons } from '../../../../../svg-icons';
+import { SafeHtmlPipe } from '../../../../../pipes/safe-html-pipe';
+import { CalendarService } from '../../../services/calendar.service';
+
+export type ACTIVATION_TYPE = 'cancel' | 'activate';
+
+@Component({
+ selector: 'app-single-event-dashboard-event-cancel',
+ imports: [
+ SingleEventDashboardEventDetailsView,
+ Button,
+ SafeHtmlPipe,
+ ],
+ templateUrl: './single-event-dashboard-event-activation.component.html',
+ styleUrl: './single-event-dashboard-event-activation.component.css',
+})
+export class SingleEventDashboardEventActivation {
+
+ mode = input('cancel');
+ calendarService = inject(CalendarService);
+ event = input();
+ onAction = input.required<(msg: string) => void>();
+
+ protected readonly SvgIcons = SvgIcons;
+
+
+ protected setEventOccurrenceActivation(activated: boolean) {
+
+ const eventId =this.event()?.id!;
+ const startTime = this.event()?.startTime!;
+
+ this.calendarService.applyException(eventId,{
+ originalStartTime: new Date(startTime),
+ isCancelled: !activated,
+ }).subscribe(
+ {
+ next: () => {
+ this.onAction()('close');
+ },
+ error: err => {
+ alert("Failed to change event");
+ }
+ }
+ )
+ }
+
+ protected cancelEventOccurrence() {
+this.setEventOccurrenceActivation(false);
+ }
+ protected activateEventOccurrence() {
+ this.setEventOccurrenceActivation(true);
+ }
+ protected closeDialog() {
+ this.onAction()('close')
+ }
+
+}
diff --git a/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-cancel/single-event-dashboard-event-cancel.html b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-cancel/single-event-dashboard-event-cancel.html
deleted file mode 100644
index fcc499e..0000000
--- a/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-cancel/single-event-dashboard-event-cancel.html
+++ /dev/null
@@ -1,12 +0,0 @@
-Esemény lemondása
-
-
-
-
- Törlés
-
-
-
- Mégsem
-
-
diff --git a/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-cancel/single-event-dashboard-event-cancel.ts b/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-cancel/single-event-dashboard-event-cancel.ts
deleted file mode 100644
index e14c4fc..0000000
--- a/admin/src/app/features/calendar/components/calendar-view/single-event-dashboard-event-cancel/single-event-dashboard-event-cancel.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { Component, input } from '@angular/core';
-import { CalendarEventDto } from '../../../models/events-in-range-dto.model';
-import {
- SingleEventDashboardEventDetailsView
-} from '../single-event-dashboard-event-details-view/single-event-dashboard-event-details-view';
-import { Button } from '@rschneider/ng-daisyui';
-import { SvgIcons } from '../../../../../svg-icons';
-import { SafeHtmlPipe } from '../../../../../pipes/safe-html-pipe';
-
-@Component({
- selector: 'app-single-event-dashboard-event-cancel',
- imports: [
- SingleEventDashboardEventDetailsView,
- Button,
- SafeHtmlPipe,
- ],
- templateUrl: './single-event-dashboard-event-cancel.html',
- styleUrl: './single-event-dashboard-event-cancel.css',
-})
-export class SingleEventDashboardEventCancel {
-
- event = input();
- onAction = input.required<(msg: string) => void>();
-
- protected readonly SvgIcons = SvgIcons;
-
- protected triggerAction() {
-
- this.onAction()('close')
- }
-}
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
index 3fca90d..1879aab 100644
--- 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
@@ -1,5 +1,9 @@
-Esemény
-
+@if (event()?.isRecurring) {
+Esemény sorozat
+}
+@if (!event()?.isRecurring) {
+ Esemény
+}
@if (config) {
- @for (card of cards; let i = $index; track i) {
+ @for (card of cards(); let i = $index; track i) {
();
config: DetailViewConfig | undefined;
- cards: CardConfig[] = [];
+ cards = signal([]);
constructor() {
effect(() => {
+ console.info("dashboard", this.event());
this.config = {
data: this.event()!,
@@ -50,8 +51,8 @@ export class SingleEventDashboard {
},
],
};
- });
- this.cards = [
+
+ this.cards.set( [
{
buttonTitle: 'Szerkesztés',
title: 'Szerkesztés',
@@ -59,11 +60,21 @@ export class SingleEventDashboard {
description: 'Az esemény módosítása',
action: 'event_edit',
},
+
+ this.event()?.isCancelled ?
+
+ {
+ buttonTitle: 'Aktiválás',
+ title: 'Előfordulás aktiválása',
+ svgIcon: SvgIcons.heroPlay,
+ description: 'Az esemény ezen előfordulásának aktiválása',
+ action: 'event_activate',
+ } :
{
buttonTitle: 'Lemondás',
- title: 'Esemény lemondása',
+ title: 'Előfordulás lemondása',
svgIcon: SvgIcons.heroXcircle,
- description: 'Az esemény lemondása',
+ description: 'Az esemény ezen előfordulásának lemondása',
action: 'event_cancel',
},
{
@@ -94,7 +105,8 @@ export class SingleEventDashboard {
description: 'Az időpont lemondása',
action: 'user_cancel',
},
- ];
+ ]);
+ });
}
onCardAction (action: string|undefined) {
diff --git a/admin/src/app/features/calendar/models/event-exception.model.ts b/admin/src/app/features/calendar/models/event-exception.model.ts
new file mode 100644
index 0000000..bd7d085
--- /dev/null
+++ b/admin/src/app/features/calendar/models/event-exception.model.ts
@@ -0,0 +1,8 @@
+export interface CreateExceptionDto {
+ originalStartTime: Date; // The start time of the instance to modify/cancel
+ isCancelled?: boolean;
+ newStartTime?: Date;
+ newEndTime?: Date;
+ title?: string;
+ description?: string;
+}
diff --git a/admin/src/app/features/calendar/models/events-in-range-dto.model.ts b/admin/src/app/features/calendar/models/events-in-range-dto.model.ts
index 21a1b2d..818fa3a 100644
--- a/admin/src/app/features/calendar/models/events-in-range-dto.model.ts
+++ b/admin/src/app/features/calendar/models/events-in-range-dto.model.ts
@@ -25,6 +25,8 @@ export type CalendarEventDto = {
description: string,
isModified?: boolean;
eventBookings: BookingWithUserDto[];
+ isCancelled: boolean;
+ isRecurring: boolean;
eventType: EventType
};
diff --git a/admin/src/app/features/calendar/services/calendar.service.ts b/admin/src/app/features/calendar/services/calendar.service.ts
index 91d4463..d69c161 100644
--- a/admin/src/app/features/calendar/services/calendar.service.ts
+++ b/admin/src/app/features/calendar/services/calendar.service.ts
@@ -5,6 +5,7 @@ import { ConfigurationService } from '../../../services/configuration.service';
import { EventFormDTO, UpdateEventFormDTO } from '../models/event-form-dto.model';
import { Event } from '../../events/models/event.model';
import { CalendarEventDto, EventsInRangeDTO } from '../models/events-in-range-dto.model';
+import { CreateExceptionDto } from '../models/event-exception.model';
@Injectable({
@@ -40,4 +41,7 @@ export class CalendarService {
return this.http.patch(this.apiUrl+'/events/'+id, data);
}
+ public applyException(eventId: number, eventException: CreateExceptionDto){
+ return this.http.post(this.apiUrl+`/events/${eventId}/exceptions`, eventException);
+ }
}
diff --git a/admin/src/app/svg-icons.ts b/admin/src/app/svg-icons.ts
index 534080d..334c2c0 100644
--- a/admin/src/app/svg-icons.ts
+++ b/admin/src/app/svg-icons.ts
@@ -39,5 +39,9 @@ export class SvgIcons {
`
+ public static heroPlay = `
+`;
}
diff --git a/admin/src/styles.css b/admin/src/styles.css
index 06f2182..4e3435d 100644
--- a/admin/src/styles.css
+++ b/admin/src/styles.css
@@ -4,3 +4,14 @@
@import "./styles/grid.css";
@source "../projects/rschneider/ng-daisyui/src";
@plugin "daisyui";
+
+.disabled-event {
+ /* Make it look faded */
+ opacity: 0.5;
+
+ /* Make it un-clickable (stops hover effects and click events) */
+ /*pointer-events: none;*/
+
+ /* Optional: Change cursor to indicate it's not interactive */
+ /*cursor: not-allowed;*/
+}
diff --git a/server/src/calendar/calendar.service.ts b/server/src/calendar/calendar.service.ts
index 29e3fb6..6dee62f 100644
--- a/server/src/calendar/calendar.service.ts
+++ b/server/src/calendar/calendar.service.ts
@@ -51,6 +51,7 @@ type BookingWithUserDto = {
// The final shape of a calendar event occurrence
export type CalendarEventDto = Omit & {
isModified?: boolean;
+ isCancelled?: boolean;
eventBookings: BookingWithUserDto[];
};
@@ -170,16 +171,20 @@ export class CalendarService {
);
if (exception) {
- if (exception.isCancelled) continue;
+ // if (exception.isCancelled) continue;
// This is a MODIFIED occurrence
- const key = `${event.id}-${exception.newStartTime.getTime()}`;
+ const key = `${event.id}-${exception.newStartTime?.getTime() || occurrenceDate.getTime()}`;
recurringOccurrences.push({
...event,
- startTime: exception.newStartTime,
- endTime: exception.newEndTime,
+ // startTime: exception.newStartTime || occurrenceDate,
+ startTime: exception.newStartTime || occurrenceDate,
+ endTime:
+ exception.newEndTime ||
+ new Date(occurrenceDate.getTime() + duration),
isModified: true,
eventBookings: bookingMap.get(key) || [],
+ isCancelled: !!exception.isCancelled,
});
} else {
// This is a REGULAR occurrence
diff --git a/server/src/calendar/dto/create-exception.dto.ts b/server/src/calendar/dto/create-exception.dto.ts
index ae03334..ec41448 100644
--- a/server/src/calendar/dto/create-exception.dto.ts
+++ b/server/src/calendar/dto/create-exception.dto.ts
@@ -1,4 +1,10 @@
-import { IsDate, IsNotEmpty, IsOptional, IsString, IsBoolean } from 'class-validator';
+import {
+ IsDate,
+ IsNotEmpty,
+ IsOptional,
+ IsString,
+ IsBoolean,
+} from 'class-validator';
import { Type } from 'class-transformer';
export class CreateExceptionDto {
@@ -28,4 +34,4 @@ export class CreateExceptionDto {
@IsOptional()
@IsString()
description?: string;
-}
\ No newline at end of file
+}