src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.ts
Display a list of entity subrecords (entities related to the current entity details view) which cover a time period.
This component is similar to RelatedEntities but provides some additional UI to help users create a new entry if no currently active entry exists. Past entries stay visible like a history, the entry covering today is highlighted.
| changeDetection | ChangeDetectionStrategy.OnPush |
| selector | app-related-time-period-entities |
| standalone | true |
| imports |
FontAwesomeModule
MatSlideToggleModule
MatTooltipModule
|
| styleUrls | ./related-time-period-entities.component.scss |
| templateUrl | ./related-time-period-entities.component.html |
No results matching.
FontAwesomeModule
EntitiesTableComponent
MatSlideToggleModule
FormsModule
MatTooltipModule
PillComponent
CustomFormLinkButtonComponent
RelatedEntitiesComponent<E>
Properties |
|
Methods |
|
Inputs |
Outputs |
| single | |
Type : boolean
|
|
Default value : true
|
|
| clickMode | |
Type : "popup" | "navigate" | "popup-details"
|
|
Default value : "popup"
|
|
|
Inherited from
RelatedEntitiesComponent
|
|
| columns | |
Type : ColumnConfig[]
|
|
Default value : []
|
|
|
Inherited from
RelatedEntitiesComponent
|
|
|
Columns to be displayed in the table |
|
| dataSource | |
Type : DataSourceType
|
|
|
Inherited from
RelatedEntitiesComponent
|
|
| editable | |
Type : boolean
|
|
Default value : true
|
|
|
Inherited from
RelatedEntitiesComponent
|
|
| entity | |
Type : Entity
|
|
|
Inherited from
RelatedEntitiesComponent
|
|
|
currently viewed/main entity for which related entities are displayed in this component |
|
| entityType | |
Type : string
|
|
|
Inherited from
RelatedEntitiesComponent
|
|
|
entity type of the related entities to be displayed |
|
| filter | |
Type : DataFilter<E>
|
|
|
Inherited from
RelatedEntitiesComponent
|
|
|
This filter is applied before displaying the data. |
|
| loaderMethod | |
Type : LoaderMethod
|
|
|
Inherited from
RelatedEntitiesComponent
|
|
|
The special service or method to load data via an index or other special method. |
|
| property | |
Type : string | string[]
|
|
|
Inherited from
RelatedEntitiesComponent
|
|
|
Property name of the related entities (type given in this.entityType) that holds the entity id to be matched with the id of the current main entity (given in this.entity). If not explicitly set, this will be inferred based on the defined relations between the entities. manually setting this is only necessary if you have multiple properties referencing the same entity type
and you want to list only records related to one of them.
For example: if you set |
|
| showInactive | |
Type : boolean | undefined
|
|
Default value : undefined
|
|
|
Inherited from
RelatedEntitiesComponent
|
|
|
Whether inactive/archived records should be shown. |
|
| showInactive | |
Type : boolean | undefined
|
|
|
Inherited from
RelatedEntitiesComponent
|
|
|
Whether inactive/archived records should be shown. |
|
| createNewRecordFactory |
createNewRecordFactory()
|
|
Inherited from
RelatedEntitiesComponent
|
|
Returns :
() => any
|
| Protected getColumns | ||||||
getColumns(value: ColumnConfig[] | undefined)
|
||||||
|
Inherited from
RelatedEntitiesComponent
|
||||||
|
Parameters :
Returns :
FormFieldConfig[]
|
| Protected getDefaultColumns |
getDefaultColumns()
|
|
Inherited from
RelatedEntitiesComponent
|
|
Returns :
FormFieldConfig[]
|
| Protected getProperty |
getProperty()
|
|
Inherited from
RelatedEntitiesComponent
|
|
Auto-detect which properties of the related entity type reference the current entity. Returns dot-paths for nested references (e.g. "attendance.participant").
Returns :
string | []
|
| Protected initFilter |
initFilter()
|
|
Inherited from
RelatedEntitiesComponent
|
|
Returns :
DataFilter<E>
|
| backgroundColorFn |
Type : unknown
|
Default value : () => {...}
|
| Readonly hasCurrentlyActiveEntry |
Type : unknown
|
Default value : computed(
() =>
this.recordsDataSource()
.allRecords()
?.some((record) => record.isActiveAt(new Date())) ?? false,
)
|
| Readonly _columns |
Type : unknown
|
Default value : computed(() => {
const entity = this.entity();
const rawCols = this.getColumns(this.columns());
if (!entity) return rawCols;
return rawCols.map((column) => {
if (typeof column.additional === "object" && column.additional !== null) {
return {
...column,
additional: { ...column.additional, relatedEntitiesParent: entity },
};
}
return column;
});
})
|
|
Inherited from
RelatedEntitiesComponent
|
| Readonly columnsToDisplay |
Type : unknown
|
Default value : computed(() =>
this._columns()
.filter((column) => {
if (column?.hideFromTable) return false;
const numericValue = ScreenSize[column?.visibleFrom];
if (numericValue === undefined) return true;
return this.currentScreenSize() >= numericValue;
})
.map((c) => c.id),
)
|
|
Inherited from
RelatedEntitiesComponent
|
| Protected Readonly entityCtr |
Type : unknown
|
Default value : computed<EntityConstructor<E> | undefined>(
() => {
const entityType = this.entityType();
if (!entityType) {
return undefined;
}
return this.entityRegistry.get(entityType) as EntityConstructor<E>;
},
)
|
|
Inherited from
RelatedEntitiesComponent
|
| Readonly filterObj |
Type : unknown
|
Default value : signal<DataFilter<E>>({})
|
|
Inherited from
RelatedEntitiesComponent
|
| Protected filterService |
Type : unknown
|
Default value : inject(FilterService)
|
|
Inherited from
RelatedEntitiesComponent
|
| recordsDataSource |
Type : unknown
|
Default value : computed(() =>
resolveDataSource<E>(this.injector, this.dataSource(), this.loaderMethod()),
)
|
|
Inherited from
RelatedEntitiesComponent
|
| Protected Readonly relationProperty |
Type : unknown
|
Default value : computed<string | string[]>(() => {
const entity = this.entity();
const entityCtr = this.entityCtr();
if (!entity || !entityCtr) {
return [];
}
const resolvedProperty = this.property() ?? this.getProperty();
return typeof resolvedProperty === "string"
? this.resolvePropertyPath(resolvedProperty)
: resolvedProperty.map((p) => this.resolvePropertyPath(p));
})
|
|
Inherited from
RelatedEntitiesComponent
|
import {
ChangeDetectionStrategy,
Component,
computed,
input,
} from "@angular/core";
import {
ColumnConfig,
FormFieldConfig,
toFormFieldConfig,
} from "../../common-components/entity-form/FormConfig";
import moment from "moment";
import { DynamicComponent } from "../../config/dynamic-components/dynamic-component.decorator";
import { FontAwesomeModule } from "@fortawesome/angular-fontawesome";
import { MatSlideToggleModule } from "@angular/material/slide-toggle";
import { FormsModule } from "@angular/forms";
import { MatTooltipModule } from "@angular/material/tooltip";
import { EntitiesTableComponent } from "../../common-components/entities-table/entities-table.component";
import { PillComponent } from "../../common-components/pill/pill.component";
import { ChildSchoolRelation } from "../../../child-dev-project/children/model/childSchoolRelation";
import { RelatedEntitiesComponent } from "../related-entities/related-entities.component";
import { TimePeriod } from "./time-period";
import { CustomFormLinkButtonComponent } from "app/features/public-form/custom-form-link-button/custom-form-link-button.component";
/** highlight color for the entry that covers the current date */
export const CURRENTLY_ACTIVE_COLOR = "#90ee9040";
/**
* Display a list of entity subrecords (entities related to the current entity details view)
* which cover a time period.
*
* This component is similar to RelatedEntities but provides some additional UI to help users
* create a new entry if no currently active entry exists.
* Past entries stay visible like a history, the entry covering today is highlighted.
*/
@DynamicComponent("RelatedTimePeriodEntities")
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: "app-related-time-period-entities",
templateUrl: "./related-time-period-entities.component.html",
styleUrls: ["./related-time-period-entities.component.scss"],
imports: [
FontAwesomeModule,
EntitiesTableComponent,
MatSlideToggleModule,
FormsModule,
MatTooltipModule,
PillComponent,
CustomFormLinkButtonComponent,
],
})
export class RelatedTimePeriodEntitiesComponent<
E extends TimePeriod,
> extends RelatedEntitiesComponent<E> {
// also see super class for Inputs
single = input(true);
backgroundColorFn = (r: E) =>
r.isActiveAt(new Date()) ? CURRENTLY_ACTIVE_COLOR : "";
readonly hasCurrentlyActiveEntry = computed(
() =>
this.recordsDataSource()
.allRecords()
?.some((record) => record.isActiveAt(new Date())) ?? false,
);
override createNewRecordFactory() {
return () => {
const newRelation = super.createNewRecordFactory()();
const currentData = this.recordsDataSource().allRecords();
newRelation.start =
currentData?.length && currentData[0].end
? moment(currentData[0].end).add(1, "day").toDate()
: moment().startOf("day").toDate();
return newRelation;
};
}
protected override getColumns(
value: ColumnConfig[] | undefined,
): FormFieldConfig[] {
if (!Array.isArray(value) || value.length === 0) {
return [
{ id: "start", visibleFrom: "md" },
{ id: "end", visibleFrom: "md" },
currentlyActiveIndicator,
];
}
return [
...value.map((column) => toFormFieldConfig(column)),
currentlyActiveIndicator,
];
}
}
export const currentlyActiveIndicator: FormFieldConfig = {
id: "currentlyActive",
label: $localize`:Label for the currently active status|e.g. Currently active:Currently`,
viewComponent: "ReadonlyFunction",
hideFromTable: true,
description: $localize`:Tooltip for the status of currently active or not:Only added to linked record if active. Change the start or end date to modify this status.`,
additional: (csr: ChildSchoolRelation) =>
csr.isActiveAt(new Date())
? $localize`:Indication for the currently active status of an entry:active`
: $localize`:Indication for the currently inactive status of an entry:not active`,
};
@if (!hasCurrentlyActiveEntry() && !recordsDataSource().isLoading()) {
<app-pill class="hint-badge">
<span i18n
>Currently there is no active entry. To add a new entry, click on the
button</span
>&ngsp;<fa-icon
class="color-accent"
aria-hidden="true"
icon="plus-circle"
></fa-icon>
</app-pill>
}
<app-entities-table
[entityType]="entityCtr()!"
[recordsDataSource]="recordsDataSource()"
[filter]="filterObj()"
[customColumns]="_columns()"
[newRecordFactory]="createNewRecordFactory()"
[getBackgroundColor]="backgroundColorFn"
[clickMode]="clickMode()"
[(showInactive)]="showInactive"
>
</app-entities-table>
<app-custom-form-link-button
[linkedEntity]="entity()"
[formEntityType]="entityCtr()!"
>
</app-custom-form-link-button>
./related-time-period-entities.component.scss
@use "variables/sizes";
@use "variables/colors";
.hint-badge {
background-color: colors.$primary;
margin-bottom: sizes.$regular;
}