src/app/features/attendance/demo-data/demo-activity-generator.service.ts
Properties |
|
Methods |
|
| assertValid |
assertValid()
|
|
Inherited from
Entity
|
|
Checks if the entity is valid and if the check fails, throws an error explaining the failed check.
Returns :
void
|
| Public copy | ||||||||||
copy(newId: string | boolean)
|
||||||||||
|
Inherited from
Entity
|
||||||||||
|
Deep copy of the entity. The resulting entity will be of the same type as this (taking into account subclassing). All schema field values that are objects or arrays are deep-cloned to avoid shared mutable state between original and copy.
Parameters :
Returns :
unknown
|
| Static createPrefixedId | ||||||||||||
createPrefixedId(type: string, id: string)
|
||||||||||||
|
Inherited from
Entity
|
||||||||||||
|
Create a prefixed id by adding the type prefix if it isn't already part of the given id.
Parameters :
Returns :
string
|
| Static extractEntityIdFromId | ||||||||
extractEntityIdFromId(id: string)
|
||||||||
|
Inherited from
Entity
|
||||||||
|
Extract entityId without prefix.
Parameters :
Returns :
string
|
| Static extractTypeFromId | ||||||||
extractTypeFromId(id: string)
|
||||||||
|
Inherited from
Entity
|
||||||||
|
Extract the ENTITY_TYPE from an id.
Parameters :
Returns :
string
|
| Public getColor |
getColor()
|
|
Inherited from
Entity
|
|
Used by some generic UI components to set the color for the entity instance. Override this method as needed.
Returns :
string
|
| Static getColorWithConditions | ||||||
getColorWithConditions(entity: Entity)
|
||||||
|
Inherited from
Entity
|
||||||
|
Static method to evaluate conditional colors for an entity based on ColorMapping configuration.
Parameters :
Returns :
string
|
| getConstructor |
getConstructor()
|
|
Inherited from
Entity
|
|
Get the class (Entity or the actual subclass of the instance) to call static methods on the correct class considering inheritance
Returns :
EntityConstructor<unknown>
|
| Public getId | ||||||||
getId(withoutPrefix: unknown)
|
||||||||
|
Inherited from
Entity
|
||||||||
|
Returns the id of this entity. Note that an id is final and can't be changed after the object has been instantiated, hence there is no
Parameters :
Returns :
string
the unique id of this entity |
| getSchema |
getSchema()
|
|
Inherited from
Entity
|
|
Get the entity schema of this class
Returns :
EntitySchema
|
| Public getType |
getType()
|
|
Inherited from
Entity
|
|
Returns the type which is used to categorize this entity in the database. Important: Do not overwrite this method! Types are handled internally.
Returns :
string
the entity's type (which is the class name). |
| Public getWarningLevel |
getWarningLevel()
|
|
Inherited from
Entity
|
|
Override getWarningLevel() to define when the entity is in a critical condition and should be color-coded and highlighted in generic components of the UI.
Returns :
WarningLevel
|
| assignedTo |
assignedTo:
|
Type : string[]
|
| participants |
participants:
|
Type : string[]
|
| title |
title:
|
Type : string
|
| type |
type:
|
Type : InteractionType
|
| _isCustomizedType |
| todo: This property is no longer used and will be removed in future versions. |
_isCustomizedType:
|
Type : boolean
|
| Optional |
|
True if this type's schema has been customized dynamically from the config. |
| _rev |
_rev:
|
Type : string
|
|
internal database doc revision, used to detect conflicts by PouchDB/CouchDB |
| anonymized |
anonymized:
|
Type : boolean
|
|
Whether this entity has been anonymized and therefore cannot be re-activated. |
| color |
color:
|
Type : string | ColorMapping[]
|
|
color used for to highlight this entity type across the app. Can be either:
|
| created |
created:
|
Type : UpdateMetadata
|
| DATABASE |
DATABASE:
|
Type : string
|
Default value: "app"
|
|
The database where these entities are stored. |
| enableUserAccounts |
enableUserAccounts:
|
Type : boolean
|
| Optional |
|
Whether to enable user account creation for this entity type. When true, the UI will allow management of user accounts associated with this entity. |
| ENTITY_TYPE |
ENTITY_TYPE:
|
Type : string
|
Default value: "Entity"
|
|
The entity's type.
In classes extending Entity this is usually overridden by the class annotation |
| hasPII |
hasPII:
|
Type : boolean
|
Default value: false
|
|
whether this entity type can contain "personally identifiable information" (PII) and therefore should follow strict data protection requirements and offer a function to anonymize records. |
| icon |
icon:
|
Type : IconName
|
|
icon id used for this entity |
| inactive |
inactive:
|
Type : boolean
|
| isInternalEntity |
isInternalEntity:
|
Type : boolean
|
| Optional |
|
if this entity type is an internal entity, i.e. only defined in the code base to store internal system data and not visible to the user for customization. |
| label |
label:
|
Type : string
|
|
human-readable name/label of the entity in the UI |
| schema |
schema:
|
Type : EntitySchema
|
|
EntitySchema defining property transformations from/to the database.
This is auto-generated from the property annotations see /additional-documentation/how-to-guides/create-a-new-entity-type.html |
| toBlockDetailsAttributes |
toBlockDetailsAttributes:
|
Type : EntityBlockConfig
|
| Optional |
|
Defining which attributes will be displayed in a tooltip on hover when the record is displayed as an entity-block. |
| updated |
updated:
|
Type : UpdateMetadata
|
import { DemoChildGenerator } from "#src/app/child-dev-project/children/demo-data-generators/demo-child-generator.service";
import { DemoDataGenerator } from "#src/app/core/demo-data/demo-data-generator";
import { inject, Injectable } from "@angular/core";
import { faker } from "#src/app/core/demo-data/faker";
import { DemoUserGeneratorService } from "#src/app/core/user/demo-user-generator.service";
import { defaultInteractionTypes } from "#src/app/core/config/default-config/default-interaction-types";
import { InteractionType } from "#src/app/child-dev-project/notes/model/interaction-type.interface";
import { Entity } from "#src/app/core/entity/model/entity";
import { createEntityOfType } from "#src/app/core/demo-data/create-entity-of-type";
import { AttendanceService } from "../attendance.service";
import { EventTypeSettings } from "../model/attendance-feature-config";
import { AttendanceItem } from "../model/attendance-item";
import { AttendanceDatatype } from "../model/attendance.datatype";
/**
* Generate activity entities based on the attendance config's eventTypes.
* Builds upon the generated demo Child entities.
*/
@Injectable()
export class DemoActivityGeneratorService extends DemoDataGenerator<Entity> {
private demoChildren = inject(DemoChildGenerator);
private demoUser = inject(DemoUserGeneratorService);
private attendanceService = inject(AttendanceService);
/**
* This function returns a provider object to be used in an Angular Module configuration:
* `providers: [DemoAttendanceGenerator.provider()]`
*/
static provider() {
return [
{
provide: DemoActivityGeneratorService,
useClass: DemoActivityGeneratorService,
},
];
}
private readonly MIN_PARTICIPANTS = 3;
private readonly MAX_PARTICIPANTS = 25;
generateEntities(): Entity[] {
const data: Entity[] = [];
const children = this.demoChildren.entities.filter((c) => c.isActive);
for (const typeSettings of this.attendanceService.eventTypeSettings) {
if (!typeSettings.activityType) continue;
let i = 0;
while (i < children.length) {
const groupSize = faker.number.int({
min: this.MIN_PARTICIPANTS,
max: this.MAX_PARTICIPANTS,
});
const participatingChildren = children.slice(i, i + groupSize);
data.push(
this.generateActivityOfType(typeSettings, participatingChildren),
);
i += groupSize;
}
}
return data;
}
private generateActivityOfType(
typeSettings: EventTypeSettings,
participants: Entity[],
): Entity {
const assignedUser = faker.helpers.arrayElement(this.demoUser.entities);
const activity = generateActivity({
participants,
assignedUser,
entityType: typeSettings.activityType!.ENTITY_TYPE,
});
// Override participants field if it differs from the default
if (typeSettings.participantsField !== "participants") {
delete activity["participants"];
const participantIds = participants.map((c) => c.getId());
const activityAttendanceField = AttendanceDatatype.detectFieldInEntity(
typeSettings.activityType,
);
const shouldWriteAttendanceItems =
activityAttendanceField === typeSettings.participantsField ||
typeSettings.participantsField === typeSettings.attendanceField;
activity[typeSettings.participantsField] = shouldWriteAttendanceItems
? participantIds.map((id) => new AttendanceItem(undefined, "", id))
: participantIds;
}
// Set assigned user via the configured field
if (typeSettings.activityAssignedUsersField) {
activity[typeSettings.activityAssignedUsersField] = [
assignedUser.getId(),
];
}
// Set mapped fields on the activity (reverse: event field → activity field)
for (const [eventField, activityField] of Object.entries(
typeSettings.fieldMapping,
)) {
if (activity[activityField] !== undefined) {
continue;
}
if (activityField === "title" || eventField === "subject") {
activity[activityField] = activity["title"] ?? activity.toString();
} else if (activityField === "type" || eventField === "category") {
activity[activityField] = activity["type"];
}
}
// Fallback: set toStringAttributes if nothing was mapped
const toStringAttrs = activity.getConstructor().toStringAttributes ?? [];
if (toStringAttrs.length > 0 && activity[toStringAttrs[0]] === undefined) {
activity[toStringAttrs[0]] = activity["title"] ?? activity.toString();
}
return activity;
}
}
export const ACTIVITY_TYPES = [
defaultInteractionTypes.find((t) => t.id === "SCHOOL_CLASS"),
defaultInteractionTypes.find((t) => t.id === "COACHING_CLASS"),
].filter((t): t is InteractionType => t !== undefined);
export interface ActivityEntity extends Entity {
title: string;
type: InteractionType;
participants: string[];
assignedTo: string[];
}
export function generateActivity({
participants,
assignedUser,
title,
entityType = "RecurringActivity",
}: {
participants: Entity[];
assignedUser?: Entity;
title?: string;
entityType?: string;
}): ActivityEntity {
const activity = createEntityOfType(
entityType,
faker.string.uuid(),
) as ActivityEntity;
const type = faker.helpers.arrayElement(ACTIVITY_TYPES);
activity.title =
title ??
type.label +
" " +
faker.number.int({ min: 1, max: 9 }) +
faker.string.alphanumeric(1).toUpperCase();
activity.type = type;
activity.participants = participants.map((c) => c.getId());
activity.assignedTo = assignedUser ? [assignedUser.getId()] : [];
return activity;
}