src/app/features/attendance/deprecated/attendance-block/attendance-block.component.ts

Description

Display attendance details of a single period for a participant as a compact block. This shows calculated attendance of multiple events.

Example

Metadata

Relationships

Used by

No results matching.

Index

Properties
Inputs

Inputs

attendanceData
Type : ActivityAttendance
forChild
Type : string

Properties

Readonly attendanceDescription
Type : unknown
Default value : computed(() => { const logicalCount = this.logicalCount(); return `${logicalCount[this.LStatus.PRESENT]} / ${ (logicalCount[this.LStatus.PRESENT] || 0) + (logicalCount[this.LStatus.ABSENT] || 0) }`; })
Readonly attendancePercentage
Type : unknown
Default value : computed(() => { const attendanceData = this.attendanceData(); const forChild = this.forChild(); if (!attendanceData || !forChild) { return "-"; } const percentage = attendanceData.getAttendancePercentage(forChild); if (!Number.isFinite(percentage)) { return "-"; } return formatPercent(percentage, this.locale, "1.0-0"); })
Readonly logicalCount
Type : unknown
Default value : computed<{ [key in AttendanceLogicalStatus]?: number; }>(() => { const attendanceData = this.attendanceData(); const forChild = this.forChild(); if (!attendanceData || !forChild) { return {}; } return attendanceData.individualLogicalStatusCounts.get(forChild) ?? {}; })
LStatus
Type : unknown
Default value : AttendanceLogicalStatus
Readonly warningLevel
Type : unknown
Default value : computed(() => { const attendanceData = this.attendanceData(); const forChild = this.forChild(); if (!attendanceData || !forChild) { return ""; } return attendanceData.getWarningLevel(forChild); })
import {
  Component,
  inject,
  LOCALE_ID,
  ChangeDetectionStrategy,
  computed,
  input,
} from "@angular/core";
import { ActivityAttendance } from "../../model/activity-attendance";
import { AttendanceLogicalStatus } from "../../model/attendance-status";
import { formatPercent, PercentPipe } from "@angular/common";
import { CustomDatePipe } from "#src/app/core/basic-datatypes/date/custom-date.pipe";
import { TemplateTooltipDirective } from "#src/app/core/common-components/template-tooltip/template-tooltip.directive";
import { AttendanceCalendarComponent } from "../../analysis/attendance-calendar/attendance-calendar.component";

/**
 * Display attendance details of a single period for a participant as a compact block.
 * This shows calculated attendance of multiple events.
 */
@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: "app-attendance-block",
  templateUrl: "./attendance-block.component.html",
  styleUrls: ["./attendance-block.component.scss"],
  imports: [
    PercentPipe,
    CustomDatePipe,
    TemplateTooltipDirective,
    AttendanceCalendarComponent,
  ],
})
export class AttendanceBlockComponent {
  private locale = inject(LOCALE_ID);

  attendanceData = input<ActivityAttendance>();
  forChild = input<string>();
  LStatus = AttendanceLogicalStatus;
  readonly logicalCount = computed<{
    [key in AttendanceLogicalStatus]?: number;
  }>(() => {
    const attendanceData = this.attendanceData();
    const forChild = this.forChild();
    if (!attendanceData || !forChild) {
      return {};
    }
    return attendanceData.individualLogicalStatusCounts.get(forChild) ?? {};
  });

  readonly attendanceDescription = computed(() => {
    const logicalCount = this.logicalCount();
    return `${logicalCount[this.LStatus.PRESENT]} / ${
      (logicalCount[this.LStatus.PRESENT] || 0) +
      (logicalCount[this.LStatus.ABSENT] || 0)
    }`;
  });

  readonly attendancePercentage = computed(() => {
    const attendanceData = this.attendanceData();
    const forChild = this.forChild();
    if (!attendanceData || !forChild) {
      return "-";
    }
    const percentage = attendanceData.getAttendancePercentage(forChild);
    if (!Number.isFinite(percentage)) {
      return "-";
    }
    return formatPercent(percentage, this.locale, "1.0-0");
  });

  readonly warningLevel = computed(() => {
    const attendanceData = this.attendanceData();
    const forChild = this.forChild();
    if (!attendanceData || !forChild) {
      return "";
    }
    return attendanceData.getWarningLevel(forChild);
  });
}
<span
  class="mat-elevation-z1 attendance-block w-{{ warningLevel() }}"
  [appTemplateTooltip]="tooltip"
>
  @if (
    attendanceData()?.getAttendancePercentage(forChild() || "") !== null &&
    attendanceData()?.getAttendancePercentage(forChild() || "") !== undefined
  ) {
    <span>
      {{
        attendanceData()?.getAttendancePercentage(forChild() || "")
          | percent: "1.0-0"
      }}
    </span>
  } @else {
    <span> - </span>
  }
</span>

<ng-template #tooltip>
  <div class="attendance-tooltip-container">
    <strong>
      {{ attendanceData()?.periodFrom | customDate: "shortDate" }} -
      {{ attendanceData()?.periodTo | customDate: "shortDate" }}
      {{ attendanceData()?.activity?.title }}
    </strong>

    <div
      i18n="
        Attended Tooltip|How many attendees were present / how many attendees
        were absent
      "
    >
      attended {{ attendanceDescription() }} events
    </div>

    @if (logicalCount()[LStatus.IGNORE] > 0) {
      <em i18n="Attended Tooltip|How many events were excluded">
        (excluding {{ logicalCount()[LStatus.IGNORE] }} events excused or
        unknown)
      </em>
    }
    <app-attendance-calendar
      [records]="attendanceData()?.events"
      [highlightForChild]="forChild()"
      [activity]="attendanceData()?.activity"
    >
    </app-attendance-calendar>
  </div>
</ng-template>

./attendance-block.component.scss

.attendance-block {
  display: inline-block;
  text-align: center;
  border-radius: 4px;
  margin: 3px;
  width: 42px;
  padding-top: 5px;
  padding-bottom: 5px;
}

.attendance-tooltip-container {
  padding: 0.5em;
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""