{"version":3,"file":"8671.17603e83cf9d4afd.js","sources":["./src/app/child-dev-project/attendance/dashboard-widgets/attendance-week-dashboard/attendance-day-block/attendance-day-block.component.ts","./src/app/child-dev-project/attendance/dashboard-widgets/attendance-week-dashboard/attendance-day-block/attendance-day-block.component.html","./src/app/child-dev-project/attendance/dashboard-widgets/attendance-week-dashboard/attendance-week-dashboard.component.html","./src/app/child-dev-project/attendance/dashboard-widgets/attendance-week-dashboard/attendance-week-dashboard.component.ts","./src/app/core/entity/model/entity-update.ts"],"sourceRoot":"webpack:///","sourcesContent":["import { Component, Input } from \"@angular/core\";\nimport { EventAttendance } from \"../../../model/event-attendance\";\nimport { MatTooltipModule } from \"@angular/material/tooltip\";\n\n@Component({\n selector: \"app-attendance-day-block]\",\n templateUrl: \"./attendance-day-block.component.html\",\n styleUrls: [\"./attendance-day-block.component.scss\"],\n imports: [MatTooltipModule],\n standalone: true,\n})\nexport class AttendanceDayBlockComponent {\n @Input() attendance?: EventAttendance;\n\n get tooltip(): string {\n if (!this.attendance) {\n return $localize`No attendance information`;\n }\n if (this.attendance?.remarks) {\n return this.attendance?.status.label + \": \" + this.attendance?.remarks;\n } else {\n return this.attendance?.status.label;\n }\n }\n}\n","\n {{ attendance?.status?.shortName || \"-\" }}\n\n","\n
\n \n \n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n
\n \n \n \n \n \n
\n\n \n no absences recorded\n
\n \n\n","import { Component, Input, OnInit } from \"@angular/core\";\nimport { Router } from \"@angular/router\";\nimport { AttendanceLogicalStatus } from \"../../model/attendance-status\";\nimport { AttendanceService } from \"../../attendance.service\";\nimport { EventAttendance } from \"../../model/event-attendance\";\nimport { ActivityAttendance } from \"../../model/activity-attendance\";\nimport { RecurringActivity } from \"../../model/recurring-activity\";\nimport moment, { Moment } from \"moment\";\nimport { groupBy } from \"../../../../utils/utils\";\nimport { MatTableModule } from \"@angular/material/table\";\nimport { DynamicComponent } from \"../../../../core/config/dynamic-components/dynamic-component.decorator\";\nimport { NgForOf, NgIf } from \"@angular/common\";\nimport { EntityBlockComponent } from \"../../../../core/basic-datatypes/entity/entity-block/entity-block.component\";\nimport { AttendanceDayBlockComponent } from \"./attendance-day-block/attendance-day-block.component\";\nimport { DashboardWidget } from \"../../../../core/dashboard/dashboard-widget/dashboard-widget\";\nimport { EventNote } from \"../../model/event-note\";\nimport { DashboardListWidgetComponent } from \"../../../../core/dashboard/dashboard-list-widget/dashboard-list-widget.component\";\nimport { EntityRegistry } from \"../../../../core/entity/database-entity.decorator\";\n\ninterface AttendanceWeekRow {\n childId: string;\n activity: RecurringActivity;\n attendanceDays: (EventAttendance | undefined)[];\n}\n\n@DynamicComponent(\"AttendanceWeekDashboard\")\n@Component({\n selector: \"app-attendance-week-dashboard\",\n templateUrl: \"./attendance-week-dashboard.component.html\",\n styleUrls: [\"./attendance-week-dashboard.component.scss\"],\n standalone: true,\n imports: [\n NgIf,\n MatTableModule,\n NgForOf,\n EntityBlockComponent,\n AttendanceDayBlockComponent,\n DashboardListWidgetComponent,\n ],\n})\nexport class AttendanceWeekDashboardComponent\n extends DashboardWidget\n implements OnInit\n{\n static override getRequiredEntities() {\n return EventNote.ENTITY_TYPE;\n }\n\n /**\n * The offset from the default time period, which is the last complete week.\n *\n * For example:\n * If you set the offset of 0, the widget displays attendance for the last completed week (i.e. ending last Saturday).\n * If you set the offset to 7 and today is Thursday, the widget displays attendance from the Monday 3 days ago\n * (i.e. the current running week).\n */\n @Input() daysOffset = 0;\n\n /**\n * description displayed to users for what this widget is analysing\n * e.g. \"Absences this week\"\n */\n @Input() label: string;\n\n @Input() periodLabel: string;\n\n /**\n * Only participants who were absent more than this threshold are counted and shown in the dashboard.\n *\n * The default is 1.\n * That means if someone was absent two or more days within a specific activity in the given week\n * the person will be counted and displayed as a critical case in this dashboard widget.\n */\n @Input() absentWarningThreshold: number = 1;\n\n /**\n * The special attendance status type for which this widget should filter.\n *\n * (Optional) If this is not set, all status types that are counted as logically \"ABSENT\" are considered.\n */\n @Input() attendanceStatusType: string;\n\n entries: AttendanceWeekRow[][];\n\n constructor(\n private attendanceService: AttendanceService,\n private router: Router,\n private entityRegistry: EntityRegistry,\n ) {\n super();\n }\n\n ngOnInit() {\n if (this.periodLabel && !this.label) {\n this.label = $localize`:Dashboard attendance component subtitle:Absences ${this.periodLabel}`;\n }\n return this.loadAttendanceOfAbsentees();\n }\n\n private async loadAttendanceOfAbsentees() {\n const previousMonday = moment()\n .startOf(\"isoWeek\")\n .subtract(1, \"week\")\n .add(this.daysOffset, \"days\");\n const previousSaturday = moment(previousMonday).add(5, \"days\");\n\n const activityAttendances =\n await this.attendanceService.getAllActivityAttendancesForPeriod(\n previousMonday.toDate(),\n previousSaturday.toDate(),\n );\n const lowAttendanceCases = new Set();\n const records: AttendanceWeekRow[] = [];\n for (const att of activityAttendances) {\n const rows = this.generateRowsFromActivityAttendance(\n att,\n moment(previousMonday),\n moment(previousSaturday),\n );\n records.push(...rows);\n\n rows\n .filter((r) => this.filterLowAttendance(r))\n .forEach((r) => lowAttendanceCases.add(r.childId));\n }\n\n const groups = groupBy(records, \"childId\");\n this.entries = groups\n .filter(([childId]) => lowAttendanceCases.has(childId))\n .map(([_, attendance]) => attendance);\n }\n\n private generateRowsFromActivityAttendance(\n att: ActivityAttendance,\n from: Moment,\n to: Moment,\n ): AttendanceWeekRow[] {\n if (!att.activity) {\n return [];\n }\n\n const results: AttendanceWeekRow[] = [];\n for (const participant of att.participants) {\n const eventAttendances = [];\n\n let day = moment(from);\n while (day.isSameOrBefore(to, \"day\")) {\n const event = att.events.find((e) => day.isSame(e.date, \"day\"));\n if (event) {\n eventAttendances.push(event.getAttendance(participant));\n } else {\n // put a \"placeholder\" into the array for the current day\n eventAttendances.push(undefined);\n }\n day = day.add(1, \"day\");\n }\n\n results.push({\n childId: participant,\n activity: att.activity,\n attendanceDays: eventAttendances,\n });\n }\n\n return results;\n }\n\n private filterLowAttendance(row: AttendanceWeekRow): boolean {\n let countAbsences = 0;\n if (!this.attendanceStatusType) {\n countAbsences = row.attendanceDays.filter(\n (e) => e?.status?.countAs === AttendanceLogicalStatus.ABSENT,\n ).length;\n } else {\n countAbsences = row.attendanceDays.filter(\n (e) => e?.status?.id === this.attendanceStatusType,\n ).length;\n }\n\n return countAbsences > this.absentWarningThreshold;\n }\n\n goToChild(childId: string) {\n const Child = this.entityRegistry.get(\"Child\");\n this.router.navigate([Child.route, childId]);\n }\n}\n","import { Entity } from \"./entity\";\n\n/**\n * Interface that conveys an updated entity as well as information\n * on the update-type\n */\nexport interface UpdatedEntity {\n /**\n * The updated entity\n */\n entity: T;\n\n /**\n * The type of the update, either:\n * \"new\" - a new entity was created,\n * \"update\" - an existing entity was updated\n * \"remove\" - the entity was deleted\n */\n type: \"new\" | \"update\" | \"remove\";\n}\n\n/**\n * Updates a list of entities given an updated version of the entity. This updated version\n * can either be a new entity (that should be inserted into the list), or an existing entity\n * that should be updated or deleted.\n * The given array will not be mutated but will be returned when the given new entity\n * or type is illegal\n * @param next An entity that should be updated as well as the type of update. This, as well as the entity\n * may be undefined or null. In this event, the entities-array is returned as is.\n * @param entities The entities to update, must be defined\n * @param addIfMissing (Optional) whether to add an entity that comes through an update event but is not part of the array yet,\n * default is to add, disable this if you do special filtering or calculations on the data\n * @return An array of the given entities with the update applied\n */\nexport function applyUpdate(\n entities: T[],\n next: UpdatedEntity,\n addIfMissing: boolean = true,\n): T[] {\n if (!next || !next.entity || !entities) {\n return entities;\n }\n\n if (\n (next.type === \"new\" || (addIfMissing && next.type === \"update\")) &&\n !entities.find((e) => e.getId() === next.entity.getId())\n ) {\n return [next.entity].concat(entities);\n }\n\n if (next.type === \"update\") {\n return entities.map((e) =>\n e.getId() === next.entity.getId() ? next.entity : e,\n );\n }\n\n if (next.type === \"remove\") {\n return entities.filter((e) => e.getId() !== next.entity.getId());\n }\n\n return entities;\n}\n"],"names":["AttendanceDayBlockComponent","tooltip","this","attendance","remarks","status","label","$localize","selectors","inputs","standalone","features","i0","decls","vars","consts","template","rf","ctx","shortName","MatTooltipModule","i1","styles","rowGroup_r2","_r1","$implicit","ctx_r2","goToChild","childId","day_r4","AttendanceWeekDashboardComponent_td_11_div_1_ng_container_1_Template","activityRecord_r5","attendanceDays","AttendanceWeekDashboardComponent_td_11_div_1_Template","rowGroup_r6","AttendanceWeekDashboardComponent","DashboardWidget","getRequiredEntities","EventNote","ENTITY_TYPE","constructor","attendanceService","router","entityRegistry","super","daysOffset","absentWarningThreshold","ngOnInit","periodLabel","loadAttendanceOfAbsentees","_this","_asyncToGenerator","previousMonday","moment","startOf","subtract","add","previousSaturday","activityAttendances","getAllActivityAttendancesForPeriod","toDate","lowAttendanceCases","Set","records","att","rows","generateRowsFromActivityAttendance","push","filter","r","filterLowAttendance","forEach","groups","groupBy","entries","has","map","_","from","to","activity","results","participant","participants","eventAttendances","day","isSameOrBefore","event","events","find","e","isSame","date","getAttendance","undefined","row","countAbsences","attendanceStatusType","id","length","countAs","AttendanceLogicalStatus","ABSENT","Child","get","navigate","route","i2","i3","i18n_0","AttendanceWeekDashboardComponent_td_9_Template","AttendanceWeekDashboardComponent_td_11_Template","AttendanceWeekDashboardComponent_tr_12_Template","AttendanceWeekDashboardComponent_div_13_Template","_c0","NgIf","MatTableModule","i4","NgForOf","EntityBlockComponent","DashboardListWidgetComponent","__decorate","DynamicComponent","tslib_es6","Sn","AttendanceService","Router","EntityRegistry","applyUpdate","entities","next","addIfMissing","entity","type","getId","concat"],"mappings":"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","debug_id":"11a89bfb-80cc-5029-8b9c-79d13caa7b7b"}