Adds hierarchical grouping and entity resolution support

Enhances calendar rendering with dynamic parent-child relationships between entities

Introduces EntityResolver for dot-notation references
Supports belongsTo configuration in grouping
Implements flexible filtering across hierarchical entities

Improves rendering flexibility for complex organizational structures
This commit is contained in:
Janus C. H. Knudsen 2025-12-15 17:10:43 +01:00
parent dd647acab8
commit d4249eecfb
17 changed files with 403 additions and 44 deletions

View file

@ -10,7 +10,7 @@ import { IStore } from './IStore';
*/
export class IndexedDBContext {
private static readonly DB_NAME = 'CalendarV2DB';
private static readonly DB_VERSION = 2;
private static readonly DB_VERSION = 3;
private db: IDBDatabase | null = null;
private initialized: boolean = false;

View file

@ -0,0 +1,44 @@
import { ITeam, EntityType, IEventBus } from '../../types/CalendarTypes';
import { TeamStore } from './TeamStore';
import { BaseEntityService } from '../BaseEntityService';
import { IndexedDBContext } from '../IndexedDBContext';
/**
* TeamService - CRUD operations for teams in IndexedDB
*
* Teams define which resources belong together for hierarchical grouping.
* Extends BaseEntityService for standard entity operations.
*/
export class TeamService extends BaseEntityService<ITeam> {
readonly storeName = TeamStore.STORE_NAME;
readonly entityType: EntityType = 'Team';
constructor(context: IndexedDBContext, eventBus: IEventBus) {
super(context, eventBus);
}
/**
* Get teams by IDs
*/
async getByIds(ids: string[]): Promise<ITeam[]> {
if (ids.length === 0) return [];
const results = await Promise.all(ids.map(id => this.get(id)));
return results.filter((t): t is ITeam => t !== null);
}
/**
* Build reverse lookup: resourceId teamId
*/
async buildResourceToTeamMap(): Promise<Record<string, string>> {
const teams = await this.getAll();
const map: Record<string, string> = {};
for (const team of teams) {
for (const resourceId of team.resourceIds) {
map[resourceId] = team.id;
}
}
return map;
}
}

View file

@ -0,0 +1,13 @@
import { IStore } from '../IStore';
/**
* TeamStore - IndexedDB ObjectStore definition for teams
*/
export class TeamStore implements IStore {
static readonly STORE_NAME = 'teams';
readonly storeName = TeamStore.STORE_NAME;
create(db: IDBDatabase): void {
db.createObjectStore(TeamStore.STORE_NAME, { keyPath: 'id' });
}
}