Enhance calendar view with resource-aware rendering
Adds support for filtering events and rendering across multiple views with resource-specific context Improves event and date rendering to handle resource-based filtering Introduces day view and extends existing calendar infrastructure to support more flexible view configurations
This commit is contained in:
parent
6fc9be9534
commit
7f6279a6f3
17 changed files with 570 additions and 38 deletions
|
|
@ -21,8 +21,14 @@ export class EventRenderer {
|
|||
|
||||
/**
|
||||
* Render events for visible dates into day columns
|
||||
* @param container - Calendar container element
|
||||
* @param filter - Filter with 'date' and optionally 'resource' arrays
|
||||
*/
|
||||
async render(container: HTMLElement, visibleDates: string[]): Promise<void> {
|
||||
async render(container: HTMLElement, filter: Record<string, string[]>): Promise<void> {
|
||||
const visibleDates = filter['date'] || [];
|
||||
|
||||
if (visibleDates.length === 0) return;
|
||||
|
||||
// Get date range for query
|
||||
const startDate = new Date(visibleDates[0]);
|
||||
const endDate = new Date(visibleDates[visibleDates.length - 1]);
|
||||
|
|
@ -31,19 +37,32 @@ export class EventRenderer {
|
|||
// Fetch events from IndexedDB
|
||||
const events = await this.eventService.getByDateRange(startDate, endDate);
|
||||
|
||||
// Group events by date
|
||||
const eventsByDate = this.groupEventsByDate(events);
|
||||
|
||||
// Find day columns
|
||||
const dayColumns = container.querySelector('swp-day-columns');
|
||||
if (!dayColumns) return;
|
||||
|
||||
const columns = dayColumns.querySelectorAll('swp-day-column');
|
||||
|
||||
// Render events into columns
|
||||
columns.forEach((column, index) => {
|
||||
const dateKey = visibleDates[index];
|
||||
const dateEvents = eventsByDate.get(dateKey) || [];
|
||||
// Render events into each column based on data attributes
|
||||
columns.forEach(column => {
|
||||
const dateKey = (column as HTMLElement).dataset.date;
|
||||
const columnResourceId = (column as HTMLElement).dataset.resourceId;
|
||||
|
||||
if (!dateKey) return;
|
||||
|
||||
// Filter events for this column
|
||||
const columnEvents = events.filter(event => {
|
||||
// Must match date
|
||||
if (getDateKey(event.start) !== dateKey) return false;
|
||||
|
||||
// If column has resourceId, event must match
|
||||
if (columnResourceId && event.resourceId !== columnResourceId) return false;
|
||||
|
||||
// If no resourceId on column but resources in filter, show all
|
||||
// (this handles 'simple' view without resources)
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// Get or create events layer
|
||||
let eventsLayer = column.querySelector('swp-events-layer');
|
||||
|
|
@ -55,8 +74,8 @@ export class EventRenderer {
|
|||
// Clear existing events
|
||||
eventsLayer.innerHTML = '';
|
||||
|
||||
// Render each event
|
||||
dateEvents.forEach(event => {
|
||||
// Render each timed event
|
||||
columnEvents.forEach(event => {
|
||||
if (!event.allDay) {
|
||||
const eventElement = this.createEventElement(event);
|
||||
eventsLayer!.appendChild(eventElement);
|
||||
|
|
@ -65,22 +84,6 @@ export class EventRenderer {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Group events by their date key
|
||||
*/
|
||||
private groupEventsByDate(events: ICalendarEvent[]): Map<string, ICalendarEvent[]> {
|
||||
const map = new Map<string, ICalendarEvent[]>();
|
||||
|
||||
events.forEach(event => {
|
||||
const dateKey = getDateKey(event.start);
|
||||
const existing = map.get(dateKey) || [];
|
||||
existing.push(event);
|
||||
map.set(dateKey, existing);
|
||||
});
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a single event element
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue