src/app/child-dev-project/notes/model/note.ts
Properties |
|
Methods |
|
attachment |
Type : string
|
Decorators :
@DatabaseField({label: undefined, dataType: 'file'})
|
category |
Type : InteractionType
|
Decorators :
@DatabaseField({label: undefined, dataType: 'configurable-enum', additional: INTERACTION_TYPE_CONFIG_ID, anonymize: 'retain'})
|
date |
Type : Date
|
Decorators :
@DatabaseField({label: undefined, dataType: 'date-only', defaultValue: undefined, anonymize: 'retain'})
|
Static hasPII |
Default value : true
|
Static icon |
Type : IconName
|
Default value : "file-alt"
|
Static label |
Default value : $localize`:label for entity:Note`
|
Static labelPlural |
Default value : $localize`:label (plural) for entity:Notes`
|
relatesTo |
Type : string
|
Decorators :
@DatabaseField({anonymize: 'retain'})
|
id referencing a different entity (e.g. a recurring activity) this note is related to |
subject |
Type : string
|
Decorators :
@DatabaseField({label: undefined})
|
text |
Type : string
|
Decorators :
@DatabaseField({label: undefined, dataType: 'long-text'})
|
Static toStringAttributes |
Type : []
|
Default value : ["subject"]
|
warningLevel |
Type : Ordering.EnumValue
|
Decorators :
@DatabaseField({label: undefined, dataType: 'configurable-enum', additional: 'warning-levels', anonymize: 'retain'})
|
addChild | ||||||||
addChild(child: Entity | string)
|
||||||||
adds a new child to this note
Parameters :
Returns :
void
|
addSchool | ||||||||
addSchool(school: Entity | string)
|
||||||||
adds a new school to this note
Parameters :
Returns :
void
|
copy |
copy()
|
Performs a deep copy of the note copying all simple data (such as the date, author, e.t.c.) as well as copying the child-array |
countWithStatus | ||||||||
countWithStatus(status: AttendanceLogicalStatus)
|
||||||||
Counts how many children have the given attendance status.
The status is counted based on the AttendanceLogicalStatus and the
Parameters :
Returns :
number
number of children with this status |
Static create | ||||||||||||||||
create(date: Date, subject: string, children: string[])
|
||||||||||||||||
Parameters :
Returns :
Note
|
getAttendance | ||||||||
getAttendance(child: string | Entity)
|
||||||||
Returns the event attendance details for the given child. This method returns a default object that can be used and updated even if no attendance has been recorded yet. Returns undefined if the child is not added to this event/note instance.
Parameters :
Returns :
EventAttendance
|
Public getColor |
getColor()
|
Returns :
any
|
Public getColorForId | ||||||
getColorForId(childId: string)
|
||||||
Parameters :
Returns :
string
|
Static getPropertyFor | ||||||
getPropertyFor(entityType: string)
|
||||||
Returns the name of the Note property where entities of the given entity type are stored
Parameters :
Returns :
"children" | "schools" | "authors" | "relatedEntities"
|
getWarningLevel |
getWarningLevel()
|
Returns :
WarningLevel
|
hasUnknownAttendances | ||||||
hasUnknownAttendances(childId?: string)
|
||||||
Whether the attendance context information available through While getAttendance will always set and return at least a default value
Parameters :
Returns :
boolean
|
removeChild | ||||||||
removeChild(childId: string)
|
||||||||
removes a specific child from this note
Parameters :
Returns :
void
|
import { DatabaseEntity } from "../../../core/entity/database-entity.decorator";
import { Entity } from "../../../core/entity/model/entity";
import { DatabaseField } from "../../../core/entity/database-field.decorator";
import {
INTERACTION_TYPE_CONFIG_ID,
InteractionType,
} from "./interaction-type.interface";
import {
EventAttendance,
EventAttendanceMap,
} from "../../attendance/model/event-attendance";
import {
AttendanceLogicalStatus,
NullAttendanceStatusType,
} from "../../attendance/model/attendance-status";
import { getWarningLevelColor, WarningLevel } from "../../warning-level";
import { Ordering } from "../../../core/basic-datatypes/configurable-enum/configurable-enum-ordering";
import { PLACEHOLDERS } from "../../../core/entity/schema/entity-schema-field";
import { IconName } from "@fortawesome/fontawesome-svg-core";
@DatabaseEntity("Note")
export class Note extends Entity {
static override toStringAttributes = ["subject"];
static override label = $localize`:label for entity:Note`;
static override labelPlural = $localize`:label (plural) for entity:Notes`;
static override icon: IconName = "file-alt";
static override hasPII = true;
static create(
date: Date,
subject: string = "",
children: string[] = [],
): Note {
const instance = new Note();
instance.date = date;
instance.subject = subject;
for (const child of children) {
instance.addChild(child);
}
return instance;
}
/**
* Returns the name of the Note property where entities of the given entity type are stored
* @param entityType
*/
static getPropertyFor(entityType: string) {
switch (entityType) {
case "Child":
return "children";
case "School":
return "schools";
case "User":
return "authors";
default:
return "relatedEntities";
}
}
// TODO: remove these special properties (children, schools) and use relatedEntities instead once the attendance system is generalized (#1364)
/** IDs of Child entities linked with this note */
@DatabaseField({
label: $localize`:Label for the participants field of a note:Participants`,
dataType: "entity",
isArray: true,
additional: "Child",
entityReferenceRole: "composite",
editComponent: "EditAttendance",
anonymize: "retain",
})
children: string[] = [];
/**
* optional additional information about attendance at this event for each of the linked children
*
* No direct access to change this property. Use the `.getAttendance()` method to have safe access.
*/
@DatabaseField({ anonymize: "retain" })
private childrenAttendance: EventAttendanceMap = new EventAttendanceMap();
@DatabaseField({
label: $localize`:Label for the date of a note:Date`,
dataType: "date-only",
defaultValue: {
mode: "dynamic",
value: PLACEHOLDERS.NOW,
},
anonymize: "retain",
})
date: Date;
@DatabaseField({
label: $localize`:Label for the subject of a note:Subject`,
})
subject: string;
@DatabaseField({
label: $localize`:Label for the actual notes of a note:Notes`,
dataType: "long-text",
})
text: string;
/** IDs of users that authored this note */
@DatabaseField({
label: $localize`:Label for the social worker(s) who created the note:Team involved`,
dataType: "entity",
isArray: true,
additional: "User",
defaultValue: {
mode: "dynamic",
value: PLACEHOLDERS.CURRENT_USER,
},
anonymize: "retain",
})
authors: string[] = [];
@DatabaseField({
label: $localize`:Label for the category of a note:Category`,
dataType: "configurable-enum",
additional: INTERACTION_TYPE_CONFIG_ID,
anonymize: "retain",
})
category: InteractionType;
@DatabaseField({
label: $localize`Attachment`,
dataType: "file",
})
attachment: string;
/**
* id referencing a different entity (e.g. a recurring activity) this note is related to
*/
@DatabaseField({
anonymize: "retain",
})
relatesTo: string;
/**
* other records (e.g. a recurring activity, group membership, ...) to which this note is related in some way,
* so that notes can be displayed linked to these entities.
*
* This property saves ids including their entity type prefix.
*/
@DatabaseField({
dataType: "entity",
isArray: true,
// by default no additional relatedEntities can be linked apart from children and schools, overwrite this in config to display (e.g. additional: "ChildSchoolRelation")
additional: undefined,
anonymize: "retain",
})
relatedEntities: string[] = [];
/**
* related school ids (e.g. to infer participants for event roll calls)
*/
@DatabaseField({
label: $localize`:label for the linked schools:Groups`,
dataType: "entity",
isArray: true,
additional: "School",
entityReferenceRole: "composite",
anonymize: "retain",
})
schools: string[] = [];
@DatabaseField({
label: $localize`:Status of a note:Status`,
dataType: "configurable-enum",
additional: "warning-levels",
anonymize: "retain",
})
warningLevel: Ordering.EnumValue;
override getWarningLevel(): WarningLevel {
if (this.warningLevel) {
return WarningLevel[this.warningLevel.id];
} else {
return WarningLevel.NONE;
}
}
public override getColor() {
const actualLevel = this.getWarningLevel();
if (actualLevel === WarningLevel.OK || actualLevel === WarningLevel.NONE) {
return this.category?.color;
} else {
return super.getColor();
}
}
public getColorForId(childId: string): string {
if (
this.category?.isMeeting &&
this.childrenAttendance.get(childId)?.status.countAs ===
AttendanceLogicalStatus.ABSENT
) {
// child is absent, highlight the entry
return getWarningLevelColor(WarningLevel.URGENT);
}
return this.getColor();
}
/**
* removes a specific child from this note
* @param childId The id of the child to exclude from the notes
*/
removeChild(childId: string) {
this.children = this.children.filter((c) => c !== childId);
this.childrenAttendance.delete(childId);
}
/**
* adds a new child to this note
* @param child The child or the id of the child to add to the notes
*/
addChild(child: Entity | string) {
const childId = typeof child === "string" ? child : child?.getId();
if (!childId || this.children.includes(childId)) {
return;
}
this.children = this.children.concat(childId);
}
/**
* adds a new school to this note
* @param school The school or its id to be added to the note
*/
addSchool(school: Entity | string) {
const schoolId = typeof school === "string" ? school : school.getId();
if (this.schools.includes(schoolId)) {
return;
}
this.schools = this.schools.concat(schoolId);
}
/**
* Returns the event attendance details for the given child.
*
* This method returns a default object that can be used and updated even if no attendance has been recorded yet.
* Returns undefined if the child is not added to this event/note instance.
*
* @param child: The child or the id of the child to look for
*/
getAttendance(child: string | Entity): EventAttendance {
const childId = typeof child === "string" ? child : child.getId();
if (!this.children.includes(childId)) {
return undefined;
}
let attendance = this.childrenAttendance.get(childId);
if (!attendance) {
attendance = new EventAttendance();
this.childrenAttendance.set(childId, attendance);
}
if (!(attendance instanceof EventAttendance)) {
attendance = Object.assign(new EventAttendance(), attendance);
}
return attendance;
}
/**
* Whether the attendance context information available through `getAttendance` is missing data for some children.
*
* While getAttendance will always set and return at least a default value `hasUnknownAttendances` can be used
* to flag events with incomplete data.
*/
hasUnknownAttendances(childId?: string): boolean {
if (childId) {
return (
this.getAttendance(childId).status.id === NullAttendanceStatusType.id
);
}
if (this.childrenAttendance.size < this.children.length) {
return true;
} else {
for (const v of this.childrenAttendance.values()) {
if (v.status.id === NullAttendanceStatusType.id) {
return true;
}
}
}
return false;
}
/**
* Counts how many children have the given attendance status.
* The status is counted based on the AttendanceLogicalStatus and the `AttendanceStatusType.countAs` attribute
* @param status which should be counted
* @returns number of children with this status
*/
countWithStatus(status: AttendanceLogicalStatus): number {
const attendanceValues = this.childrenAttendance.values();
return [...attendanceValues].filter(
(attendance) => attendance.status.countAs === status,
).length;
}
/**
* Performs a deep copy of the note copying all simple data
* (such as the date, author, e.t.c.) as well as copying the
* child-array
*/
override copy(): this {
const note = super.copy();
note.children = [...this.children];
note.schools = [...this.schools];
note.relatedEntities = [...this.relatedEntities];
note.authors = [...this.authors];
note.childrenAttendance = new EventAttendanceMap();
this.childrenAttendance.forEach((value, key) => {
note.childrenAttendance.set(key, value.copy());
});
return note;
}
}