From 1dd2703fcf2fd13d02f1c5b6b5f9b1b3572d4d62 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Thu, 21 Dec 2023 20:59:04 +0100 Subject: [PATCH 01/58] first step (mostly working) refactoring of entities-table component --- .../activities-overview.component.ts | 4 +- ...activity-attendance-section.component.html | 7 +- .../activity-attendance-section.component.ts | 5 +- .../attendance-details.component.html | 7 +- .../attendance-details.component.ts | 5 +- .../aser/aser-component/aser.component.ts | 13 +- .../children-list/children-list.component.ts | 5 +- .../health-checkup.component.html | 7 +- .../health-checkup.component.ts | 6 +- .../notes-manager.component.html | 1 - .../notes-manager/notes-manager.component.ts | 4 +- .../notes-related-to-entity.component.html | 8 +- .../notes-related-to-entity.component.ts | 30 +- .../child-school-overview.component.ts | 24 +- .../configure-enum-popup.component.ts | 1 - .../entities-table.component.html} | 78 +-- .../entities-table.component.scss} | 10 + .../entities-table.component.spec.ts} | 125 +--- .../entities-table.component.ts | 403 +++++++++++++ .../entity-subrecord-config.ts | 11 +- .../entity-subrecord.component.ts | 545 ------------------ .../entity-subrecord.stories.ts | 109 ---- .../entity-subrecord/table-sort.ts | 2 +- ...lated-entities-with-summary.component.html | 8 +- ...related-entities-with-summary.component.ts | 4 +- .../related-entities.component.html | 9 +- .../related-entities.component.ts | 84 ++- ...elated-time-period-entities.component.html | 15 +- .../related-time-period-entities.component.ts | 5 +- src/app/core/entity-list/EntityListConfig.ts | 4 +- .../entity-list/entity-list.component.html | 13 +- .../entity-list/entity-list.component.ts | 69 +-- src/app/core/filter/filter.service.ts | 3 +- .../import-review-data.component.html | 5 +- .../import-review-data.component.ts | 16 +- .../historical-data.component.ts | 15 +- .../matching-entities.component.html | 7 +- .../matching-entities.component.ts | 4 +- .../todos-related-to-entity.component.html | 8 +- .../todos-related-to-entity.component.ts | 14 +- 40 files changed, 719 insertions(+), 974 deletions(-) rename src/app/core/common-components/{entity-subrecord/entity-subrecord/entity-subrecord.component.html => entities-table/entities-table.component.html} (74%) rename src/app/core/common-components/{entity-subrecord/entity-subrecord/entity-subrecord.component.scss => entities-table/entities-table.component.scss} (80%) rename src/app/core/common-components/{entity-subrecord/entity-subrecord/entity-subrecord.component.spec.ts => entities-table/entities-table.component.spec.ts} (70%) create mode 100644 src/app/core/common-components/entities-table/entities-table.component.ts delete mode 100644 src/app/core/common-components/entity-subrecord/entity-subrecord/entity-subrecord.component.ts delete mode 100644 src/app/core/common-components/entity-subrecord/entity-subrecord/entity-subrecord.stories.ts diff --git a/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts b/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts index 09c82acb86..65c7f81b34 100644 --- a/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts +++ b/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts @@ -2,9 +2,9 @@ import { Component, OnInit } from "@angular/core"; import { RecurringActivity } from "../model/recurring-activity"; import { DynamicComponent } from "../../../core/config/dynamic-components/dynamic-component.decorator"; import { RelatedEntitiesComponent } from "../../../core/entity-details/related-entities/related-entities.component"; -import { EntitySubrecordComponent } from "../../../core/common-components/entity-subrecord/entity-subrecord/entity-subrecord.component"; import { ColumnConfig } from "../../../core/common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; import { FormFieldConfig } from "../../../core/common-components/entity-form/entity-form/FormConfig"; +import { EntitiesTableComponent } from "../../../core/common-components/entities-table/entities-table.component"; /** * @deprecated configure a RelatedEntitiesComponent instead @@ -14,7 +14,7 @@ import { FormFieldConfig } from "../../../core/common-components/entity-form/ent selector: "app-activities-overview", templateUrl: "../../../core/entity-details/related-entities/related-entities.component.html", - imports: [EntitySubrecordComponent], + imports: [EntitiesTableComponent], standalone: true, }) export class ActivitiesOverviewComponent diff --git a/src/app/child-dev-project/attendance/activity-attendance-section/activity-attendance-section.component.html b/src/app/child-dev-project/attendance/activity-attendance-section/activity-attendance-section.component.html index 5b38fa7ecd..fca5ed4321 100644 --- a/src/app/child-dev-project/attendance/activity-attendance-section/activity-attendance-section.component.html +++ b/src/app/child-dev-project/attendance/activity-attendance-section/activity-attendance-section.component.html @@ -17,15 +17,16 @@ > - - +
- - + `, + >`, standalone: true, - imports: [EntitySubrecordComponent, NgIf], + imports: [EntitiesTableComponent], }) export class AserComponent implements OnInit { @Input() entity: Child; @@ -31,6 +31,7 @@ export class AserComponent implements OnInit { ], }; records: Aser[]; + entityCtr = Aser; constructor(private childrenService: ChildrenService) {} diff --git a/src/app/child-dev-project/children/children-list/children-list.component.ts b/src/app/child-dev-project/children/children-list/children-list.component.ts index d417239f68..bd1c7ed4ff 100644 --- a/src/app/child-dev-project/children/children-list/children-list.component.ts +++ b/src/app/child-dev-project/children/children-list/children-list.component.ts @@ -14,7 +14,6 @@ import { RouteTarget } from "../../../route-target"; `, @@ -22,10 +21,9 @@ import { RouteTarget } from "../../../route-target"; imports: [EntityListComponent], }) export class ChildrenListComponent implements OnInit { - childrenList: Child[] = []; + childrenList: Child[]; listConfig: EntityListConfig; childConstructor = Child; - isLoading = true; constructor( private childrenService: ChildrenService, @@ -40,6 +38,5 @@ export class ChildrenListComponent implements OnInit { (this.listConfig = data.config), ); this.childrenList = await this.childrenService.getChildren(); - this.isLoading = false; } } diff --git a/src/app/child-dev-project/children/health-checkup/health-checkup-component/health-checkup.component.html b/src/app/child-dev-project/children/health-checkup/health-checkup-component/health-checkup.component.html index 49581c5a4d..abc3e9a1d7 100644 --- a/src/app/child-dev-project/children/health-checkup/health-checkup-component/health-checkup.component.html +++ b/src/app/child-dev-project/children/health-checkup/health-checkup-component/health-checkup.component.html @@ -1,5 +1,6 @@ - +> diff --git a/src/app/child-dev-project/children/health-checkup/health-checkup-component/health-checkup.component.ts b/src/app/child-dev-project/children/health-checkup/health-checkup-component/health-checkup.component.ts index cc1cec1c36..67d5a89ec8 100644 --- a/src/app/child-dev-project/children/health-checkup/health-checkup-component/health-checkup.component.ts +++ b/src/app/child-dev-project/children/health-checkup/health-checkup-component/health-checkup.component.ts @@ -4,17 +4,19 @@ import { ChildrenService } from "../../children.service"; import { Child } from "../../model/child"; import { FormFieldConfig } from "../../../../core/common-components/entity-form/entity-form/FormConfig"; import { DynamicComponent } from "../../../../core/config/dynamic-components/dynamic-component.decorator"; -import { EntitySubrecordComponent } from "../../../../core/common-components/entity-subrecord/entity-subrecord/entity-subrecord.component"; +import { EntitiesTableComponent } from "../../../../core/common-components/entities-table/entities-table.component"; @DynamicComponent("HealthCheckup") @Component({ selector: "app-health-checkup", templateUrl: "./health-checkup.component.html", - imports: [EntitySubrecordComponent], + imports: [EntitiesTableComponent], standalone: true, }) export class HealthCheckupComponent implements OnInit { records: HealthCheck[] = []; + entityCtr = HealthCheck; + /** * Column Description for the SubentityRecordComponent * The Date-Column needs to be transformed to apply the MathFormCheck in the SubentityRecordComponent diff --git a/src/app/child-dev-project/notes/notes-manager/notes-manager.component.html b/src/app/child-dev-project/notes/notes-manager/notes-manager.component.html index 9209cd4b07..ff9ffa00fe 100644 --- a/src/app/child-dev-project/notes/notes-manager/notes-manager.component.html +++ b/src/app/child-dev-project/notes/notes-manager/notes-manager.component.html @@ -1,7 +1,6 @@ [] = [ @@ -117,7 +117,6 @@ export class NotesManagerComponent implements OnInit { const eventNotes = await this.entityMapperService.loadType(EventNote); notes = notes.concat(eventNotes); } - this.isLoading = false; return notes; } @@ -141,7 +140,6 @@ export class NotesManagerComponent implements OnInit { async updateIncludeEvents() { this.includeEventNotes = !this.includeEventNotes; - this.isLoading = true; this.notes = await this.loadEntities(); } diff --git a/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.html b/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.html index 60bc4d9906..b6c73f57d4 100644 --- a/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.html +++ b/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.html @@ -1,11 +1,11 @@ - - + diff --git a/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts b/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts index 3cdeee1543..2f132193d9 100644 --- a/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts +++ b/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts @@ -14,26 +14,30 @@ import { FilterService } from "../../../core/filter/filter.service"; import { Child } from "../../children/model/child"; import { School } from "../../schools/model/school"; import { ChildSchoolRelation } from "../../children/model/childSchoolRelation"; -import { EntitySubrecordComponent } from "../../../core/common-components/entity-subrecord/entity-subrecord/entity-subrecord.component"; import { EntityDatatype } from "../../../core/basic-datatypes/entity/entity.datatype"; import { EntityArrayDatatype } from "../../../core/basic-datatypes/entity-array/entity-array.datatype"; import { asArray } from "../../../utils/utils"; +import { Subscription } from "rxjs"; +import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; +import { applyUpdate } from "../../../core/entity/model/entity-update"; +import { EntitiesTableComponent } from "../../../core/common-components/entities-table/entities-table.component"; +import { EntityMapperService } from "../../../core/entity/entity-mapper/entity-mapper.service"; /** * The component that is responsible for listing the Notes that are related to a certain entity. */ @DynamicComponent("NotesRelatedToEntity") @DynamicComponent("NotesOfChild") // for backward compatibility +@UntilDestroy() @Component({ selector: "app-notes-related-to-entity", templateUrl: "./notes-related-to-entity.component.html", - imports: [EntitySubrecordComponent], + imports: [EntitiesTableComponent], standalone: true, }) export class NotesRelatedToEntityComponent implements OnInit { @Input() entity: Entity; - records: Array = []; - isLoading: boolean; + records: Array; @Input() columns: ColumnConfig[] = [ { id: "date", visibleFrom: "xs" }, @@ -51,8 +55,11 @@ export class NotesRelatedToEntityComponent implements OnInit { getColor = (note: Note) => note?.getColor(); newRecordFactory: () => Note; + entityConstructor = Note; + constructor( private childrenService: ChildrenService, + private entityMapper: EntityMapperService, private formDialog: FormDialogService, private filterService: FilterService, ) {} @@ -67,8 +74,6 @@ export class NotesRelatedToEntityComponent implements OnInit { } private async initNotesOfEntity() { - this.isLoading = true; - this.records = await this.childrenService .getNotesRelatedTo(this.entity.getId(true)) .then((notes: Note[]) => { @@ -81,8 +86,19 @@ export class NotesRelatedToEntityComponent implements OnInit { }); return notes; }); + } - this.isLoading = false; + private updateSubscription: Subscription; + + private listenToEntityUpdates() { + if (!this.updateSubscription && this.entityConstructor) { + this.updateSubscription = this.entityMapper + .receiveUpdates(this.entityConstructor) + .pipe(untilDestroyed(this)) + .subscribe((next) => { + this.records = applyUpdate(this.records, next, true); + }); + } } generateNewRecordFactory() { diff --git a/src/app/child-dev-project/schools/child-school-overview/child-school-overview.component.ts b/src/app/child-dev-project/schools/child-school-overview/child-school-overview.component.ts index 2ac5ade5e0..2871c34b6d 100644 --- a/src/app/child-dev-project/schools/child-school-overview/child-school-overview.component.ts +++ b/src/app/child-dev-project/schools/child-school-overview/child-school-overview.component.ts @@ -10,14 +10,19 @@ import { MatSlideToggleModule } from "@angular/material/slide-toggle"; import { FormsModule } from "@angular/forms"; import { MatTooltipModule } from "@angular/material/tooltip"; import { NgIf } from "@angular/common"; -import { EntitySubrecordComponent } from "../../../core/common-components/entity-subrecord/entity-subrecord/entity-subrecord.component"; import { PillComponent } from "../../../core/common-components/pill/pill.component"; import { RelatedTimePeriodEntitiesComponent } from "../../../core/entity-details/related-time-period-entities/related-time-period-entities.component"; +import { EntitiesTableComponent } from "../../../core/common-components/entities-table/entities-table.component"; +import { EntityMapperService } from "../../../core/entity/entity-mapper/entity-mapper.service"; +import { EntityRegistry } from "../../../core/entity/database-entity.decorator"; +import { ScreenWidthObserver } from "../../../utils/media/screen-size-observer.service"; +import { UntilDestroy } from "@ngneat/until-destroy"; // TODO: once schema-generated indices are available (#262), remove this component and use its generic super class directly @DynamicComponent("ChildSchoolOverview") @DynamicComponent("PreviousSchools") @DynamicComponent("ChildrenOverview") +@UntilDestroy() @Component({ selector: "app-child-school-overview", templateUrl: @@ -27,7 +32,7 @@ import { RelatedTimePeriodEntitiesComponent } from "../../../core/entity-details ], imports: [ FontAwesomeModule, - EntitySubrecordComponent, + EntitiesTableComponent, MatSlideToggleModule, FormsModule, MatTooltipModule, @@ -42,11 +47,16 @@ export class ChildSchoolOverviewComponent { mode: "child" | "school" = "child"; @Input() showInactive = false; + entityCtr = ChildSchoolRelation; - constructor(private childrenService: ChildrenService) { - super(null, null); + constructor( + private childrenService: ChildrenService, + entityMapper: EntityMapperService, + entityRegistry: EntityRegistry, + screenWidthObserver: ScreenWidthObserver, + ) { + super(entityMapper, entityRegistry, screenWidthObserver); - this.entityCtr = ChildSchoolRelation; this.columns = [ { id: "childId" }, // schoolId/childId replaced dynamically during init { id: "start", visibleFrom: "md" }, @@ -62,6 +72,7 @@ export class ChildSchoolOverviewComponent await this.loadData(); super.onIsActiveFilterChange(this.showInactive); + super.listenToEntityUpdates(); } private inferMode(entity: Entity): "child" | "school" { @@ -90,12 +101,9 @@ export class ChildSchoolOverviewComponent return; } - this.isLoading = true; this.data = await this.childrenService.queryRelationsOf( this.mode, this.entity.getId(false), ); - - this.isLoading = false; } } diff --git a/src/app/core/basic-datatypes/configurable-enum/configure-enum-popup/configure-enum-popup.component.ts b/src/app/core/basic-datatypes/configurable-enum/configure-enum-popup/configure-enum-popup.component.ts index bffccff20a..5f5713440c 100644 --- a/src/app/core/basic-datatypes/configurable-enum/configure-enum-popup/configure-enum-popup.component.ts +++ b/src/app/core/basic-datatypes/configurable-enum/configure-enum-popup/configure-enum-popup.component.ts @@ -135,5 +135,4 @@ export class ConfigureEnumPopupComponent { }); this.newOptionInput = ""; } - mynewFun() {} } diff --git a/src/app/core/common-components/entity-subrecord/entity-subrecord/entity-subrecord.component.html b/src/app/core/common-components/entities-table/entities-table.component.html similarity index 74% rename from src/app/core/common-components/entity-subrecord/entity-subrecord/entity-subrecord.component.html rename to src/app/core/common-components/entities-table/entities-table.component.html index 046db6baa6..c4408c4e1f 100644 --- a/src/app/core/common-components/entity-subrecord/entity-subrecord/entity-subrecord.component.html +++ b/src/app/core/common-components/entities-table/entities-table.component.html @@ -2,24 +2,14 @@ -
+
- - - - - - + - + + + + - + - - +
- - + + + + + + +
- + - +
+ + diff --git a/src/app/features/matching-entities/matching-entities/matching-entities.component.ts b/src/app/features/matching-entities/matching-entities/matching-entities.component.ts index 247c614730..83b5b59e48 100644 --- a/src/app/features/matching-entities/matching-entities/matching-entities.component.ts +++ b/src/app/features/matching-entities/matching-entities/matching-entities.component.ts @@ -31,7 +31,6 @@ import { MatTooltipModule } from "@angular/material/tooltip"; import { NgForOf, NgIf } from "@angular/common"; import { MatButtonModule } from "@angular/material/button"; import { EntityFieldViewComponent } from "../../../core/common-components/entity-field-view/entity-field-view.component"; -import { EntitySubrecordComponent } from "../../../core/common-components/entity-subrecord/entity-subrecord/entity-subrecord.component"; import { MapComponent } from "../../location/map/map.component"; import { FilterComponent } from "../../../core/filter/filter/filter.component"; import { Coordinates } from "../../location/coordinates"; @@ -42,6 +41,7 @@ import { FlattenArrayPipe } from "../../../utils/flatten-array/flatten-array.pip import { isArrayDataType } from "../../../core/basic-datatypes/datatype-utils"; import { FormFieldConfig } from "../../../core/common-components/entity-form/entity-form/FormConfig"; import { RouteTarget } from "../../../route-target"; +import { EntitiesTableComponent } from "../../../core/common-components/entities-table/entities-table.component"; export interface MatchingSide extends MatchingSideConfig { /** pass along filters from app-filter to subrecord component */ @@ -78,7 +78,7 @@ export interface MatchingSide extends MatchingSideConfig { NgIf, MatButtonModule, NgForOf, - EntitySubrecordComponent, + EntitiesTableComponent, EntityFieldViewComponent, MapComponent, FilterComponent, diff --git a/src/app/features/todos/todos-related-to-entity/todos-related-to-entity.component.html b/src/app/features/todos/todos-related-to-entity/todos-related-to-entity.component.html index 7f11ce30ab..e504e1a8c0 100644 --- a/src/app/features/todos/todos-related-to-entity/todos-related-to-entity.component.html +++ b/src/app/features/todos/todos-related-to-entity/todos-related-to-entity.component.html @@ -1,10 +1,10 @@ - +> diff --git a/src/app/features/todos/todos-related-to-entity/todos-related-to-entity.component.ts b/src/app/features/todos/todos-related-to-entity/todos-related-to-entity.component.ts index b8f69d9846..00c7be80bf 100644 --- a/src/app/features/todos/todos-related-to-entity/todos-related-to-entity.component.ts +++ b/src/app/features/todos/todos-related-to-entity/todos-related-to-entity.component.ts @@ -7,9 +7,9 @@ import { DynamicComponent } from "../../../core/config/dynamic-components/dynami import { FormDialogService } from "../../../core/form-dialog/form-dialog.service"; import { TodoDetailsComponent } from "../todo-details/todo-details.component"; import { DataFilter } from "../../../core/common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; -import { EntitySubrecordComponent } from "../../../core/common-components/entity-subrecord/entity-subrecord/entity-subrecord.component"; import { MatSlideToggleModule } from "@angular/material/slide-toggle"; import { FormsModule } from "@angular/forms"; +import { EntitiesTableComponent } from "../../../core/common-components/entities-table/entities-table.component"; @DynamicComponent("TodosRelatedToEntity") @Component({ @@ -17,11 +17,11 @@ import { FormsModule } from "@angular/forms"; templateUrl: "./todos-related-to-entity.component.html", styleUrls: ["./todos-related-to-entity.component.scss"], standalone: true, - imports: [EntitySubrecordComponent, MatSlideToggleModule, FormsModule], + imports: [EntitiesTableComponent, MatSlideToggleModule, FormsModule], }) export class TodosRelatedToEntityComponent implements OnInit { entries: Todo[] = []; - isLoading: boolean; + entityCtr = Todo; @Input() entity: Entity; @Input() columns: FormFieldConfig[] = [ @@ -42,7 +42,6 @@ export class TodosRelatedToEntityComponent implements OnInit { // TODO: filter by current user as default in UX? --> custom filter component or some kind of variable interpolation? filter: DataFilter = { isActive: true }; - includeInactive: boolean; backgroundColorFn = (r: Todo) => { if (!r.isActive) { return "#e0e0e0"; @@ -69,9 +68,7 @@ export class TodosRelatedToEntityComponent implements OnInit { } private async loadDataFor(entityId: string): Promise { - this.isLoading = true; - - const data = await this.dbIndexingService.queryIndexDocs( + return this.dbIndexingService.queryIndexDocs( Todo, "todo_index/by_" + this.referenceProperty, { @@ -80,9 +77,6 @@ export class TodosRelatedToEntityComponent implements OnInit { descending: true, }, ); - - this.isLoading = false; - return data; } public getNewEntryFunction(): () => Todo { From a16d52b067ec1e711ec2f99ff9baee2aab5057da Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Fri, 22 Dec 2023 14:08:13 +0100 Subject: [PATCH 02/58] move code locations --- .../activities-overview.component.ts | 6 +++-- .../roll-call-setup.component.ts | 2 +- .../aser/aser-component/aser.component.ts | 3 ++- .../health-checkup.component.ts | 2 +- .../notes-related-to-entity.component.ts | 6 ++--- .../admin-entity-form.component.spec.ts | 2 +- .../admin-entity-form.component.ts | 4 ++-- .../entities-table.component.ts | 16 ++++++------- .../list-paginator.component.html | 0 .../list-paginator.component.scss | 2 +- .../list-paginator.component.spec.ts | 0 .../list-paginator.component.ts | 0 .../table-sort}/table-sort.spec.ts | 0 .../table-sort}/table-sort.ts | 4 ++-- .../value-accessor}/value-accessor.spec.ts | 0 .../value-accessor}/value-accessor.ts | 0 .../entity-field-edit.component.ts | 6 +++-- .../entity-field-label.component.ts | 6 +++-- .../entity-field-view.component.ts | 6 +++-- .../entity-form/entity-form.service.ts | 10 ++++---- .../entity-form/entity-form/FormConfig.ts | 13 ++++++++++ .../entity-subrecord-config.ts | 23 ------------------ .../core/entity-details/form/field-group.ts | 2 +- .../related-entities.component.ts | 10 ++++---- src/app/core/entity-list/EntityListConfig.ts | 2 +- .../entity-list/entity-list.component.ts | 2 +- .../data-transformation.service.ts | 2 +- .../download-service/download.service.ts | 2 +- .../filter-generator/filter-predicate.ts | 2 +- .../filter-overlay.component.ts | 2 +- src/app/core/filter/filter.service.spec.ts | 2 +- src/app/core/filter/filter.service.ts | 2 +- .../core/filter/filter/filter.component.ts | 3 +-- src/app/core/filter/filters/filters.ts | 10 +++++++- .../core/form-dialog/form-dialog.service.ts | 6 ++--- .../row-details/row-details.component.html | 0 .../row-details/row-details.component.spec.ts | 6 ++--- .../row-details/row-details.component.ts | 24 +++++++++---------- .../matching-entities-config.ts | 6 ++--- .../matching-entities.component.ts | 10 ++++---- .../todo-details/todo-details.component.ts | 2 +- .../todo-details/todo-details.stories.ts | 2 +- .../todos-related-to-entity.component.ts | 4 ++-- src/app/utils/utils.ts | 2 +- 44 files changed, 108 insertions(+), 106 deletions(-) rename src/app/core/common-components/{entity-subrecord => entities-table}/list-paginator/list-paginator.component.html (100%) rename src/app/core/common-components/{entity-subrecord => entities-table}/list-paginator/list-paginator.component.scss (92%) rename src/app/core/common-components/{entity-subrecord => entities-table}/list-paginator/list-paginator.component.spec.ts (100%) rename src/app/core/common-components/{entity-subrecord => entities-table}/list-paginator/list-paginator.component.ts (100%) rename src/app/core/common-components/{entity-subrecord/entity-subrecord => entities-table/table-sort}/table-sort.spec.ts (100%) rename src/app/core/common-components/{entity-subrecord/entity-subrecord => entities-table/table-sort}/table-sort.ts (93%) rename src/app/core/common-components/{entity-subrecord/entity-subrecord => entities-table/value-accessor}/value-accessor.spec.ts (100%) rename src/app/core/common-components/{entity-subrecord/entity-subrecord => entities-table/value-accessor}/value-accessor.ts (100%) delete mode 100644 src/app/core/common-components/entity-subrecord/entity-subrecord/entity-subrecord-config.ts rename src/app/core/{common-components/entity-subrecord => form-dialog}/row-details/row-details.component.html (100%) rename src/app/core/{common-components/entity-subrecord => form-dialog}/row-details/row-details.component.spec.ts (85%) rename src/app/core/{common-components/entity-subrecord => form-dialog}/row-details/row-details.component.ts (66%) diff --git a/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts b/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts index 65c7f81b34..be81226855 100644 --- a/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts +++ b/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts @@ -2,8 +2,10 @@ import { Component, OnInit } from "@angular/core"; import { RecurringActivity } from "../model/recurring-activity"; import { DynamicComponent } from "../../../core/config/dynamic-components/dynamic-component.decorator"; import { RelatedEntitiesComponent } from "../../../core/entity-details/related-entities/related-entities.component"; -import { ColumnConfig } from "../../../core/common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; -import { FormFieldConfig } from "../../../core/common-components/entity-form/entity-form/FormConfig"; +import { + ColumnConfig, + FormFieldConfig, +} from "../../../core/common-components/entity-form/entity-form/FormConfig"; import { EntitiesTableComponent } from "../../../core/common-components/entities-table/entities-table.component"; /** diff --git a/src/app/child-dev-project/attendance/add-day-attendance/roll-call-setup/roll-call-setup.component.ts b/src/app/child-dev-project/attendance/add-day-attendance/roll-call-setup/roll-call-setup.component.ts index ec16b5c1d4..6f664253d5 100644 --- a/src/app/child-dev-project/attendance/add-day-attendance/roll-call-setup/roll-call-setup.component.ts +++ b/src/app/child-dev-project/attendance/add-day-attendance/roll-call-setup/roll-call-setup.component.ts @@ -15,7 +15,6 @@ import { AlertService } from "../../../../core/alerts/alert.service"; import { AlertDisplay } from "../../../../core/alerts/alert-display"; import { FormsModule, NgModel } from "@angular/forms"; import { FilterService } from "../../../../core/filter/filter.service"; -import { DataFilter } from "../../../../core/common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; import { FilterConfig } from "../../../../core/entity-list/EntityListConfig"; import { MatFormFieldModule } from "@angular/material/form-field"; import { MatInputModule } from "@angular/material/input"; @@ -27,6 +26,7 @@ import { MatProgressBarModule } from "@angular/material/progress-bar"; import { ActivityCardComponent } from "../../activity-card/activity-card.component"; import { MatButtonModule } from "@angular/material/button"; import { CurrentUserSubject } from "../../../../core/session/current-user-subject"; +import { DataFilter } from "../../../../core/filter/filters/filters"; @Component({ selector: "app-roll-call-setup", diff --git a/src/app/child-dev-project/children/aser/aser-component/aser.component.ts b/src/app/child-dev-project/children/aser/aser-component/aser.component.ts index 9e99b531bd..328adf72c2 100644 --- a/src/app/child-dev-project/children/aser/aser-component/aser.component.ts +++ b/src/app/child-dev-project/children/aser/aser-component/aser.component.ts @@ -4,7 +4,8 @@ import { ChildrenService } from "../../children.service"; import { Child } from "../../model/child"; import { DynamicComponent } from "../../../../core/config/dynamic-components/dynamic-component.decorator"; import { EntitiesTableComponent } from "../../../../core/common-components/entities-table/entities-table.component"; -import { ColumnConfig } from "../../../../core/common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; + +import { ColumnConfig } from "../../../../core/common-components/entity-form/entity-form/FormConfig"; @DynamicComponent("Aser") @Component({ diff --git a/src/app/child-dev-project/children/health-checkup/health-checkup-component/health-checkup.component.ts b/src/app/child-dev-project/children/health-checkup/health-checkup-component/health-checkup.component.ts index 67d5a89ec8..c862d46050 100644 --- a/src/app/child-dev-project/children/health-checkup/health-checkup-component/health-checkup.component.ts +++ b/src/app/child-dev-project/children/health-checkup/health-checkup-component/health-checkup.component.ts @@ -2,7 +2,7 @@ import { Component, Input, OnInit } from "@angular/core"; import { HealthCheck } from "../model/health-check"; import { ChildrenService } from "../../children.service"; import { Child } from "../../model/child"; -import { FormFieldConfig } from "../../../../core/common-components/entity-form/entity-form/FormConfig"; +import { FormFieldConfig } from "../../../../core/common-components/entity-form/FormConfig"; import { DynamicComponent } from "../../../../core/config/dynamic-components/dynamic-component.decorator"; import { EntitiesTableComponent } from "../../../../core/common-components/entities-table/entities-table.component"; diff --git a/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts b/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts index 2f132193d9..8a29f5be0f 100644 --- a/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts +++ b/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts @@ -6,10 +6,6 @@ import moment from "moment"; import { FormDialogService } from "../../../core/form-dialog/form-dialog.service"; import { DynamicComponent } from "../../../core/config/dynamic-components/dynamic-component.decorator"; import { Entity } from "../../../core/entity/model/entity"; -import { - ColumnConfig, - DataFilter, -} from "../../../core/common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; import { FilterService } from "../../../core/filter/filter.service"; import { Child } from "../../children/model/child"; import { School } from "../../schools/model/school"; @@ -22,6 +18,8 @@ import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; import { applyUpdate } from "../../../core/entity/model/entity-update"; import { EntitiesTableComponent } from "../../../core/common-components/entities-table/entities-table.component"; import { EntityMapperService } from "../../../core/entity/entity-mapper/entity-mapper.service"; +import { ColumnConfig } from "../../../core/common-components/entity-form/entity-form/FormConfig"; +import { DataFilter } from "../../../core/filter/filters/filters"; /** * The component that is responsible for listing the Notes that are related to a certain entity. diff --git a/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.spec.ts b/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.spec.ts index b99a191966..0833959158 100644 --- a/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.spec.ts +++ b/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.spec.ts @@ -15,9 +15,9 @@ import { FormGroup } from "@angular/forms"; import { NoopAnimationsModule } from "@angular/platform-browser/animations"; import { CdkDragDrop } from "@angular/cdk/drag-drop"; import { of } from "rxjs"; -import { ColumnConfig } from "../../../common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; import { AdminModule } from "../../admin.module"; import { FormConfig } from "../../../entity-details/form/form.component"; +import { ColumnConfig } from "../../../common-components/entity-form/entity-form/FormConfig"; describe("AdminEntityFormComponent", () => { let component: AdminEntityFormComponent; diff --git a/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.ts b/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.ts index e1a0c46628..719a615d32 100644 --- a/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.ts +++ b/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.ts @@ -12,9 +12,9 @@ import { } from "@angular/cdk/drag-drop"; import { ColumnConfig, + FormFieldConfig, toFormFieldConfig, -} from "../../../common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; -import { FormFieldConfig } from "../../../common-components/entity-form/entity-form/FormConfig"; +} from "../../../common-components/entity-form/entity-form/FormConfig"; import { AdminEntityService } from "../../admin-entity.service"; import { lastValueFrom } from "rxjs"; import { NgForOf, NgIf } from "@angular/common"; diff --git a/src/app/core/common-components/entities-table/entities-table.component.ts b/src/app/core/common-components/entities-table/entities-table.component.ts index e867fd6631..19b0a4820f 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.ts +++ b/src/app/core/common-components/entities-table/entities-table.component.ts @@ -13,7 +13,7 @@ import { EntityFieldLabelComponent } from "../entity-field-label/entity-field-la import { EntityFieldMenuComponent } from "../entity-field-menu/entity-field-menu.component"; import { EntityFieldViewComponent } from "../entity-field-view/entity-field-view.component"; import { FaIconComponent } from "@fortawesome/angular-fontawesome"; -import { ListPaginatorComponent } from "../entity-subrecord/list-paginator/list-paginator.component"; +import { ListPaginatorComponent } from "./list-paginator/list-paginator.component"; import { MatButtonModule } from "@angular/material/button"; import { MatCheckboxChange, @@ -29,7 +29,11 @@ import { } from "@angular/material/sort"; import { MatTableDataSource, MatTableModule } from "@angular/material/table"; import { Entity, EntityConstructor } from "../../entity/model/entity"; -import { FormFieldConfig } from "../entity-form/entity-form/FormConfig"; +import { + ColumnConfig, + FormFieldConfig, + toFormFieldConfig, +} from "../entity-form/entity-form/FormConfig"; import { InvalidFormFieldError } from "../entity-form/invalid-form-field.error"; import { AlertService } from "../../alerts/alert.service"; import { @@ -37,17 +41,13 @@ import { EntityFormService, } from "../entity-form/entity-form.service"; import { EntityActionsService } from "../../entity/entity-actions/entity-actions.service"; -import { - ColumnConfig, - DataFilter, - toFormFieldConfig, -} from "../entity-subrecord/entity-subrecord/entity-subrecord-config"; -import { tableSort } from "../entity-subrecord/entity-subrecord/table-sort"; +import { tableSort } from "./table-sort/table-sort"; import { UntilDestroy } from "@ngneat/until-destroy"; import { entityFilterPredicate } from "../../filter/filter-generator/filter-predicate"; import { FormDialogService } from "../../form-dialog/form-dialog.service"; import { Router } from "@angular/router"; import { FilterService } from "../../filter/filter.service"; +import { DataFilter } from "../../filter/filters/filters"; /** * A simple display component (no logic and transformations) to display a table of entities. diff --git a/src/app/core/common-components/entity-subrecord/list-paginator/list-paginator.component.html b/src/app/core/common-components/entities-table/list-paginator/list-paginator.component.html similarity index 100% rename from src/app/core/common-components/entity-subrecord/list-paginator/list-paginator.component.html rename to src/app/core/common-components/entities-table/list-paginator/list-paginator.component.html diff --git a/src/app/core/common-components/entity-subrecord/list-paginator/list-paginator.component.scss b/src/app/core/common-components/entities-table/list-paginator/list-paginator.component.scss similarity index 92% rename from src/app/core/common-components/entity-subrecord/list-paginator/list-paginator.component.scss rename to src/app/core/common-components/entities-table/list-paginator/list-paginator.component.scss index 2dad93cb08..25c27ed543 100644 --- a/src/app/core/common-components/entity-subrecord/list-paginator/list-paginator.component.scss +++ b/src/app/core/common-components/entities-table/list-paginator/list-paginator.component.scss @@ -1,4 +1,4 @@ -@use "variables/sizes"; +@use "../../../../../styles/variables/sizes"; // The paginator is usually a little smaller than this $approx-width-paginator: 450px; diff --git a/src/app/core/common-components/entity-subrecord/list-paginator/list-paginator.component.spec.ts b/src/app/core/common-components/entities-table/list-paginator/list-paginator.component.spec.ts similarity index 100% rename from src/app/core/common-components/entity-subrecord/list-paginator/list-paginator.component.spec.ts rename to src/app/core/common-components/entities-table/list-paginator/list-paginator.component.spec.ts diff --git a/src/app/core/common-components/entity-subrecord/list-paginator/list-paginator.component.ts b/src/app/core/common-components/entities-table/list-paginator/list-paginator.component.ts similarity index 100% rename from src/app/core/common-components/entity-subrecord/list-paginator/list-paginator.component.ts rename to src/app/core/common-components/entities-table/list-paginator/list-paginator.component.ts diff --git a/src/app/core/common-components/entity-subrecord/entity-subrecord/table-sort.spec.ts b/src/app/core/common-components/entities-table/table-sort/table-sort.spec.ts similarity index 100% rename from src/app/core/common-components/entity-subrecord/entity-subrecord/table-sort.spec.ts rename to src/app/core/common-components/entities-table/table-sort/table-sort.spec.ts diff --git a/src/app/core/common-components/entity-subrecord/entity-subrecord/table-sort.ts b/src/app/core/common-components/entities-table/table-sort/table-sort.ts similarity index 93% rename from src/app/core/common-components/entity-subrecord/entity-subrecord/table-sort.ts rename to src/app/core/common-components/entities-table/table-sort/table-sort.ts index cd75e91bec..5172e5fbe0 100644 --- a/src/app/core/common-components/entity-subrecord/entity-subrecord/table-sort.ts +++ b/src/app/core/common-components/entities-table/table-sort/table-sort.ts @@ -1,7 +1,7 @@ -import { getReadableValue } from "./value-accessor"; +import { getReadableValue } from "../value-accessor/value-accessor"; import { Entity } from "../../../entity/model/entity"; import { Ordering } from "../../../basic-datatypes/configurable-enum/configurable-enum-ordering"; -import { TableRow } from "../../entities-table/entities-table.component"; +import { TableRow } from "../entities-table.component"; /** * Custom sort implementation for a MatTableDataSource> diff --git a/src/app/core/common-components/entity-subrecord/entity-subrecord/value-accessor.spec.ts b/src/app/core/common-components/entities-table/value-accessor/value-accessor.spec.ts similarity index 100% rename from src/app/core/common-components/entity-subrecord/entity-subrecord/value-accessor.spec.ts rename to src/app/core/common-components/entities-table/value-accessor/value-accessor.spec.ts diff --git a/src/app/core/common-components/entity-subrecord/entity-subrecord/value-accessor.ts b/src/app/core/common-components/entities-table/value-accessor/value-accessor.ts similarity index 100% rename from src/app/core/common-components/entity-subrecord/entity-subrecord/value-accessor.ts rename to src/app/core/common-components/entities-table/value-accessor/value-accessor.ts diff --git a/src/app/core/common-components/entity-field-edit/entity-field-edit.component.ts b/src/app/core/common-components/entity-field-edit/entity-field-edit.component.ts index 0f191972c9..edad79c445 100644 --- a/src/app/core/common-components/entity-field-edit/entity-field-edit.component.ts +++ b/src/app/core/common-components/entity-field-edit/entity-field-edit.component.ts @@ -6,8 +6,10 @@ import { EntityForm, EntityFormService, } from "../entity-form/entity-form.service"; -import { ColumnConfig } from "../entity-subrecord/entity-subrecord/entity-subrecord-config"; -import { FormFieldConfig } from "../entity-form/entity-form/FormConfig"; +import { + ColumnConfig, + FormFieldConfig, +} from "../entity-form/entity-form/FormConfig"; import { NgIf } from "@angular/common"; import { EntityFieldViewComponent } from "../entity-field-view/entity-field-view.component"; diff --git a/src/app/core/common-components/entity-field-label/entity-field-label.component.ts b/src/app/core/common-components/entity-field-label/entity-field-label.component.ts index ff661a3095..921aeaf95d 100644 --- a/src/app/core/common-components/entity-field-label/entity-field-label.component.ts +++ b/src/app/core/common-components/entity-field-label/entity-field-label.component.ts @@ -1,8 +1,10 @@ import { Component, Input, OnChanges, SimpleChanges } from "@angular/core"; import { MatTooltipModule } from "@angular/material/tooltip"; import { EntityConstructor } from "../../entity/model/entity"; -import { ColumnConfig } from "../entity-subrecord/entity-subrecord/entity-subrecord-config"; -import { FormFieldConfig } from "../entity-form/entity-form/FormConfig"; +import { + ColumnConfig, + FormFieldConfig, +} from "../entity-form/entity-form/FormConfig"; import { EntityFormService } from "../entity-form/entity-form.service"; import { NgIf } from "@angular/common"; diff --git a/src/app/core/common-components/entity-field-view/entity-field-view.component.ts b/src/app/core/common-components/entity-field-view/entity-field-view.component.ts index e0084080fa..b1942fcd03 100644 --- a/src/app/core/common-components/entity-field-view/entity-field-view.component.ts +++ b/src/app/core/common-components/entity-field-view/entity-field-view.component.ts @@ -6,10 +6,12 @@ import { SimpleChanges, } from "@angular/core"; import { Entity } from "../../entity/model/entity"; -import { ColumnConfig } from "../entity-subrecord/entity-subrecord/entity-subrecord-config"; import { NgIf } from "@angular/common"; import { DynamicComponentDirective } from "../../config/dynamic-components/dynamic-component.directive"; -import { FormFieldConfig } from "../entity-form/entity-form/FormConfig"; +import { + ColumnConfig, + FormFieldConfig, +} from "../entity-form/entity-form/FormConfig"; import { EntityFormService } from "../entity-form/entity-form.service"; import { PillComponent } from "../pill/pill.component"; diff --git a/src/app/core/common-components/entity-form/entity-form.service.ts b/src/app/core/common-components/entity-form/entity-form.service.ts index 9a8f536b15..152cbb313e 100644 --- a/src/app/core/common-components/entity-form/entity-form.service.ts +++ b/src/app/core/common-components/entity-form/entity-form.service.ts @@ -1,6 +1,10 @@ import { Injectable } from "@angular/core"; import { FormBuilder, FormGroup, ɵElement } from "@angular/forms"; -import { FormFieldConfig } from "./entity-form/FormConfig"; +import { + ColumnConfig, + FormFieldConfig, + toFormFieldConfig, +} from "./entity-form/FormConfig"; import { Entity, EntityConstructor } from "../../entity/model/entity"; import { EntityMapperService } from "../../entity/entity-mapper/entity-mapper.service"; import { EntitySchemaService } from "../../entity/schema/entity-schema.service"; @@ -17,10 +21,6 @@ import { PLACEHOLDERS, } from "../../entity/schema/entity-schema-field"; import { isArrayDataType } from "../../basic-datatypes/datatype-utils"; -import { - ColumnConfig, - toFormFieldConfig, -} from "../entity-subrecord/entity-subrecord/entity-subrecord-config"; import { CurrentUserSubject } from "../../session/current-user-subject"; /** diff --git a/src/app/core/common-components/entity-form/entity-form/FormConfig.ts b/src/app/core/common-components/entity-form/entity-form/FormConfig.ts index a84081e286..4a78404e78 100644 --- a/src/app/core/common-components/entity-form/entity-form/FormConfig.ts +++ b/src/app/core/common-components/entity-form/entity-form/FormConfig.ts @@ -44,3 +44,16 @@ export interface FormFieldConfig extends EntitySchemaField { */ forTable?: boolean; } + +/** + * Type for the definition of a single column in the EntitySubrecord + */ +export type ColumnConfig = string | FormFieldConfig; + +export function toFormFieldConfig(column: ColumnConfig): FormFieldConfig { + if (typeof column === "string") { + return { id: column }; + } else { + return column; + } +} diff --git a/src/app/core/common-components/entity-subrecord/entity-subrecord/entity-subrecord-config.ts b/src/app/core/common-components/entity-subrecord/entity-subrecord/entity-subrecord-config.ts deleted file mode 100644 index a65a593e63..0000000000 --- a/src/app/core/common-components/entity-subrecord/entity-subrecord/entity-subrecord-config.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { FormFieldConfig } from "../../entity-form/entity-form/FormConfig"; -import { MongoQuery } from "@casl/ability"; - -/** - * Type for the definition of a single column in the EntitySubrecord - */ -export type ColumnConfig = string | FormFieldConfig; - -export function toFormFieldConfig(column: ColumnConfig): FormFieldConfig { - if (typeof column === "string") { - return { id: column }; - } else { - return column; - } -} - -/** - * This filter can be used to filter an array of entities. - * It has to follow the MongoDB Query Syntax {@link https://www.mongodb.com/docs/manual/reference/operator/query/}. - * - * The filter is parsed using ucast {@link https://github.com/stalniy/ucast/tree/master/packages/mongo2js} - */ -export type DataFilter = MongoQuery | {}; diff --git a/src/app/core/entity-details/form/field-group.ts b/src/app/core/entity-details/form/field-group.ts index 9cd3b3c380..f9f299eef3 100644 --- a/src/app/core/entity-details/form/field-group.ts +++ b/src/app/core/entity-details/form/field-group.ts @@ -1,4 +1,4 @@ -import { ColumnConfig } from "../../common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; +import { ColumnConfig } from "../../common-components/entity-form/entity-form/FormConfig"; /** * A group of related form fields displayed within a Form component. diff --git a/src/app/core/entity-details/related-entities/related-entities.component.ts b/src/app/core/entity-details/related-entities/related-entities.component.ts index 869704a120..b4c66d280d 100644 --- a/src/app/core/entity-details/related-entities/related-entities.component.ts +++ b/src/app/core/entity-details/related-entities/related-entities.component.ts @@ -2,11 +2,6 @@ import { Component, Input, OnInit } from "@angular/core"; import { DynamicComponent } from "../../config/dynamic-components/dynamic-component.decorator"; import { EntityMapperService } from "../../entity/entity-mapper/entity-mapper.service"; import { Entity, EntityConstructor } from "../../entity/model/entity"; -import { - ColumnConfig, - DataFilter, - toFormFieldConfig, -} from "../../common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; import { EntityRegistry } from "../../entity/database-entity.decorator"; import { isArrayProperty } from "../../basic-datatypes/datatype-utils"; import { EntitiesTableComponent } from "../../common-components/entities-table/entities-table.component"; @@ -17,6 +12,11 @@ import { ScreenSize, ScreenWidthObserver, } from "../../../utils/media/screen-size-observer.service"; +import { + ColumnConfig, + toFormFieldConfig, +} from "../../common-components/entity-form/entity-form/FormConfig"; +import { DataFilter } from "../../filter/filters/filters"; /** * Load and display a list of entity subrecords (entities related to the current entity details view). diff --git a/src/app/core/entity-list/EntityListConfig.ts b/src/app/core/entity-list/EntityListConfig.ts index 5e45ca2267..ec0f8edf82 100644 --- a/src/app/core/entity-list/EntityListConfig.ts +++ b/src/app/core/entity-list/EntityListConfig.ts @@ -1,5 +1,5 @@ import { FilterSelectionOption } from "../filter/filters/filters"; -import { FormFieldConfig } from "../common-components/entity-form/entity-form/FormConfig"; +import { FormFieldConfig } from "../common-components/entity-form/FormConfig"; import { ExportColumnConfig } from "../export/data-transformation-service/export-column-config"; import { Sort } from "@angular/material/sort"; import { unitOfTime } from "moment"; diff --git a/src/app/core/entity-list/entity-list/entity-list.component.ts b/src/app/core/entity-list/entity-list/entity-list.component.ts index 6844fe338b..57d2ee3f66 100644 --- a/src/app/core/entity-list/entity-list/entity-list.component.ts +++ b/src/app/core/entity-list/entity-list/entity-list.component.ts @@ -20,7 +20,6 @@ import { EntityMapperService } from "../../entity/entity-mapper/entity-mapper.se import { EntityRegistry } from "../../entity/database-entity.decorator"; import { ScreenWidthObserver } from "../../../utils/media/screen-size-observer.service"; import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; -import { DataFilter } from "../../common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; import { FilterOverlayComponent } from "../../filter/filter-overlay/filter-overlay.component"; import { MatDialog } from "@angular/material/dialog"; import { NgForOf, NgIf, NgStyle, NgTemplateOutlet } from "@angular/common"; @@ -45,6 +44,7 @@ import { RouteTarget } from "../../../route-target"; import { EntitiesTableComponent } from "../../common-components/entities-table/entities-table.component"; import { applyUpdate } from "../../entity/model/entity-update"; import { Subscription } from "rxjs"; +import { DataFilter } from "../../filter/filters/filters"; /** * This component allows to create a full-blown table with pagination, filtering, searching and grouping. diff --git a/src/app/core/export/data-transformation-service/data-transformation.service.ts b/src/app/core/export/data-transformation-service/data-transformation.service.ts index 0844337268..b307584c09 100644 --- a/src/app/core/export/data-transformation-service/data-transformation.service.ts +++ b/src/app/core/export/data-transformation-service/data-transformation.service.ts @@ -2,7 +2,7 @@ import { Injectable } from "@angular/core"; import { getReadableValue, transformToReadableFormat, -} from "../../common-components/entity-subrecord/entity-subrecord/value-accessor"; +} from "../../common-components/entities-table/value-accessor/value-accessor"; import { ExportColumnConfig } from "./export-column-config"; import { QueryService } from "../query.service"; import { groupBy } from "../../../utils/utils"; diff --git a/src/app/core/export/download-service/download.service.ts b/src/app/core/export/download-service/download.service.ts index 2f78122c73..85012822c6 100644 --- a/src/app/core/export/download-service/download.service.ts +++ b/src/app/core/export/download-service/download.service.ts @@ -3,7 +3,7 @@ import { ExportColumnConfig } from "../data-transformation-service/export-column import { ExportDataFormat } from "../export-data-directive/export-data.directive"; import { LoggingService } from "../../logging/logging.service"; import { DataTransformationService } from "../data-transformation-service/data-transformation.service"; -import { transformToReadableFormat } from "../../common-components/entity-subrecord/entity-subrecord/value-accessor"; +import { transformToReadableFormat } from "../../common-components/entities-table/value-accessor/value-accessor"; import { Papa } from "ngx-papaparse"; import { EntitySchemaField } from "app/core/entity/schema/entity-schema-field"; diff --git a/src/app/core/filter/filter-generator/filter-predicate.ts b/src/app/core/filter/filter-generator/filter-predicate.ts index 7192f68faa..632ac14e16 100644 --- a/src/app/core/filter/filter-generator/filter-predicate.ts +++ b/src/app/core/filter/filter-generator/filter-predicate.ts @@ -1,5 +1,5 @@ import { Entity } from "../../entity/model/entity"; -import { getReadableValue } from "../../common-components/entity-subrecord/entity-subrecord/value-accessor"; +import { getReadableValue } from "../../common-components/entities-table/value-accessor/value-accessor"; export function entityFilterPredicate(data: Entity, filter: string): boolean { return [...Object.values(data)].some((value) => diff --git a/src/app/core/filter/filter-overlay/filter-overlay.component.ts b/src/app/core/filter/filter-overlay/filter-overlay.component.ts index 7a2ecd925e..63c082be66 100644 --- a/src/app/core/filter/filter-overlay/filter-overlay.component.ts +++ b/src/app/core/filter/filter-overlay/filter-overlay.component.ts @@ -1,10 +1,10 @@ import { Component, Inject } from "@angular/core"; import { MAT_DIALOG_DATA, MatDialogModule } from "@angular/material/dialog"; import { Entity, EntityConstructor } from "../../entity/model/entity"; -import { DataFilter } from "../../common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; import { FilterConfig } from "../../entity-list/EntityListConfig"; import { FilterComponent } from "../filter/filter.component"; import { MatButtonModule } from "@angular/material/button"; +import { DataFilter } from "../filters/filters"; export interface FilterOverlayData { filterConfig: FilterConfig[]; diff --git a/src/app/core/filter/filter.service.spec.ts b/src/app/core/filter/filter.service.spec.ts index 3e00bf7cbd..40a675270a 100644 --- a/src/app/core/filter/filter.service.spec.ts +++ b/src/app/core/filter/filter.service.spec.ts @@ -2,11 +2,11 @@ import { TestBed } from "@angular/core/testing"; import { FilterService } from "./filter.service"; import { defaultInteractionTypes } from "../config/default-config/default-interaction-types"; -import { DataFilter } from "../common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; import { Note } from "../../child-dev-project/notes/model/note"; import { ConfigurableEnumService } from "../basic-datatypes/configurable-enum/configurable-enum.service"; import { createTestingConfigurableEnumService } from "../basic-datatypes/configurable-enum/configurable-enum-testing"; import moment from "moment"; +import { DataFilter } from "./filters/filters"; describe("FilterService", () => { let service: FilterService; diff --git a/src/app/core/filter/filter.service.ts b/src/app/core/filter/filter.service.ts index 633b8f3239..455b878b9e 100644 --- a/src/app/core/filter/filter.service.ts +++ b/src/app/core/filter/filter.service.ts @@ -1,6 +1,5 @@ import { Injectable } from "@angular/core"; import { EntitySchemaField } from "../entity/schema/entity-schema-field"; -import { DataFilter } from "../common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; import { Entity } from "../entity/model/entity"; import { allInterpreters, @@ -12,6 +11,7 @@ import { import moment from "moment"; import { ConfigurableEnumService } from "../basic-datatypes/configurable-enum/configurable-enum.service"; import { MongoQuery } from "@casl/ability"; +import { DataFilter } from "./filters/filters"; /** * Utility service to help handling and aligning filters with entities. diff --git a/src/app/core/filter/filter/filter.component.ts b/src/app/core/filter/filter/filter.component.ts index 710298369f..bfb27e8e9a 100644 --- a/src/app/core/filter/filter/filter.component.ts +++ b/src/app/core/filter/filter/filter.component.ts @@ -8,7 +8,6 @@ import { } from "@angular/core"; import { FilterConfig } from "../../entity-list/EntityListConfig"; import { Entity, EntityConstructor } from "../../entity/model/entity"; -import { DataFilter } from "../../common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; import { FilterGeneratorService } from "../filter-generator/filter-generator.service"; import { ActivatedRoute, Params, Router } from "@angular/router"; import { getUrlWithoutParams } from "../../../utils/utils"; @@ -16,7 +15,7 @@ import { ListFilterComponent } from "../list-filter/list-filter.component"; import { NgForOf, NgIf } from "@angular/common"; import { Angulartics2Module } from "angulartics2"; import { DateRangeFilterComponent } from "../../basic-datatypes/date/date-range-filter/date-range-filter.component"; -import { Filter } from "../filters/filters"; +import { DataFilter, Filter } from "../filters/filters"; /** * This component can be used to display filters, for example above tables. diff --git a/src/app/core/filter/filters/filters.ts b/src/app/core/filter/filters/filters.ts index ab60a04953..9ed1a92ba2 100644 --- a/src/app/core/filter/filters/filters.ts +++ b/src/app/core/filter/filters/filters.ts @@ -20,12 +20,20 @@ import { BooleanFilterConfig, DateRangeFilterConfigOption, } from "../../entity-list/EntityListConfig"; -import { DataFilter } from "../../common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; import { Entity } from "../../entity/model/entity"; import { DateRange } from "@angular/material/datepicker"; import { isValidDate } from "../../../utils/utils"; import { calculateDateRange } from "../../basic-datatypes/date/date-range-filter/date-range-filter-panel/date-range-filter-panel.component"; import moment from "moment/moment"; +import { MongoQuery } from "@casl/ability"; + +/** + * This filter can be used to filter an array of entities. + * It has to follow the MongoDB Query Syntax {@link https://www.mongodb.com/docs/manual/reference/operator/query/}. + * + * The filter is parsed using ucast {@link https://github.com/stalniy/ucast/tree/master/packages/mongo2js} + */ +export type DataFilter = MongoQuery | {}; export abstract class Filter { public selectedOption: string; diff --git a/src/app/core/form-dialog/form-dialog.service.ts b/src/app/core/form-dialog/form-dialog.service.ts index 82cfef8e0e..eca3617729 100644 --- a/src/app/core/form-dialog/form-dialog.service.ts +++ b/src/app/core/form-dialog/form-dialog.service.ts @@ -6,12 +6,12 @@ import { } from "@angular/material/dialog"; import { ComponentType } from "@angular/cdk/overlay"; import { Entity } from "../entity/model/entity"; -import { RowDetailsComponent } from "../common-components/entity-subrecord/row-details/row-details.component"; -import { FormFieldConfig } from "../common-components/entity-form/entity-form/FormConfig"; +import { RowDetailsComponent } from "./row-details/row-details.component"; import { ColumnConfig, + FormFieldConfig, toFormFieldConfig, -} from "../common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; +} from "../common-components/entity-form/entity-form/FormConfig"; import { EntitySchemaService } from "../entity/schema/entity-schema.service"; @Injectable({ providedIn: "root" }) diff --git a/src/app/core/common-components/entity-subrecord/row-details/row-details.component.html b/src/app/core/form-dialog/row-details/row-details.component.html similarity index 100% rename from src/app/core/common-components/entity-subrecord/row-details/row-details.component.html rename to src/app/core/form-dialog/row-details/row-details.component.html diff --git a/src/app/core/common-components/entity-subrecord/row-details/row-details.component.spec.ts b/src/app/core/form-dialog/row-details/row-details.component.spec.ts similarity index 85% rename from src/app/core/common-components/entity-subrecord/row-details/row-details.component.spec.ts rename to src/app/core/form-dialog/row-details/row-details.component.spec.ts index 8c8d8f2589..391500ce30 100644 --- a/src/app/core/common-components/entity-subrecord/row-details/row-details.component.spec.ts +++ b/src/app/core/form-dialog/row-details/row-details.component.spec.ts @@ -5,9 +5,9 @@ import { RowDetailsComponent, } from "./row-details.component"; import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; -import { Entity } from "../../../entity/model/entity"; -import { MockedTestingModule } from "../../../../utils/mocked-testing.module"; -import { EntityAbility } from "../../../permissions/ability/entity-ability"; +import { Entity } from "../../entity/model/entity"; +import { MockedTestingModule } from "../../../utils/mocked-testing.module"; +import { EntityAbility } from "../../permissions/ability/entity-ability"; import { NEVER } from "rxjs"; describe("RowDetailsComponent", () => { diff --git a/src/app/core/common-components/entity-subrecord/row-details/row-details.component.ts b/src/app/core/form-dialog/row-details/row-details.component.ts similarity index 66% rename from src/app/core/common-components/entity-subrecord/row-details/row-details.component.ts rename to src/app/core/form-dialog/row-details/row-details.component.ts index 06c0f52aac..8935b20167 100644 --- a/src/app/core/common-components/entity-subrecord/row-details/row-details.component.ts +++ b/src/app/core/form-dialog/row-details/row-details.component.ts @@ -1,23 +1,23 @@ import { Component, Inject } from "@angular/core"; -import { FormFieldConfig } from "../../entity-form/entity-form/FormConfig"; +import { FormFieldConfig } from "../../common-components/entity-form/entity-form/FormConfig"; import { MAT_DIALOG_DATA, MatDialogModule } from "@angular/material/dialog"; -import { Entity } from "../../../entity/model/entity"; +import { Entity } from "../../entity/model/entity"; import { EntityForm, EntityFormService, -} from "../../entity-form/entity-form.service"; -import { DialogCloseComponent } from "../../dialog-close/dialog-close.component"; -import { EntityFormComponent } from "../../entity-form/entity-form/entity-form.component"; +} from "../../common-components/entity-form/entity-form.service"; +import { DialogCloseComponent } from "../../common-components/dialog-close/dialog-close.component"; +import { EntityFormComponent } from "../../common-components/entity-form/entity-form/entity-form.component"; import { NgForOf, NgIf } from "@angular/common"; -import { PillComponent } from "../../pill/pill.component"; -import { DynamicComponentDirective } from "../../../config/dynamic-components/dynamic-component.directive"; +import { PillComponent } from "../../common-components/pill/pill.component"; +import { DynamicComponentDirective } from "../../config/dynamic-components/dynamic-component.directive"; import { MatTooltipModule } from "@angular/material/tooltip"; import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; -import { DialogButtonsComponent } from "../../../form-dialog/dialog-buttons/dialog-buttons.component"; -import { EntityArchivedInfoComponent } from "../../../entity-details/entity-archived-info/entity-archived-info.component"; -import { FieldGroup } from "../../../entity-details/form/field-group"; -import { EntityFieldEditComponent } from "../../entity-field-edit/entity-field-edit.component"; -import { EntityFieldViewComponent } from "../../entity-field-view/entity-field-view.component"; +import { DialogButtonsComponent } from "../dialog-buttons/dialog-buttons.component"; +import { EntityArchivedInfoComponent } from "../../entity-details/entity-archived-info/entity-archived-info.component"; +import { FieldGroup } from "../../entity-details/form/field-group"; +import { EntityFieldEditComponent } from "../../common-components/entity-field-edit/entity-field-edit.component"; +import { EntityFieldViewComponent } from "../../common-components/entity-field-view/entity-field-view.component"; /** * Data interface that must be given when opening the dialog diff --git a/src/app/features/matching-entities/matching-entities/matching-entities-config.ts b/src/app/features/matching-entities/matching-entities/matching-entities-config.ts index b3569f83ee..d8c56f5a5f 100644 --- a/src/app/features/matching-entities/matching-entities/matching-entities-config.ts +++ b/src/app/features/matching-entities/matching-entities/matching-entities-config.ts @@ -1,9 +1,7 @@ import { FilterConfig } from "../../../core/entity-list/EntityListConfig"; -import { - ColumnConfig, - DataFilter, -} from "../../../core/common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; import { Entity, EntityConstructor } from "../../../core/entity/model/entity"; +import { ColumnConfig } from "../../../core/common-components/entity-form/entity-form/FormConfig"; +import { DataFilter } from "../../../core/filter/filters/filters"; /** * Config to be defined to set up a MatchingEntitiesComponent. diff --git a/src/app/features/matching-entities/matching-entities/matching-entities.component.ts b/src/app/features/matching-entities/matching-entities/matching-entities.component.ts index 83b5b59e48..2bf7109458 100644 --- a/src/app/features/matching-entities/matching-entities/matching-entities.component.ts +++ b/src/app/features/matching-entities/matching-entities/matching-entities.component.ts @@ -15,10 +15,6 @@ import { MatchingSideConfig, NewMatchAction, } from "./matching-entities-config"; -import { - ColumnConfig, - DataFilter, -} from "../../../core/common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; import { DynamicComponentConfig } from "../../../core/config/dynamic-components/dynamic-component-config.interface"; import { ActivatedRoute } from "@angular/router"; import { FormDialogService } from "../../../core/form-dialog/form-dialog.service"; @@ -39,9 +35,13 @@ import { LocationProperties } from "../../location/map/map-properties-popup/map- import { getLocationProperties } from "../../location/map-utils"; import { FlattenArrayPipe } from "../../../utils/flatten-array/flatten-array.pipe"; import { isArrayDataType } from "../../../core/basic-datatypes/datatype-utils"; -import { FormFieldConfig } from "../../../core/common-components/entity-form/entity-form/FormConfig"; +import { + ColumnConfig, + FormFieldConfig, +} from "../../../core/common-components/entity-form/entity-form/FormConfig"; import { RouteTarget } from "../../../route-target"; import { EntitiesTableComponent } from "../../../core/common-components/entities-table/entities-table.component"; +import { DataFilter } from "../../../core/filter/filters/filters"; export interface MatchingSide extends MatchingSideConfig { /** pass along filters from app-filter to subrecord component */ diff --git a/src/app/features/todos/todo-details/todo-details.component.ts b/src/app/features/todos/todo-details/todo-details.component.ts index c5d930712a..3886b6bde5 100644 --- a/src/app/features/todos/todo-details/todo-details.component.ts +++ b/src/app/features/todos/todo-details/todo-details.component.ts @@ -12,7 +12,7 @@ import { MatDialogModule, MatDialogRef, } from "@angular/material/dialog"; -import { DetailsComponentData } from "../../../core/common-components/entity-subrecord/row-details/row-details.component"; +import { DetailsComponentData } from "../../../core/form-dialog/row-details/row-details.component"; import { TodoService } from "../todo.service"; import { EntityForm, diff --git a/src/app/features/todos/todo-details/todo-details.stories.ts b/src/app/features/todos/todo-details/todo-details.stories.ts index be14167891..036b1b3822 100644 --- a/src/app/features/todos/todo-details/todo-details.stories.ts +++ b/src/app/features/todos/todo-details/todo-details.stories.ts @@ -2,7 +2,7 @@ import { applicationConfig, Meta, StoryFn } from "@storybook/angular"; import { StorybookBaseModule } from "../../../utils/storybook-base.module"; import { TodoDetailsComponent } from "./todo-details.component"; import { Todo } from "../model/todo"; -import { FormFieldConfig } from "../../../core/common-components/entity-form/entity-form/FormConfig"; +import { FormFieldConfig } from "../../../core/common-components/entity-form/FormConfig"; import { importProvidersFrom } from "@angular/core"; import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; import { NEVER } from "rxjs"; diff --git a/src/app/features/todos/todos-related-to-entity/todos-related-to-entity.component.ts b/src/app/features/todos/todos-related-to-entity/todos-related-to-entity.component.ts index 00c7be80bf..334a0ddf14 100644 --- a/src/app/features/todos/todos-related-to-entity/todos-related-to-entity.component.ts +++ b/src/app/features/todos/todos-related-to-entity/todos-related-to-entity.component.ts @@ -1,15 +1,15 @@ import { Component, Input, OnInit } from "@angular/core"; -import { FormFieldConfig } from "../../../core/common-components/entity-form/entity-form/FormConfig"; +import { FormFieldConfig } from "../../../core/common-components/entity-form/FormConfig"; import { Entity } from "../../../core/entity/model/entity"; import { Todo } from "../model/todo"; import { DatabaseIndexingService } from "../../../core/entity/database-indexing/database-indexing.service"; import { DynamicComponent } from "../../../core/config/dynamic-components/dynamic-component.decorator"; import { FormDialogService } from "../../../core/form-dialog/form-dialog.service"; import { TodoDetailsComponent } from "../todo-details/todo-details.component"; -import { DataFilter } from "../../../core/common-components/entity-subrecord/entity-subrecord/entity-subrecord-config"; import { MatSlideToggleModule } from "@angular/material/slide-toggle"; import { FormsModule } from "@angular/forms"; import { EntitiesTableComponent } from "../../../core/common-components/entities-table/entities-table.component"; +import { DataFilter } from "../../../core/filter/filters/filters"; @DynamicComponent("TodosRelatedToEntity") @Component({ diff --git a/src/app/utils/utils.ts b/src/app/utils/utils.ts index 6a41a2a1e0..5fda46858a 100644 --- a/src/app/utils/utils.ts +++ b/src/app/utils/utils.ts @@ -5,7 +5,7 @@ import { Router } from "@angular/router"; import { ConfigurableEnumValue } from "../core/basic-datatypes/configurable-enum/configurable-enum.interface"; import { FactoryProvider, Injector } from "@angular/core"; -import { isConfigurableEnum } from "../core/common-components/entity-subrecord/entity-subrecord/value-accessor"; +import { isConfigurableEnum } from "../core/common-components/entities-table/value-accessor/value-accessor"; export function isValidDate(date: any): boolean { return ( From 2785f19349947d9d0e0a285e9d558adf6bcfea91 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Fri, 22 Dec 2023 14:32:27 +0100 Subject: [PATCH 03/58] extract inline-edit --- .../activities-overview.component.ts | 2 +- .../activity-attendance-section.component.ts | 2 +- .../attendance-details.component.ts | 2 +- .../attendance-summary.component.ts | 2 +- .../aser/aser-component/aser.component.ts | 2 +- .../notes-related-to-entity.component.ts | 2 +- .../admin-entity-form.component.spec.ts | 2 +- .../admin-entity-form.component.ts | 2 +- .../entity-reference-array.stories.ts | 2 +- .../entity-reference.stories.ts | 2 +- .../edit-description-only.component.ts | 2 +- .../entities-table.component.html | 51 +------------ .../entities-table.component.ts | 73 +++--------------- .../entity-inline-edit-actions.component.html | 48 ++++++++++++ .../entity-inline-edit-actions.component.scss | 0 ...tity-inline-edit-actions.component.spec.ts | 23 ++++++ .../entity-inline-edit-actions.component.ts | 76 +++++++++++++++++++ .../entity-field-edit.component.ts | 5 +- .../entity-field-label.component.ts | 5 +- .../entity-field-view.component.ts | 5 +- .../{entity-form => }/FormConfig.ts | 2 +- .../entity-form/entity-form.service.spec.ts | 2 +- .../entity-form/entity-form.service.ts | 6 +- .../core/entity-details/form/field-group.ts | 2 +- .../related-entities.component.ts | 2 +- .../related-time-period-entities.component.ts | 2 +- .../entity-list/entity-list.component.html | 1 + .../entity-list/entity-list.component.ts | 2 +- .../edit-component-story-utils.ts | 2 +- .../entity/default-datatype/edit-component.ts | 2 +- .../core/form-dialog/form-dialog.service.ts | 2 +- .../row-details/row-details.component.ts | 2 +- .../historical-data.component.ts | 2 +- .../historical-data.stories.ts | 2 +- .../matching-entities-config.ts | 2 +- .../matching-entities.component.spec.ts | 2 +- .../matching-entities.component.ts | 2 +- 37 files changed, 192 insertions(+), 153 deletions(-) create mode 100644 src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.html create mode 100644 src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.scss create mode 100644 src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.spec.ts create mode 100644 src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.ts rename src/app/core/common-components/entity-form/{entity-form => }/FormConfig.ts (95%) diff --git a/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts b/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts index be81226855..ed8c9bf7a8 100644 --- a/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts +++ b/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts @@ -5,7 +5,7 @@ import { RelatedEntitiesComponent } from "../../../core/entity-details/related-e import { ColumnConfig, FormFieldConfig, -} from "../../../core/common-components/entity-form/entity-form/FormConfig"; +} from "../../../core/common-components/entity-form/FormConfig"; import { EntitiesTableComponent } from "../../../core/common-components/entities-table/entities-table.component"; /** diff --git a/src/app/child-dev-project/attendance/activity-attendance-section/activity-attendance-section.component.ts b/src/app/child-dev-project/attendance/activity-attendance-section/activity-attendance-section.component.ts index e53daf401f..82db4598e6 100644 --- a/src/app/child-dev-project/attendance/activity-attendance-section/activity-attendance-section.component.ts +++ b/src/app/child-dev-project/attendance/activity-attendance-section/activity-attendance-section.component.ts @@ -5,7 +5,7 @@ import { AttendanceService } from "../attendance.service"; import { formatPercent, NgIf } from "@angular/common"; import { ActivityAttendance } from "../model/activity-attendance"; import moment from "moment"; -import { FormFieldConfig } from "../../../core/common-components/entity-form/entity-form/FormConfig"; +import { FormFieldConfig } from "../../../core/common-components/entity-form/FormConfig"; import { DynamicComponent } from "../../../core/config/dynamic-components/dynamic-component.decorator"; import { MatProgressBarModule } from "@angular/material/progress-bar"; import { MatSlideToggleModule } from "@angular/material/slide-toggle"; diff --git a/src/app/child-dev-project/attendance/attendance-details/attendance-details.component.ts b/src/app/child-dev-project/attendance/attendance-details/attendance-details.component.ts index 78c096e7e3..60a04da918 100644 --- a/src/app/child-dev-project/attendance/attendance-details/attendance-details.component.ts +++ b/src/app/child-dev-project/attendance/attendance-details/attendance-details.component.ts @@ -3,7 +3,7 @@ import { ActivityAttendance } from "../model/activity-attendance"; import { NoteDetailsComponent } from "../../notes/note-details/note-details.component"; import { Note } from "../../notes/model/note"; import { calculateAverageAttendance } from "../model/calculate-average-event-attendance"; -import { FormFieldConfig } from "../../../core/common-components/entity-form/entity-form/FormConfig"; +import { FormFieldConfig } from "../../../core/common-components/entity-form/FormConfig"; import { FormDialogService } from "../../../core/form-dialog/form-dialog.service"; import { EventNote } from "../model/event-note"; import { DialogCloseComponent } from "../../../core/common-components/dialog-close/dialog-close.component"; diff --git a/src/app/child-dev-project/attendance/attendance-summary/attendance-summary.component.ts b/src/app/child-dev-project/attendance/attendance-summary/attendance-summary.component.ts index 4feb6fa7f1..47ea5a35fc 100644 --- a/src/app/child-dev-project/attendance/attendance-summary/attendance-summary.component.ts +++ b/src/app/child-dev-project/attendance/attendance-summary/attendance-summary.component.ts @@ -1,6 +1,6 @@ import { Component, Input } from "@angular/core"; import { ActivityAttendance } from "../model/activity-attendance"; -import { FormFieldConfig } from "../../../core/common-components/entity-form/entity-form/FormConfig"; +import { FormFieldConfig } from "../../../core/common-components/entity-form/FormConfig"; import { DatePipe, NgForOf, NgIf } from "@angular/common"; import { DynamicComponentDirective } from "../../../core/config/dynamic-components/dynamic-component.directive"; diff --git a/src/app/child-dev-project/children/aser/aser-component/aser.component.ts b/src/app/child-dev-project/children/aser/aser-component/aser.component.ts index 328adf72c2..839978d176 100644 --- a/src/app/child-dev-project/children/aser/aser-component/aser.component.ts +++ b/src/app/child-dev-project/children/aser/aser-component/aser.component.ts @@ -5,7 +5,7 @@ import { Child } from "../../model/child"; import { DynamicComponent } from "../../../../core/config/dynamic-components/dynamic-component.decorator"; import { EntitiesTableComponent } from "../../../../core/common-components/entities-table/entities-table.component"; -import { ColumnConfig } from "../../../../core/common-components/entity-form/entity-form/FormConfig"; +import { ColumnConfig } from "../../../../core/common-components/entity-form/FormConfig"; @DynamicComponent("Aser") @Component({ diff --git a/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts b/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts index 8a29f5be0f..bfa13e9e0a 100644 --- a/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts +++ b/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts @@ -18,7 +18,7 @@ import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; import { applyUpdate } from "../../../core/entity/model/entity-update"; import { EntitiesTableComponent } from "../../../core/common-components/entities-table/entities-table.component"; import { EntityMapperService } from "../../../core/entity/entity-mapper/entity-mapper.service"; -import { ColumnConfig } from "../../../core/common-components/entity-form/entity-form/FormConfig"; +import { ColumnConfig } from "../../../core/common-components/entity-form/FormConfig"; import { DataFilter } from "../../../core/filter/filters/filters"; /** diff --git a/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.spec.ts b/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.spec.ts index 0833959158..bd3a2ea960 100644 --- a/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.spec.ts +++ b/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.spec.ts @@ -17,7 +17,7 @@ import { CdkDragDrop } from "@angular/cdk/drag-drop"; import { of } from "rxjs"; import { AdminModule } from "../../admin.module"; import { FormConfig } from "../../../entity-details/form/form.component"; -import { ColumnConfig } from "../../../common-components/entity-form/entity-form/FormConfig"; +import { ColumnConfig } from "../../../common-components/entity-form/FormConfig"; describe("AdminEntityFormComponent", () => { let component: AdminEntityFormComponent; diff --git a/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.ts b/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.ts index 719a615d32..4d21022718 100644 --- a/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.ts +++ b/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.ts @@ -14,7 +14,7 @@ import { ColumnConfig, FormFieldConfig, toFormFieldConfig, -} from "../../../common-components/entity-form/entity-form/FormConfig"; +} from "../../../common-components/entity-form/FormConfig"; import { AdminEntityService } from "../../admin-entity.service"; import { lastValueFrom } from "rxjs"; import { NgForOf, NgIf } from "@angular/common"; diff --git a/src/app/core/basic-datatypes/entity-array/edit-entity-array/entity-reference-array.stories.ts b/src/app/core/basic-datatypes/entity-array/edit-entity-array/entity-reference-array.stories.ts index e574e338e3..b10f433b97 100644 --- a/src/app/core/basic-datatypes/entity-array/edit-entity-array/entity-reference-array.stories.ts +++ b/src/app/core/basic-datatypes/entity-array/edit-entity-array/entity-reference-array.stories.ts @@ -1,5 +1,5 @@ import { applicationConfig, Meta, StoryFn } from "@storybook/angular"; -import { FormFieldConfig } from "../../../common-components/entity-form/entity-form/FormConfig"; +import { FormFieldConfig } from "../../../common-components/entity-form/FormConfig"; import { entityFormStorybookDefaultParameters, StorybookBaseModule, diff --git a/src/app/core/basic-datatypes/entity/edit-single-entity/entity-reference.stories.ts b/src/app/core/basic-datatypes/entity/edit-single-entity/entity-reference.stories.ts index 0e47704df8..1af5e35840 100644 --- a/src/app/core/basic-datatypes/entity/edit-single-entity/entity-reference.stories.ts +++ b/src/app/core/basic-datatypes/entity/edit-single-entity/entity-reference.stories.ts @@ -1,5 +1,5 @@ import { applicationConfig, Meta, StoryFn } from "@storybook/angular"; -import { FormFieldConfig } from "../../../common-components/entity-form/entity-form/FormConfig"; +import { FormFieldConfig } from "../../../common-components/entity-form/FormConfig"; import { entityFormStorybookDefaultParameters, StorybookBaseModule, diff --git a/src/app/core/common-components/description-only/edit-description-only/edit-description-only.component.ts b/src/app/core/common-components/description-only/edit-description-only/edit-description-only.component.ts index d4eb424984..f8fac8ff55 100644 --- a/src/app/core/common-components/description-only/edit-description-only/edit-description-only.component.ts +++ b/src/app/core/common-components/description-only/edit-description-only/edit-description-only.component.ts @@ -1,6 +1,6 @@ import { Component, Input } from "@angular/core"; import { DynamicComponent } from "../../../config/dynamic-components/dynamic-component.decorator"; -import { FormFieldConfig } from "../../entity-form/entity-form/FormConfig"; +import { FormFieldConfig } from "../../entity-form/FormConfig"; @DynamicComponent("EditDescriptionOnly") @Component({ diff --git a/src/app/core/common-components/entities-table/entities-table.component.html b/src/app/core/common-components/entities-table/entities-table.component.html index c4408c4e1f..621dbfcffa 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.html +++ b/src/app/core/common-components/entities-table/entities-table.component.html @@ -82,54 +82,9 @@ - -
- - - - - - - - -
+ + + diff --git a/src/app/core/common-components/entities-table/entities-table.component.ts b/src/app/core/common-components/entities-table/entities-table.component.ts index 19b0a4820f..21f3c0c39e 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.ts +++ b/src/app/core/common-components/entities-table/entities-table.component.ts @@ -10,7 +10,6 @@ import { Angulartics2Module } from "angulartics2"; import { DisableEntityOperationDirective } from "../../permissions/permission-directive/disable-entity-operation.directive"; import { EntityFieldEditComponent } from "../entity-field-edit/entity-field-edit.component"; import { EntityFieldLabelComponent } from "../entity-field-label/entity-field-label.component"; -import { EntityFieldMenuComponent } from "../entity-field-menu/entity-field-menu.component"; import { EntityFieldViewComponent } from "../entity-field-view/entity-field-view.component"; import { FaIconComponent } from "@fortawesome/angular-fontawesome"; import { ListPaginatorComponent } from "./list-paginator/list-paginator.component"; @@ -33,14 +32,11 @@ import { ColumnConfig, FormFieldConfig, toFormFieldConfig, -} from "../entity-form/entity-form/FormConfig"; -import { InvalidFormFieldError } from "../entity-form/invalid-form-field.error"; -import { AlertService } from "../../alerts/alert.service"; +} from "../entity-form/FormConfig"; import { EntityForm, EntityFormService, } from "../entity-form/entity-form.service"; -import { EntityActionsService } from "../../entity/entity-actions/entity-actions.service"; import { tableSort } from "./table-sort/table-sort"; import { UntilDestroy } from "@ngneat/until-destroy"; import { entityFilterPredicate } from "../../filter/filter-generator/filter-predicate"; @@ -48,6 +44,7 @@ import { FormDialogService } from "../../form-dialog/form-dialog.service"; import { Router } from "@angular/router"; import { FilterService } from "../../filter/filter.service"; import { DataFilter } from "../../filter/filters/filters"; +import { EntityInlineEditActionsComponent } from "./entity-inline-edit-actions/entity-inline-edit-actions.component"; /** * A simple display component (no logic and transformations) to display a table of entities. @@ -62,7 +59,6 @@ import { DataFilter } from "../../filter/filters/filters"; DisableEntityOperationDirective, EntityFieldEditComponent, EntityFieldLabelComponent, - EntityFieldMenuComponent, EntityFieldViewComponent, FaIconComponent, ListPaginatorComponent, @@ -72,6 +68,7 @@ import { DataFilter } from "../../filter/filters/filters"; MatSlideToggleModule, MatSortModule, MatTableModule, + EntityInlineEditActionsComponent, ], templateUrl: "./entities-table.component.html", styleUrl: "./entities-table.component.scss", @@ -126,7 +123,10 @@ export class EntitiesTableComponent { */ @Input() set columnsToDisplay(value: string[]) { if (!value || value.length === 0) { - value = (this._customColumns ?? this._columns).map((c) => c.id); + value = (this._customColumns ?? this._columns) + .map((c) => c.id) + // remove internal action columns: + .filter((c) => !c.startsWith("__")); } const cols = []; @@ -235,14 +235,10 @@ export class EntitiesTableComponent { } /** - * - * * INLINE EDIT * User can switch a row into edit mode to change and save field values directly from within the table - * - * */ - @Input() editable: boolean = false; + @Input() editable: boolean = true; readonly ACTIONCOLUMN_EDIT = "__edit"; /** * factory method to create a new instance of the displayed Entity type @@ -250,47 +246,6 @@ export class EntitiesTableComponent { */ @Input() newRecordFactory: () => T; - edit(row: TableRow) { - if (!row.formGroup) { - row.formGroup = this.entityFormService.createFormGroup( - this._columns, - row.record, - true, - ); - } - row.formGroup.enable(); - } - - /** - * Save an edited record to the database (if validation succeeds). - * @param row The entity to be saved. - */ - async save(row: TableRow): Promise { - try { - row.record = await this.entityFormService.saveChanges( - row.formGroup, - row.record, - ); - row.formGroup.disable(); - } catch (err) { - if (!(err instanceof InvalidFormFieldError)) { - this.alertService.addDanger(err.message); - } - } - } - - async delete(row: TableRow): Promise { - await this.entityRemoveService.delete(row.record); - } - - /** - * Discard any changes to the given entity and reset it to the state before the user started editing. - * @param row The entity to be reset. - */ - resetChanges(row: TableRow) { - row.formGroup = null; - } - /** * Create a new entity. * The entity is only written to the database when the user saves this record which is newly added in edit mode. @@ -326,9 +281,7 @@ export class EntitiesTableComponent { } constructor( - private alertService: AlertService, private entityFormService: EntityFormService, - private entityRemoveService: EntityActionsService, private formDialog: FormDialogService, private router: Router, private filterService: FilterService, @@ -384,6 +337,9 @@ export class EntitiesTableComponent { } } +/** + * Wrapper to keep additional form data for each row of an entity, required for inline editing. + */ export interface TableRow { record: T; formGroup?: EntityForm; @@ -394,10 +350,3 @@ export interface TableRow { * * - RelatedTimePeriodEntity.onIsActiveFilterChange */ - -/***************************************************** - ***************************************************** - * - * - edit code & buttons --> in own component - ***************************************************** - */ diff --git a/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.html b/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.html new file mode 100644 index 0000000000..09f52a71a1 --- /dev/null +++ b/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.html @@ -0,0 +1,48 @@ + + + + +
+ + + + + +
diff --git a/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.scss b/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.spec.ts b/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.spec.ts new file mode 100644 index 0000000000..6b94274b0b --- /dev/null +++ b/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EntityInlineEditActionsComponent } from './entity-inline-edit-actions.component'; + +describe('EntityInlineEditActionsComponent', () => { + let component: EntityInlineEditActionsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [EntityInlineEditActionsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(EntityInlineEditActionsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.ts b/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.ts new file mode 100644 index 0000000000..2f16de786e --- /dev/null +++ b/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.ts @@ -0,0 +1,76 @@ +import { Component, Input } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { Angulartics2OnModule } from "angulartics2"; +import { DisableEntityOperationDirective } from "../../../permissions/permission-directive/disable-entity-operation.directive"; +import { FaIconComponent } from "@fortawesome/angular-fontawesome"; +import { MatButtonModule } from "@angular/material/button"; +import { TableRow } from "../entities-table.component"; +import { Entity } from "../../../entity/model/entity"; +import { InvalidFormFieldError } from "../../entity-form/invalid-form-field.error"; +import { EntityFormService } from "../../entity-form/entity-form.service"; +import { AlertService } from "../../../alerts/alert.service"; +import { EntityActionsService } from "../../../entity/entity-actions/entity-actions.service"; + +@Component({ + selector: "app-entity-inline-edit-actions", + standalone: true, + imports: [ + CommonModule, + Angulartics2OnModule, + DisableEntityOperationDirective, + FaIconComponent, + MatButtonModule, + ], + templateUrl: "./entity-inline-edit-actions.component.html", + styleUrl: "./entity-inline-edit-actions.component.scss", +}) +export class EntityInlineEditActionsComponent { + @Input() row: TableRow; + + constructor( + private entityFormService: EntityFormService, + private alertService: AlertService, + private entityRemoveService: EntityActionsService, + ) {} + + edit(row: TableRow) { + if (!row.formGroup) { + row.formGroup = this.entityFormService.createFormGroup( + Array.from(this.row.record.getSchema().keys()), + row.record, + true, + ); + } + row.formGroup.enable(); + } + + /** + * Save an edited record to the database (if validation succeeds). + * @param row The entity to be saved. + */ + async save(row: TableRow): Promise { + try { + row.record = await this.entityFormService.saveChanges( + row.formGroup, + row.record, + ); + row.formGroup.disable(); + } catch (err) { + if (!(err instanceof InvalidFormFieldError)) { + this.alertService.addDanger(err.message); + } + } + } + + async delete(row: TableRow): Promise { + await this.entityRemoveService.delete(row.record); + } + + /** + * Discard any changes to the given entity and reset it to the state before the user started editing. + * @param row The entity to be reset. + */ + resetChanges(row: TableRow) { + row.formGroup = null; + } +} diff --git a/src/app/core/common-components/entity-field-edit/entity-field-edit.component.ts b/src/app/core/common-components/entity-field-edit/entity-field-edit.component.ts index edad79c445..c0fa8985b2 100644 --- a/src/app/core/common-components/entity-field-edit/entity-field-edit.component.ts +++ b/src/app/core/common-components/entity-field-edit/entity-field-edit.component.ts @@ -6,10 +6,7 @@ import { EntityForm, EntityFormService, } from "../entity-form/entity-form.service"; -import { - ColumnConfig, - FormFieldConfig, -} from "../entity-form/entity-form/FormConfig"; +import { ColumnConfig, FormFieldConfig } from "../entity-form/FormConfig"; import { NgIf } from "@angular/common"; import { EntityFieldViewComponent } from "../entity-field-view/entity-field-view.component"; diff --git a/src/app/core/common-components/entity-field-label/entity-field-label.component.ts b/src/app/core/common-components/entity-field-label/entity-field-label.component.ts index 921aeaf95d..476fd3aafc 100644 --- a/src/app/core/common-components/entity-field-label/entity-field-label.component.ts +++ b/src/app/core/common-components/entity-field-label/entity-field-label.component.ts @@ -1,10 +1,7 @@ import { Component, Input, OnChanges, SimpleChanges } from "@angular/core"; import { MatTooltipModule } from "@angular/material/tooltip"; import { EntityConstructor } from "../../entity/model/entity"; -import { - ColumnConfig, - FormFieldConfig, -} from "../entity-form/entity-form/FormConfig"; +import { ColumnConfig, FormFieldConfig } from "../entity-form/FormConfig"; import { EntityFormService } from "../entity-form/entity-form.service"; import { NgIf } from "@angular/common"; diff --git a/src/app/core/common-components/entity-field-view/entity-field-view.component.ts b/src/app/core/common-components/entity-field-view/entity-field-view.component.ts index b1942fcd03..effac0e7f4 100644 --- a/src/app/core/common-components/entity-field-view/entity-field-view.component.ts +++ b/src/app/core/common-components/entity-field-view/entity-field-view.component.ts @@ -8,10 +8,7 @@ import { import { Entity } from "../../entity/model/entity"; import { NgIf } from "@angular/common"; import { DynamicComponentDirective } from "../../config/dynamic-components/dynamic-component.directive"; -import { - ColumnConfig, - FormFieldConfig, -} from "../entity-form/entity-form/FormConfig"; +import { ColumnConfig, FormFieldConfig } from "../entity-form/FormConfig"; import { EntityFormService } from "../entity-form/entity-form.service"; import { PillComponent } from "../pill/pill.component"; diff --git a/src/app/core/common-components/entity-form/entity-form/FormConfig.ts b/src/app/core/common-components/entity-form/FormConfig.ts similarity index 95% rename from src/app/core/common-components/entity-form/entity-form/FormConfig.ts rename to src/app/core/common-components/entity-form/FormConfig.ts index 4a78404e78..88af58ece3 100644 --- a/src/app/core/common-components/entity-form/entity-form/FormConfig.ts +++ b/src/app/core/common-components/entity-form/FormConfig.ts @@ -1,4 +1,4 @@ -import { EntitySchemaField } from "../../../entity/schema/entity-schema-field"; +import { EntitySchemaField } from "../../entity/schema/entity-schema-field"; /** * The general configuration for fields in tables and forms. diff --git a/src/app/core/common-components/entity-form/entity-form.service.spec.ts b/src/app/core/common-components/entity-form/entity-form.service.spec.ts index 638bdb3ade..777745b9b0 100644 --- a/src/app/core/common-components/entity-form/entity-form.service.spec.ts +++ b/src/app/core/common-components/entity-form/entity-form.service.spec.ts @@ -24,7 +24,7 @@ import { EntityArrayDatatype } from "../../basic-datatypes/entity-array/entity-a import { Child } from "../../../child-dev-project/children/model/child"; import { DatabaseField } from "../../entity/database-field.decorator"; import { EntitySchemaService } from "../../entity/schema/entity-schema.service"; -import { FormFieldConfig } from "./entity-form/FormConfig"; +import { FormFieldConfig } from "./FormConfig"; import { TEST_USER } from "../../user/demo-user-generator.service"; describe("EntityFormService", () => { diff --git a/src/app/core/common-components/entity-form/entity-form.service.ts b/src/app/core/common-components/entity-form/entity-form.service.ts index 152cbb313e..2cf4092961 100644 --- a/src/app/core/common-components/entity-form/entity-form.service.ts +++ b/src/app/core/common-components/entity-form/entity-form.service.ts @@ -1,10 +1,6 @@ import { Injectable } from "@angular/core"; import { FormBuilder, FormGroup, ɵElement } from "@angular/forms"; -import { - ColumnConfig, - FormFieldConfig, - toFormFieldConfig, -} from "./entity-form/FormConfig"; +import { ColumnConfig, FormFieldConfig, toFormFieldConfig } from "./FormConfig"; import { Entity, EntityConstructor } from "../../entity/model/entity"; import { EntityMapperService } from "../../entity/entity-mapper/entity-mapper.service"; import { EntitySchemaService } from "../../entity/schema/entity-schema.service"; diff --git a/src/app/core/entity-details/form/field-group.ts b/src/app/core/entity-details/form/field-group.ts index f9f299eef3..631a177671 100644 --- a/src/app/core/entity-details/form/field-group.ts +++ b/src/app/core/entity-details/form/field-group.ts @@ -1,4 +1,4 @@ -import { ColumnConfig } from "../../common-components/entity-form/entity-form/FormConfig"; +import { ColumnConfig } from "../../common-components/entity-form/FormConfig"; /** * A group of related form fields displayed within a Form component. diff --git a/src/app/core/entity-details/related-entities/related-entities.component.ts b/src/app/core/entity-details/related-entities/related-entities.component.ts index b4c66d280d..571bd96db1 100644 --- a/src/app/core/entity-details/related-entities/related-entities.component.ts +++ b/src/app/core/entity-details/related-entities/related-entities.component.ts @@ -15,7 +15,7 @@ import { import { ColumnConfig, toFormFieldConfig, -} from "../../common-components/entity-form/entity-form/FormConfig"; +} from "../../common-components/entity-form/FormConfig"; import { DataFilter } from "../../filter/filters/filters"; /** diff --git a/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.ts b/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.ts index 58e7680c1c..b2336a5f7a 100644 --- a/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.ts +++ b/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.ts @@ -1,5 +1,5 @@ import { Component, Input, OnInit } from "@angular/core"; -import { FormFieldConfig } from "../../common-components/entity-form/entity-form/FormConfig"; +import { FormFieldConfig } 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"; diff --git a/src/app/core/entity-list/entity-list/entity-list.component.html b/src/app/core/entity-list/entity-list/entity-list.component.html index fc48055561..8fcbd2ef30 100644 --- a/src/app/core/entity-list/entity-list/entity-list.component.html +++ b/src/app/core/entity-list/entity-list/entity-list.component.html @@ -33,6 +33,7 @@ > Add New + diff --git a/src/app/core/entity-list/entity-list/entity-list.component.ts b/src/app/core/entity-list/entity-list/entity-list.component.ts index 57d2ee3f66..b4d5d9690e 100644 --- a/src/app/core/entity-list/entity-list/entity-list.component.ts +++ b/src/app/core/entity-list/entity-list/entity-list.component.ts @@ -14,7 +14,7 @@ import { GroupConfig, } from "../EntityListConfig"; import { Entity, EntityConstructor } from "../../entity/model/entity"; -import { FormFieldConfig } from "../../common-components/entity-form/entity-form/FormConfig"; +import { FormFieldConfig } from "../../common-components/entity-form/FormConfig"; import { AnalyticsService } from "../../analytics/analytics.service"; import { EntityMapperService } from "../../entity/entity-mapper/entity-mapper.service"; import { EntityRegistry } from "../../entity/database-entity.decorator"; diff --git a/src/app/core/entity/default-datatype/edit-component-story-utils.ts b/src/app/core/entity/default-datatype/edit-component-story-utils.ts index ceef497458..14ff591777 100644 --- a/src/app/core/entity/default-datatype/edit-component-story-utils.ts +++ b/src/app/core/entity/default-datatype/edit-component-story-utils.ts @@ -2,7 +2,7 @@ import { FormComponent } from "../../entity-details/form/form.component"; import { Entity, EntityConstructor } from "../model/entity"; import { DatabaseEntity } from "../database-entity.decorator"; import { DatabaseField } from "../database-field.decorator"; -import { FormFieldConfig } from "../../common-components/entity-form/entity-form/FormConfig"; +import { FormFieldConfig } from "../../common-components/entity-form/FormConfig"; import { applicationConfig, Meta } from "@storybook/angular"; import { entityFormStorybookDefaultParameters, diff --git a/src/app/core/entity/default-datatype/edit-component.ts b/src/app/core/entity/default-datatype/edit-component.ts index 94cf8fd975..56dfec3698 100644 --- a/src/app/core/entity/default-datatype/edit-component.ts +++ b/src/app/core/entity/default-datatype/edit-component.ts @@ -1,5 +1,5 @@ import { FormControl, FormGroup } from "@angular/forms"; -import { FormFieldConfig } from "../../common-components/entity-form/entity-form/FormConfig"; +import { FormFieldConfig } from "../../common-components/entity-form/FormConfig"; import { Entity } from "../model/entity"; import { Directive, Input, OnChanges, OnInit } from "@angular/core"; diff --git a/src/app/core/form-dialog/form-dialog.service.ts b/src/app/core/form-dialog/form-dialog.service.ts index eca3617729..ed8a666254 100644 --- a/src/app/core/form-dialog/form-dialog.service.ts +++ b/src/app/core/form-dialog/form-dialog.service.ts @@ -11,7 +11,7 @@ import { ColumnConfig, FormFieldConfig, toFormFieldConfig, -} from "../common-components/entity-form/entity-form/FormConfig"; +} from "../common-components/entity-form/FormConfig"; import { EntitySchemaService } from "../entity/schema/entity-schema.service"; @Injectable({ providedIn: "root" }) diff --git a/src/app/core/form-dialog/row-details/row-details.component.ts b/src/app/core/form-dialog/row-details/row-details.component.ts index 8935b20167..dcebe47d03 100644 --- a/src/app/core/form-dialog/row-details/row-details.component.ts +++ b/src/app/core/form-dialog/row-details/row-details.component.ts @@ -1,5 +1,5 @@ import { Component, Inject } from "@angular/core"; -import { FormFieldConfig } from "../../common-components/entity-form/entity-form/FormConfig"; +import { FormFieldConfig } from "../../common-components/entity-form/FormConfig"; import { MAT_DIALOG_DATA, MatDialogModule } from "@angular/material/dialog"; import { Entity } from "../../entity/model/entity"; import { diff --git a/src/app/features/historical-data/historical-data/historical-data.component.ts b/src/app/features/historical-data/historical-data/historical-data.component.ts index 214f08d5e1..2904ed908f 100644 --- a/src/app/features/historical-data/historical-data/historical-data.component.ts +++ b/src/app/features/historical-data/historical-data/historical-data.component.ts @@ -2,7 +2,7 @@ import { Component, Input, OnInit } from "@angular/core"; import { HistoricalEntityData } from "../model/historical-entity-data"; import { Entity } from "../../../core/entity/model/entity"; import { HistoricalDataService } from "../historical-data.service"; -import { FormFieldConfig } from "../../../core/common-components/entity-form/entity-form/FormConfig"; +import { FormFieldConfig } from "../../../core/common-components/entity-form/FormConfig"; import { DynamicComponent } from "../../../core/config/dynamic-components/dynamic-component.decorator"; import { EntitiesTableComponent } from "../../../core/common-components/entities-table/entities-table.component"; diff --git a/src/app/features/historical-data/historical-data/historical-data.stories.ts b/src/app/features/historical-data/historical-data/historical-data.stories.ts index cfc02bccfc..1ae6520166 100644 --- a/src/app/features/historical-data/historical-data/historical-data.stories.ts +++ b/src/app/features/historical-data/historical-data/historical-data.stories.ts @@ -5,7 +5,7 @@ import { HistoricalDataService } from "../historical-data.service"; import { ratingAnswers } from "../model/rating-answers"; import { StorybookBaseModule } from "../../../utils/storybook-base.module"; import { importProvidersFrom } from "@angular/core"; -import { FormFieldConfig } from "../../../core/common-components/entity-form/entity-form/FormConfig"; +import { FormFieldConfig } from "../../../core/common-components/entity-form/FormConfig"; export default { title: "Features/HistoricalDataComponent", diff --git a/src/app/features/matching-entities/matching-entities/matching-entities-config.ts b/src/app/features/matching-entities/matching-entities/matching-entities-config.ts index d8c56f5a5f..df34be677b 100644 --- a/src/app/features/matching-entities/matching-entities/matching-entities-config.ts +++ b/src/app/features/matching-entities/matching-entities/matching-entities-config.ts @@ -1,6 +1,6 @@ import { FilterConfig } from "../../../core/entity-list/EntityListConfig"; import { Entity, EntityConstructor } from "../../../core/entity/model/entity"; -import { ColumnConfig } from "../../../core/common-components/entity-form/entity-form/FormConfig"; +import { ColumnConfig } from "../../../core/common-components/entity-form/FormConfig"; import { DataFilter } from "../../../core/filter/filters/filters"; /** diff --git a/src/app/features/matching-entities/matching-entities/matching-entities.component.spec.ts b/src/app/features/matching-entities/matching-entities/matching-entities.component.spec.ts index 1ade62f967..3be050af4e 100644 --- a/src/app/features/matching-entities/matching-entities/matching-entities.component.spec.ts +++ b/src/app/features/matching-entities/matching-entities/matching-entities.component.spec.ts @@ -17,7 +17,7 @@ import { ActivatedRoute } from "@angular/router"; import { FormDialogService } from "../../../core/form-dialog/form-dialog.service"; import { ConfigService } from "../../../core/config/config.service"; import { BehaviorSubject, NEVER, Subject } from "rxjs"; -import { FormFieldConfig } from "../../../core/common-components/entity-form/entity-form/FormConfig"; +import { FormFieldConfig } from "../../../core/common-components/entity-form/FormConfig"; import { Coordinates } from "../../location/coordinates"; import { MockedTestingModule } from "../../../utils/mocked-testing.module"; import { School } from "../../../child-dev-project/schools/model/school"; diff --git a/src/app/features/matching-entities/matching-entities/matching-entities.component.ts b/src/app/features/matching-entities/matching-entities/matching-entities.component.ts index 2bf7109458..81d030b54d 100644 --- a/src/app/features/matching-entities/matching-entities/matching-entities.component.ts +++ b/src/app/features/matching-entities/matching-entities/matching-entities.component.ts @@ -38,7 +38,7 @@ import { isArrayDataType } from "../../../core/basic-datatypes/datatype-utils"; import { ColumnConfig, FormFieldConfig, -} from "../../../core/common-components/entity-form/entity-form/FormConfig"; +} from "../../../core/common-components/entity-form/FormConfig"; import { RouteTarget } from "../../../route-target"; import { EntitiesTableComponent } from "../../../core/common-components/entities-table/entities-table.component"; import { DataFilter } from "../../../core/filter/filters/filters"; From fb2186d1674776a112a002f7fa40d48804268052 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Fri, 22 Dec 2023 15:18:07 +0100 Subject: [PATCH 04/58] extract create button --- .../aser/aser-component/aser.component.ts | 74 ++++++++++--------- .../entities-table.component.html | 29 ++------ .../entities-table.component.scss | 13 ---- .../entities-table.component.ts | 23 +----- .../entity-create-button.component.html | 25 +++++++ .../entity-create-button.component.scss | 18 +++++ .../entity-create-button.component.spec.ts | 23 ++++++ .../entity-create-button.component.ts | 54 ++++++++++++++ ...elated-time-period-entities.component.html | 6 +- .../entity-list/entity-list.component.html | 27 +------ .../entity-list/entity-list.component.scss | 5 -- .../entity-list/entity-list.component.ts | 2 + 12 files changed, 177 insertions(+), 122 deletions(-) create mode 100644 src/app/core/common-components/entity-create-button/entity-create-button.component.html create mode 100644 src/app/core/common-components/entity-create-button/entity-create-button.component.scss create mode 100644 src/app/core/common-components/entity-create-button/entity-create-button.component.spec.ts create mode 100644 src/app/core/common-components/entity-create-button/entity-create-button.component.ts diff --git a/src/app/child-dev-project/children/aser/aser-component/aser.component.ts b/src/app/child-dev-project/children/aser/aser-component/aser.component.ts index 839978d176..31a5fba7f6 100644 --- a/src/app/child-dev-project/children/aser/aser-component/aser.component.ts +++ b/src/app/child-dev-project/children/aser/aser-component/aser.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, OnInit } from "@angular/core"; +import { Component, Input } from "@angular/core"; import { Aser } from "../model/aser"; import { ChildrenService } from "../../children.service"; import { Child } from "../../model/child"; @@ -6,55 +6,59 @@ import { DynamicComponent } from "../../../../core/config/dynamic-components/dyn import { EntitiesTableComponent } from "../../../../core/common-components/entities-table/entities-table.component"; import { ColumnConfig } from "../../../../core/common-components/entity-form/FormConfig"; +import { RelatedEntitiesComponent } from "../../../../core/entity-details/related-entities/related-entities.component"; +import { EntityMapperService } from "../../../../core/entity/entity-mapper/entity-mapper.service"; +import { EntityRegistry } from "../../../../core/entity/database-entity.decorator"; +import { ScreenWidthObserver } from "../../../../utils/media/screen-size-observer.service"; +import { UntilDestroy } from "@ngneat/until-destroy"; @DynamicComponent("Aser") +@UntilDestroy() @Component({ selector: "app-aser", - template: ``, + templateUrl: + "../../../../core/entity-details/related-entities/related-entities.component.html", standalone: true, imports: [EntitiesTableComponent], }) -export class AserComponent implements OnInit { +export class AserComponent extends RelatedEntitiesComponent { @Input() entity: Child; - @Input() config: { columns: ColumnConfig[] } = { - columns: [ - { id: "date", visibleFrom: "xs" }, - { id: "math", visibleFrom: "xs" }, - { id: "english", visibleFrom: "xs" }, - { id: "hindi", visibleFrom: "md" }, - { id: "bengali", visibleFrom: "md" }, - { id: "remarks", visibleFrom: "md" }, - ], - }; - records: Aser[]; + property = "child"; entityCtr = Aser; - constructor(private childrenService: ChildrenService) {} + protected _columns: ColumnConfig[] = [ + { id: "date", visibleFrom: "xs" }, + { id: "math", visibleFrom: "xs" }, + { id: "english", visibleFrom: "xs" }, + { id: "hindi", visibleFrom: "md" }, + { id: "bengali", visibleFrom: "md" }, + { id: "remarks", visibleFrom: "md" }, + ]; - ngOnInit() { - return this.loadData(); + /** + * @deprecated only for backward compatibility of old configs + */ + @Input() set config(value: { columns: ColumnConfig[] }) { + if (value.columns) { + this.columns = value.columns; + } } - async loadData() { - this.records = await this.childrenService.getAserResultsOfChild( - this.entity.getId(), - ); - this.records.sort( + constructor( + private childrenService: ChildrenService, + entityMapper: EntityMapperService, + entityRegistry: EntityRegistry, + screenWidthObserver: ScreenWidthObserver, + ) { + super(entityMapper, entityRegistry, screenWidthObserver); + } + + override async initData() { + this.data = ( + await this.childrenService.getAserResultsOfChild(this.entity.getId()) + ).sort( (a, b) => (b.date ? b.date.valueOf() : 0) - (a.date ? a.date.valueOf() : 0), ); } - - generateNewRecordFactory() { - return () => { - const newAtt = new Aser(Date.now().toString()); - newAtt.child = this.entity.getId(); - return newAtt; - }; - } } diff --git a/src/app/core/common-components/entities-table/entities-table.component.html b/src/app/core/common-components/entities-table/entities-table.component.html index 621dbfcffa..06258db099 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.html +++ b/src/app/core/common-components/entities-table/entities-table.component.html @@ -58,28 +58,13 @@ INLINE EDIT ACTIONS --> - - - - + + diff --git a/src/app/core/common-components/entities-table/entities-table.component.scss b/src/app/core/common-components/entities-table/entities-table.component.scss index 048ae31624..79afdf72c8 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.scss +++ b/src/app/core/common-components/entities-table/entities-table.component.scss @@ -12,19 +12,6 @@ right: 0; } -.table-action-button { - border: 1px solid lightgrey; - border-radius: 4px; - margin: sizes.$small; - color: colors.$accent; -} - -.mat-column-actions { - width: 1px; - white-space: nowrap; - text-align: center; -} - .table-row:hover { background: #f5f5f5; } diff --git a/src/app/core/common-components/entities-table/entities-table.component.ts b/src/app/core/common-components/entities-table/entities-table.component.ts index 21f3c0c39e..ba4bfc5f54 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.ts +++ b/src/app/core/common-components/entities-table/entities-table.component.ts @@ -6,14 +6,10 @@ import { ViewChild, } from "@angular/core"; import { CommonModule } from "@angular/common"; -import { Angulartics2Module } from "angulartics2"; -import { DisableEntityOperationDirective } from "../../permissions/permission-directive/disable-entity-operation.directive"; import { EntityFieldEditComponent } from "../entity-field-edit/entity-field-edit.component"; import { EntityFieldLabelComponent } from "../entity-field-label/entity-field-label.component"; import { EntityFieldViewComponent } from "../entity-field-view/entity-field-view.component"; -import { FaIconComponent } from "@fortawesome/angular-fontawesome"; import { ListPaginatorComponent } from "./list-paginator/list-paginator.component"; -import { MatButtonModule } from "@angular/material/button"; import { MatCheckboxChange, MatCheckboxModule, @@ -45,6 +41,7 @@ import { Router } from "@angular/router"; import { FilterService } from "../../filter/filter.service"; import { DataFilter } from "../../filter/filters/filters"; import { EntityInlineEditActionsComponent } from "./entity-inline-edit-actions/entity-inline-edit-actions.component"; +import { EntityCreateButtonComponent } from "../entity-create-button/entity-create-button.component"; /** * A simple display component (no logic and transformations) to display a table of entities. @@ -55,20 +52,17 @@ import { EntityInlineEditActionsComponent } from "./entity-inline-edit-actions/e standalone: true, imports: [ CommonModule, - Angulartics2Module, - DisableEntityOperationDirective, EntityFieldEditComponent, EntityFieldLabelComponent, EntityFieldViewComponent, - FaIconComponent, ListPaginatorComponent, - MatButtonModule, MatCheckboxModule, MatProgressBarModule, MatSlideToggleModule, MatSortModule, MatTableModule, EntityInlineEditActionsComponent, + EntityCreateButtonComponent, ], templateUrl: "./entities-table.component.html", styleUrl: "./entities-table.component.scss", @@ -246,15 +240,6 @@ export class EntitiesTableComponent { */ @Input() newRecordFactory: () => T; - /** - * Create a new entity. - * The entity is only written to the database when the user saves this record which is newly added in edit mode. - */ - create() { - const newRecord = this.newRecordFactory(); - this.showEntity(newRecord); - } - /** * Show one record's details in a modal dialog (if configured). * @param row The entity whose details should be displayed. @@ -263,9 +248,10 @@ export class EntitiesTableComponent { if (!row.formGroup || row.formGroup.disabled) { this.showEntity(row.record); } + this.rowClick.emit(row.record); } - private showEntity(entity: T) { + showEntity(entity: T) { switch (this.clickMode) { case "popup": this.formDialog.openFormPopup(entity, this.columnsToDisplay); // TODO this.formDialog.openFormPopup(entity, this._columns) @@ -277,7 +263,6 @@ export class EntitiesTableComponent { ]); break; } - this.rowClick.emit(entity); } constructor( diff --git a/src/app/core/common-components/entity-create-button/entity-create-button.component.html b/src/app/core/common-components/entity-create-button/entity-create-button.component.html new file mode 100644 index 0000000000..e1d4f5088a --- /dev/null +++ b/src/app/core/common-components/entity-create-button/entity-create-button.component.html @@ -0,0 +1,25 @@ + diff --git a/src/app/core/common-components/entity-create-button/entity-create-button.component.scss b/src/app/core/common-components/entity-create-button/entity-create-button.component.scss new file mode 100644 index 0000000000..a9d6f86ad4 --- /dev/null +++ b/src/app/core/common-components/entity-create-button/entity-create-button.component.scss @@ -0,0 +1,18 @@ +@use "variables/sizes"; +@use "variables/colors"; + +.standard-add-button { + background-color: white !important; + height: 100%; +} + +.table-action-button { + border: 1px solid lightgrey; + border-radius: 4px; + margin: sizes.$small; + color: colors.$accent; +} + +.icon-only { + vertical-align: initial; +} diff --git a/src/app/core/common-components/entity-create-button/entity-create-button.component.spec.ts b/src/app/core/common-components/entity-create-button/entity-create-button.component.spec.ts new file mode 100644 index 0000000000..3ffd81f70c --- /dev/null +++ b/src/app/core/common-components/entity-create-button/entity-create-button.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EntityCreateButtonComponent } from './entity-create-button.component'; + +describe('EntityCreateButtonComponent', () => { + let component: EntityCreateButtonComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [EntityCreateButtonComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(EntityCreateButtonComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/core/common-components/entity-create-button/entity-create-button.component.ts b/src/app/core/common-components/entity-create-button/entity-create-button.component.ts new file mode 100644 index 0000000000..0a8bdbe52c --- /dev/null +++ b/src/app/core/common-components/entity-create-button/entity-create-button.component.ts @@ -0,0 +1,54 @@ +import { Component, EventEmitter, Input, Output } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { DisableEntityOperationDirective } from "../../permissions/permission-directive/disable-entity-operation.directive"; +import { FaIconComponent } from "@fortawesome/angular-fontawesome"; +import { MatButtonModule } from "@angular/material/button"; +import { MatTableModule } from "@angular/material/table"; +import { Entity, EntityConstructor } from "../../entity/model/entity"; +import { Angulartics2OnModule } from "angulartics2"; +import { MatTooltipModule } from "@angular/material/tooltip"; + +@Component({ + selector: "app-entity-create-button", + standalone: true, + imports: [ + CommonModule, + DisableEntityOperationDirective, + FaIconComponent, + MatButtonModule, + MatTableModule, + Angulartics2OnModule, + MatTooltipModule, + ], + templateUrl: "./entity-create-button.component.html", + styleUrl: "./entity-create-button.component.scss", +}) +export class EntityCreateButtonComponent { + @Input() entityType: EntityConstructor; + + /** + * Optional factory method to create a new entity instance with some default values. + * If not provided, the simple entityType constructor is used. + */ + @Input() newRecordFactory?: () => T; + + /** + * Emits a new entity instance when the user clicks the button. + */ + @Output() entityCreate = new EventEmitter(); + + /** + * Whether only an icon button without text should be displayed. + * Default is false + */ + @Input() iconOnly: boolean = false; + + /** + * Create a new entity. + * The entity is only written to the database when the user saves this record which is newly added in edit mode. + */ + create() { + const newRecord = this.newRecordFactory(); + this.entityCreate.emit(newRecord); + } +} diff --git a/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.html b/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.html index 042bc44031..9566c06902 100644 --- a/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.html +++ b/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.html @@ -1,10 +1,6 @@ Currently there is no active entry. To add a new entry, click on the - + button. diff --git a/src/app/core/entity-list/entity-list/entity-list.component.html b/src/app/core/entity-list/entity-list/entity-list.component.html index 8fcbd2ef30..83234dad12 100644 --- a/src/app/core/entity-list/entity-list/entity-list.component.html +++ b/src/app/core/entity-list/entity-list/entity-list.component.html @@ -10,29 +10,10 @@
- + -
+
+ + +
diff --git a/src/app/core/common-components/entities-table/entities-table.component.scss b/src/app/core/common-components/entities-table/entities-table.component.scss index 79afdf72c8..67129e877c 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.scss +++ b/src/app/core/common-components/entities-table/entities-table.component.scss @@ -4,12 +4,17 @@ .table-container { position: relative; // anchor for further absolute positioning of child elements + + padding: 4px; // ensure elevation shadow is visible } -.column-menu { +.fields-menu { position: absolute; - top: 0; - right: 0; + top: 4px; + right: 4px; +} +.th-field-menu-spacing:last-child { + padding-right: 48px; } .table-row:hover { diff --git a/src/app/core/common-components/entities-table/entities-table.component.ts b/src/app/core/common-components/entities-table/entities-table.component.ts index 1edccbaf5f..2ff3150c7b 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.ts +++ b/src/app/core/common-components/entities-table/entities-table.component.ts @@ -46,6 +46,7 @@ import { DateDatatype } from "../../basic-datatypes/date/date.datatype"; import { DateOnlyDatatype } from "../../basic-datatypes/date-only/date-only.datatype"; import { DateWithAgeDatatype } from "../../basic-datatypes/date-with-age/date-with-age.datatype"; import { MonthDatatype } from "../../basic-datatypes/month/month.datatype"; +import { EntityFieldsMenuComponent } from "../entity-fields-menu/entity-fields-menu.component"; /** * A simple display component (no logic and transformations) to display a table of entities. @@ -67,6 +68,7 @@ import { MonthDatatype } from "../../basic-datatypes/month/month.datatype"; MatTableModule, EntityInlineEditActionsComponent, EntityCreateButtonComponent, + EntityFieldsMenuComponent, ], templateUrl: "./entities-table.component.html", styleUrl: "./entities-table.component.scss", diff --git a/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.html b/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.html new file mode 100644 index 0000000000..35e5656dfa --- /dev/null +++ b/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.html @@ -0,0 +1,26 @@ + + + + + diff --git a/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.scss b/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.scss new file mode 100644 index 0000000000..deb0ee55e3 --- /dev/null +++ b/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.scss @@ -0,0 +1,6 @@ +.square-button { + border-radius: 0 0 0 4px; +} +:host ::ng-deep .mat-mdc-icon-button .mat-mdc-button-persistent-ripple { + border-radius: 0 0 0 4px; +} diff --git a/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.spec.ts b/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.spec.ts new file mode 100644 index 0000000000..bf6378fe92 --- /dev/null +++ b/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from "@angular/core/testing"; + +import { EntityFieldsMenuComponent } from "./entity-fields-menu.component"; +import { FontAwesomeTestingModule } from "@fortawesome/angular-fontawesome/testing"; + +describe("EntityFieldsMenuComponent", () => { + let component: EntityFieldsMenuComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [EntityFieldsMenuComponent, FontAwesomeTestingModule], + }).compileComponents(); + + fixture = TestBed.createComponent(EntityFieldsMenuComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.ts b/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.ts new file mode 100644 index 0000000000..7c78712f1e --- /dev/null +++ b/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.ts @@ -0,0 +1,53 @@ +import { Component, EventEmitter, Input, Output } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { FaIconComponent } from "@fortawesome/angular-fontawesome"; +import { MatMenuModule } from "@angular/material/menu"; +import { MatButtonModule } from "@angular/material/button"; +import { MatTooltipModule } from "@angular/material/tooltip"; +import { IconProp } from "@fortawesome/fontawesome-svg-core"; +import { EntityFieldLabelComponent } from "../entity-field-label/entity-field-label.component"; +import { EntityConstructor } from "../../entity/model/entity"; +import { + ColumnConfig, + FormFieldConfig, + toFormFieldConfig, +} from "../entity-form/FormConfig"; + +@Component({ + selector: "app-entity-fields-menu", + standalone: true, + imports: [ + CommonModule, + FaIconComponent, + MatMenuModule, + MatButtonModule, + MatTooltipModule, + EntityFieldLabelComponent, + ], + templateUrl: "./entity-fields-menu.component.html", + styleUrl: "./entity-fields-menu.component.scss", +}) +export class EntityFieldsMenuComponent { + @Input() icon: IconProp = "eye"; + + @Input() entityType: EntityConstructor; + + @Input() set availableFields(value: ColumnConfig[]) { + this._availableFields = value + .map((field) => toFormFieldConfig(field)) + .filter((field) => field.label); + } + _availableFields: FormFieldConfig[]; + + @Input() activeFields: string[]; + @Output() activeFieldsChange = new EventEmitter(); + + toggleFieldSelection(field: FormFieldConfig) { + if (this.activeFields.includes(field.id)) { + this.activeFields = this.activeFields.filter((f) => f !== field.id); + } else { + this.activeFields = [...this.activeFields, field.id]; + } + this.activeFieldsChange.emit(this.activeFields); + } +} From 30d84447098ee5b42ed5a127abf6305c6830c895 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Mon, 8 Jan 2024 13:10:30 +0100 Subject: [PATCH 11/58] remove unnecessary @UntilDestroy from child classes --- .../activities-overview/activities-overview.component.ts | 2 -- .../children/aser/aser-component/aser.component.ts | 2 -- .../child-school-overview/child-school-overview.component.ts | 2 -- .../related-time-period-entities.component.ts | 2 -- 4 files changed, 8 deletions(-) diff --git a/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts b/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts index c25bcaad0b..ed8c9bf7a8 100644 --- a/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts +++ b/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts @@ -7,13 +7,11 @@ import { FormFieldConfig, } from "../../../core/common-components/entity-form/FormConfig"; import { EntitiesTableComponent } from "../../../core/common-components/entities-table/entities-table.component"; -import { UntilDestroy } from "@ngneat/until-destroy"; /** * @deprecated configure a RelatedEntitiesComponent instead */ @DynamicComponent("ActivitiesOverview") -@UntilDestroy() @Component({ selector: "app-activities-overview", templateUrl: diff --git a/src/app/child-dev-project/children/aser/aser-component/aser.component.ts b/src/app/child-dev-project/children/aser/aser-component/aser.component.ts index 31a5fba7f6..04cd3e878b 100644 --- a/src/app/child-dev-project/children/aser/aser-component/aser.component.ts +++ b/src/app/child-dev-project/children/aser/aser-component/aser.component.ts @@ -10,10 +10,8 @@ import { RelatedEntitiesComponent } from "../../../../core/entity-details/relate import { EntityMapperService } from "../../../../core/entity/entity-mapper/entity-mapper.service"; import { EntityRegistry } from "../../../../core/entity/database-entity.decorator"; import { ScreenWidthObserver } from "../../../../utils/media/screen-size-observer.service"; -import { UntilDestroy } from "@ngneat/until-destroy"; @DynamicComponent("Aser") -@UntilDestroy() @Component({ selector: "app-aser", templateUrl: diff --git a/src/app/child-dev-project/schools/child-school-overview/child-school-overview.component.ts b/src/app/child-dev-project/schools/child-school-overview/child-school-overview.component.ts index 053fba6752..f366e4336f 100644 --- a/src/app/child-dev-project/schools/child-school-overview/child-school-overview.component.ts +++ b/src/app/child-dev-project/schools/child-school-overview/child-school-overview.component.ts @@ -16,13 +16,11 @@ import { EntitiesTableComponent } from "../../../core/common-components/entities import { EntityMapperService } from "../../../core/entity/entity-mapper/entity-mapper.service"; import { EntityRegistry } from "../../../core/entity/database-entity.decorator"; import { ScreenWidthObserver } from "../../../utils/media/screen-size-observer.service"; -import { UntilDestroy } from "@ngneat/until-destroy"; // TODO: once schema-generated indices are available (#262), remove this component and use its generic super class directly @DynamicComponent("ChildSchoolOverview") @DynamicComponent("PreviousSchools") @DynamicComponent("ChildrenOverview") -@UntilDestroy() @Component({ selector: "app-child-school-overview", templateUrl: diff --git a/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.ts b/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.ts index 44b4f3c177..a8bc026f72 100644 --- a/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.ts +++ b/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.ts @@ -12,7 +12,6 @@ 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 { UntilDestroy } from "@ngneat/until-destroy"; /** * Display a list of entity subrecords (entities related to the current entity details view) @@ -23,7 +22,6 @@ import { UntilDestroy } from "@ngneat/until-destroy"; * show/hide inactive entries from the list. */ @DynamicComponent("RelatedTimePeriodEntities") -@UntilDestroy() @Component({ selector: "app-related-time-period-entities", templateUrl: "./related-time-period-entities.component.html", From d1c7a524cf2ecd1a574956fa00f761aeda72beb2 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Mon, 8 Jan 2024 13:20:24 +0100 Subject: [PATCH 12/58] use base class onInit for ChildSchoolOverview --- .../child-school-overview.component.ts | 6 ++---- .../related-time-period-entities.component.ts | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/app/child-dev-project/schools/child-school-overview/child-school-overview.component.ts b/src/app/child-dev-project/schools/child-school-overview/child-school-overview.component.ts index f366e4336f..36d2e72fbd 100644 --- a/src/app/child-dev-project/schools/child-school-overview/child-school-overview.component.ts +++ b/src/app/child-dev-project/schools/child-school-overview/child-school-overview.component.ts @@ -68,9 +68,7 @@ export class ChildSchoolOverviewComponent this.mode = this.inferMode(this.entity); this.switchRelatedEntityColumnForMode(); - await this.loadData(); - super.onIsActiveFilterChange(); - super.listenToEntityUpdates(); + await super.ngOnInit(); } private inferMode(entity: Entity): "child" | "school" { @@ -94,7 +92,7 @@ export class ChildSchoolOverviewComponent } } - async loadData() { + override async initData() { if (!this.mode) { return; } diff --git a/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.ts b/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.ts index a8bc026f72..c584f4f26c 100644 --- a/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.ts +++ b/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.ts @@ -64,7 +64,7 @@ export class RelatedTimePeriodEntitiesComponent hasCurrentlyActiveEntry: boolean; async ngOnInit() { - await super.initData(); + await this.initData(); super.listenToEntityUpdates(); this.onIsActiveFilterChange(); } From 5162288c358921d8f028ec26614de6e6988374ce Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Mon, 8 Jan 2024 13:25:14 +0100 Subject: [PATCH 13/58] remove ngIf for table action columns --- .../entities-table/entities-table.component.html | 3 +-- .../todos-related-to-entity.component.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/app/core/common-components/entities-table/entities-table.component.html b/src/app/core/common-components/entities-table/entities-table.component.html index e5c94c31c0..148698db8d 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.html +++ b/src/app/core/common-components/entities-table/entities-table.component.html @@ -47,7 +47,6 @@ @@ -57,7 +56,7 @@ - + Date: Mon, 8 Jan 2024 13:28:23 +0100 Subject: [PATCH 14/58] clarify comment for duplicate column config removal --- .../entities-table/entities-table.component.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/app/core/common-components/entities-table/entities-table.component.ts b/src/app/core/common-components/entities-table/entities-table.component.ts index 1edccbaf5f..841e980f21 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.ts +++ b/src/app/core/common-components/entities-table/entities-table.component.ts @@ -104,7 +104,8 @@ export class EntitiesTableComponent { const allColumns = [...entityColumns, ...this._customColumns]; this._columns = allColumns - // remove duplicates (keep customColumn = last in array) + // remove duplicates + // if there is a customColumn for a field from entity config, the custom FormFieldConfig takes precedent (which is the latter item with the same id in array) .filter((v) => allColumns.find((c) => c.id === v.id) === v); if (!this.columnsToDisplay) { @@ -205,12 +206,8 @@ export class EntitiesTableComponent { @Output() rowClick: EventEmitter = new EventEmitter(); /** - * - * * BULK SELECT * User can use checkboxes to select multiple rows, so that parent components can execute bulk actions on them. - * - * */ @Input() set selectable(v: boolean) { this._selectable = v; @@ -317,12 +314,8 @@ export class EntitiesTableComponent { } /** - * - * * FILTER ARCHIVED RECORDS * User can hide / show inactive records through a toggle - * - * */ @Input() set showInactive(value: boolean) { if (value === this._showInactive) { From d1c0cb4c5bfbf0dd83368a33acbae0eae7ff3853 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Mon, 8 Jan 2024 13:56:00 +0100 Subject: [PATCH 15/58] remove unnecessary updateSubscription variables --- .../notes-related-to-entity.component.ts | 18 +++++++----------- .../related-entities.component.ts | 17 ++++++----------- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts b/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts index bfa13e9e0a..26933993c2 100644 --- a/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts +++ b/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts @@ -13,7 +13,6 @@ import { ChildSchoolRelation } from "../../children/model/childSchoolRelation"; import { EntityDatatype } from "../../../core/basic-datatypes/entity/entity.datatype"; import { EntityArrayDatatype } from "../../../core/basic-datatypes/entity-array/entity-array.datatype"; import { asArray } from "../../../utils/utils"; -import { Subscription } from "rxjs"; import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; import { applyUpdate } from "../../../core/entity/model/entity-update"; import { EntitiesTableComponent } from "../../../core/common-components/entities-table/entities-table.component"; @@ -69,6 +68,7 @@ export class NotesRelatedToEntityComponent implements OnInit { } this.newRecordFactory = this.generateNewRecordFactory(); this.initNotesOfEntity(); + this.listenToEntityUpdates(); } private async initNotesOfEntity() { @@ -86,17 +86,13 @@ export class NotesRelatedToEntityComponent implements OnInit { }); } - private updateSubscription: Subscription; - private listenToEntityUpdates() { - if (!this.updateSubscription && this.entityConstructor) { - this.updateSubscription = this.entityMapper - .receiveUpdates(this.entityConstructor) - .pipe(untilDestroyed(this)) - .subscribe((next) => { - this.records = applyUpdate(this.records, next, true); - }); - } + this.entityMapper + .receiveUpdates(this.entityConstructor) + .pipe(untilDestroyed(this)) + .subscribe((next) => { + this.records = applyUpdate(this.records, next, true); + }); } generateNewRecordFactory() { diff --git a/src/app/core/entity-details/related-entities/related-entities.component.ts b/src/app/core/entity-details/related-entities/related-entities.component.ts index c87bb9fdca..323426d45d 100644 --- a/src/app/core/entity-details/related-entities/related-entities.component.ts +++ b/src/app/core/entity-details/related-entities/related-entities.component.ts @@ -5,7 +5,6 @@ import { Entity, EntityConstructor } from "../../entity/model/entity"; import { EntityRegistry } from "../../entity/database-entity.decorator"; import { isArrayProperty } from "../../basic-datatypes/datatype-utils"; import { EntitiesTableComponent } from "../../common-components/entities-table/entities-table.component"; -import { Subscription } from "rxjs"; import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; import { applyUpdate } from "../../entity/model/entity-update"; import { @@ -103,17 +102,13 @@ export class RelatedEntitiesComponent implements OnInit { } } - private updateSubscription: Subscription; - protected listenToEntityUpdates() { - if (!this.updateSubscription && this.entityCtr) { - this.updateSubscription = this.entityMapper - .receiveUpdates(this.entityCtr) - .pipe(untilDestroyed(this)) - .subscribe((next) => { - this.data = applyUpdate(this.data, next, true); - }); - } + this.entityMapper + .receiveUpdates(this.entityCtr) + .pipe(untilDestroyed(this)) + .subscribe((next) => { + this.data = applyUpdate(this.data, next, true); + }); } createNewRecordFactory() { From 73ccb14c27046e142eef11b41722d5f61b0cdfd6 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Mon, 8 Jan 2024 14:06:42 +0100 Subject: [PATCH 16/58] simplify updateColumnsToDisplayForScreenSize --- .../activities-overview.component.ts | 15 +++++------- .../aser/aser-component/aser.component.ts | 7 ++++-- .../related-entities.component.html | 2 +- .../related-entities.component.ts | 23 +++++++++---------- 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts b/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts index ed8c9bf7a8..c161e5dc30 100644 --- a/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts +++ b/src/app/child-dev-project/attendance/activities-overview/activities-overview.component.ts @@ -2,10 +2,7 @@ import { Component, OnInit } from "@angular/core"; import { RecurringActivity } from "../model/recurring-activity"; import { DynamicComponent } from "../../../core/config/dynamic-components/dynamic-component.decorator"; import { RelatedEntitiesComponent } from "../../../core/entity-details/related-entities/related-entities.component"; -import { - ColumnConfig, - FormFieldConfig, -} from "../../../core/common-components/entity-form/FormConfig"; +import { FormFieldConfig } from "../../../core/common-components/entity-form/FormConfig"; import { EntitiesTableComponent } from "../../../core/common-components/entities-table/entities-table.component"; /** @@ -35,12 +32,12 @@ export class ActivitiesOverviewComponent relevantValue: "", }, }; - _columns: ColumnConfig[] = [ + override _columns: FormFieldConfig[] = [ this.titleColumn, - "type", - "assignedTo", - "linkedGroups", - "excludedParticipants", + { id: "type" }, + { id: "assignedTo" }, + { id: "linkedGroups" }, + { id: "excludedParticipants" }, ]; async ngOnInit() { diff --git a/src/app/child-dev-project/children/aser/aser-component/aser.component.ts b/src/app/child-dev-project/children/aser/aser-component/aser.component.ts index 04cd3e878b..7bc6a7baf5 100644 --- a/src/app/child-dev-project/children/aser/aser-component/aser.component.ts +++ b/src/app/child-dev-project/children/aser/aser-component/aser.component.ts @@ -5,7 +5,10 @@ import { Child } from "../../model/child"; import { DynamicComponent } from "../../../../core/config/dynamic-components/dynamic-component.decorator"; import { EntitiesTableComponent } from "../../../../core/common-components/entities-table/entities-table.component"; -import { ColumnConfig } from "../../../../core/common-components/entity-form/FormConfig"; +import { + ColumnConfig, + FormFieldConfig, +} from "../../../../core/common-components/entity-form/FormConfig"; import { RelatedEntitiesComponent } from "../../../../core/entity-details/related-entities/related-entities.component"; import { EntityMapperService } from "../../../../core/entity/entity-mapper/entity-mapper.service"; import { EntityRegistry } from "../../../../core/entity/database-entity.decorator"; @@ -24,7 +27,7 @@ export class AserComponent extends RelatedEntitiesComponent { property = "child"; entityCtr = Aser; - protected _columns: ColumnConfig[] = [ + override _columns: FormFieldConfig[] = [ { id: "date", visibleFrom: "xs" }, { id: "math", visibleFrom: "xs" }, { id: "english", visibleFrom: "xs" }, diff --git a/src/app/core/entity-details/related-entities/related-entities.component.html b/src/app/core/entity-details/related-entities/related-entities.component.html index 6c22e70a28..b54a0757d0 100644 --- a/src/app/core/entity-details/related-entities/related-entities.component.html +++ b/src/app/core/entity-details/related-entities/related-entities.component.html @@ -2,7 +2,7 @@ [entityType]="entityCtr" [records]="data" [filter]="filter" - [customColumns]="columns" + [customColumns]="_columns" [columnsToDisplay]="columnsToDisplay" [newRecordFactory]="createNewRecordFactory()" [showInactive]="showInactive" diff --git a/src/app/core/entity-details/related-entities/related-entities.component.ts b/src/app/core/entity-details/related-entities/related-entities.component.ts index 323426d45d..6d6f137408 100644 --- a/src/app/core/entity-details/related-entities/related-entities.component.ts +++ b/src/app/core/entity-details/related-entities/related-entities.component.ts @@ -13,6 +13,7 @@ import { } from "../../../utils/media/screen-size-observer.service"; import { ColumnConfig, + FormFieldConfig, toFormFieldConfig, } from "../../common-components/entity-form/FormConfig"; import { DataFilter } from "../../filter/filters/filters"; @@ -43,13 +44,14 @@ export class RelatedEntitiesComponent implements OnInit { @Input() public set columns(value: ColumnConfig[]) { - this._columns = value; + if (!Array.isArray(value)) { + return; + } + + this._columns = value.map((c) => toFormFieldConfig(c)); this.updateColumnsToDisplayForScreenSize(); } - public get columns(): ColumnConfig[] { - return this._columns; - } - protected _columns: ColumnConfig[]; + protected _columns: FormFieldConfig[]; columnsToDisplay: string[]; @@ -123,15 +125,12 @@ export class RelatedEntitiesComponent implements OnInit { } private updateColumnsToDisplayForScreenSize() { - if (!this.columns) { + if (!this._columns) { return; } - this.columnsToDisplay = this.columns - .filter((c) => { - const column = toFormFieldConfig( - (this.columns ?? []).find((x) => toFormFieldConfig(x).id === c), - ); + this.columnsToDisplay = this._columns + .filter((column) => { if (column?.hideFromTable) { return false; } @@ -142,6 +141,6 @@ export class RelatedEntitiesComponent implements OnInit { } return this.screenWidthObserver.currentScreenSize() >= numericValue; }) - .map((c) => toFormFieldConfig(c).id); + .map((c) => c.id); } } From bc1e2bbcf209e823a4fe0a5cd25915fe2e3453ce Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Mon, 8 Jan 2024 14:08:19 +0100 Subject: [PATCH 17/58] use super.ngOnInit --- .../related-time-period-entities.component.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.ts b/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.ts index c584f4f26c..aebec695e6 100644 --- a/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.ts +++ b/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.ts @@ -64,8 +64,7 @@ export class RelatedTimePeriodEntitiesComponent hasCurrentlyActiveEntry: boolean; async ngOnInit() { - await this.initData(); - super.listenToEntityUpdates(); + await super.ngOnInit(); this.onIsActiveFilterChange(); } From d08bb4415bb3b72497c11f6a0bdd79319db679e4 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Mon, 8 Jan 2024 14:15:50 +0100 Subject: [PATCH 18/58] fix test --- .../related-entities/related-entities.component.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/core/entity-details/related-entities/related-entities.component.spec.ts b/src/app/core/entity-details/related-entities/related-entities.component.spec.ts index 8890ed30d6..b19a6de5e7 100644 --- a/src/app/core/entity-details/related-entities/related-entities.component.spec.ts +++ b/src/app/core/entity-details/related-entities/related-entities.component.spec.ts @@ -59,7 +59,6 @@ describe("RelatedEntitiesComponent", () => { component.filter = filter; await component.ngOnInit(); - expect(component.columns).toBe(columns); expect(component.data).toEqual([r1, r2]); expect(component.filter).toEqual({ ...filter, childId: c1.getId() }); }); From 96648420b13f7d74f8153bdbc0fa69049b936b29 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Mon, 8 Jan 2024 14:31:26 +0100 Subject: [PATCH 19/58] fix ed mat --- .../related-entities-with-summary.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/core/entity-details/related-entities-with-summary/related-entities-with-summary.component.html b/src/app/core/entity-details/related-entities-with-summary/related-entities-with-summary.component.html index 69ece98b6c..8e10854001 100644 --- a/src/app/core/entity-details/related-entities-with-summary/related-entities-with-summary.component.html +++ b/src/app/core/entity-details/related-entities-with-summary/related-entities-with-summary.component.html @@ -2,7 +2,7 @@ [entityType]="entityCtr" [records]="data" [filter]="filter" - [customColumns]="columns" + [customColumns]="_columns" [newRecordFactory]="createNewRecordFactory()" > From dacfe714d9a3f862f46db43a9ba55672298954d0 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Mon, 8 Jan 2024 14:41:19 +0100 Subject: [PATCH 20/58] fix inline editing UI + triggering popup --- .../entities-table/entities-table.component.html | 1 + .../entities-table/entities-table.component.ts | 6 ++++-- .../entity-field-edit/entity-field-edit.component.html | 5 ++++- .../entity-field-edit/entity-field-edit.component.ts | 5 +++++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/app/core/common-components/entities-table/entities-table.component.html b/src/app/core/common-components/entities-table/entities-table.component.html index 148698db8d..bcbf9f8b7b 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.html +++ b/src/app/core/common-components/entities-table/entities-table.component.html @@ -28,6 +28,7 @@ [field]="col" [entity]="row.record" [form]="row.formGroup" + [compactMode]="true" > diff --git a/src/app/core/common-components/entities-table/entities-table.component.ts b/src/app/core/common-components/entities-table/entities-table.component.ts index 841e980f21..0b22deb88f 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.ts +++ b/src/app/core/common-components/entities-table/entities-table.component.ts @@ -258,9 +258,11 @@ export class EntitiesTableComponent { * @param row The entity whose details should be displayed. */ onRowClick(row: TableRow) { - if (!row.formGroup || row.formGroup.disabled) { - this.showEntity(row.record); + if (row.formGroup && !row.formGroup.disabled) { + return; } + + this.showEntity(row.record); this.rowClick.emit(row.record); } diff --git a/src/app/core/common-components/entity-field-edit/entity-field-edit.component.html b/src/app/core/common-components/entity-field-edit/entity-field-edit.component.html index 85e740c7a2..a6c3d3feae 100644 --- a/src/app/core/common-components/entity-field-edit/entity-field-edit.component.html +++ b/src/app/core/common-components/entity-field-edit/entity-field-edit.component.html @@ -12,7 +12,10 @@ >
- +
diff --git a/src/app/core/common-components/entity-field-edit/entity-field-edit.component.ts b/src/app/core/common-components/entity-field-edit/entity-field-edit.component.ts index c0fa8985b2..24ffbc6d20 100644 --- a/src/app/core/common-components/entity-field-edit/entity-field-edit.component.ts +++ b/src/app/core/common-components/entity-field-edit/entity-field-edit.component.ts @@ -41,6 +41,11 @@ export class EntityFieldEditComponent @Input() entity: T; @Input() form: EntityForm; + /** + * Whether to display the field in a limited space, hiding details like the help description button. + */ + @Input() compactMode: boolean; + constructor(private entityFormService: EntityFormService) {} ngOnChanges(changes: SimpleChanges): void { From c2e4d6e67ee5811d8ff71dfe70475f0845347f4e Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Mon, 8 Jan 2024 14:56:00 +0100 Subject: [PATCH 21/58] fix inline editing unsavedChanges --- .../entity-inline-edit-actions.component.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.ts b/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.ts index c47b43c7a4..f6cd80969a 100644 --- a/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.ts +++ b/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.ts @@ -37,13 +37,11 @@ export class EntityInlineEditActionsComponent { ) {} edit() { - if (!this.row.formGroup) { - this.row.formGroup = this.entityFormService.createFormGroup( - Array.from(this.row.record.getSchema().keys()), - this.row.record, - true, - ); - } + this.row.formGroup = this.entityFormService.createFormGroup( + Array.from(this.row.record.getSchema().keys()), + this.row.record, + true, + ); this.row.formGroup.enable(); } @@ -57,7 +55,7 @@ export class EntityInlineEditActionsComponent { this.row.formGroup, this.row.record, ); - this.row.formGroup.disable(); + delete this.row.formGroup; } catch (err) { if (!(err instanceof InvalidFormFieldError)) { this.alertService.addDanger(err.message); From 6c6f6e9c0b8a6d114c76e39e134aeb89172c2f9f Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Mon, 8 Jan 2024 15:26:36 +0100 Subject: [PATCH 22/58] correctly display relevant fields in popup --- .../entities-table/entities-table.component.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/core/common-components/entities-table/entities-table.component.ts b/src/app/core/common-components/entities-table/entities-table.component.ts index 0b22deb88f..70b4c399e8 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.ts +++ b/src/app/core/common-components/entities-table/entities-table.component.ts @@ -109,7 +109,9 @@ export class EntitiesTableComponent { .filter((v) => allColumns.find((c) => c.id === v.id) === v); if (!this.columnsToDisplay) { - this.columnsToDisplay = this._customColumns.map((c) => c.id); + this.columnsToDisplay = this._customColumns + .filter((c) => !c.hideFromTable) + .map((c) => c.id); } this.idForSavingPagination = this._customColumns @@ -269,7 +271,7 @@ export class EntitiesTableComponent { showEntity(entity: T) { switch (this.clickMode) { case "popup": - this.formDialog.openFormPopup(entity, this.columnsToDisplay); // TODO this.formDialog.openFormPopup(entity, this._columns) + this.formDialog.openFormPopup(entity, this._customColumns); break; case "navigate": this.router.navigate([ From 1213ff619f6267426219c8c10fb18e458bfbc2ab Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Mon, 8 Jan 2024 16:23:27 +0100 Subject: [PATCH 23/58] fix sort issue when setting programmatically from config --- .../notes-manager.component.html | 2 +- .../notes-manager/notes-manager.component.ts | 2 +- .../entities-table.component.html | 2 + .../entities-table.component.ts | 36 ++--- .../entity-create-button.component.ts | 4 +- src/app/core/config/config-fix.ts | 6 - .../entity-list/entity-list.component.html | 2 +- .../entity-list/entity-list.component.ts | 4 + .../todos/todo-list/todo-list.component.ts | 131 ++++++++++++------ 9 files changed, 121 insertions(+), 68 deletions(-) diff --git a/src/app/child-dev-project/notes/notes-manager/notes-manager.component.html b/src/app/child-dev-project/notes/notes-manager/notes-manager.component.html index ff9ffa00fe..cad8702d47 100644 --- a/src/app/child-dev-project/notes/notes-manager/notes-manager.component.html +++ b/src/app/child-dev-project/notes/notes-manager/notes-manager.component.html @@ -1,7 +1,7 @@ [] = [ diff --git a/src/app/core/common-components/entities-table/entities-table.component.html b/src/app/core/common-components/entities-table/entities-table.component.html index bcbf9f8b7b..93d979e8d8 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.html +++ b/src/app/core/common-components/entities-table/entities-table.component.html @@ -7,6 +7,8 @@ mat-table [dataSource]="recordsDataSource" matSort + [matSortActive]="_sortBy?.active" + [matSortDirection]="_sortBy?.direction" class="full-width table" > diff --git a/src/app/core/common-components/entities-table/entities-table.component.ts b/src/app/core/common-components/entities-table/entities-table.component.ts index 70b4c399e8..649e006f7b 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.ts +++ b/src/app/core/common-components/entities-table/entities-table.component.ts @@ -1,4 +1,5 @@ import { + AfterViewInit, Component, EventEmitter, Input, @@ -71,7 +72,7 @@ import { MonthDatatype } from "../../basic-datatypes/month/month.datatype"; templateUrl: "./entities-table.component.html", styleUrl: "./entities-table.component.scss", }) -export class EntitiesTableComponent { +export class EntitiesTableComponent implements AfterViewInit { @Input() set records(value: T[]) { if (!value) { return; @@ -83,7 +84,7 @@ export class EntitiesTableComponent { } _records: T[] = []; /** data displayed in the template's table */ - recordsDataSource = new MatTableDataSource>(); + recordsDataSource: MatTableDataSource>; isLoading: boolean = true; /** @@ -157,20 +158,6 @@ export class EntitiesTableComponent { } this._sortBy = value; - - this.recordsDataSource.sort = this.sort; - - this.recordsDataSource.sortData = (data, sort) => - tableSort(data, { - active: sort.active as keyof Entity | "", - direction: sort.direction, - }); - - this.sort.sort({ - id: value.active, - start: value.direction, - disableClear: false, - }); } _sortBy: Sort; @ViewChild(MatSort, { static: true }) sort: MatSort; @@ -288,8 +275,23 @@ export class EntitiesTableComponent { private router: Router, private filterService: FilterService, ) { - this.recordsDataSource.filterPredicate = (data, filter) => + this.recordsDataSource = this.createDataSource(); + } + + ngAfterViewInit(): void { + this.recordsDataSource.sort = this.sort; + } + + private createDataSource() { + const dataSource = new MatTableDataSource>(); + dataSource.sortData = (data, sort) => + tableSort(data, { + active: sort.active as keyof Entity | "", + direction: sort.direction, + }); + dataSource.filterPredicate = (data, filter) => entityFilterPredicate(data.record, filter); + return dataSource; } private inferDefaultSort(): Sort { diff --git a/src/app/core/common-components/entity-create-button/entity-create-button.component.ts b/src/app/core/common-components/entity-create-button/entity-create-button.component.ts index 0a8bdbe52c..573a698a3b 100644 --- a/src/app/core/common-components/entity-create-button/entity-create-button.component.ts +++ b/src/app/core/common-components/entity-create-button/entity-create-button.component.ts @@ -48,7 +48,9 @@ export class EntityCreateButtonComponent { * The entity is only written to the database when the user saves this record which is newly added in edit mode. */ create() { - const newRecord = this.newRecordFactory(); + const newRecord = this.newRecordFactory + ? this.newRecordFactory() + : new this.entityType(); this.entityCreate.emit(newRecord); } } diff --git a/src/app/core/config/config-fix.ts b/src/app/core/config/config-fix.ts index 611643676f..6f25242354 100644 --- a/src/app/core/config/config-fix.ts +++ b/src/app/core/config/config-fix.ts @@ -168,12 +168,6 @@ export const defaultJsonConfig = { "title": $localize`:Title for notes overview:Notes & Reports`, "includeEventNotes": false, "showEventNotesToggle": true, - "columns": [ - { - "id": "children", - "noSorting": true - } - ], "columnGroups": { "default": $localize`:Translated name of default column group:Standard`, "mobile": $localize`:Translated name of mobile column group:Mobile`, diff --git a/src/app/core/entity-list/entity-list/entity-list.component.html b/src/app/core/entity-list/entity-list/entity-list.component.html index 83234dad12..1ad7d5965c 100644 --- a/src/app/core/entity-list/entity-list/entity-list.component.html +++ b/src/app/core/entity-list/entity-list/entity-list.component.html @@ -108,7 +108,7 @@

{{ title }}

[customColumns]="columns" [editable]="false" [clickMode]="clickMode" - (rowClick)="elementClick.emit($event)" + (rowClick)="onRowClick($event)" [columnsToDisplay]="columnsToDisplay" [filter]="filterObj" [sortBy]="defaultSort" diff --git a/src/app/core/entity-list/entity-list/entity-list.component.ts b/src/app/core/entity-list/entity-list/entity-list.component.ts index b0d05925c4..8643a032f8 100644 --- a/src/app/core/entity-list/entity-list/entity-list.component.ts +++ b/src/app/core/entity-list/entity-list/entity-list.component.ts @@ -293,4 +293,8 @@ export class EntityListComponent this.duplicateRecord.duplicateRecord(this.selectedRows); this.selectedRows = undefined; } + + onRowClick(row: T) { + this.elementClick.emit(row); + } } diff --git a/src/app/features/todos/todo-list/todo-list.component.ts b/src/app/features/todos/todo-list/todo-list.component.ts index 09bcdaef42..995db3771d 100644 --- a/src/app/features/todos/todo-list/todo-list.component.ts +++ b/src/app/features/todos/todo-list/todo-list.component.ts @@ -1,72 +1,119 @@ import { Component, OnInit } from "@angular/core"; -import { ActivatedRoute } from "@angular/router"; import { Todo } from "../model/todo"; -import { - EntityListConfig, - PrebuiltFilterConfig, -} from "../../../core/entity-list/EntityListConfig"; -import { DynamicComponentConfig } from "../../../core/config/dynamic-components/dynamic-component-config.interface"; -import { FormDialogService } from "../../../core/form-dialog/form-dialog.service"; +import { PrebuiltFilterConfig } from "../../../core/entity-list/EntityListConfig"; import { TodoDetailsComponent } from "../todo-details/todo-details.component"; -import { LoggingService } from "../../../core/logging/logging.service"; import moment from "moment"; import { EntityListComponent } from "../../../core/entity-list/entity-list/entity-list.component"; import { FilterSelectionOption } from "../../../core/filter/filters/filters"; import { RouteTarget } from "../../../route-target"; -import { CurrentUserSubject } from "../../../core/session/current-user-subject"; import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; +import { Sort } from "@angular/material/sort"; +import { ScreenWidthObserver } from "../../../utils/media/screen-size-observer.service"; +import { ActivatedRoute, Router, RouterLink } from "@angular/router"; +import { AnalyticsService } from "../../../core/analytics/analytics.service"; +import { EntityMapperService } from "../../../core/entity/entity-mapper/entity-mapper.service"; +import { EntityRegistry } from "../../../core/entity/database-entity.decorator"; +import { MatDialog } from "@angular/material/dialog"; +import { DuplicateRecordService } from "../../../core/entity-list/duplicate-records/duplicate-records.service"; +import { CurrentUserSubject } from "../../../core/session/current-user-subject"; +import { FormDialogService } from "../../../core/form-dialog/form-dialog.service"; +import { LoggingService } from "../../../core/logging/logging.service"; +import { NgForOf, NgIf, NgStyle, NgTemplateOutlet } from "@angular/common"; +import { MatButtonModule } from "@angular/material/button"; +import { Angulartics2OnModule } from "angulartics2"; +import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; +import { MatMenuModule } from "@angular/material/menu"; +import { MatTabsModule } from "@angular/material/tabs"; +import { MatFormFieldModule } from "@angular/material/form-field"; +import { MatInputModule } from "@angular/material/input"; +import { EntitiesTableComponent } from "../../../core/common-components/entities-table/entities-table.component"; +import { FormsModule } from "@angular/forms"; +import { FilterComponent } from "../../../core/filter/filter/filter.component"; +import { TabStateModule } from "../../../utils/tab-state/tab-state.module"; +import { ViewTitleComponent } from "../../../core/common-components/view-title/view-title.component"; +import { ExportDataDirective } from "../../../core/export/export-data-directive/export-data.directive"; +import { DisableEntityOperationDirective } from "../../../core/permissions/permission-directive/disable-entity-operation.directive"; +import { MatTooltipModule } from "@angular/material/tooltip"; +import { EntityCreateButtonComponent } from "../../../core/common-components/entity-create-button/entity-create-button.component"; @UntilDestroy() @RouteTarget("TodoList") @Component({ selector: "app-todo-list", - template: ` - - `, + templateUrl: + "../../../core/entity-list/entity-list/entity-list.component.html", standalone: true, - imports: [EntityListComponent], + + imports: [ + NgIf, + NgStyle, + MatButtonModule, + Angulartics2OnModule, + FontAwesomeModule, + MatMenuModule, + NgTemplateOutlet, + MatTabsModule, + NgForOf, + MatFormFieldModule, + MatInputModule, + EntitiesTableComponent, + FormsModule, + FilterComponent, + TabStateModule, + ViewTitleComponent, + ExportDataDirective, + DisableEntityOperationDirective, + RouterLink, + MatTooltipModule, + EntityCreateButtonComponent, + ], }) -export class TodoListComponent implements OnInit { +export class TodoListComponent + extends EntityListComponent + implements OnInit +{ // TODO: make this component obsolete by generalizing Entity and EntityList so that we can define a viewDetailsComponent on the entity that gets opened as popup? - listConfig: EntityListConfig; entityConstructor = Todo; + override defaultSort: Sort = { + active: "deadline", + direction: "asc", + }; + constructor( - private route: ActivatedRoute, + screenWidthObserver: ScreenWidthObserver, + router: Router, + activatedRoute: ActivatedRoute, + analyticsService: AnalyticsService, + entityMapperService: EntityMapperService, + entities: EntityRegistry, + dialog: MatDialog, + duplicateRecord: DuplicateRecordService, private currentUser: CurrentUserSubject, private formDialog: FormDialogService, private logger: LoggingService, - ) {} - - ngOnInit() { - this.route.data.subscribe( - (data: DynamicComponentConfig) => - // TODO replace this use of route and rely on the RoutedViewComponent instead - this.init(data.config), + ) { + super( + screenWidthObserver, + router, + activatedRoute, + analyticsService, + entityMapperService, + entities, + dialog, + duplicateRecord, ); } - private init(config: EntityListConfig) { - this.listConfig = config; - this.listConfig.defaultSort = this.listConfig.defaultSort ?? { - active: "deadline", - direction: "asc", - }; + ngOnInit() { this.addPrebuiltFilters(); } private addPrebuiltFilters() { this.setFilterDefaultToCurrentUser(); - for (const prebuiltFilter of this.listConfig.filters.filter( + for (const prebuiltFilter of this.filters.filter( (filter) => filter.type === "prebuilt", )) { switch (prebuiltFilter.id) { @@ -88,9 +135,7 @@ export class TodoListComponent implements OnInit { } private setFilterDefaultToCurrentUser() { - const assignedToFilter = this.listConfig.filters.find( - (c) => c.id === "assignedTo", - ); + const assignedToFilter = this.filters.find((c) => c.id === "assignedTo"); if (assignedToFilter && !assignedToFilter.default) { // filter based on currently logged-in user this.currentUser @@ -123,10 +168,14 @@ export class TodoListComponent implements OnInit { filter.default = filter.default ?? "current"; } - createNew() { + override addNew() { this.showDetails(new Todo()); } + override onRowClick(entity: Todo) { + this.showDetails(entity); + } + showDetails(entity: Todo) { this.formDialog.openFormPopup(entity, undefined, TodoDetailsComponent); } From 39a6c6bdfbbe61e4da3237a4c43026a8f1f769ca Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Mon, 8 Jan 2024 16:25:57 +0100 Subject: [PATCH 24/58] use inheritance to identify date types --- .../entities-table/entities-table.component.ts | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/app/core/common-components/entities-table/entities-table.component.ts b/src/app/core/common-components/entities-table/entities-table.component.ts index 649e006f7b..991696872a 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.ts +++ b/src/app/core/common-components/entities-table/entities-table.component.ts @@ -44,9 +44,7 @@ import { DataFilter } from "../../filter/filters/filters"; import { EntityInlineEditActionsComponent } from "./entity-inline-edit-actions/entity-inline-edit-actions.component"; import { EntityCreateButtonComponent } from "../entity-create-button/entity-create-button.component"; import { DateDatatype } from "../../basic-datatypes/date/date.datatype"; -import { DateOnlyDatatype } from "../../basic-datatypes/date-only/date-only.datatype"; -import { DateWithAgeDatatype } from "../../basic-datatypes/date-with-age/date-with-age.datatype"; -import { MonthDatatype } from "../../basic-datatypes/month/month.datatype"; +import { EntitySchemaService } from "../../entity/schema/entity-schema.service"; /** * A simple display component (no logic and transformations) to display a table of entities. @@ -274,6 +272,7 @@ export class EntitiesTableComponent implements AfterViewInit { private formDialog: FormDialogService, private router: Router, private filterService: FilterService, + private schemaService: EntitySchemaService, ) { this.recordsDataSource = this.createDataSource(); } @@ -305,12 +304,8 @@ export class EntitiesTableComponent implements AfterViewInit { if ( sortByColumn?.viewComponent === "DisplayDate" || sortByColumn?.viewComponent === "DisplayMonth" || - [ - DateDatatype.dataType, - DateOnlyDatatype.dataType, - DateWithAgeDatatype.dataType, - MonthDatatype.dataType, - ].includes(sortByColumn?.dataType) + this.schemaService.getDatatypeOrDefault(sortByColumn?.dataType) instanceof + DateDatatype ) { // flip default sort order for dates (latest first) sortDirection = "desc"; From 36a687e1151cc34ceb862ad54288dafdf8c761b0 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Mon, 8 Jan 2024 16:43:27 +0100 Subject: [PATCH 25/58] fix tests --- .../entities-table/entities-table.component.spec.ts | 7 ++++++- .../entity-inline-edit-actions.component.spec.ts | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/app/core/common-components/entities-table/entities-table.component.spec.ts b/src/app/core/common-components/entities-table/entities-table.component.spec.ts index 39cfe288b9..fbf6cea707 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.spec.ts +++ b/src/app/core/common-components/entities-table/entities-table.component.spec.ts @@ -18,7 +18,7 @@ import { of } from "rxjs"; import { CoreTestingModule } from "../../../utils/core-testing.module"; import { FormDialogService } from "../../form-dialog/form-dialog.service"; -describe("EntityTableComponent", () => { +describe("EntitiesTableComponent", () => { let component: EntitiesTableComponent; let fixture: ComponentFixture>; @@ -102,6 +102,7 @@ describe("EntityTableComponent", () => { const oldNote = Note.create(moment().subtract(1, "day").toDate()); const newNote = Note.create(new Date()); component.records = [oldNote, newNote]; + fixture.detectChanges(); expect(component.recordsDataSource.sort.direction).toBe("desc"); expect(component.recordsDataSource.sort.active).toBe("date"); @@ -117,6 +118,7 @@ describe("EntityTableComponent", () => { component.records = [n3, n1, n2]; component.sortBy = { active: "subject", direction: "asc" }; + fixture.detectChanges(); expect(component.recordsDataSource.sort.direction).toBe("asc"); expect(component.recordsDataSource.sort.active).toBe("subject"); @@ -136,6 +138,7 @@ describe("EntityTableComponent", () => { component.records = children; component.sortBy = { active: "name", direction: "asc" }; + fixture.detectChanges(); const sortedIds = component.recordsDataSource ._orderData(component.recordsDataSource.data) @@ -152,6 +155,7 @@ describe("EntityTableComponent", () => { component.records = notes; component.sortBy = { active: "category", direction: "asc" }; + fixture.detectChanges(); const sortedIds = component.recordsDataSource ._orderData(component.recordsDataSource.data) @@ -164,6 +168,7 @@ describe("EntityTableComponent", () => { component.records = names.map((name) => Child.create(name)); component.sortBy = { active: "name", direction: "asc" }; + fixture.detectChanges(); const sortedNames = component.recordsDataSource ._orderData(component.recordsDataSource.data) diff --git a/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.spec.ts b/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.spec.ts index 776ea2db98..ee4fa9310b 100644 --- a/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.spec.ts +++ b/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.spec.ts @@ -89,7 +89,7 @@ describe("EntityInlineEditActionsComponent", () => { expect(entityMapper.save).toHaveBeenCalledWith(component.row.record); expect(component.row.record.name).toBe("New Name"); expect(component.row.record.gender).toBe(genders[2]); - expect(component.row.formGroup).not.toBeEnabled(); + expect(component.row.formGroup).toBeUndefined(); })); it("should show a error message when saving fails", fakeAsync(() => { From c193b497577e0e8fbeeb05b81b4185b669e7d521 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 10 Jan 2024 12:31:04 +0100 Subject: [PATCH 26/58] Update src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.ts Co-authored-by: Simon --- .../entity-inline-edit-actions.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.ts b/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.ts index f6cd80969a..4d29793732 100644 --- a/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.ts +++ b/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.ts @@ -72,6 +72,6 @@ export class EntityInlineEditActionsComponent { * @param row The entity to be reset. */ resetChanges() { - this.row.formGroup = null; + delete this.row.formGroup; } } From a28498c8f6aca619b6756a53610c65072fa58120 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Wed, 10 Jan 2024 12:09:42 +0100 Subject: [PATCH 27/58] fix todo list also navigating in addition to popup --- src/app/features/todos/todo-list/todo-list.component.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/features/todos/todo-list/todo-list.component.ts b/src/app/features/todos/todo-list/todo-list.component.ts index 995db3771d..8da397b3da 100644 --- a/src/app/features/todos/todo-list/todo-list.component.ts +++ b/src/app/features/todos/todo-list/todo-list.component.ts @@ -76,6 +76,8 @@ export class TodoListComponent entityConstructor = Todo; + override clickMode: "navigate" | "popup" | "none" = "none"; + override defaultSort: Sort = { active: "deadline", direction: "asc", From a3e51dd05950828ebdbfa3ef82e38a5ac040ab84 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Wed, 10 Jan 2024 12:30:22 +0100 Subject: [PATCH 28/58] fix notes list not updating on undo delete --- .../attendance-calendar.component.ts | 2 +- .../notes-related-to-entity.component.ts | 2 +- .../related-entities-with-summary.component.ts | 2 +- .../related-entities/related-entities.component.ts | 2 +- .../entity-list/entity-list/entity-list.component.ts | 2 +- src/app/core/entity/model/entity-update.spec.ts | 12 ++++++++---- src/app/core/entity/model/entity-update.ts | 5 +++-- 7 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.ts b/src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.ts index 7f72cd3ae2..d4082dd081 100644 --- a/src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.ts +++ b/src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.ts @@ -82,7 +82,7 @@ export class AttendanceCalendarComponent implements OnChanges { .receiveUpdates(EventNote) .pipe(untilDestroyed(this)) .subscribe((newNotes) => { - this.records = applyUpdate(this.records, newNotes); + this.records = applyUpdate(this.records, newNotes, false); this.selectDay(this.selectedDate?.toDate()); }); } diff --git a/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts b/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts index 26933993c2..c0718ce383 100644 --- a/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts +++ b/src/app/child-dev-project/notes/notes-related-to-entity/notes-related-to-entity.component.ts @@ -91,7 +91,7 @@ export class NotesRelatedToEntityComponent implements OnInit { .receiveUpdates(this.entityConstructor) .pipe(untilDestroyed(this)) .subscribe((next) => { - this.records = applyUpdate(this.records, next, true); + this.records = applyUpdate(this.records, next); }); } diff --git a/src/app/core/entity-details/related-entities-with-summary/related-entities-with-summary.component.ts b/src/app/core/entity-details/related-entities-with-summary/related-entities-with-summary.component.ts index 77bc22f9d9..bc0cc73248 100644 --- a/src/app/core/entity-details/related-entities-with-summary/related-entities-with-summary.component.ts +++ b/src/app/core/entity-details/related-entities-with-summary/related-entities-with-summary.component.ts @@ -51,7 +51,7 @@ export class RelatedEntitiesWithSummaryComponent ), ) .subscribe((update) => { - this.data = applyUpdate(this.data, update); + this.data = applyUpdate(this.data, update, false); this.updateSummary(); }); } diff --git a/src/app/core/entity-details/related-entities/related-entities.component.ts b/src/app/core/entity-details/related-entities/related-entities.component.ts index 6d6f137408..37e9d766e8 100644 --- a/src/app/core/entity-details/related-entities/related-entities.component.ts +++ b/src/app/core/entity-details/related-entities/related-entities.component.ts @@ -109,7 +109,7 @@ export class RelatedEntitiesComponent implements OnInit { .receiveUpdates(this.entityCtr) .pipe(untilDestroyed(this)) .subscribe((next) => { - this.data = applyUpdate(this.data, next, true); + this.data = applyUpdate(this.data, next); }); } diff --git a/src/app/core/entity-list/entity-list/entity-list.component.ts b/src/app/core/entity-list/entity-list/entity-list.component.ts index 8643a032f8..2191bd84b6 100644 --- a/src/app/core/entity-list/entity-list/entity-list.component.ts +++ b/src/app/core/entity-list/entity-list/entity-list.component.ts @@ -223,7 +223,7 @@ export class EntityListComponent .receiveUpdates(this.entityConstructor) .pipe(untilDestroyed(this)) .subscribe((next) => { - this.allEntities = applyUpdate(this.allEntities, next, true); + this.allEntities = applyUpdate(this.allEntities, next); }); } } diff --git a/src/app/core/entity/model/entity-update.spec.ts b/src/app/core/entity/model/entity-update.spec.ts index e2b0a181c8..96b2a55e8d 100644 --- a/src/app/core/entity/model/entity-update.spec.ts +++ b/src/app/core/entity/model/entity-update.spec.ts @@ -66,10 +66,14 @@ describe("entity-update", () => { }); it("does not change the list when an updated entity is not in the list", () => { - const newEntities = applyUpdate(existingEntities, { - entity: new TestEntity("n6", 1), - type: "update", - }); + const newEntities = applyUpdate( + existingEntities, + { + entity: new TestEntity("n6", 1), + type: "update", + }, + false, + ); expect(newEntities).toEqual(existingEntities); }); diff --git a/src/app/core/entity/model/entity-update.ts b/src/app/core/entity/model/entity-update.ts index a0b5e05e25..51c7737945 100644 --- a/src/app/core/entity/model/entity-update.ts +++ b/src/app/core/entity/model/entity-update.ts @@ -28,13 +28,14 @@ export interface UpdatedEntity { * @param next An entity that should be updated as well as the type of update. This, as well as the entity * may be undefined or null. In this event, the entities-array is returned as is. * @param entities The entities to update, must be defined - * @param addIfMissing (Optional) whether to add an entity that comes through an update event but is not part of the array yet (default is to ignore) + * @param addIfMissing (Optional) whether to add an entity that comes through an update event but is not part of the array yet, + * default is to add, disable this if you do special filtering or calculations on the data * @return An array of the given entities with the update applied */ export function applyUpdate( entities: T[], next: UpdatedEntity, - addIfMissing: boolean = false, + addIfMissing: boolean = true, ): T[] { if (!next || !next.entity || !entities) { return entities; From a3d2046db8775a877a44de98bdb46023eccb97f0 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Wed, 10 Jan 2024 13:48:45 +0100 Subject: [PATCH 29/58] remove deprecated, unused code --- .../children/aser/aser-component/aser.component.ts | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/app/child-dev-project/children/aser/aser-component/aser.component.ts b/src/app/child-dev-project/children/aser/aser-component/aser.component.ts index 7bc6a7baf5..2ecc12de9f 100644 --- a/src/app/child-dev-project/children/aser/aser-component/aser.component.ts +++ b/src/app/child-dev-project/children/aser/aser-component/aser.component.ts @@ -5,10 +5,7 @@ import { Child } from "../../model/child"; import { DynamicComponent } from "../../../../core/config/dynamic-components/dynamic-component.decorator"; import { EntitiesTableComponent } from "../../../../core/common-components/entities-table/entities-table.component"; -import { - ColumnConfig, - FormFieldConfig, -} from "../../../../core/common-components/entity-form/FormConfig"; +import { FormFieldConfig } from "../../../../core/common-components/entity-form/FormConfig"; import { RelatedEntitiesComponent } from "../../../../core/entity-details/related-entities/related-entities.component"; import { EntityMapperService } from "../../../../core/entity/entity-mapper/entity-mapper.service"; import { EntityRegistry } from "../../../../core/entity/database-entity.decorator"; @@ -36,15 +33,6 @@ export class AserComponent extends RelatedEntitiesComponent { { id: "remarks", visibleFrom: "md" }, ]; - /** - * @deprecated only for backward compatibility of old configs - */ - @Input() set config(value: { columns: ColumnConfig[] }) { - if (value.columns) { - this.columns = value.columns; - } - } - constructor( private childrenService: ChildrenService, entityMapper: EntityMapperService, From 4353bc4145f4cc480902bc45eadbe64a8db5e3d9 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Wed, 10 Jan 2024 14:05:10 +0100 Subject: [PATCH 30/58] ensure default sort by first column --- .../entities-table/entities-table.component.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/core/common-components/entities-table/entities-table.component.ts b/src/app/core/common-components/entities-table/entities-table.component.ts index 991696872a..beb2a49cf2 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.ts +++ b/src/app/core/common-components/entities-table/entities-table.component.ts @@ -141,8 +141,9 @@ export class EntitiesTableComponent implements AfterViewInit { cols.push(...value); this._columnsToDisplay = cols; - if (!this._sortBy) { + if (this.sortIsInferred) { this.sortBy = this.inferDefaultSort(); + this.sortIsInferred = true; } } _columnsToDisplay: string[]; @@ -156,9 +157,11 @@ export class EntitiesTableComponent implements AfterViewInit { } this._sortBy = value; + this.sortIsInferred = false; } _sortBy: Sort; @ViewChild(MatSort, { static: true }) sort: MatSort; + private sortIsInferred: boolean = true; /** * Adds a filter for the displayed data. From 8aefdac8b54f7f4015377e205c6065d8911c71a3 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Wed, 10 Jan 2024 14:33:52 +0100 Subject: [PATCH 31/58] fix switch highlighting of active entries --- .../related-time-period-entities.component.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.html b/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.html index 9566c06902..14662fa85c 100644 --- a/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.html +++ b/src/app/core/entity-details/related-time-period-entities/related-time-period-entities.component.html @@ -10,8 +10,10 @@ [filter]="filter" [customColumns]="_columns" [newRecordFactory]="generateNewRecordFactory()" - [getBackgroundColor]="backgroundColorFn" + [getBackgroundColor]=" + hasCurrentlyActiveEntry && showInactive ? backgroundColorFn : undefined + " [clickMode]="clickMode" - [showInactive]="showInactive" + [(showInactive)]="showInactive" > From 19f07cc9d8edeab747554209b74b8fad4cf482d7 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Wed, 10 Jan 2024 14:48:46 +0100 Subject: [PATCH 32/58] fix allowing to overwrite schema field with custom column config --- .../entities-table/entities-table.component.spec.ts | 13 +++++++++++++ .../entities-table/entities-table.component.ts | 12 +++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/app/core/common-components/entities-table/entities-table.component.spec.ts b/src/app/core/common-components/entities-table/entities-table.component.spec.ts index fbf6cea707..a1d8428c5a 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.spec.ts +++ b/src/app/core/common-components/entities-table/entities-table.component.spec.ts @@ -248,4 +248,17 @@ describe("EntitiesTableComponent", () => { expect(component.recordsDataSource.data).toEqual([{ record: active1 }]); }); + + it("should overwrite entity schema fields with customColumn config", async () => { + component.entityType = Child; + const customField = { + id: "name", + label: "Custom Name Label", + }; + component.customColumns = [customField]; + + expect(component._columns.find((c) => c.id === customField.id).label).toBe( + customField.label, + ); + }); }); diff --git a/src/app/core/common-components/entities-table/entities-table.component.ts b/src/app/core/common-components/entities-table/entities-table.component.ts index beb2a49cf2..18730eb8e4 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.ts +++ b/src/app/core/common-components/entities-table/entities-table.component.ts @@ -101,11 +101,13 @@ export class EntitiesTableComponent implements AfterViewInit { ) : []; - const allColumns = [...entityColumns, ...this._customColumns]; - this._columns = allColumns - // remove duplicates - // if there is a customColumn for a field from entity config, the custom FormFieldConfig takes precedent (which is the latter item with the same id in array) - .filter((v) => allColumns.find((c) => c.id === v.id) === v); + this._columns = [ + ...entityColumns.filter( + // if there is a customColumn for a field from entity config, don't add the base schema field + (c) => !this._customColumns.some((customCol) => customCol.id === c.id), + ), + ...this._customColumns, + ]; if (!this.columnsToDisplay) { this.columnsToDisplay = this._customColumns From 68abce49166cba7c0d880d7ee92117f84d3a8c43 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Wed, 10 Jan 2024 14:57:06 +0100 Subject: [PATCH 33/58] fix test --- .../entities-table/entities-table.component.spec.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/app/core/common-components/entities-table/entities-table.component.spec.ts b/src/app/core/common-components/entities-table/entities-table.component.spec.ts index a1d8428c5a..05aba91cb8 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.spec.ts +++ b/src/app/core/common-components/entities-table/entities-table.component.spec.ts @@ -17,6 +17,7 @@ import { CurrentUserSubject } from "../../session/current-user-subject"; import { of } from "rxjs"; import { CoreTestingModule } from "../../../utils/core-testing.module"; import { FormDialogService } from "../../form-dialog/form-dialog.service"; +import { DateDatatype } from "../../basic-datatypes/date/date.datatype"; describe("EntitiesTableComponent", () => { let component: EntitiesTableComponent; @@ -96,7 +97,10 @@ describe("EntitiesTableComponent", () => { it("should apply default sort on first column and order dates descending", () => { component.entityType = Note; - component.customColumns = ["date", "subject"]; + component.customColumns = [ + { id: "date", dataType: DateDatatype.dataType }, + "subject", + ]; component.columnsToDisplay = ["date", "subject"]; const oldNote = Note.create(moment().subtract(1, "day").toDate()); From 3d70d13f78c792cf748f043b874c7cd414f1c277 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Thu, 11 Jan 2024 09:44:35 +0100 Subject: [PATCH 34/58] fix(core): related-entities can handle records where the mapped field is undefined fixes #2172 --- .../related-entities.component.spec.ts | 24 +++++++++++++++++-- .../related-entities.component.ts | 2 +- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/app/core/entity-details/related-entities/related-entities.component.spec.ts b/src/app/core/entity-details/related-entities/related-entities.component.spec.ts index 49a1a1f2f5..384bfc306a 100644 --- a/src/app/core/entity-details/related-entities/related-entities.component.spec.ts +++ b/src/app/core/entity-details/related-entities/related-entities.component.spec.ts @@ -5,10 +5,13 @@ import { MockedTestingModule } from "../../../utils/mocked-testing.module"; import { EntityMapperService } from "../../entity/entity-mapper/entity-mapper.service"; import { Child } from "../../../child-dev-project/children/model/child"; import { ChildSchoolRelation } from "../../../child-dev-project/children/model/childSchoolRelation"; +import { Note } from "../../../child-dev-project/notes/model/note"; describe("RelatedEntitiesComponent", () => { - let component: RelatedEntitiesComponent; - let fixture: ComponentFixture>; + let component: RelatedEntitiesComponent; + let fixture: ComponentFixture< + RelatedEntitiesComponent + >; beforeEach(async () => { await TestBed.configureTestingModule({ @@ -56,6 +59,23 @@ describe("RelatedEntitiesComponent", () => { expect(component.filter).toEqual({ ...filter, childId: c1.getId() }); }); + it("should ignore entities of the related type where the matching field is undefined instead of array", async () => { + const c1 = new Child(); + const r1 = new Note(); + r1.children = [c1.getId()]; + const rEmpty = new Note(); + delete rEmpty.children; // some entity types will not have a default empty array + const entityMapper = TestBed.inject(EntityMapperService); + await entityMapper.saveAll([c1, r1, rEmpty]); + + component.entity = c1; + component.entityType = Note.ENTITY_TYPE; + component.property = "children"; + await component.ngOnInit(); + + expect(component.data).toEqual([r1]); + }); + it("should create a new entity that references the related one", async () => { const related = new Child(); component.entity = related; diff --git a/src/app/core/entity-details/related-entities/related-entities.component.ts b/src/app/core/entity-details/related-entities/related-entities.component.ts index ddefb12814..76684c739f 100644 --- a/src/app/core/entity-details/related-entities/related-entities.component.ts +++ b/src/app/core/entity-details/related-entities/related-entities.component.ts @@ -69,7 +69,7 @@ export class RelatedEntitiesComponent implements OnInit { this.data = (await this.entityMapper.loadType(this.entityType)).filter( (e) => this.isArray - ? e[this.property].includes(this.entity.getId()) + ? e[this.property]?.includes(this.entity.getId()) : e[this.property] === this.entity.getId(), ); this.filter = { From d3fd01d3c49e32a656ff98b78483eec03524f834 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Thu, 11 Jan 2024 17:55:23 +0100 Subject: [PATCH 35/58] show inactive on todo-list --- src/app/features/todos/todo-list/todo-list.component.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/features/todos/todo-list/todo-list.component.ts b/src/app/features/todos/todo-list/todo-list.component.ts index 8da397b3da..e4834c3190 100644 --- a/src/app/features/todos/todo-list/todo-list.component.ts +++ b/src/app/features/todos/todo-list/todo-list.component.ts @@ -83,6 +83,8 @@ export class TodoListComponent direction: "asc", }; + override showInactive = true; + constructor( screenWidthObserver: ScreenWidthObserver, router: Router, From 365775661df4cef8412147279f9fd2a81426b9a8 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Thu, 11 Jan 2024 17:55:59 +0100 Subject: [PATCH 36/58] disable un-sortable columns sort header automatically --- .../entities-table.component.html | 4 +-- .../entities-table.component.spec.ts | 8 +++++ .../entities-table.component.ts | 33 ++++++++++++++++--- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/app/core/common-components/entities-table/entities-table.component.html b/src/app/core/common-components/entities-table/entities-table.component.html index 93d979e8d8..dd5bfac392 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.html +++ b/src/app/core/common-components/entities-table/entities-table.component.html @@ -20,7 +20,7 @@ > @@ -62,7 +62,7 @@ { customField.label, ); }); + + it("should set noSorting if dataType cannot be sorted properly", () => { + component.entityType = Note; + + expect( + component._columns.find((c) => c.id === "children").noSorting, + ).toBeTrue(); + }); }); diff --git a/src/app/core/common-components/entities-table/entities-table.component.ts b/src/app/core/common-components/entities-table/entities-table.component.ts index 18730eb8e4..e28dfbc4ca 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.ts +++ b/src/app/core/common-components/entities-table/entities-table.component.ts @@ -45,6 +45,8 @@ import { EntityInlineEditActionsComponent } from "./entity-inline-edit-actions/e import { EntityCreateButtonComponent } from "../entity-create-button/entity-create-button.component"; import { DateDatatype } from "../../basic-datatypes/date/date.datatype"; import { EntitySchemaService } from "../../entity/schema/entity-schema.service"; +import { EntityArrayDatatype } from "../../basic-datatypes/entity-array/entity-array.datatype"; +import { EntityDatatype } from "../../basic-datatypes/entity/entity.datatype"; /** * A simple display component (no logic and transformations) to display a table of entities. @@ -91,12 +93,12 @@ export class EntitiesTableComponent implements AfterViewInit { */ @Input() set customColumns(value: ColumnConfig[]) { this._customColumns = (value ?? []).map((c) => - this.entityType - ? this.entityFormService.extendFormFieldConfig(c, this.entityType) + this._entityType + ? this.entityFormService.extendFormFieldConfig(c, this._entityType) : toFormFieldConfig(c), ); - const entityColumns = this.entityType?.schema - ? [...this.entityType.schema.entries()].map( + const entityColumns = this._entityType?.schema + ? [...this._entityType.schema.entries()].map( ([id, field]) => ({ ...field, id }) as FormFieldConfig, ) : []; @@ -108,6 +110,7 @@ export class EntitiesTableComponent implements AfterViewInit { ), ...this._customColumns, ]; + this._columns.forEach((c) => this.disableSortingHeaderForAdvancedFields(c)); if (!this.columnsToDisplay) { this.columnsToDisplay = this._customColumns @@ -150,7 +153,11 @@ export class EntitiesTableComponent implements AfterViewInit { } _columnsToDisplay: string[]; - @Input() entityType: EntityConstructor; + @Input() set entityType(value: EntityConstructor) { + this._entityType = value; + this.customColumns = this._customColumns; + } + _entityType: EntityConstructor; /** how to sort data by default during initialization */ @Input() set sortBy(value: Sort) { @@ -319,6 +326,22 @@ export class EntitiesTableComponent implements AfterViewInit { return sortBy ? { active: sortBy, direction: sortDirection } : undefined; } + /** + * Advanced fields like entity references cannot be sorted sensibly yet - disable sort for them. + * @param c + * @private + */ + private disableSortingHeaderForAdvancedFields(c: FormFieldConfig) { + // if no dataType is defined, these are dynamic, display-only components + if ( + c.dataType === EntityArrayDatatype.dataType || + c.dataType === EntityDatatype.dataType || + !c.dataType + ) { + c.noSorting = true; + } + } + /** * FILTER ARCHIVED RECORDS * User can hide / show inactive records through a toggle From aea5bd0161092ff3986aa1a89a96aa703952a676 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Fri, 12 Jan 2024 10:50:08 +0100 Subject: [PATCH 37/58] reset unsaved changes on inline cancel --- .../entity-inline-edit-actions.component.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.ts b/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.ts index 4d29793732..c56160d926 100644 --- a/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.ts +++ b/src/app/core/common-components/entities-table/entity-inline-edit-actions/entity-inline-edit-actions.component.ts @@ -10,6 +10,7 @@ import { InvalidFormFieldError } from "../../entity-form/invalid-form-field.erro import { EntityFormService } from "../../entity-form/entity-form.service"; import { AlertService } from "../../../alerts/alert.service"; import { EntityActionsService } from "../../../entity/entity-actions/entity-actions.service"; +import { UnsavedChangesService } from "../../../entity-details/form/unsaved-changes.service"; /** * Buttons to edit an (entities-table) row inline, handling the necessary logic and UI buttons. @@ -34,6 +35,7 @@ export class EntityInlineEditActionsComponent { private entityFormService: EntityFormService, private alertService: AlertService, private entityRemoveService: EntityActionsService, + private unsavedChanges: UnsavedChangesService, ) {} edit() { @@ -47,7 +49,6 @@ export class EntityInlineEditActionsComponent { /** * Save an edited record to the database (if validation succeeds). - * @param row The entity to be saved. */ async save(): Promise { try { @@ -69,9 +70,9 @@ export class EntityInlineEditActionsComponent { /** * Discard any changes to the given entity and reset it to the state before the user started editing. - * @param row The entity to be reset. */ resetChanges() { delete this.row.formGroup; + this.unsavedChanges.pending = false; } } From 334095bc03263ff28d086e78be33e54ffa0aa67b Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Tue, 6 Feb 2024 19:55:22 +0100 Subject: [PATCH 38/58] fix ui --- .../entities-table/entities-table.component.html | 2 +- .../entities-table/entities-table.component.spec.ts | 2 ++ .../entity-fields-menu/entity-fields-menu.component.html | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/core/common-components/entities-table/entities-table.component.html b/src/app/core/common-components/entities-table/entities-table.component.html index 9dda92036a..e47a9f6824 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.html +++ b/src/app/core/common-components/entities-table/entities-table.component.html @@ -112,7 +112,7 @@ --> diff --git a/src/app/core/common-components/entities-table/entities-table.component.spec.ts b/src/app/core/common-components/entities-table/entities-table.component.spec.ts index ba3887961c..abc0e3468a 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.spec.ts +++ b/src/app/core/common-components/entities-table/entities-table.component.spec.ts @@ -19,6 +19,7 @@ import { CoreTestingModule } from "../../../utils/core-testing.module"; import { FormDialogService } from "../../form-dialog/form-dialog.service"; import { DateDatatype } from "../../basic-datatypes/date/date.datatype"; import { Router } from "@angular/router"; +import { FontAwesomeTestingModule } from "@fortawesome/angular-fontawesome/testing"; describe("EntitiesTableComponent", () => { let component: EntitiesTableComponent; @@ -37,6 +38,7 @@ describe("EntitiesTableComponent", () => { EntitiesTableComponent, CoreTestingModule, NoopAnimationsModule, + FontAwesomeTestingModule, ], providers: [ { provide: EntityFormService, useValue: mockFormService }, diff --git a/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.html b/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.html index 35e5656dfa..d4436a3132 100644 --- a/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.html +++ b/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.html @@ -18,6 +18,7 @@ class="standard-icon-with-text" [icon]="activeFields.includes(field.id) ? 'toggle-on' : 'toggle-off'" > + Date: Tue, 5 Mar 2024 11:50:02 +0100 Subject: [PATCH 39/58] add admin-entity-list component --- .../admin-entity-list.component.html | 1 + .../admin-entity-list.component.scss | 0 .../admin-entity-list.component.spec.ts | 23 +++++++++++++++++++ .../admin-entity-list.component.ts | 13 +++++++++++ src/app/core/admin/admin.module.ts | 7 ++++++ src/app/core/admin/admin.routing.ts | 10 ++++++++ .../entity-list/entity-list.component.html | 12 ++++++++++ .../entity-list/entity-list.component.ts | 13 ++++++++++- .../todos/todo-list/todo-list.component.ts | 11 ++++++++- 9 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 src/app/core/admin/admin-entity-list/admin-entity-list.component.html create mode 100644 src/app/core/admin/admin-entity-list/admin-entity-list.component.scss create mode 100644 src/app/core/admin/admin-entity-list/admin-entity-list.component.spec.ts create mode 100644 src/app/core/admin/admin-entity-list/admin-entity-list.component.ts diff --git a/src/app/core/admin/admin-entity-list/admin-entity-list.component.html b/src/app/core/admin/admin-entity-list/admin-entity-list.component.html new file mode 100644 index 0000000000..d3fb5f0db7 --- /dev/null +++ b/src/app/core/admin/admin-entity-list/admin-entity-list.component.html @@ -0,0 +1 @@ +

admin-entity-list works!

diff --git a/src/app/core/admin/admin-entity-list/admin-entity-list.component.scss b/src/app/core/admin/admin-entity-list/admin-entity-list.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/core/admin/admin-entity-list/admin-entity-list.component.spec.ts b/src/app/core/admin/admin-entity-list/admin-entity-list.component.spec.ts new file mode 100644 index 0000000000..b306706023 --- /dev/null +++ b/src/app/core/admin/admin-entity-list/admin-entity-list.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AdminEntityListComponent } from './admin-entity-list.component'; + +describe('AdminEntityListComponent', () => { + let component: AdminEntityListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [AdminEntityListComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AdminEntityListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts b/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts new file mode 100644 index 0000000000..111775bd6f --- /dev/null +++ b/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts @@ -0,0 +1,13 @@ +import { Component } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-admin-entity-list', + standalone: true, + imports: [CommonModule], + templateUrl: './admin-entity-list.component.html', + styleUrl: './admin-entity-list.component.scss' +}) +export class AdminEntityListComponent { + +} diff --git a/src/app/core/admin/admin.module.ts b/src/app/core/admin/admin.module.ts index b35cf2718c..88f4f980e2 100644 --- a/src/app/core/admin/admin.module.ts +++ b/src/app/core/admin/admin.module.ts @@ -30,6 +30,13 @@ export class AdminModule { "./admin-entity-details/admin-entity/admin-entity-details.component" ).then((c) => c.AdminEntityDetailsComponent), ], + [ + "AdminEntityList", + () => + import("./admin-entity-list/admin-entity-list.component").then( + (c) => c.AdminEntityListComponent, + ), + ], ]); } } diff --git a/src/app/core/admin/admin.routing.ts b/src/app/core/admin/admin.routing.ts index 4c035d12d0..df029751f2 100644 --- a/src/app/core/admin/admin.routing.ts +++ b/src/app/core/admin/admin.routing.ts @@ -15,6 +15,16 @@ export const adminRoutes: Routes = [ permittedUserRoles: ["admin_app"], }, }, + { + path: "entity/:entityType/list", + component: RoutedViewComponent, + data: { + component: "AdminEntityList", + entity: "Config", + requiredPermissionOperation: "update", + }, + canActivate: [EntityPermissionGuard], + }, { path: "entity/:entityType/details", component: RoutedViewComponent, diff --git a/src/app/core/entity-list/entity-list/entity-list.component.html b/src/app/core/entity-list/entity-list/entity-list.component.html index f5fe81e634..2f60cd9516 100644 --- a/src/app/core/entity-list/entity-list/entity-list.component.html +++ b/src/app/core/entity-list/entity-list/entity-list.component.html @@ -220,6 +220,18 @@

{{ title }}

Bulk Actions + + diff --git a/src/app/core/entity-list/entity-list/entity-list.component.ts b/src/app/core/entity-list/entity-list/entity-list.component.ts index e0a5510c18..2d32087907 100644 --- a/src/app/core/entity-list/entity-list/entity-list.component.ts +++ b/src/app/core/entity-list/entity-list/entity-list.component.ts @@ -22,7 +22,13 @@ import { ScreenWidthObserver } from "../../../utils/media/screen-size-observer.s import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; import { FilterOverlayComponent } from "../../filter/filter-overlay/filter-overlay.component"; import { MatDialog } from "@angular/material/dialog"; -import { NgForOf, NgIf, NgStyle, NgTemplateOutlet } from "@angular/common"; +import { + AsyncPipe, + NgForOf, + NgIf, + NgStyle, + NgTemplateOutlet, +} from "@angular/common"; import { MatButtonModule } from "@angular/material/button"; import { Angulartics2OnModule } from "angulartics2"; import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; @@ -47,6 +53,8 @@ import { applyUpdate } from "../../entity/model/entity-update"; import { Subscription } from "rxjs"; import { DataFilter } from "../../filter/filters/filters"; import { EntityCreateButtonComponent } from "../../common-components/entity-create-button/entity-create-button.component"; +import { AbilityModule } from "@casl/angular"; +import { EntityActionsMenuComponent } from "../../entity-details/entity-actions-menu/entity-actions-menu.component"; /** * This component allows to create a full-blown table with pagination, filtering, searching and grouping. @@ -85,6 +93,9 @@ import { EntityCreateButtonComponent } from "../../common-components/entity-crea RouterLink, MatTooltipModule, EntityCreateButtonComponent, + AbilityModule, + AsyncPipe, + EntityActionsMenuComponent, ], standalone: true, }) diff --git a/src/app/features/todos/todo-list/todo-list.component.ts b/src/app/features/todos/todo-list/todo-list.component.ts index 373ed9180a..abc95a3caa 100644 --- a/src/app/features/todos/todo-list/todo-list.component.ts +++ b/src/app/features/todos/todo-list/todo-list.component.ts @@ -21,7 +21,13 @@ import { DuplicateRecordService } from "../../../core/entity-list/duplicate-reco import { CurrentUserSubject } from "../../../core/session/current-user-subject"; import { FormDialogService } from "../../../core/form-dialog/form-dialog.service"; import { LoggingService } from "../../../core/logging/logging.service"; -import { NgForOf, NgIf, NgStyle, NgTemplateOutlet } from "@angular/common"; +import { + AsyncPipe, + NgForOf, + NgIf, + NgStyle, + NgTemplateOutlet, +} from "@angular/common"; import { MatButtonModule } from "@angular/material/button"; import { Angulartics2OnModule } from "angulartics2"; import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; @@ -39,6 +45,7 @@ import { DisableEntityOperationDirective } from "../../../core/permissions/permi import { MatTooltipModule } from "@angular/material/tooltip"; import { EntityCreateButtonComponent } from "../../../core/common-components/entity-create-button/entity-create-button.component"; import { EntityActionsService } from "app/core/entity/entity-actions/entity-actions.service"; +import { AbilityModule } from "@casl/angular"; @UntilDestroy() @RouteTarget("TodoList") @@ -70,6 +77,8 @@ import { EntityActionsService } from "app/core/entity/entity-actions/entity-acti RouterLink, MatTooltipModule, EntityCreateButtonComponent, + AbilityModule, + AsyncPipe, ], }) export class TodoListComponent From 66f804f3a498bd78723721f80122db612d310e4d Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Wed, 6 Mar 2024 10:32:20 +0100 Subject: [PATCH 40/58] introduce parent component for all config related to an entity type --- src/app/app.component.ts | 21 ++- .../admin-entity-details.component.html | 26 +-- .../admin-entity-details.component.scss | 0 .../admin-entity-details.component.spec.ts | 66 ++++++++ .../admin-entity-details.component.ts | 64 +++++++ .../admin-entity-details.stories.ts | 0 .../admin-entity-details.component.ts | 157 ------------------ .../admin-entity-list.component.html | 26 ++- .../admin-entity-list.component.spec.ts | 23 ++- .../admin-entity-list.component.ts | 26 ++- .../admin-entity/admin-entity.component.html | 57 +++++++ .../admin-entity/admin-entity.component.scss | 19 +++ .../admin-entity.component.spec.ts} | 51 +++--- .../admin-entity/admin-entity.component.ts | 147 ++++++++++++++++ src/app/core/admin/admin.module.ts | 11 +- src/app/core/admin/admin.routing.ts | 12 +- .../entity-details.component.html | 2 +- .../entity-list/entity-list.component.html | 2 +- src/app/core/entity/entity-config.service.ts | 7 +- 19 files changed, 461 insertions(+), 256 deletions(-) rename src/app/core/admin/admin-entity-details/{admin-entity => admin-entity-details}/admin-entity-details.component.html (75%) rename src/app/core/admin/admin-entity-details/{admin-entity => admin-entity-details}/admin-entity-details.component.scss (100%) create mode 100644 src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.spec.ts create mode 100644 src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.ts rename src/app/core/admin/admin-entity-details/{admin-entity => admin-entity-details}/admin-entity-details.stories.ts (100%) delete mode 100644 src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.ts create mode 100644 src/app/core/admin/admin-entity/admin-entity.component.html create mode 100644 src/app/core/admin/admin-entity/admin-entity.component.scss rename src/app/core/admin/{admin-entity-details/admin-entity/admin-entity-details.component.spec.ts => admin-entity/admin-entity.component.spec.ts} (69%) create mode 100644 src/app/core/admin/admin-entity/admin-entity.component.ts diff --git a/src/app/app.component.ts b/src/app/app.component.ts index f78b371f37..0fe380b002 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -16,6 +16,8 @@ */ import { Component } from "@angular/core"; +import { NavigationEnd, Router } from "@angular/router"; +import { filter } from "rxjs/operators"; /** * Component as the main entry point for the app. @@ -23,6 +25,21 @@ import { Component } from "@angular/core"; */ @Component({ selector: "app-root", - template: "", + template: + "", }) -export class AppComponent {} +export class AppComponent { + configFullscreen: boolean = false; + + constructor(private router: Router) { + this.detectConfigMode(); + router.events + .pipe(filter((e) => e instanceof NavigationEnd)) + .subscribe(() => this.detectConfigMode()); + } + + private detectConfigMode() { + const currentUrl = this.router.url; + this.configFullscreen = currentUrl.startsWith("/admin/entity"); + } +} diff --git a/src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html similarity index 75% rename from src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html rename to src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html index aafce2a0a1..668beb7610 100644 --- a/src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html +++ b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html @@ -1,27 +1,5 @@ -
- - Editing details page for "{{ entityType | entityTypeLabel }}" records - - -
- - -
-
- - + {{ panelConfig.title }} @@ -31,7 +9,7 @@
diff --git a/src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.scss b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.scss similarity index 100% rename from src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.scss rename to src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.scss diff --git a/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.spec.ts b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.spec.ts new file mode 100644 index 0000000000..7837af049d --- /dev/null +++ b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.spec.ts @@ -0,0 +1,66 @@ +import { ComponentFixture, TestBed } from "@angular/core/testing"; + +import { AdminEntityDetailsComponent } from "./admin-entity-details.component"; +import { EntityDetailsConfig } from "../../../entity-details/EntityDetailsConfig"; +import { Entity } from "../../../entity/model/entity"; +import { MatTabsModule } from "@angular/material/tabs"; +import { NoopAnimationsModule } from "@angular/platform-browser/animations"; +import { DatabaseEntity } from "../../../entity/database-entity.decorator"; +import { DatabaseField } from "../../../entity/database-field.decorator"; +import { FontAwesomeTestingModule } from "@fortawesome/angular-fontawesome/testing"; + +describe("AdminEntityDetailsComponent", () => { + let component: AdminEntityDetailsComponent; + let fixture: ComponentFixture; + + let viewConfig: EntityDetailsConfig; + let viewConfigId, entityConfigId; + + @DatabaseEntity("AdminDetailsTest") + class AdminDetailsTestEntity extends Entity { + static readonly ENTITY_TYPE = "AdminDetailsTest"; + + @DatabaseField({ label: "Name" }) name: string; + } + + beforeEach(() => { + viewConfigId = `view:${AdminDetailsTestEntity.route.substring(1)}/:id`; + entityConfigId = `entity:${AdminDetailsTestEntity.ENTITY_TYPE}`; + viewConfig = { + entity: AdminDetailsTestEntity.ENTITY_TYPE, + panels: [{ title: "Tab 1", components: [] }], + }; + + TestBed.configureTestingModule({ + imports: [ + AdminEntityDetailsComponent, + MatTabsModule, + NoopAnimationsModule, + FontAwesomeTestingModule, + ], + }); + fixture = TestBed.createComponent(AdminEntityDetailsComponent); + component = fixture.componentInstance; + + component.entityConstructor = AdminDetailsTestEntity; + component.config = JSON.parse(JSON.stringify(viewConfig)); + + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); + + it("should add new panel (tab) to config", () => { + component.createPanel(); + + expect(component.config.panels.length).toBe(viewConfig.panels.length + 1); + }); + + it("should add new section (component in panel) to config", () => { + component.addComponent(component.config.panels[0]); + + expect(component.config.panels[0].components.length).toBe(1); + }); +}); diff --git a/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.ts b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.ts new file mode 100644 index 0000000000..c6fa2c9228 --- /dev/null +++ b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.ts @@ -0,0 +1,64 @@ +import { Component, Input, ViewChild } from "@angular/core"; +import { + EntityDetailsConfig, + Panel, +} from "../../../entity-details/EntityDetailsConfig"; +import { EntityConstructor } from "../../../entity/model/entity"; +import { DynamicComponent } from "../../../config/dynamic-components/dynamic-component.decorator"; +import { NgForOf, NgIf } from "@angular/common"; +import { MatTabGroup, MatTabsModule } from "@angular/material/tabs"; +import { FaIconComponent } from "@fortawesome/angular-fontawesome"; +import { MatButtonModule } from "@angular/material/button"; +import { EntityTypeLabelPipe } from "../../../common-components/entity-type-label/entity-type-label.pipe"; +import { ViewTitleComponent } from "../../../common-components/view-title/view-title.component"; +import { AdminSectionHeaderComponent } from "../admin-section-header/admin-section-header.component"; +import { AdminEntityFormComponent } from "../admin-entity-form/admin-entity-form.component"; +import { AdminEntityPanelComponentComponent } from "../admin-entity-panel-component/admin-entity-panel-component.component"; +import { MatTooltipModule } from "@angular/material/tooltip"; + +@DynamicComponent("AdminEntityDetails") +@Component({ + selector: "app-admin-entity-details", + templateUrl: "./admin-entity-details.component.html", + styleUrls: ["./admin-entity-details.component.scss"], + standalone: true, + imports: [ + MatTabsModule, + FaIconComponent, + MatButtonModule, + EntityTypeLabelPipe, + ViewTitleComponent, + AdminSectionHeaderComponent, + AdminEntityFormComponent, + AdminEntityPanelComponentComponent, + MatTooltipModule, + NgForOf, + NgIf, + ], +}) +export class AdminEntityDetailsComponent { + @Input() entityConstructor: EntityConstructor; + @Input() config: EntityDetailsConfig; + + @ViewChild(MatTabGroup) tabGroup: MatTabGroup; + + createPanel() { + const newPanel: Panel = { title: "New Tab", components: [] }; + this.config.panels.push(newPanel); + + // wait until view has actually added the new tab before we can auto-select it + setTimeout(() => { + const newTabIndex = this.config.panels.length - 1; + this.tabGroup.selectedIndex = newTabIndex; + this.tabGroup.focusTab(newTabIndex); + }); + } + + addComponent(panel: Panel) { + panel.components.push({ + title: $localize`:Default title:New Section`, + component: "Form", // TODO: make this configurable + config: { fieldGroups: [] }, + }); + } +} diff --git a/src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.stories.ts b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.stories.ts similarity index 100% rename from src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.stories.ts rename to src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.stories.ts diff --git a/src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.ts b/src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.ts deleted file mode 100644 index e9692342b5..0000000000 --- a/src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { Component, Input, OnInit, ViewChild } from "@angular/core"; -import { - EntityDetailsConfig, - Panel, -} from "../../../entity-details/EntityDetailsConfig"; -import { EntityConstructor } from "../../../entity/model/entity"; -import { EntityRegistry } from "../../../entity/database-entity.decorator"; -import { ConfigService } from "../../../config/config.service"; -import { ViewConfig } from "../../../config/dynamic-routing/view-config.interface"; -import { DynamicComponent } from "../../../config/dynamic-components/dynamic-component.decorator"; -import { Location, NgForOf, NgIf } from "@angular/common"; -import { EntityMapperService } from "../../../entity/entity-mapper/entity-mapper.service"; -import { Config } from "../../../config/config"; -import { EntityConfigService } from "../../../entity/entity-config.service"; -import { EntityConfig } from "../../../entity/entity-config"; -import { MatTabGroup, MatTabsModule } from "@angular/material/tabs"; -import { EntityActionsService } from "../../../entity/entity-actions/entity-actions.service"; -import { EntitySchemaField } from "../../../entity/schema/entity-schema-field"; -import { FaIconComponent } from "@fortawesome/angular-fontawesome"; -import { MatButtonModule } from "@angular/material/button"; -import { EntityTypeLabelPipe } from "../../../common-components/entity-type-label/entity-type-label.pipe"; -import { ViewTitleComponent } from "../../../common-components/view-title/view-title.component"; -import { AdminSectionHeaderComponent } from "../admin-section-header/admin-section-header.component"; -import { AdminEntityFormComponent } from "../admin-entity-form/admin-entity-form.component"; -import { AdminEntityPanelComponentComponent } from "../admin-entity-panel-component/admin-entity-panel-component.component"; -import { MatTooltipModule } from "@angular/material/tooltip"; - -@DynamicComponent("AdminEntityDetails") -@Component({ - selector: "app-admin-entity-details", - templateUrl: "./admin-entity-details.component.html", - styleUrls: ["./admin-entity-details.component.scss"], - standalone: true, - imports: [ - MatTabsModule, - FaIconComponent, - MatButtonModule, - EntityTypeLabelPipe, - ViewTitleComponent, - AdminSectionHeaderComponent, - AdminEntityFormComponent, - AdminEntityPanelComponentComponent, - MatTooltipModule, - NgForOf, - NgIf, - ], -}) -export class AdminEntityDetailsComponent implements OnInit { - @Input() entityType: string; - entityConstructor: EntityConstructor; - private originalEntitySchemaFields: [string, EntitySchemaField][]; - - configDetailsView: EntityDetailsConfig; - - @ViewChild(MatTabGroup) tabGroup: MatTabGroup; - - constructor( - private entities: EntityRegistry, - private configService: ConfigService, - private location: Location, - private entityMapper: EntityMapperService, - private entityActionsService: EntityActionsService, - ) {} - - ngOnInit(): void { - this.init(); - } - - private init() { - this.entityConstructor = this.entities.get(this.entityType); - this.originalEntitySchemaFields = JSON.parse( - JSON.stringify(Array.from(this.entityConstructor.schema.entries())), - ); - - const detailsView: ViewConfig = - this.configService.getConfig( - EntityConfigService.getDetailsViewId(this.entityConstructor), - ); - if (detailsView.component !== "EntityDetails") { - // not supported currently - return; - } - - // work on a deep copy as we are editing in place (for titles, sections, etc.) - this.configDetailsView = JSON.parse(JSON.stringify(detailsView.config)); - } - - cancel() { - this.entityConstructor.schema = new Map(this.originalEntitySchemaFields); - this.location.back(); - } - - async save() { - const originalConfig = await this.entityMapper.load( - Config, - Config.CONFIG_KEY, - ); - const newConfig = originalConfig.copy(); - - this.setViewConfig(newConfig); - this.setEntityConfig(newConfig); - - await this.entityMapper.save(newConfig); - this.entityActionsService.showSnackbarConfirmationWithUndo( - $localize`:Save config confirmation message:Configuration updated`, - [originalConfig], - ); - - this.location.back(); - } - - private setViewConfig(newConfig: Config) { - const viewId = EntityConfigService.getDetailsViewId(this.entityConstructor); - newConfig.data[viewId].config = this.configDetailsView; - } - - private setEntityConfig(newConfig: Config) { - const entityConfigKey = - EntityConfigService.PREFIX_ENTITY_CONFIG + this.entityType; - - // init config if not present - newConfig.data[entityConfigKey] = - newConfig.data[entityConfigKey] ?? ({ attributes: {} } as EntityConfig); - newConfig.data[entityConfigKey].attributes = - newConfig.data[entityConfigKey].attributes ?? {}; - - const entitySchemaConfig: EntityConfig = newConfig.data[entityConfigKey]; - - for (const [fieldId, field] of this.entityConstructor.schema.entries()) { - if (!field._isCustomizedField) { - // do not write unchanged default fields from the classes into config - continue; - } - entitySchemaConfig.attributes[fieldId] = field; - } - } - - createPanel() { - const newPanel: Panel = { title: "New Tab", components: [] }; - this.configDetailsView.panels.push(newPanel); - - // wait until view has actually added the new tab before we can auto-select it - setTimeout(() => { - const newTabIndex = this.configDetailsView.panels.length - 1; - this.tabGroup.selectedIndex = newTabIndex; - this.tabGroup.focusTab(newTabIndex); - }); - } - - addComponent(panel: Panel) { - panel.components.push({ - title: $localize`:Default title:New Section`, - component: "Form", // TODO: make this configurable - config: { fieldGroups: [] }, - }); - } -} diff --git a/src/app/core/admin/admin-entity-list/admin-entity-list.component.html b/src/app/core/admin/admin-entity-list/admin-entity-list.component.html index d3fb5f0db7..ae8f00abd9 100644 --- a/src/app/core/admin/admin-entity-list/admin-entity-list.component.html +++ b/src/app/core/admin/admin-entity-list/admin-entity-list.component.html @@ -1 +1,25 @@ -

admin-entity-list works!

+ +
+ +
+ +
+ + + + + +
diff --git a/src/app/core/admin/admin-entity-list/admin-entity-list.component.spec.ts b/src/app/core/admin/admin-entity-list/admin-entity-list.component.spec.ts index b306706023..d849883e8f 100644 --- a/src/app/core/admin/admin-entity-list/admin-entity-list.component.spec.ts +++ b/src/app/core/admin/admin-entity-list/admin-entity-list.component.spec.ts @@ -1,23 +1,30 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { AdminEntityListComponent } from './admin-entity-list.component'; +import { AdminEntityListComponent } from "./admin-entity-list.component"; +import { FilterGeneratorService } from "../../filter/filter-generator/filter-generator.service"; +import { FilterService } from "../../filter/filter.service"; +import { ActivatedRoute } from "@angular/router"; -describe('AdminEntityListComponent', () => { +describe("AdminEntityListComponent", () => { let component: AdminEntityListComponent; let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [AdminEntityListComponent] - }) - .compileComponents(); - + imports: [AdminEntityListComponent], + providers: [ + { provide: FilterGeneratorService, useValue: {} }, + { provide: FilterService, useValue: {} }, + { provide: ActivatedRoute, useValue: {} }, + ], + }).compileComponents(); + fixture = TestBed.createComponent(AdminEntityListComponent); component = fixture.componentInstance; fixture.detectChanges(); }); - it('should create', () => { + it("should create", () => { expect(component).toBeTruthy(); }); }); diff --git a/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts b/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts index 111775bd6f..b6e24b3c48 100644 --- a/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts +++ b/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts @@ -1,13 +1,25 @@ -import { Component } from '@angular/core'; -import { CommonModule } from '@angular/common'; +import { Component, Input } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { FilterComponent } from "../../filter/filter/filter.component"; +import { MatTab, MatTabGroup } from "@angular/material/tabs"; +import { EntitiesTableComponent } from "../../common-components/entities-table/entities-table.component"; +import { EntityConstructor } from "../../entity/model/entity"; +import { EntityListConfig } from "../../entity-list/EntityListConfig"; @Component({ - selector: 'app-admin-entity-list', + selector: "app-admin-entity-list", standalone: true, - imports: [CommonModule], - templateUrl: './admin-entity-list.component.html', - styleUrl: './admin-entity-list.component.scss' + imports: [ + CommonModule, + FilterComponent, + MatTabGroup, + EntitiesTableComponent, + MatTab, + ], + templateUrl: "./admin-entity-list.component.html", + styleUrl: "./admin-entity-list.component.scss", }) export class AdminEntityListComponent { - + @Input() entityConstructor: EntityConstructor; + @Input() config: EntityListConfig; } diff --git a/src/app/core/admin/admin-entity/admin-entity.component.html b/src/app/core/admin/admin-entity/admin-entity.component.html new file mode 100644 index 0000000000..5017755184 --- /dev/null +++ b/src/app/core/admin/admin-entity/admin-entity.component.html @@ -0,0 +1,57 @@ +
+
+ + Editing data structure for "{{ entityType | entityTypeLabel }}" records + + +
+ + +
+
+ +
+ + + Details View & Fields + + + List View + + + General Settings + + + +
+ + + + +
COMING SOON
+
+
+
diff --git a/src/app/core/admin/admin-entity/admin-entity.component.scss b/src/app/core/admin/admin-entity/admin-entity.component.scss new file mode 100644 index 0000000000..c64f174693 --- /dev/null +++ b/src/app/core/admin/admin-entity/admin-entity.component.scss @@ -0,0 +1,19 @@ +.host-container { + height: 100vh; +} + +.header { + margin: 20px; +} + +.main-container { + width: 100%; + min-height: 0; + flex-grow: 1; +} + +.config-component { + min-width: 0; + padding: 8px; + overflow-y: auto; +} diff --git a/src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.spec.ts b/src/app/core/admin/admin-entity/admin-entity.component.spec.ts similarity index 69% rename from src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.spec.ts rename to src/app/core/admin/admin-entity/admin-entity.component.spec.ts index e9ba2b06f0..26fd519626 100644 --- a/src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.spec.ts +++ b/src/app/core/admin/admin-entity/admin-entity.component.spec.ts @@ -5,33 +5,34 @@ import { tick, } from "@angular/core/testing"; -import { AdminEntityDetailsComponent } from "./admin-entity-details.component"; -import { ConfigService } from "../../../config/config.service"; -import { EntityMapperService } from "../../../entity/entity-mapper/entity-mapper.service"; +import { AdminEntityComponent } from "./admin-entity.component"; +import { AdminEntityDetailsComponent } from "../admin-entity-details/admin-entity-details/admin-entity-details.component"; +import { ConfigService } from "../../config/config.service"; import { mockEntityMapper, MockEntityMapperService, -} from "../../../entity/entity-mapper/mock-entity-mapper-service"; -import { Config } from "../../../config/config"; -import { EntityActionsService } from "../../../entity/entity-actions/entity-actions.service"; -import { CoreModule } from "../../../core.module"; -import { CoreTestingModule } from "../../../../utils/core-testing.module"; -import { EntityTypeLabelPipe } from "../../../common-components/entity-type-label/entity-type-label.pipe"; +} from "../../entity/entity-mapper/mock-entity-mapper-service"; import { EntityDetailsConfig, Panel, -} from "../../../entity-details/EntityDetailsConfig"; -import { Entity } from "../../../entity/model/entity"; +} from "../../entity-details/EntityDetailsConfig"; +import { DatabaseEntity } from "../../entity/database-entity.decorator"; +import { Entity } from "../../entity/model/entity"; +import { DatabaseField } from "../../entity/database-field.decorator"; +import { Config } from "../../config/config"; +import { CoreTestingModule } from "../../../utils/core-testing.module"; +import { CoreModule } from "../../core.module"; +import { EntityTypeLabelPipe } from "../../common-components/entity-type-label/entity-type-label.pipe"; import { MatTabsModule } from "@angular/material/tabs"; import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { EntitySchemaField } from "../../../entity/schema/entity-schema-field"; -import { DatabaseEntity } from "../../../entity/database-entity.decorator"; -import { DatabaseField } from "../../../entity/database-field.decorator"; import { FontAwesomeTestingModule } from "@fortawesome/angular-fontawesome/testing"; +import { EntityMapperService } from "../../entity/entity-mapper/entity-mapper.service"; +import { EntityActionsService } from "../../entity/entity-actions/entity-actions.service"; +import { EntitySchemaField } from "../../entity/schema/entity-schema-field"; -describe("AdminEntityDetailsComponent", () => { - let component: AdminEntityDetailsComponent; - let fixture: ComponentFixture; +describe("AdminEntityComponent", () => { + let component: AdminEntityComponent; + let fixture: ComponentFixture; let mockConfigService: jasmine.SpyObj; let entityMapper: MockEntityMapperService; @@ -89,7 +90,7 @@ describe("AdminEntityDetailsComponent", () => { }, ], }); - fixture = TestBed.createComponent(AdminEntityDetailsComponent); + fixture = TestBed.createComponent(AdminEntityComponent); component = fixture.componentInstance; component.entityType = AdminTestEntity.ENTITY_TYPE; @@ -101,20 +102,6 @@ describe("AdminEntityDetailsComponent", () => { expect(component).toBeTruthy(); }); - it("should add new panel (tab) to config", () => { - component.createPanel(); - - expect(component.configDetailsView.panels.length).toBe( - viewConfig.panels.length + 1, - ); - }); - - it("should add new section (component in panel) to config", () => { - component.addComponent(component.configDetailsView.panels[0]); - - expect(component.configDetailsView.panels[0].components.length).toBe(1); - }); - it("should reset all entity schema changes on cancel", () => { // simulate schema changes done through the field config popup form AdminTestEntity.schema.set("testField", { label: "New field" }); diff --git a/src/app/core/admin/admin-entity/admin-entity.component.ts b/src/app/core/admin/admin-entity/admin-entity.component.ts new file mode 100644 index 0000000000..7823a2a441 --- /dev/null +++ b/src/app/core/admin/admin-entity/admin-entity.component.ts @@ -0,0 +1,147 @@ +import { Component, ContentChild, Input, TemplateRef } from "@angular/core"; +import { CommonModule, Location } from "@angular/common"; +import { EntityRegistry } from "../../entity/database-entity.decorator"; +import { ConfigService } from "../../config/config.service"; +import { EntityMapperService } from "../../entity/entity-mapper/entity-mapper.service"; +import { EntityActionsService } from "../../entity/entity-actions/entity-actions.service"; +import { ViewConfig } from "../../config/dynamic-routing/view-config.interface"; +import { EntityDetailsConfig } from "../../entity-details/EntityDetailsConfig"; +import { EntityConfigService } from "../../entity/entity-config.service"; +import { Config } from "../../config/config"; +import { EntityConfig } from "../../entity/entity-config"; +import { EntityConstructor } from "../../entity/model/entity"; +import { EntitySchemaField } from "../../entity/schema/entity-schema-field"; +import { EntityListConfig } from "../../entity-list/EntityListConfig"; +import { EntityTypeLabelPipe } from "../../common-components/entity-type-label/entity-type-label.pipe"; +import { MatButton, MatIconButton } from "@angular/material/button"; +import { ViewTitleComponent } from "../../common-components/view-title/view-title.component"; +import { AdminEntityListComponent } from "../admin-entity-list/admin-entity-list.component"; +import { + MatSidenav, + MatSidenavContainer, + MatSidenavContent, +} from "@angular/material/sidenav"; +import { FaIconComponent } from "@fortawesome/angular-fontawesome"; +import { RouterLink } from "@angular/router"; +import { MatListItem, MatNavList } from "@angular/material/list"; +import { AdminEntityDetailsComponent } from "../admin-entity-details/admin-entity-details/admin-entity-details.component"; + +@Component({ + selector: "app-admin-entity", + standalone: true, + imports: [ + CommonModule, + EntityTypeLabelPipe, + MatButton, + ViewTitleComponent, + AdminEntityListComponent, + MatSidenav, + MatSidenavContainer, + MatSidenavContent, + FaIconComponent, + MatIconButton, + RouterLink, + MatNavList, + MatListItem, + AdminEntityDetailsComponent, + ], + templateUrl: "./admin-entity.component.html", + styleUrl: "./admin-entity.component.scss", +}) +export class AdminEntityComponent { + @Input() entityType: string; + entityConstructor: EntityConstructor; + private originalEntitySchemaFields: [string, EntitySchemaField][]; + + configDetailsView: EntityDetailsConfig; + configListView: EntityListConfig; + + @ContentChild(TemplateRef) templateRef: TemplateRef; + + constructor( + private entities: EntityRegistry, + private configService: ConfigService, + private location: Location, + private entityMapper: EntityMapperService, + private entityActionsService: EntityActionsService, + ) {} + + ngOnInit(): void { + this.init(); + } + + private init() { + this.entityConstructor = this.entities.get(this.entityType); + this.originalEntitySchemaFields = JSON.parse( + JSON.stringify(Array.from(this.entityConstructor.schema.entries())), + ); + + this.configDetailsView = this.loadViewConfig( + EntityConfigService.getDetailsViewId(this.entityConstructor), + ); + this.configListView = this.loadViewConfig( + EntityConfigService.getListViewId(this.entityConstructor), + ); + } + + private loadViewConfig( + viewId: string, + ): C { + const viewConfig: ViewConfig = this.configService.getConfig(viewId); + + // work on a deep copy as we are editing in place (for titles, sections, etc.) + return JSON.parse(JSON.stringify(viewConfig.config)); + } + + cancel() { + this.entityConstructor.schema = new Map(this.originalEntitySchemaFields); + this.location.back(); + } + + async save() { + const originalConfig = await this.entityMapper.load( + Config, + Config.CONFIG_KEY, + ); + const newConfig = originalConfig.copy(); + + this.setViewConfig(newConfig); + this.setEntityConfig(newConfig); + + await this.entityMapper.save(newConfig); + this.entityActionsService.showSnackbarConfirmationWithUndo( + $localize`:Save config confirmation message:Configuration updated`, + [originalConfig], + ); + + this.location.back(); + } + + private setViewConfig(newConfig: Config) { + const viewId = EntityConfigService.getDetailsViewId(this.entityConstructor); + newConfig.data[viewId].config = this.configDetailsView; + } + + private setEntityConfig(newConfig: Config) { + const entityConfigKey = + EntityConfigService.PREFIX_ENTITY_CONFIG + this.entityType; + + // init config if not present + newConfig.data[entityConfigKey] = + newConfig.data[entityConfigKey] ?? ({ attributes: {} } as EntityConfig); + newConfig.data[entityConfigKey].attributes = + newConfig.data[entityConfigKey].attributes ?? {}; + + const entitySchemaConfig: EntityConfig = newConfig.data[entityConfigKey]; + + for (const [fieldId, field] of this.entityConstructor.schema.entries()) { + if (!field._isCustomizedField) { + // do not write unchanged default fields from the classes into config + continue; + } + entitySchemaConfig.attributes[fieldId] = field; + } + } + + protected mode: "details" | "list" | "general" = "details"; +} diff --git a/src/app/core/admin/admin.module.ts b/src/app/core/admin/admin.module.ts index 88f4f980e2..11fc83eac7 100644 --- a/src/app/core/admin/admin.module.ts +++ b/src/app/core/admin/admin.module.ts @@ -26,15 +26,8 @@ export class AdminModule { [ "AdminEntity", () => - import( - "./admin-entity-details/admin-entity/admin-entity-details.component" - ).then((c) => c.AdminEntityDetailsComponent), - ], - [ - "AdminEntityList", - () => - import("./admin-entity-list/admin-entity-list.component").then( - (c) => c.AdminEntityListComponent, + import("./admin-entity/admin-entity.component").then( + (c) => c.AdminEntityComponent, ), ], ]); diff --git a/src/app/core/admin/admin.routing.ts b/src/app/core/admin/admin.routing.ts index df029751f2..941be0388d 100644 --- a/src/app/core/admin/admin.routing.ts +++ b/src/app/core/admin/admin.routing.ts @@ -16,17 +16,7 @@ export const adminRoutes: Routes = [ }, }, { - path: "entity/:entityType/list", - component: RoutedViewComponent, - data: { - component: "AdminEntityList", - entity: "Config", - requiredPermissionOperation: "update", - }, - canActivate: [EntityPermissionGuard], - }, - { - path: "entity/:entityType/details", + path: "entity/:entityType", component: RoutedViewComponent, data: { component: "AdminEntity", diff --git a/src/app/core/entity-details/entity-details/entity-details.component.html b/src/app/core/entity-details/entity-details/entity-details.component.html index 3192b33ff7..58d5043fcf 100644 --- a/src/app/core/entity-details/entity-details/entity-details.component.html +++ b/src/app/core/entity-details/entity-details/entity-details.component.html @@ -31,7 +31,7 @@
diff --git a/src/app/core/common-components/entities-table/entities-table.component.ts b/src/app/core/common-components/entities-table/entities-table.component.ts index 8871559b8b..5c0ef22b0d 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.ts +++ b/src/app/core/common-components/entities-table/entities-table.component.ts @@ -44,7 +44,6 @@ import { DateDatatype } from "../../basic-datatypes/date/date.datatype"; import { EntitySchemaService } from "../../entity/schema/entity-schema.service"; import { EntityArrayDatatype } from "../../basic-datatypes/entity-array/entity-array.datatype"; import { EntityDatatype } from "../../basic-datatypes/entity/entity.datatype"; -import { EntityFieldsMenuComponent } from "../entity-fields-menu/entity-fields-menu.component"; /** * A simple display component (no logic and transformations) to display a table of entities. @@ -66,7 +65,6 @@ import { EntityFieldsMenuComponent } from "../entity-fields-menu/entity-fields-m MatTableModule, EntityInlineEditActionsComponent, EntityCreateButtonComponent, - EntityFieldsMenuComponent, ], templateUrl: "./entities-table.component.html", styleUrl: "./entities-table.component.scss", diff --git a/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.ts b/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.ts index 7c78712f1e..52a49f7e59 100644 --- a/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.ts +++ b/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.ts @@ -1,4 +1,10 @@ -import { Component, EventEmitter, Input, Output } from "@angular/core"; +import { + Component, + EventEmitter, + Input, + Optional, + Output, +} from "@angular/core"; import { CommonModule } from "@angular/common"; import { FaIconComponent } from "@fortawesome/angular-fontawesome"; import { MatMenuModule } from "@angular/material/menu"; @@ -12,6 +18,7 @@ import { FormFieldConfig, toFormFieldConfig, } from "../entity-form/FormConfig"; +import { EntityFormService } from "../entity-form/entity-form.service"; @Component({ selector: "app-entity-fields-menu", @@ -34,14 +41,24 @@ export class EntityFieldsMenuComponent { @Input() set availableFields(value: ColumnConfig[]) { this._availableFields = value - .map((field) => toFormFieldConfig(field)) - .filter((field) => field.label); + .map((field) => + this.entityFormService && this.entityType + ? this.entityFormService.extendFormFieldConfig(field, this.entityType) + : toFormFieldConfig(field), + ) + .filter((field) => field.label) + // filter duplicates: + .filter( + (item, pos, arr) => arr.findIndex((x) => x.id === item.id) === pos, + ); } _availableFields: FormFieldConfig[]; @Input() activeFields: string[]; @Output() activeFieldsChange = new EventEmitter(); + constructor(@Optional() private entityFormService: EntityFormService) {} + toggleFieldSelection(field: FormFieldConfig) { if (this.activeFields.includes(field.id)) { this.activeFields = this.activeFields.filter((f) => f !== field.id); From 352a24194b55fdbc375cde923dd7bbe6b62e41eb Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Wed, 6 Mar 2024 16:30:42 +0100 Subject: [PATCH 42/58] move admin-section-header --- .../admin-entity-details/admin-entity-details.component.ts | 2 +- .../admin-entity-form/admin-entity-form.component.ts | 4 ++-- .../admin-section-header/admin-section-header.component.html | 0 .../admin-section-header/admin-section-header.component.scss | 0 .../admin-section-header.component.spec.ts | 0 .../admin-section-header/admin-section-header.component.ts | 0 6 files changed, 3 insertions(+), 3 deletions(-) rename src/app/core/admin/{admin-entity-details => building-blocks}/admin-section-header/admin-section-header.component.html (100%) rename src/app/core/admin/{admin-entity-details => building-blocks}/admin-section-header/admin-section-header.component.scss (100%) rename src/app/core/admin/{admin-entity-details => building-blocks}/admin-section-header/admin-section-header.component.spec.ts (100%) rename src/app/core/admin/{admin-entity-details => building-blocks}/admin-section-header/admin-section-header.component.ts (100%) diff --git a/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.ts b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.ts index c6fa2c9228..62c42a337f 100644 --- a/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.ts +++ b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.ts @@ -11,7 +11,7 @@ import { FaIconComponent } from "@fortawesome/angular-fontawesome"; import { MatButtonModule } from "@angular/material/button"; import { EntityTypeLabelPipe } from "../../../common-components/entity-type-label/entity-type-label.pipe"; import { ViewTitleComponent } from "../../../common-components/view-title/view-title.component"; -import { AdminSectionHeaderComponent } from "../admin-section-header/admin-section-header.component"; +import { AdminSectionHeaderComponent } from "../../building-blocks/admin-section-header/admin-section-header.component"; import { AdminEntityFormComponent } from "../admin-entity-form/admin-entity-form.component"; import { AdminEntityPanelComponentComponent } from "../admin-entity-panel-component/admin-entity-panel-component.component"; import { MatTooltipModule } from "@angular/material/tooltip"; diff --git a/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.ts b/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.ts index 213e1cc421..c7270b9438 100644 --- a/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.ts +++ b/src/app/core/admin/admin-entity-details/admin-entity-form/admin-entity-form.component.ts @@ -24,7 +24,7 @@ import { MatTooltipModule } from "@angular/material/tooltip"; import { MatCardModule } from "@angular/material/card"; import { EntityFieldLabelComponent } from "../../../common-components/entity-field-label/entity-field-label.component"; import { EntityFieldEditComponent } from "../../../common-components/entity-field-edit/entity-field-edit.component"; -import { AdminSectionHeaderComponent } from "../admin-section-header/admin-section-header.component"; +import { AdminSectionHeaderComponent } from "../../building-blocks/admin-section-header/admin-section-header.component"; import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; import { FormConfig } from "../../../entity-details/form/form.component"; @@ -34,7 +34,7 @@ import { FormConfig } from "../../../entity-details/form/form.component"; templateUrl: "./admin-entity-form.component.html", styleUrls: [ "./admin-entity-form.component.scss", - "../admin-section-header/admin-section-header.component.scss", + "../../building-blocks/admin-section-header/admin-section-header.component.scss", "../../../common-components/entity-form/entity-form/entity-form.component.scss", ], standalone: true, diff --git a/src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.html b/src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.html similarity index 100% rename from src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.html rename to src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.html diff --git a/src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.scss b/src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.scss similarity index 100% rename from src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.scss rename to src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.scss diff --git a/src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.spec.ts b/src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.spec.ts similarity index 100% rename from src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.spec.ts rename to src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.spec.ts diff --git a/src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.ts b/src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.ts similarity index 100% rename from src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.ts rename to src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.ts From fc01814e82cf93df1a084aaec5e0a19feba087ce Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Wed, 6 Mar 2024 17:01:17 +0100 Subject: [PATCH 43/58] support simplified config without columnGroups --- .../admin-entity-list.component.ts | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts b/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts index b868da0f06..35bd6cba0e 100644 --- a/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts +++ b/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts @@ -53,10 +53,33 @@ export class AdminEntityListComponent implements OnChanges { ngOnChanges(changes: SimpleChanges): void { if (changes.config) { this.config.filters = this.config.filters ?? []; + + this.initColumnGroupsIfNecessary(); + this.initAvailableFields(); } } + /** + * Config allows to not have columnGroups and by default then display all `columns`, + * create an initial columnGroup in this case to allow full editing. + * @private + */ + private initColumnGroupsIfNecessary() { + if (!this.config.columnGroups) { + this.config.columnGroups = { + groups: [ + { + name: "", + columns: this.config.columns.map((c) => + typeof c === "string" ? c : c.id, + ), + }, + ], + }; + } + } + private initAvailableFields() { this.allFields = [ ...this.config.columns, From cf9981fa78f376c10a80d85f240f3a5f07a2b8d4 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Wed, 6 Mar 2024 17:32:22 +0100 Subject: [PATCH 44/58] fix tests --- .../admin-entity-list.component.spec.ts | 5 ++- .../admin-entity-list.component.ts | 9 +++-- .../admin-entity/admin-entity.component.ts | 36 +++++++++++++++---- .../entity-fields-menu.component.spec.ts | 2 ++ src/app/core/entity-list/EntityListConfig.ts | 7 ++-- 5 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/app/core/admin/admin-entity-list/admin-entity-list.component.spec.ts b/src/app/core/admin/admin-entity-list/admin-entity-list.component.spec.ts index d849883e8f..c7bf6b3650 100644 --- a/src/app/core/admin/admin-entity-list/admin-entity-list.component.spec.ts +++ b/src/app/core/admin/admin-entity-list/admin-entity-list.component.spec.ts @@ -4,6 +4,8 @@ import { AdminEntityListComponent } from "./admin-entity-list.component"; import { FilterGeneratorService } from "../../filter/filter-generator/filter-generator.service"; import { FilterService } from "../../filter/filter.service"; import { ActivatedRoute } from "@angular/router"; +import { EntityFormService } from "../../common-components/entity-form/entity-form.service"; +import { FontAwesomeTestingModule } from "@fortawesome/angular-fontawesome/testing"; describe("AdminEntityListComponent", () => { let component: AdminEntityListComponent; @@ -11,11 +13,12 @@ describe("AdminEntityListComponent", () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [AdminEntityListComponent], + imports: [AdminEntityListComponent, FontAwesomeTestingModule], providers: [ { provide: FilterGeneratorService, useValue: {} }, { provide: FilterService, useValue: {} }, { provide: ActivatedRoute, useValue: {} }, + { provide: EntityFormService, useValue: {} }, ], }).compileComponents(); diff --git a/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts b/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts index 35bd6cba0e..825e9b3210 100644 --- a/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts +++ b/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts @@ -47,11 +47,14 @@ export class AdminEntityListComponent implements OnChanges { @Input() entityConstructor: EntityConstructor; @Input() config: EntityListConfig; - allFields: ColumnConfig[]; + allFields: ColumnConfig[] = []; filters: string[]; ngOnChanges(changes: SimpleChanges): void { if (changes.config) { + this.config = this.config ?? { + entity: this.entityConstructor.ENTITY_TYPE, + }; this.config.filters = this.config.filters ?? []; this.initColumnGroupsIfNecessary(); @@ -71,7 +74,7 @@ export class AdminEntityListComponent implements OnChanges { groups: [ { name: "", - columns: this.config.columns.map((c) => + columns: (this.config.columns ?? []).map((c) => typeof c === "string" ? c : c.id, ), }, @@ -82,7 +85,7 @@ export class AdminEntityListComponent implements OnChanges { private initAvailableFields() { this.allFields = [ - ...this.config.columns, + ...(this.config.columns ?? []), ...this.entityConstructor.schema.keys(), ]; this.filters = (this.config.filters ?? []).map((f) => f.id); diff --git a/src/app/core/admin/admin-entity/admin-entity.component.ts b/src/app/core/admin/admin-entity/admin-entity.component.ts index a7ce613914..4ed4c3ae86 100644 --- a/src/app/core/admin/admin-entity/admin-entity.component.ts +++ b/src/app/core/admin/admin-entity/admin-entity.component.ts @@ -107,12 +107,18 @@ export class AdminEntityComponent { ); const newConfig = originalConfig.copy(); - newConfig.data[ - EntityConfigService.getDetailsViewId(this.entityConstructor) - ].config = this.configDetailsView; - newConfig.data[ - EntityConfigService.getListViewId(this.entityConstructor) - ].config = this.configListView; + this.setViewConfig( + newConfig, + EntityConfigService.getDetailsViewId(this.entityConstructor), + this.configDetailsView, + "EntityDetails", + ); + this.setViewConfig( + newConfig, + EntityConfigService.getListViewId(this.entityConstructor), + this.configListView, + "EntityList", + ); this.setEntityConfig(newConfig); await this.entityMapper.save(newConfig); @@ -144,4 +150,22 @@ export class AdminEntityComponent { entitySchemaConfig.attributes[fieldId] = field; } } + + private setViewConfig( + targetConfig, + detailsViewId: string, + viewConfig: EntityDetailsConfig | EntityListConfig, + componentForNewConfig: string, + ) { + if (targetConfig.data[detailsViewId]) { + targetConfig.data[detailsViewId].config = viewConfig; + } else { + // create new config + viewConfig.entity = this.entityType; + targetConfig.data[detailsViewId] = { + component: componentForNewConfig, + config: viewConfig, + } as ViewConfig; + } + } } diff --git a/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.spec.ts b/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.spec.ts index bf6378fe92..63e4432b94 100644 --- a/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.spec.ts +++ b/src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.spec.ts @@ -2,6 +2,7 @@ import { ComponentFixture, TestBed } from "@angular/core/testing"; import { EntityFieldsMenuComponent } from "./entity-fields-menu.component"; import { FontAwesomeTestingModule } from "@fortawesome/angular-fontawesome/testing"; +import { EntityFormService } from "../entity-form/entity-form.service"; describe("EntityFieldsMenuComponent", () => { let component: EntityFieldsMenuComponent; @@ -10,6 +11,7 @@ describe("EntityFieldsMenuComponent", () => { beforeEach(async () => { await TestBed.configureTestingModule({ imports: [EntityFieldsMenuComponent, FontAwesomeTestingModule], + providers: [{ provide: EntityFormService, useValue: null }], }).compileComponents(); fixture = TestBed.createComponent(EntityFieldsMenuComponent); diff --git a/src/app/core/entity-list/EntityListConfig.ts b/src/app/core/entity-list/EntityListConfig.ts index 61e485f976..f2bfc9ac44 100644 --- a/src/app/core/entity-list/EntityListConfig.ts +++ b/src/app/core/entity-list/EntityListConfig.ts @@ -8,7 +8,7 @@ export interface EntityListConfig { /** * Title that is shown on top of the component */ - title: string; + title?: string; /** * Select which entities should be displayed in the table @@ -17,11 +17,12 @@ export interface EntityListConfig { entity?: string; /** - * The columns to be displayed in the table. + * Custom overwrites or additional columns to be displayed in the table. * * If any special columns aside from the entity's fields are needed, add them here. + * Fields of the entity type are available automatically. */ - columns: (FormFieldConfig | string)[]; + columns?: (FormFieldConfig | string)[]; /** * Optional config for which columns are displayed. From 11e1d6feb796f2ac8ae70c0cd13bb1394ffda2ea Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Wed, 6 Mar 2024 17:46:17 +0100 Subject: [PATCH 45/58] code cleanup --- src/app/app.component.ts | 4 ++++ .../entities-table/entities-table.component.scss | 11 ----------- .../entities-table/entities-table.component.spec.ts | 2 -- 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 0fe380b002..17c354473b 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -38,6 +38,10 @@ export class AppComponent { .subscribe(() => this.detectConfigMode()); } + /** + * Switch the layout for certain admin routes to display those fullscreen without app menu and toolbar. + * @private + */ private detectConfigMode() { const currentUrl = this.router.url; this.configFullscreen = currentUrl.startsWith("/admin/entity"); diff --git a/src/app/core/common-components/entities-table/entities-table.component.scss b/src/app/core/common-components/entities-table/entities-table.component.scss index 0e96fa4afd..79afdf72c8 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.scss +++ b/src/app/core/common-components/entities-table/entities-table.component.scss @@ -4,17 +4,6 @@ .table-container { position: relative; // anchor for further absolute positioning of child elements - - padding: 4px; // ensure elevation shadow is visible -} - -.fields-menu { - position: absolute; - top: 4px; - right: 4px; -} -.th-field-menu-spacing:last-child { - padding-right: 48px; } .column-menu { diff --git a/src/app/core/common-components/entities-table/entities-table.component.spec.ts b/src/app/core/common-components/entities-table/entities-table.component.spec.ts index abc0e3468a..ba3887961c 100644 --- a/src/app/core/common-components/entities-table/entities-table.component.spec.ts +++ b/src/app/core/common-components/entities-table/entities-table.component.spec.ts @@ -19,7 +19,6 @@ import { CoreTestingModule } from "../../../utils/core-testing.module"; import { FormDialogService } from "../../form-dialog/form-dialog.service"; import { DateDatatype } from "../../basic-datatypes/date/date.datatype"; import { Router } from "@angular/router"; -import { FontAwesomeTestingModule } from "@fortawesome/angular-fontawesome/testing"; describe("EntitiesTableComponent", () => { let component: EntitiesTableComponent; @@ -38,7 +37,6 @@ describe("EntitiesTableComponent", () => { EntitiesTableComponent, CoreTestingModule, NoopAnimationsModule, - FontAwesomeTestingModule, ], providers: [ { provide: EntityFormService, useValue: mockFormService }, From 0d6a1e598177392cb2ec83f09cdb4dc5d59c0a02 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Wed, 6 Mar 2024 17:46:17 +0100 Subject: [PATCH 46/58] code cleanup --- src/app/app.component.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 17c354473b..ed6f838388 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -25,8 +25,11 @@ import { filter } from "rxjs/operators"; */ @Component({ selector: "app-root", - template: - "", + template: `@if (configFullscreen) { + + } @else { + + }`, }) export class AppComponent { configFullscreen: boolean = false; From 52326d68c701401b48555d363a6c45032837548d Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Thu, 7 Mar 2024 09:05:39 +0100 Subject: [PATCH 47/58] better indentation with latest prettier --- package-lock.json | 288 ++---------------- package.json | 6 +- .../admin-entity/admin-entity.component.html | 30 +- 3 files changed, 44 insertions(+), 280 deletions(-) diff --git a/package-lock.json b/package-lock.json index e7e9481d77..3f03821680 100644 --- a/package-lock.json +++ b/package-lock.json @@ -90,8 +90,8 @@ "babel-loader": "^9.1.3", "cypress": "13.6.0", "eslint": "^8.54.0", - "eslint-config-prettier": "^9.0.0", - "eslint-plugin-prettier": "^5.0.1", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-storybook": "^0.6.15", "jasmine-core": "^5.1.1", "jasmine-spec-reporter": "^7.0.0", @@ -103,7 +103,7 @@ "karma-jasmine-html-reporter": "^2.1.0", "mockdate": "^3.0.5", "ngx-i18nsupport": "^0.17.1", - "prettier": "~3.0.2", + "prettier": "^3.2.5", "react": "^18.2.0", "react-dom": "^18.2.0", "storybook": "^7.5.3", @@ -6202,19 +6202,11 @@ "node": ">=14" } }, - "node_modules/@pkgr/utils": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", - "integrity": "sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==", + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "fast-glob": "^3.3.0", - "is-glob": "^4.0.3", - "open": "^9.1.0", - "picocolors": "^1.0.0", - "tslib": "^2.6.0" - }, "engines": { "node": "^12.20.0 || ^14.18.0 || >=16.0.0" }, @@ -6222,36 +6214,6 @@ "url": "https://opencollective.com/unts" } }, - "node_modules/@pkgr/utils/node_modules/define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@pkgr/utils/node_modules/open": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", - "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", - "dev": true, - "dependencies": { - "default-browser": "^4.0.0", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@radix-ui/number": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.1.tgz", @@ -12608,21 +12570,6 @@ "semver": "^7.0.0" } }, - "node_modules/bundle-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", - "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", - "dev": true, - "dependencies": { - "run-applescript": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -14574,24 +14521,6 @@ "node": ">=0.10.0" } }, - "node_modules/default-browser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", - "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", - "dev": true, - "dependencies": { - "bundle-name": "^3.0.0", - "default-browser-id": "^3.0.0", - "execa": "^7.1.1", - "titleize": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/default-browser-id": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", @@ -14608,116 +14537,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/default-browser/node_modules/execa": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", - "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/default-browser/node_modules/human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", - "dev": true, - "engines": { - "node": ">=14.18.0" - } - }, - "node_modules/default-browser/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/default-gateway": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", @@ -15924,9 +15743,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz", - "integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, "bin": { "eslint-config-prettier": "bin/cli.js" @@ -15936,23 +15755,24 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz", - "integrity": "sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", + "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", "dev": true, "dependencies": { "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.8.5" + "synckit": "^0.8.6" }, "engines": { "node": "^14.18.0 || >=16.0.0" }, "funding": { - "url": "https://opencollective.com/prettier" + "url": "https://opencollective.com/eslint-plugin-prettier" }, "peerDependencies": { "@types/eslint": ">=8.0.0", "eslint": ">=8.0.0", + "eslint-config-prettier": "*", "prettier": ">=3.0.0" }, "peerDependenciesMeta": { @@ -18793,39 +18613,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "dev": true, - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-inside-container/node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-installed-globally": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", @@ -23980,9 +23767,9 @@ } }, "node_modules/prettier": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", - "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -25401,21 +25188,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/run-applescript": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", - "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", - "dev": true, - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/run-async": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", @@ -27073,13 +26845,13 @@ "dev": true }, "node_modules/synckit": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz", - "integrity": "sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==", + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", + "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", "dev": true, "dependencies": { - "@pkgr/utils": "^2.3.1", - "tslib": "^2.5.0" + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -27551,18 +27323,6 @@ "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==", "dev": true }, - "node_modules/titleize": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", - "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", diff --git a/package.json b/package.json index e5136b59e4..f5b7458751 100644 --- a/package.json +++ b/package.json @@ -101,8 +101,8 @@ "babel-loader": "^9.1.3", "cypress": "13.6.0", "eslint": "^8.54.0", - "eslint-config-prettier": "^9.0.0", - "eslint-plugin-prettier": "^5.0.1", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-storybook": "^0.6.15", "jasmine-core": "^5.1.1", "jasmine-spec-reporter": "^7.0.0", @@ -114,7 +114,7 @@ "karma-jasmine-html-reporter": "^2.1.0", "mockdate": "^3.0.5", "ngx-i18nsupport": "^0.17.1", - "prettier": "~3.0.2", + "prettier": "^3.2.5", "react": "^18.2.0", "react-dom": "^18.2.0", "storybook": "^7.5.3", diff --git a/src/app/core/admin/admin-entity/admin-entity.component.html b/src/app/core/admin/admin-entity/admin-entity.component.html index 5017755184..3c81c8e192 100644 --- a/src/app/core/admin/admin-entity/admin-entity.component.html +++ b/src/app/core/admin/admin-entity/admin-entity.component.html @@ -39,19 +39,23 @@
- - - - -
COMING SOON
+ @switch (mode) { + @case ("details") { + + } + @case ("list") { + + } + @case ("general") { +
COMING SOON
+ } + }
From 848f84c7caad6a3f2053282e673fb20b3f0a1aa8 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Thu, 7 Mar 2024 10:26:49 +0100 Subject: [PATCH 48/58] generalize admin-tabs component --- .../admin-entity-details.component.html | 95 +++++++------------ .../admin-entity-details.component.scss | 8 -- .../admin-entity-details.component.spec.ts | 6 -- .../admin-entity-details.component.ts | 22 ++--- .../admin-entity-list.component.html | 72 +++++++------- .../admin-entity-list.component.spec.ts | 7 +- .../admin-entity-list.component.ts | 13 ++- .../admin-tab-template.directive.ts | 24 +++++ .../admin-tabs/admin-tabs.component.html | 38 ++++++++ .../admin-tabs/admin-tabs.component.scss | 8 ++ .../admin-tabs/admin-tabs.component.spec.ts | 41 ++++++++ .../admin-tabs/admin-tabs.component.ts | 79 +++++++++++++++ 12 files changed, 284 insertions(+), 129 deletions(-) create mode 100644 src/app/core/admin/building-blocks/admin-tabs/admin-tab-template.directive.ts create mode 100644 src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.html create mode 100644 src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.scss create mode 100644 src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.spec.ts create mode 100644 src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.ts diff --git a/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html index 668beb7610..cd92b43323 100644 --- a/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html +++ b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html @@ -1,75 +1,44 @@ - - - - - {{ panelConfig.title }} - - - + + +
+
- + [(title)]="componentConfig.title" + (remove)="item.components.splice(j, 1)" + > - -
-
- + - + - - - - - -
- - + > +
-
- - - - - - - +
+ + diff --git a/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.scss b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.scss index e6cd7e82a4..69d82f2a88 100644 --- a/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.scss +++ b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.scss @@ -26,11 +26,3 @@ padding: sizes.$large; margin: sizes.$small; } - -:host ::ng-deep .mat-mdc-tab { - // adjust tab header height to properly display mat-form-field for editing tab label - height: 60px !important; -} -app-admin-section-header { - margin-bottom: -1em; -} diff --git a/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.spec.ts b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.spec.ts index 7837af049d..34b95993f6 100644 --- a/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.spec.ts +++ b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.spec.ts @@ -52,12 +52,6 @@ describe("AdminEntityDetailsComponent", () => { expect(component).toBeTruthy(); }); - it("should add new panel (tab) to config", () => { - component.createPanel(); - - expect(component.config.panels.length).toBe(viewConfig.panels.length + 1); - }); - it("should add new section (component in panel) to config", () => { component.addComponent(component.config.panels[0]); diff --git a/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.ts b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.ts index 62c42a337f..de20e36fcc 100644 --- a/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.ts +++ b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, ViewChild } from "@angular/core"; +import { Component, Input } from "@angular/core"; import { EntityDetailsConfig, Panel, @@ -6,7 +6,7 @@ import { import { EntityConstructor } from "../../../entity/model/entity"; import { DynamicComponent } from "../../../config/dynamic-components/dynamic-component.decorator"; import { NgForOf, NgIf } from "@angular/common"; -import { MatTabGroup, MatTabsModule } from "@angular/material/tabs"; +import { MatTabsModule } from "@angular/material/tabs"; import { FaIconComponent } from "@fortawesome/angular-fontawesome"; import { MatButtonModule } from "@angular/material/button"; import { EntityTypeLabelPipe } from "../../../common-components/entity-type-label/entity-type-label.pipe"; @@ -15,6 +15,8 @@ import { AdminSectionHeaderComponent } from "../../building-blocks/admin-section import { AdminEntityFormComponent } from "../admin-entity-form/admin-entity-form.component"; import { AdminEntityPanelComponentComponent } from "../admin-entity-panel-component/admin-entity-panel-component.component"; import { MatTooltipModule } from "@angular/material/tooltip"; +import { AdminTabsComponent } from "../../building-blocks/admin-tabs/admin-tabs.component"; +import { AdminTabTemplateDirective } from "../../building-blocks/admin-tabs/admin-tab-template.directive"; @DynamicComponent("AdminEntityDetails") @Component({ @@ -34,24 +36,16 @@ import { MatTooltipModule } from "@angular/material/tooltip"; MatTooltipModule, NgForOf, NgIf, + AdminTabsComponent, + AdminTabTemplateDirective, ], }) export class AdminEntityDetailsComponent { @Input() entityConstructor: EntityConstructor; @Input() config: EntityDetailsConfig; - @ViewChild(MatTabGroup) tabGroup: MatTabGroup; - - createPanel() { - const newPanel: Panel = { title: "New Tab", components: [] }; - this.config.panels.push(newPanel); - - // wait until view has actually added the new tab before we can auto-select it - setTimeout(() => { - const newTabIndex = this.config.panels.length - 1; - this.tabGroup.selectedIndex = newTabIndex; - this.tabGroup.focusTab(newTabIndex); - }); + newPanelFactory(): Panel { + return { title: "New Tab", components: [] }; } addComponent(panel: Panel) { diff --git a/src/app/core/admin/admin-entity-list/admin-entity-list.component.html b/src/app/core/admin/admin-entity-list/admin-entity-list.component.html index 3acc241a90..0d5f34d142 100644 --- a/src/app/core/admin/admin-entity-list/admin-entity-list.component.html +++ b/src/app/core/admin/admin-entity-list/admin-entity-list.component.html @@ -7,25 +7,25 @@

Filters

class="drop-list flex-row gap-regular flex-wrap gap-large" > @for (filter of config?.filters; track filter) { -
- +
+ - - - - - + + + + + - -
+ +
}
@@ -44,30 +44,30 @@

Filters

Table Views

- - + +
- @for (col of columnGroup.columns; track col) { -
- + @for (col of item["columns"]; track col) { +
+ - {{ col }} + {{ col }} - -
+ +
}
@@ -75,12 +75,12 @@

Table Views

Drag & drop table column headers and add columns using the button
-
-
+ + diff --git a/src/app/core/admin/admin-entity-list/admin-entity-list.component.spec.ts b/src/app/core/admin/admin-entity-list/admin-entity-list.component.spec.ts index c7bf6b3650..4ba46818ac 100644 --- a/src/app/core/admin/admin-entity-list/admin-entity-list.component.spec.ts +++ b/src/app/core/admin/admin-entity-list/admin-entity-list.component.spec.ts @@ -6,6 +6,7 @@ import { FilterService } from "../../filter/filter.service"; import { ActivatedRoute } from "@angular/router"; import { EntityFormService } from "../../common-components/entity-form/entity-form.service"; import { FontAwesomeTestingModule } from "@fortawesome/angular-fontawesome/testing"; +import { NoopAnimationsModule } from "@angular/platform-browser/animations"; describe("AdminEntityListComponent", () => { let component: AdminEntityListComponent; @@ -13,7 +14,11 @@ describe("AdminEntityListComponent", () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [AdminEntityListComponent, FontAwesomeTestingModule], + imports: [ + AdminEntityListComponent, + FontAwesomeTestingModule, + NoopAnimationsModule, + ], providers: [ { provide: FilterGeneratorService, useValue: {} }, { provide: FilterService, useValue: {} }, diff --git a/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts b/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts index 825e9b3210..5e4f26941c 100644 --- a/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts +++ b/src/app/core/admin/admin-entity-list/admin-entity-list.component.ts @@ -4,7 +4,10 @@ import { FilterComponent } from "../../filter/filter/filter.component"; import { MatTab, MatTabGroup } from "@angular/material/tabs"; import { EntitiesTableComponent } from "../../common-components/entities-table/entities-table.component"; import { EntityConstructor } from "../../entity/model/entity"; -import { EntityListConfig } from "../../entity-list/EntityListConfig"; +import { + EntityListConfig, + GroupConfig, +} from "../../entity-list/EntityListConfig"; import { EntityFieldsMenuComponent } from "../../common-components/entity-fields-menu/entity-fields-menu.component"; import { ColumnConfig } from "../../common-components/entity-form/FormConfig"; import { MatTableModule } from "@angular/material/table"; @@ -19,6 +22,8 @@ import { FaIconComponent } from "@fortawesome/angular-fontawesome"; import { MatIconButton } from "@angular/material/button"; import { MatFormField, MatLabel } from "@angular/material/form-field"; import { MatSelect } from "@angular/material/select"; +import { AdminTabsComponent } from "../building-blocks/admin-tabs/admin-tabs.component"; +import { AdminTabTemplateDirective } from "../building-blocks/admin-tabs/admin-tab-template.directive"; @Component({ selector: "app-admin-entity-list", @@ -39,6 +44,8 @@ import { MatSelect } from "@angular/material/select"; MatFormField, MatLabel, MatSelect, + AdminTabsComponent, + AdminTabTemplateDirective, ], templateUrl: "./admin-entity-list.component.html", styleUrl: "./admin-entity-list.component.scss", @@ -101,6 +108,10 @@ export class AdminEntityListComponent implements OnChanges { ); } + newColumnGroupFactory(): GroupConfig { + return { name: "", columns: [] }; + } + removeItem(array: E[], item: E) { array.splice(array.indexOf(item), 1); } diff --git a/src/app/core/admin/building-blocks/admin-tabs/admin-tab-template.directive.ts b/src/app/core/admin/building-blocks/admin-tabs/admin-tab-template.directive.ts new file mode 100644 index 0000000000..bfc4e1f482 --- /dev/null +++ b/src/app/core/admin/building-blocks/admin-tabs/admin-tab-template.directive.ts @@ -0,0 +1,24 @@ +import { Directive, Input } from "@angular/core"; + +// following guide from https://medium.com/@thomas.laforge/ngtemplateoutlet-type-checking-5d2dcb07a2c6 +// to ensure typing of ng-template context + +interface AdminTabTemplateContext { + $implicit: T; + index: number; +} + +@Directive({ + selector: "ng-template[appAdminTabTemplate]", + standalone: true, +}) +export class AdminTabTemplateDirective { + @Input("appAdminTabTemplate") tabs!: T[]; + + static ngTemplateContextGuard( + dir: AdminTabTemplateDirective, + ctx: unknown, + ): ctx is AdminTabTemplateContext { + return true; + } +} diff --git a/src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.html b/src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.html new file mode 100644 index 0000000000..2e5b7e90cc --- /dev/null +++ b/src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.html @@ -0,0 +1,38 @@ + + + + @if (tabIndex === matTabGroup.selectedIndex) { + + } @else { + + {{ tab["title"] ?? tab["name"] }} + } + + + + + + + + + + + + + + diff --git a/src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.scss b/src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.scss new file mode 100644 index 0000000000..1c7e1539cd --- /dev/null +++ b/src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.scss @@ -0,0 +1,8 @@ + +:host ::ng-deep .mat-mdc-tab { + // adjust tab header height to properly display mat-form-field for editing tab label + height: 60px !important; +} +app-admin-section-header { + margin-bottom: -1em; +} diff --git a/src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.spec.ts b/src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.spec.ts new file mode 100644 index 0000000000..7f26fd0a21 --- /dev/null +++ b/src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.spec.ts @@ -0,0 +1,41 @@ +import { ComponentFixture, TestBed } from "@angular/core/testing"; + +import { AdminTabsComponent } from "./admin-tabs.component"; +import { NoopAnimationsModule } from "@angular/platform-browser/animations"; +import { FontAwesomeTestingModule } from "@fortawesome/angular-fontawesome/testing"; + +describe("AdminTabsComponent", () => { + let component: AdminTabsComponent; + let fixture: ComponentFixture>; + + let tabs: any[]; + + beforeEach(async () => { + tabs = [{ title: "Tab 1" }, { title: "Tab 2" }]; + + await TestBed.configureTestingModule({ + imports: [ + AdminTabsComponent, + NoopAnimationsModule, + FontAwesomeTestingModule, + ], + }).compileComponents(); + + fixture = TestBed.createComponent(AdminTabsComponent); + component = fixture.componentInstance; + + component.tabs = tabs; + + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); + + it("should add new tab to config", () => { + component.createTab(); + + expect(component.tabs.length).toBe(3); + }); +}); diff --git a/src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.ts b/src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.ts new file mode 100644 index 0000000000..831c3468d7 --- /dev/null +++ b/src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.ts @@ -0,0 +1,79 @@ +import { + Component, + ContentChild, + Input, + TemplateRef, + ViewChild, +} from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { AdminEntityFormComponent } from "../../admin-entity-details/admin-entity-form/admin-entity-form.component"; +import { AdminEntityPanelComponentComponent } from "../../admin-entity-details/admin-entity-panel-component/admin-entity-panel-component.component"; +import { AdminSectionHeaderComponent } from "../admin-section-header/admin-section-header.component"; +import { FaIconComponent } from "@fortawesome/angular-fontawesome"; +import { MatButton } from "@angular/material/button"; +import { + MatTab, + MatTabContent, + MatTabGroup, + MatTabLabel, +} from "@angular/material/tabs"; +import { MatTooltip } from "@angular/material/tooltip"; +import { AdminTabTemplateDirective } from "./admin-tab-template.directive"; + +/** + * Building block for drag&drop form builder to let an admin user manage multiple tabs. + * + * Provide a template for the tab content when using this component: + + + + {{ item.title }} + + + */ +@Component({ + selector: "app-admin-tabs", + standalone: true, + imports: [ + CommonModule, + AdminEntityFormComponent, + AdminEntityPanelComponentComponent, + AdminSectionHeaderComponent, + FaIconComponent, + MatButton, + MatTab, + MatTabContent, + MatTabGroup, + MatTabLabel, + MatTooltip, + AdminTabTemplateDirective, + ], + templateUrl: "./admin-tabs.component.html", + styleUrl: "./admin-tabs.component.scss", +}) +export class AdminTabsComponent< + E extends { title: string } | { name: string }, +> { + @Input() tabs: E[]; + @Input() newTabFactory: () => E = () => ({ title: "" }) as E; + + @ContentChild(AdminTabTemplateDirective, { read: TemplateRef }) + tabTemplate: TemplateRef; + + @ViewChild(MatTabGroup) tabGroup: MatTabGroup; + + createTab() { + const newTab = this.newTabFactory(); + this.tabs.push(newTab); + + // wait until view has actually added the new tab before we can auto-select it + setTimeout(() => { + const newTabIndex = this.tabs.length - 1; + this.tabGroup.selectedIndex = newTabIndex; + this.tabGroup.focusTab(newTabIndex); + }); + } +} From 9d97dcc190737cf17e59fb8d5b8631da98e35886 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Thu, 7 Mar 2024 10:28:33 +0100 Subject: [PATCH 49/58] code cleanup --- src/app/app.component.ts | 4 ++-- .../activity-card.component.html | 4 ++-- .../attendance-calendar.component.html | 21 +++++++++++++------ .../admin-entity/admin-entity.component.ts | 10 +++++++-- src/app/core/export/query.service.ts | 7 +++---- .../list-filter/list-filter.component.html | 14 ++++++------- .../latest-changes/latest-changes.service.ts | 6 +++--- 7 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index ed6f838388..ac1e213d7c 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -26,9 +26,9 @@ import { filter } from "rxjs/operators"; @Component({ selector: "app-root", template: `@if (configFullscreen) { - + } @else { - + }`, }) export class AppComponent { diff --git a/src/app/child-dev-project/attendance/activity-card/activity-card.component.html b/src/app/child-dev-project/attendance/activity-card/activity-card.component.html index 8615c04c21..720bce2440 100644 --- a/src/app/child-dev-project/attendance/activity-card/activity-card.component.html +++ b/src/app/child-dev-project/attendance/activity-card/activity-card.component.html @@ -8,8 +8,8 @@ - {{ event.children.length }} { event.children.length, plural, one - {participant} other {participants} } + {{ event.children.length }} + {event.children.length, plural, one {participant} other {participants}} / diff --git a/src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html b/src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html index d827a6d481..c84825c978 100644 --- a/src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html +++ b/src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html @@ -48,15 +48,21 @@

> All excused (out of {{ selectedEvent.children.length }} - { selectedEvent.children.length, plural, one {participant} other - {participants} } ) + {selectedEvent.children.length, plural, + one {participant} + other {participants} + } + )
{{ selectedEventStats.average | percent: "1.0-0" }} attended (of {{ selectedEvent.children.length }} - { selectedEvent.children.length, plural, one {participant} other - {participants} }) + {selectedEvent.children.length, plural, + one {participant} + other {participants} + + })
class="unknown-status-notice" > {{ selectedEventStats.excludedUnknown }} - { selectedEventStats.excludedUnknown, plural, one {participant} other - {participants} } without recorded status + {selectedEventStats.excludedUnknown, plural, + one {participant} + other {participants} + } + without recorded status
+ + + +

+ codo ist als Software bereits genau auf die Betreuung von Patenschaften + zugeschnitten. Unsere langjährige Erfahrungen der BürgerStiftung Hamburg + und Stiftung Bürgermut in der Betreuung solcher Projekte sind die Basis + für codo und das System wurde in enger Zusammenarbeit mit einer + Fokusgruppe von Projekten entwickelt.
+ Damit codo optimal auf euer Projekt passt, könnt ihr innerhalb der + vorhandenen Datenstrukturen zusätzliche Felder und Formularbereiche + individuell anpassen. +

+ + + + + + + + +
+ + +

+ Falls ihr bestehende Daten bisheriger Patenschaften habt, könnt ihr diese + einfach importieren. Dazu müssen diese aus Excel im ".csv"-Format + abgespeichert werden. Das Import-Modul von codo hilft euch dabei, die + Tabellen den passenden Datenfeldern zuzuordnen. +

+ +
+ +
+ + +
+ + +

+ Ihr könnt in codo sehr einfach als Team zusammenarbeiten. Die Daten sind + für alle synchronisiert und auf dem aktuellsten Stand. Weitere + Nutzer-Accounts könnt ihr jederzeit selbst erstellen. +

+ +
+ +
+ + +
+ + +

+ Mehr gibt es eigentlich nicht zu beachten. Ihr könnt jetzt loslegen und + codo ausprobieren. Bei Fragen oder Problemen wendet euch gerne an xxx.de +

+ +

Ein paar Tipps und mögliche erste Schritte zum Abschluss: ...

+ + +
+ diff --git a/src/app/core/admin/setup-wizard/setup-wizard.component.scss b/src/app/core/admin/setup-wizard/setup-wizard.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/core/admin/setup-wizard/setup-wizard.component.spec.ts b/src/app/core/admin/setup-wizard/setup-wizard.component.spec.ts new file mode 100644 index 0000000000..9d21bad33e --- /dev/null +++ b/src/app/core/admin/setup-wizard/setup-wizard.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SetupWizardComponent } from './setup-wizard.component'; + +describe('SetupWizardComponent', () => { + let component: SetupWizardComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [SetupWizardComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(SetupWizardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/core/admin/setup-wizard/setup-wizard.component.ts b/src/app/core/admin/setup-wizard/setup-wizard.component.ts new file mode 100644 index 0000000000..27e2af3e1a --- /dev/null +++ b/src/app/core/admin/setup-wizard/setup-wizard.component.ts @@ -0,0 +1,24 @@ +import { Component } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { MatStep, MatStepper, MatStepperNext } from "@angular/material/stepper"; +import { MatActionList, MatListItem } from "@angular/material/list"; +import { RouterLink } from "@angular/router"; +import { MatButton } from "@angular/material/button"; + +@Component({ + selector: "app-setup-wizard", + standalone: true, + imports: [ + CommonModule, + MatStepper, + MatStep, + MatActionList, + MatListItem, + RouterLink, + MatButton, + MatStepperNext, + ], + templateUrl: "./setup-wizard.component.html", + styleUrl: "./setup-wizard.component.scss", +}) +export class SetupWizardComponent {} diff --git a/src/app/core/admin/setup-wizard/setup-wizard.stories.ts b/src/app/core/admin/setup-wizard/setup-wizard.stories.ts new file mode 100644 index 0000000000..7cf01b361a --- /dev/null +++ b/src/app/core/admin/setup-wizard/setup-wizard.stories.ts @@ -0,0 +1,30 @@ +import { + applicationConfig, + Meta, + moduleMetadata, + StoryFn, +} from "@storybook/angular"; +import { importProvidersFrom } from "@angular/core"; +import { StorybookBaseModule } from "../../../utils/storybook-base.module"; +import { SetupWizardComponent } from "./setup-wizard.component"; + +export default { + title: "Core/Admin/Setup Wizard", + component: SetupWizardComponent, + decorators: [ + applicationConfig({ + providers: [importProvidersFrom(StorybookBaseModule)], + }), + moduleMetadata({ + imports: [SetupWizardComponent], + }), + ], +} as Meta; + +const Template: StoryFn = (args) => ({ + component: SetupWizardComponent, + props: args, +}); + +export const Primary = Template.bind({}); +Primary.args = {}; diff --git a/src/app/core/ui/ui/ui.component.html b/src/app/core/ui/ui/ui.component.html index 5956669a07..b4f0c6c4cf 100644 --- a/src/app/core/ui/ui/ui.component.html +++ b/src/app/core/ui/ui/ui.component.html @@ -82,6 +82,16 @@
+ +
diff --git a/src/app/core/ui/ui/ui.component.ts b/src/app/core/ui/ui/ui.component.ts index dd77edbe89..c9b50b3a50 100644 --- a/src/app/core/ui/ui/ui.component.ts +++ b/src/app/core/ui/ui/ui.component.ts @@ -16,16 +16,14 @@ */ import { Component, ViewChild } from "@angular/core"; -import { Title } from "@angular/platform-browser"; import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; import { MatDrawerMode, MatSidenavModule } from "@angular/material/sidenav"; -import { ConfigService } from "../../config/config.service"; import { ScreenWidthObserver } from "../../../utils/media/screen-size-observer.service"; import { MatToolbarModule } from "@angular/material/toolbar"; import { NgIf } from "@angular/common"; import { MatButtonModule } from "@angular/material/button"; import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; -import { Router, RouterLink, RouterOutlet } from "@angular/router"; +import { RouterLink, RouterOutlet } from "@angular/router"; import { Angulartics2Module } from "angulartics2"; import { SearchComponent } from "../search/search.component"; import { SyncStatusComponent } from "../sync-status/sync-status/sync-status.component"; @@ -79,10 +77,7 @@ export class UiComponent { siteSettings = new SiteSettings(); constructor( - private titleService: Title, - private configService: ConfigService, private screenWidthObserver: ScreenWidthObserver, - private router: Router, private siteSettingsService: SiteSettingsService, private loginState: LoginStateSubject, private sessionManager: SessionManagerService, From b7dc4e44aff5bf4d24bda6a22991afe502af958b Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Thu, 7 Mar 2024 18:09:02 +0100 Subject: [PATCH 51/58] layout tuning --- .../admin-entity-details.component.html | 4 ++++ .../admin-entity-list.component.html | 6 ++++-- .../admin-entity-list.component.scss | 4 ++++ .../admin-entity-list/admin-entity-list.component.ts | 2 ++ .../admin/admin-entity/admin-entity.component.html | 2 +- .../admin/admin-entity/admin-entity.component.scss | 12 +++++++++++- .../view-title/view-title.component.ts | 2 +- 7 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html index cd92b43323..f5f258e264 100644 --- a/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html +++ b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html @@ -1,3 +1,7 @@ + + <Name of displayed {{ this.entityConstructor?.label }}> + +
diff --git a/src/app/core/admin/admin-entity-list/admin-entity-list.component.html b/src/app/core/admin/admin-entity-list/admin-entity-list.component.html index 0d5f34d142..2efe59917e 100644 --- a/src/app/core/admin/admin-entity-list/admin-entity-list.component.html +++ b/src/app/core/admin/admin-entity-list/admin-entity-list.component.html @@ -1,4 +1,7 @@ -

Filters

+ + {{ entityConstructor.labelPlural }} + +
Filters

-

Table Views

- + Date: Tue, 12 Mar 2024 17:37:49 +0100 Subject: [PATCH 52/58] translations and styling --- .../admin-entity-list.component.html | 10 +- .../admin-entity-list.component.scss | 6 + .../admin-entity/admin-entity.component.html | 19 +- .../entity-field-label.component.html | 2 +- src/assets/locale/messages.de.xlf | 336 +++++++++++------- src/assets/locale/messages.fr.xlf | 330 +++++++++++------ src/assets/locale/messages.it.xlf | 336 +++++++++++------- src/assets/locale/messages.xlf | 336 +++++++++++------- 8 files changed, 878 insertions(+), 497 deletions(-) diff --git a/src/app/core/admin/admin-entity-list/admin-entity-list.component.html b/src/app/core/admin/admin-entity-list/admin-entity-list.component.html index 2efe59917e..5fa79af680 100644 --- a/src/app/core/admin/admin-entity-list/admin-entity-list.component.html +++ b/src/app/core/admin/admin-entity-list/admin-entity-list.component.html @@ -32,7 +32,7 @@ }
-
+
Drag & drop filters and add filters using the - {{ col }} + + -
+
Drag & drop table column headers and add columns using the
- - +
@@ -24,15 +17,21 @@ Details View & Fields - + List View General Settings diff --git a/src/app/core/common-components/entity-field-label/entity-field-label.component.html b/src/app/core/common-components/entity-field-label/entity-field-label.component.html index 8d2ba65d73..a4282d1a85 100644 --- a/src/app/core/common-components/entity-field-label/entity-field-label.component.html +++ b/src/app/core/common-components/entity-field-label/entity-field-label.component.html @@ -1,3 +1,3 @@ - {{ _field?.label }} + {{ _field?.label ?? _field?.id }} diff --git a/src/assets/locale/messages.de.xlf b/src/assets/locale/messages.de.xlf index bd4740e4b9..8eabbd84a3 100644 --- a/src/assets/locale/messages.de.xlf +++ b/src/assets/locale/messages.de.xlf @@ -173,56 +173,63 @@ 33 - - All excused (out of ) + + All excused (out of ) Alle entschuldigt (von ) src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 48,53 + 48,56 How many participants attended at an event (in percent) Event participants - + {VAR_PLURAL, plural, one {participant} other {participants}} - {VAR_PLURAL, plural, one {Teilnehmer:in} other {Teilnehmer:innen}} + {VAR_PLURAL, plural, one {Teilnehmer} other {Teilnehmer}} src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 51 + 51,54 src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 58 + 61,65 - - attended (of ) + + attended (of ) haben teilgenommen (von ) src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 54 + 57,66 - - without recorded status + + without recorded status ohne aufgenommenen Status src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 65,69 + 71,78 How many children are without a status Unknown status - + {VAR_PLURAL, plural, one {participant} other {participants}} {VAR_PLURAL, plural, one {Teilnehmer} other {Teilnehmer}} src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 67 + 73,76 @@ -233,7 +240,7 @@ Show Details Button src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 81 + 90 @@ -243,7 +250,7 @@ No Events src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 91 + 100 @@ -254,7 +261,7 @@ Add New Event Button src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 105 + 114 @@ -1343,6 +1350,10 @@ src/app/core/admin/admin-entity-details/admin-entity-field/admin-entity-field.component.html 182 + + src/app/core/admin/admin-entity/admin-entity.component.html + 11 + src/app/core/basic-datatypes/date/date-import-config/date-import-config.component.html 38 @@ -1438,11 +1449,11 @@ link to another record verknüpfe mit einem anderen Eintrag + datatype-label src/app/core/basic-datatypes/entity/entity.datatype.ts - 37 + 36 - datatype-label month (date without day of month) @@ -3450,6 +3461,20 @@ 39 + + Add Section + Sektion hinzufügen + + src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html + 39,45 + + Configure Field "" Feld "" konfigurieren @@ -3637,79 +3662,140 @@ 4,6 - - Editing details page for "" records - Bearbeite Detailansicht für "" Einträge - - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 2,4 + + Drag & drop filters and add filters using the button + Verschieben Sie Filter per Drag & Drop und fügen Sie neue Filter über den Button hinzu + + src/app/core/admin/admin-entity-list/admin-entity-list.component.html + 35,45 + + + + Drag & drop table column headers and add columns using the button + Verschieben Sie Tabellen-Spalten per Drag & Drop und fügen Sie neue Spalten über den Button hinzu + + src/app/core/admin/admin-entity-list/admin-entity-list.component.html + 76,85 + + + + Editing data structure for "" records + Datenstruktur für ""-Einträge anpassen + + src/app/core/admin/admin-entity/admin-entity.component.html + 3,5 page title - - Add Section - Sektion hinzufügen + + Save + Speichern - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 72 + src/app/core/admin/admin-entity/admin-entity.component.html + 8,10 + + Details View & Fields + Detail-Ansicht & Felder + + src/app/core/admin/admin-entity/admin-entity.component.html + 21,23 + + admin entity: nav item + + + List View + Listen-Ansicht + + src/app/core/admin/admin-entity/admin-entity.component.html + 28,30 + + admin entity: nav item + + + General Settings + Allgemeine Einstellungen + + src/app/core/admin/admin-entity/admin-entity.component.html + 35,37 + + admin entity: nav item + add a new tab neuen Tab hinzufügen - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 89 + src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.html + 30 Configuration updated Konfiguration aktualisiert + Save config confirmation message - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.ts - 105 + src/app/core/admin/admin-entity/admin-entity.component.ts + 132 - Save config confirmation message New Section Neue Sektion + Default title - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.ts - 152 + src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.ts + 53 - Default title (no title) (kein Titel) + Placeholder for entering a title - src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.html + src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.html 8 - Placeholder for entering a title Delete Section? Sektion löschen? + Admin UI - Delete Section Confirmation Title - src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.ts + src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.ts 58 - Admin UI - Delete Section Confirmation Title Do you really want to delete this section with all its content? Sind Sie sicher, dass Sie diese Sektion mit alles darin befindliche löschen wollen? + Admin UI - Delete Section Confirmation Text - src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.ts + src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.ts 59 - Admin UI - Delete Section Confirmation Text Conflicting Entity: @@ -4020,7 +4106,7 @@ 54 - src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.ts + src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.ts 47 @@ -4064,7 +4150,7 @@ src/app/child-dev-project/notes/model/note.ts - 166 + 165 @@ -4149,7 +4235,7 @@ src/app/child-dev-project/notes/model/note.ts - 175 + 174 src/app/core/config/config-fix.ts @@ -4249,12 +4335,12 @@ 46 - + {VAR_PLURAL, plural, one {participant} other {participants}} {VAR_PLURAL, plural, one {Teilnehmer} other {Teilnehmer}} src/app/child-dev-project/attendance/activity-card/activity-card.component.html - 11,12 + 12 @@ -4671,7 +4757,7 @@ Label for adding an option in a dropdown src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html - 52 + 65 @@ -4866,11 +4952,19 @@ Edit Data Structure - Bearbeite Datenstruktur + Datenstruktur anpassen src/app/core/entity-details/entity-details/entity-details.component.html 41 + + src/app/core/entity-list/entity-list/entity-list.component.html + 232 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 232 + Save the new record to create it before accessing other details @@ -4957,30 +5051,30 @@ 200 - - Current user is not permitted to save these changes - Sie haben nicht die nötigen Berechtigungen um die Änderungen zu speicher + + Could not save : + Speichern von fehlgeschlagen: src/app/core/common-components/entity-form/entity-form.service.ts - 245 + 253 - - Could not save : - Speichern von fehlgeschlagen: + + Current user is not permitted to save these changes: + Ihr Account hat nicht die nötigen Berechtigungen um diese Änderungen zu speichern: src/app/core/common-components/entity-form/entity-form.service.ts - 256 + 281,283 Save Speichern - Button label - - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 12 - + Save button for forms src/app/core/user/user-security/user-security.component.html 60 @@ -4989,11 +5083,7 @@ Cancel Abbrechen - Button label - - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 15 - + Cancel button for forms src/app/core/user/user-security/user-security.component.html 69 @@ -5211,7 +5301,7 @@ the - + Definite article singular src/app/core/entity/entity-actions/entity-actions.service.ts @@ -5422,11 +5512,11 @@ Aktionen auf allen markierten Datensätzen: src/app/core/entity-list/entity-list/entity-list.component.html - 228 + 240 src/app/core/entity-list/entity-list/entity-list.component.html - 228 + 240 @@ -5434,11 +5524,11 @@ Zeilen auswählen, um Aktion auf mehreren Datensätzen auszuführen src/app/core/entity-list/entity-list/entity-list.component.html - 232 + 244 src/app/core/entity-list/entity-list/entity-list.component.html - 232 + 244 @@ -5447,25 +5537,25 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 241 + 253 src/app/core/entity-list/entity-list/entity-list.component.html - 241 + 253 Anonymize Anonymisieren + bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 250,252 + 262 src/app/core/entity-list/entity-list/entity-list.component.html - 250,252 + 262 - bulk action button Delete @@ -5473,11 +5563,11 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 259 + 271 src/app/core/entity-list/entity-list/entity-list.component.html - 259 + 271 @@ -5486,11 +5576,11 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 268 + 280 src/app/core/entity-list/entity-list/entity-list.component.html - 268 + 280 @@ -5498,11 +5588,11 @@ Abbrechen src/app/core/entity-list/entity-list/entity-list.component.html - 272 + 284 src/app/core/entity-list/entity-list/entity-list.component.html - 272 + 284 @@ -5586,18 +5676,18 @@ context Add User(s) Placeholder for input to add entities - src/app/core/basic-datatypes/entity-array/edit-entity-array/edit-entity-array.component.ts - 27 + src/app/core/basic-datatypes/entity-array/edit-entity/edit-entity.component.ts + 36 link to other records (multi-select) mit anderem Datentyp verknüpfen (mehrfach Auswahl) + datatype-label src/app/core/basic-datatypes/entity-array/entity-array.datatype.ts - 35 + 34 - datatype-label Select matching property @@ -5630,7 +5720,7 @@ Erstelle eine neue Option src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.ts - 213 + 274 @@ -5638,7 +5728,7 @@ Wollen sie die neue Option "" erstellen? src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.ts - 214 + 275 @@ -5766,21 +5856,11 @@ remove entfernen - tooltip for remove icon-button + tooltip for remove icon on chips of dropdown item - src/app/core/common-components/entity-select/entity-select.component.html - 33 - - - - Also show inactive - Auch inaktive anzeigen - - src/app/core/common-components/entity-select/entity-select.component.html - 67,69 + src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html + 112 - e.g. include inactive children - Label for checkbox loading... @@ -5788,7 +5868,7 @@ A placeholder for the input element when select options are not loaded yet src/app/core/common-components/entity-select/entity-select.component.ts - 54 + 51 @@ -5817,6 +5897,14 @@ 24 + + Add or remove visible fields + Angezeigte Felder hinzufügen oder entfernen + + src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.html + 4 + + in total @@ -6339,6 +6427,16 @@ 19 + + Also show inactive + Auch inaktive anzeigen + + src/app/core/common-components/entity-select/entity-select.component.html + 28,29 + + e.g. include inactive children + Label for checkbox + Email Email @@ -7306,7 +7404,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 196 + 205 @@ -7315,7 +7413,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 162 + 171 @@ -7324,7 +7422,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 167 + 176 @@ -7333,7 +7431,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 172 + 181 @@ -7341,7 +7439,7 @@ Alle src/app/features/todos/todo-list/todo-list.component.ts - 175 + 184 @@ -7349,7 +7447,7 @@ fällige Aufgaben src/app/features/todos/todo-list/todo-list.component.ts - 177 + 186 diff --git a/src/assets/locale/messages.fr.xlf b/src/assets/locale/messages.fr.xlf index 59d180611d..49dfdabaef 100644 --- a/src/assets/locale/messages.fr.xlf +++ b/src/assets/locale/messages.fr.xlf @@ -260,12 +260,12 @@ 46 - + {VAR_PLURAL, plural, one {participant} other {participants}} {VAR_PLURAL, plural, one {participant} other {participants}} src/app/child-dev-project/attendance/activity-card/activity-card.component.html - 11,12 + 12 @@ -465,58 +465,65 @@ 33 - - All excused (out of ) + + All excused (out of ) All excused (out of ) src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 48,53 + 48,56 How many participants attended at an event (in percent) Event participants - + {VAR_PLURAL, plural, one {participant} other {participants}} {VAR_PLURAL, plural, one {participant} other {participants}} src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 51 + 51,54 src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 58 + 61,65 - - attended (of ) + + attended (of ) présents (sur ) src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 54 + 57,66 - - without recorded status + + without recorded status sans statut enregistré src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 65,69 + 71,78 How many children are without a status Unknown status - + {VAR_PLURAL, plural, one {participant} other {participants}} {VAR_PLURAL, plural, one {participant} other {participants}} src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 67 + 73,76 @@ -527,7 +534,7 @@ Show Details Button src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 81 + 90 @@ -537,7 +544,7 @@ No Events src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 91 + 100 @@ -548,7 +555,7 @@ Add New Event Button src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 105 + 114 @@ -875,7 +882,7 @@ 54 - src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.ts + src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.ts 47 @@ -919,7 +926,7 @@ src/app/child-dev-project/notes/model/note.ts - 166 + 165 @@ -1222,7 +1229,7 @@ src/app/child-dev-project/notes/model/note.ts - 175 + 174 src/app/core/config/config-fix.ts @@ -2514,6 +2521,10 @@ src/app/core/admin/admin-entity-details/admin-entity-field/admin-entity-field.component.html 182 + + src/app/core/admin/admin-entity/admin-entity.component.html + 11 + src/app/core/basic-datatypes/date/date-import-config/date-import-config.component.html 38 @@ -2609,11 +2620,11 @@ link to another record link to another record + datatype-label src/app/core/basic-datatypes/entity/entity.datatype.ts - 37 + 36 - datatype-label month (date without day of month) @@ -2941,6 +2952,20 @@ 39 + + Add Section + Add Section + + src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html + 39,45 + + Configure Field "" Configure Field "" @@ -3128,79 +3153,140 @@ 4,6 - - Editing details page for "" records - Editing details page for "" records - - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 2,4 + + Drag & drop filters and add filters using the button + Drag & drop filters and add filters using the button + + src/app/core/admin/admin-entity-list/admin-entity-list.component.html + 35,45 + + + + Drag & drop table column headers and add columns using the button + Drag & drop table column headers and add columns using the button + + src/app/core/admin/admin-entity-list/admin-entity-list.component.html + 76,85 + + + + Editing data structure for "" records + Editing data structure for "" records + + src/app/core/admin/admin-entity/admin-entity.component.html + 3,5 page title - - Add Section - Add Section + + Save + Sauvegarder - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 72 + src/app/core/admin/admin-entity/admin-entity.component.html + 8,10 + + + + Details View & Fields + Details View & Fields + + src/app/core/admin/admin-entity/admin-entity.component.html + 21,23 + + admin entity: nav item + + + List View + List View + + src/app/core/admin/admin-entity/admin-entity.component.html + 28,30 + + admin entity: nav item + + + General Settings + General Settings + + src/app/core/admin/admin-entity/admin-entity.component.html + 35,37 + admin entity: nav item add a new tab add a new tab - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 89 + src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.html + 30 Configuration updated Configuration updated + Save config confirmation message - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.ts - 105 + src/app/core/admin/admin-entity/admin-entity.component.ts + 132 - Save config confirmation message New Section New Section + Default title - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.ts - 152 + src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.ts + 53 - Default title (no title) (no title) + Placeholder for entering a title - src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.html + src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.html 8 - Placeholder for entering a title Delete Section? Delete Section? + Admin UI - Delete Section Confirmation Title - src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.ts + src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.ts 58 - Admin UI - Delete Section Confirmation Title Do you really want to delete this section with all its content? Do you really want to delete this section with all its content? + Admin UI - Delete Section Confirmation Text - src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.ts + src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.ts 59 - Admin UI - Delete Section Confirmation Text Conflicting Entity: @@ -4359,7 +4445,7 @@ Label for adding an option in a dropdown src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html - 52 + 65 @@ -4408,7 +4494,7 @@ Create new option src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.ts - 213 + 274 @@ -4416,7 +4502,7 @@ Do you want to create the new option ""? src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.ts - 214 + 275 @@ -4601,6 +4687,14 @@ src/app/core/entity-details/entity-details/entity-details.component.html 41 + + src/app/core/entity-list/entity-list/entity-list.component.html + 232 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 232 + Save the new record to create it before accessing other details @@ -4687,20 +4781,24 @@ 200 - - Current user is not permitted to save these changes - Current user is not permitted to save these changes + + Could not save : + Echec pour sauvegarder : src/app/core/common-components/entity-form/entity-form.service.ts - 245 + 253 - - Could not save : - Echec pour sauvegarder : + + Current user is not permitted to save these changes: + Current user is not permitted to save these changes: src/app/core/common-components/entity-form/entity-form.service.ts - 256 + 281,283 @@ -4849,11 +4947,11 @@ Actions on selected records: src/app/core/entity-list/entity-list/entity-list.component.html - 228 + 240 src/app/core/entity-list/entity-list/entity-list.component.html - 228 + 240 @@ -4861,11 +4959,11 @@ Select rows for an action on multiple records src/app/core/entity-list/entity-list/entity-list.component.html - 232 + 244 src/app/core/entity-list/entity-list/entity-list.component.html - 232 + 244 @@ -4874,25 +4972,25 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 241 + 253 src/app/core/entity-list/entity-list/entity-list.component.html - 241 + 253 Anonymize Anonymize + bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 250,252 + 262 src/app/core/entity-list/entity-list/entity-list.component.html - 250,252 + 262 - bulk action button Delete @@ -4900,11 +4998,11 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 259 + 271 src/app/core/entity-list/entity-list/entity-list.component.html - 259 + 271 @@ -4913,11 +5011,11 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 268 + 280 src/app/core/entity-list/entity-list/entity-list.component.html - 268 + 280 @@ -4925,11 +5023,11 @@ Annuler src/app/core/entity-list/entity-list/entity-list.component.html - 272 + 284 src/app/core/entity-list/entity-list/entity-list.component.html - 272 + 284 @@ -5004,18 +5102,18 @@ context Add User(s) Placeholder for input to add entities - src/app/core/basic-datatypes/entity-array/edit-entity-array/edit-entity-array.component.ts - 27 + src/app/core/basic-datatypes/entity-array/edit-entity/edit-entity.component.ts + 36 link to other records (multi-select) link to other records (multi-select) + datatype-label src/app/core/basic-datatypes/entity-array/entity-array.datatype.ts - 35 + 34 - datatype-label Select matching property @@ -5097,21 +5195,11 @@ remove remove - tooltip for remove icon-button - - src/app/core/common-components/entity-select/entity-select.component.html - 33 - - - - Also show inactive - Also show inactive + tooltip for remove icon on chips of dropdown item - src/app/core/common-components/entity-select/entity-select.component.html - 67,69 + src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html + 112 - e.g. include inactive children - Label for checkbox loading... @@ -5119,7 +5207,7 @@ A placeholder for the input element when select options are not loaded yet src/app/core/common-components/entity-select/entity-select.component.ts - 54 + 51 @@ -5148,6 +5236,14 @@ 24 + + Add or remove visible fields + Add or remove visible fields + + src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.html + 4 + + in total @@ -5998,6 +6094,16 @@ 19 + + Also show inactive + Also show inactive + + src/app/core/common-components/entity-select/entity-select.component.html + 28,29 + + e.g. include inactive children + Label for checkbox + Email Email @@ -6471,11 +6577,7 @@ Save Sauvegarder - Button label - - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 12 - + Save button for forms src/app/core/user/user-security/user-security.component.html 60 @@ -6484,11 +6586,7 @@ Cancel Annuler - Button label - - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 15 - + Cancel button for forms src/app/core/user/user-security/user-security.component.html 69 @@ -7378,7 +7476,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 196 + 205 @@ -7387,7 +7485,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 162 + 171 @@ -7396,7 +7494,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 167 + 176 @@ -7405,7 +7503,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 172 + 181 @@ -7413,7 +7511,7 @@ Any src/app/features/todos/todo-list/todo-list.component.ts - 175 + 184 @@ -7421,7 +7519,7 @@ Tasks due src/app/features/todos/todo-list/todo-list.component.ts - 177 + 186 diff --git a/src/assets/locale/messages.it.xlf b/src/assets/locale/messages.it.xlf index 0647d17d2e..a36527377b 100644 --- a/src/assets/locale/messages.it.xlf +++ b/src/assets/locale/messages.it.xlf @@ -79,12 +79,12 @@ 46 - + {VAR_PLURAL, plural, one {participant} other {participants}} {VAR_PLURAL, plural, one {participant} other {participants}} src/app/child-dev-project/attendance/activity-card/activity-card.component.html - 11,12 + 12 @@ -284,56 +284,63 @@ 33 - - All excused (out of ) + + All excused (out of ) All excused (out of ) src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 48,53 + 48,56 How many participants attended at an event (in percent) Event participants - + {VAR_PLURAL, plural, one {participant} other {participants}} - {VAR_PLURAL, plural, one {participant} other {participants}} + {VAR_PLURAL, plural, one {participant} other {participants}} src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 51 + 51,54 src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 58 + 61,65 - - attended (of ) - attended (of ) + + attended (of ) + attended (of ) src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 54 + 57,66 - - without recorded status + + without recorded status without recorded status src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 65,69 + 71,78 How many children are without a status Unknown status - + {VAR_PLURAL, plural, one {participant} other {participants}} - {VAR_PLURAL, plural, one {participant} other {participants}} + {VAR_PLURAL, plural, one {participant} other {participants}} src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 67 + 73,76 @@ -344,7 +351,7 @@ Show Details Button src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 81 + 90 @@ -354,7 +361,7 @@ No Events src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 91 + 100 @@ -365,7 +372,7 @@ Add New Event Button src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 105 + 114 @@ -668,7 +675,7 @@ 54 - src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.ts + src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.ts 47 @@ -712,7 +719,7 @@ src/app/child-dev-project/notes/model/note.ts - 166 + 165 @@ -1408,7 +1415,7 @@ src/app/child-dev-project/notes/model/note.ts - 175 + 174 src/app/core/config/config-fix.ts @@ -2223,18 +2230,18 @@ context Add User(s) Placeholder for input to add entities - src/app/core/basic-datatypes/entity-array/edit-entity-array/edit-entity-array.component.ts - 27 + src/app/core/basic-datatypes/entity-array/edit-entity/edit-entity.component.ts + 36 link to other records (multi-select) link to other records (multi-select) + datatype-label src/app/core/basic-datatypes/entity-array/entity-array.datatype.ts - 35 + 34 - datatype-label Select matching property @@ -2428,6 +2435,20 @@ 39 + + Add Section + Add Section + + src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html + 39,45 + + Configure Field "" Configure Field "" @@ -2615,79 +2636,140 @@ 4,6 - - Editing details page for "" records - Editing details page for "" records - - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 2,4 + + Drag & drop filters and add filters using the button + Drag & drop filters and add filters using the button + + src/app/core/admin/admin-entity-list/admin-entity-list.component.html + 35,45 + + + + Drag & drop table column headers and add columns using the button + Drag & drop table column headers and add columns using the button + + src/app/core/admin/admin-entity-list/admin-entity-list.component.html + 76,85 + + + + Editing data structure for "" records + Editing data structure for "" records + + src/app/core/admin/admin-entity/admin-entity.component.html + 3,5 page title - - Add Section - Add Section + + Save + Salva - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 72 + src/app/core/admin/admin-entity/admin-entity.component.html + 8,10 + + Details View & Fields + Details View & Fields + + src/app/core/admin/admin-entity/admin-entity.component.html + 21,23 + + admin entity: nav item + + + List View + List View + + src/app/core/admin/admin-entity/admin-entity.component.html + 28,30 + + admin entity: nav item + + + General Settings + General Settings + + src/app/core/admin/admin-entity/admin-entity.component.html + 35,37 + + admin entity: nav item + add a new tab add a new tab - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 89 + src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.html + 30 Configuration updated Configuration updated + Save config confirmation message - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.ts - 105 + src/app/core/admin/admin-entity/admin-entity.component.ts + 132 - Save config confirmation message New Section New Section + Default title - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.ts - 152 + src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.ts + 53 - Default title (no title) (no title) + Placeholder for entering a title - src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.html + src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.html 8 - Placeholder for entering a title Delete Section? Delete Section? + Admin UI - Delete Section Confirmation Title - src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.ts + src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.ts 58 - Admin UI - Delete Section Confirmation Title Do you really want to delete this section with all its content? Do you really want to delete this section with all its content? + Admin UI - Delete Section Confirmation Text - src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.ts + src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.ts 59 - Admin UI - Delete Section Confirmation Text Conflicting Entity: @@ -3495,7 +3577,7 @@ Label for adding an option in a dropdown src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html - 52 + 65 @@ -3879,7 +3961,7 @@ Create new option src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.ts - 213 + 274 @@ -3887,7 +3969,7 @@ Do you want to create the new option ""? src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.ts - 214 + 275 @@ -4080,6 +4162,14 @@ src/app/core/entity-details/entity-details/entity-details.component.html 41 + + src/app/core/entity-list/entity-list/entity-list.component.html + 232 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 232 + Save the new record to create it before accessing other details @@ -4154,30 +4244,30 @@ 200 - - Current user is not permitted to save these changes - Current user is not permitted to save these changes + + Could not save : + Could not save : src/app/core/common-components/entity-form/entity-form.service.ts - 245 + 253 - - Could not save : - Could not save : + + Current user is not permitted to save these changes: + Current user is not permitted to save these changes: src/app/core/common-components/entity-form/entity-form.service.ts - 256 + 281,283 Save Salva - Button label - - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 12 - + Save button for forms src/app/core/user/user-security/user-security.component.html 60 @@ -4186,11 +4276,7 @@ Cancel Cancella - Button label - - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 15 - + Cancel button for forms src/app/core/user/user-security/user-security.component.html 69 @@ -4333,11 +4419,11 @@ Actions on selected records: src/app/core/entity-list/entity-list/entity-list.component.html - 228 + 240 src/app/core/entity-list/entity-list/entity-list.component.html - 228 + 240 @@ -4345,11 +4431,11 @@ Select rows for an action on multiple records src/app/core/entity-list/entity-list/entity-list.component.html - 232 + 244 src/app/core/entity-list/entity-list/entity-list.component.html - 232 + 244 @@ -4358,25 +4444,25 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 241 + 253 src/app/core/entity-list/entity-list/entity-list.component.html - 241 + 253 Anonymize Anonymize + bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 250,252 + 262 src/app/core/entity-list/entity-list/entity-list.component.html - 250,252 + 262 - bulk action button Delete @@ -4384,11 +4470,11 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 259 + 271 src/app/core/entity-list/entity-list/entity-list.component.html - 259 + 271 @@ -4397,11 +4483,11 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 268 + 280 src/app/core/entity-list/entity-list/entity-list.component.html - 268 + 280 @@ -4409,11 +4495,11 @@ Cancella src/app/core/entity-list/entity-list/entity-list.component.html - 272 + 284 src/app/core/entity-list/entity-list/entity-list.component.html - 272 + 284 @@ -4545,21 +4631,11 @@ remove rimuovere - tooltip for remove icon-button + tooltip for remove icon on chips of dropdown item - src/app/core/common-components/entity-select/entity-select.component.html - 33 - - - - Also show inactive - Also show inactive - - src/app/core/common-components/entity-select/entity-select.component.html - 67,69 + src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html + 112 - e.g. include inactive children - Label for checkbox loading... @@ -4567,7 +4643,7 @@ A placeholder for the input element when select options are not loaded yet src/app/core/common-components/entity-select/entity-select.component.ts - 54 + 51 @@ -4596,6 +4672,14 @@ 24 + + Add or remove visible fields + Add or remove visible fields + + src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.html + 4 + + in total @@ -5672,6 +5756,16 @@ 19 + + Also show inactive + Also show inactive + + src/app/core/common-components/entity-select/entity-select.component.html + 28,29 + + e.g. include inactive children + Label for checkbox + Email Email @@ -6709,6 +6803,10 @@ src/app/core/admin/admin-entity-details/admin-entity-field/admin-entity-field.component.html 182 + + src/app/core/admin/admin-entity/admin-entity.component.html + 11 + src/app/core/basic-datatypes/date/date-import-config/date-import-config.component.html 38 @@ -6804,11 +6902,11 @@ link to another record link to another record + datatype-label src/app/core/basic-datatypes/entity/entity.datatype.ts - 37 + 36 - datatype-label month (date without day of month) @@ -7566,7 +7664,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 196 + 205 @@ -7575,7 +7673,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 162 + 171 @@ -7584,7 +7682,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 167 + 176 @@ -7593,7 +7691,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 172 + 181 @@ -7601,7 +7699,7 @@ Any src/app/features/todos/todo-list/todo-list.component.ts - 175 + 184 @@ -7609,7 +7707,7 @@ Tasks due src/app/features/todos/todo-list/todo-list.component.ts - 177 + 186 diff --git a/src/assets/locale/messages.xlf b/src/assets/locale/messages.xlf index 93b9db854a..b9a608d364 100644 --- a/src/assets/locale/messages.xlf +++ b/src/assets/locale/messages.xlf @@ -72,11 +72,11 @@ Percentage of people that attended an event - + {VAR_PLURAL, plural, one {participant} other {participants}} src/app/child-dev-project/attendance/activity-card/activity-card.component.html - 11,12 + 12 @@ -266,58 +266,65 @@ given Remarks - - All excused (out of ) + + All excused (out of ) src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 48,53 + 48,56 How many participants attended at an event (in percent) Event participants - + {VAR_PLURAL, plural, one {participant} other {participants}} src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 51,52 + 51,54 src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 58,59 + 61,65 - - attended (of ) + + attended (of ) src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 54,60 + 57,66 - - without recorded status + + without recorded status src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 65,69 + 71,78 How many children are without a status Unknown status - + {VAR_PLURAL, plural, one {participant} other {participants}} src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 67,68 + 73,76 Details src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 81,83 + 90,92 Allows the user to see details of an event that took place at a particular day @@ -327,7 +334,7 @@ no events on this date src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 91,93 + 100,102 Informs the user that there are no events at a particular date No Events @@ -336,7 +343,7 @@ Add new event src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html - 105,107 + 114,116 Allows the user to create a new event for the selected date @@ -623,7 +630,7 @@ 54 - src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.ts + src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.ts 47 Label for the title of a recurring activity @@ -664,7 +671,7 @@ src/app/child-dev-project/notes/model/note.ts - 166 + 165 Label for the linked schools of a recurring activity @@ -1225,7 +1232,7 @@ src/app/child-dev-project/notes/model/note.ts - 175 + 174 src/app/core/config/config-fix.ts @@ -2026,6 +2033,25 @@ Label warning level + + Add Section + + src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html + 39,45 + + + + New Section + + src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.ts + 53 + + Default title + Configure Field "" @@ -2173,6 +2199,10 @@ src/app/core/admin/admin-entity-details/admin-entity-field/admin-entity-field.component.html 182 + + src/app/core/admin/admin-entity/admin-entity.component.html + 11 + src/app/core/basic-datatypes/date/date-import-config/date-import-config.component.html 38 @@ -2256,74 +2286,105 @@ 4,6 - - Editing details page for "" records + + Drag & drop filters and add filters using the button - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 2,4 + src/app/core/admin/admin-entity-list/admin-entity-list.component.html + 35,45 - page title - - Save + + Drag & drop table column headers and add columns using the button - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 12,14 + src/app/core/admin/admin-entity-list/admin-entity-list.component.html + 76,85 + + + Editing data structure for "" records - src/app/core/user/user-security/user-security.component.html - 60,62 + src/app/core/admin/admin-entity/admin-entity.component.html + 3,5 - Button label + page title - - Cancel + + Save - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 15,17 + src/app/core/admin/admin-entity/admin-entity.component.html + 8,10 + + + Details View & Fields - src/app/core/user/user-security/user-security.component.html - 69,71 + src/app/core/admin/admin-entity/admin-entity.component.html + 21,23 - Button label + admin entity: nav item - - Add Section + + List View - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 72,78 + src/app/core/admin/admin-entity/admin-entity.component.html + 28,30 + admin entity: nav item - - add a new tab + + General Settings - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.html - 89 + src/app/core/admin/admin-entity/admin-entity.component.html + 35,37 + admin entity: nav item Configuration updated - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.ts - 105 + src/app/core/admin/admin-entity/admin-entity.component.ts + 132 Save config confirmation message - - New Section + + Site Settings - src/app/core/admin/admin-entity-details/admin-entity/admin-entity-details.component.ts - 152 + src/app/core/admin/admin.routing.ts + 39 - Default title + + + Site Settings + + src/app/core/admin/admin/admin.component.html + 12,14 + + admin menu item + + + Database Conflicts + + src/app/core/admin/admin/admin.component.html + 16,18 + + admin menu item (no title) - src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.html + src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.html 8 Placeholder for entering a title @@ -2331,7 +2392,7 @@ Delete Section? - src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.ts + src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.ts 58 Admin UI - Delete Section Confirmation Title @@ -2339,33 +2400,17 @@ Do you really want to delete this section with all its content? - src/app/core/admin/admin-entity-details/admin-section-header/admin-section-header.component.ts + src/app/core/admin/building-blocks/admin-section-header/admin-section-header.component.ts 59 Admin UI - Delete Section Confirmation Text - - Site Settings - - src/app/core/admin/admin.routing.ts - 39 - - - - Site Settings - - src/app/core/admin/admin/admin.component.html - 12,14 - - admin menu item - - - Database Conflicts + + add a new tab - src/app/core/admin/admin/admin.component.html - 16,18 + src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.html + 30 - admin menu item dismiss @@ -2689,8 +2734,8 @@ Add - src/app/core/basic-datatypes/entity-array/edit-entity-array/edit-entity-array.component.ts - 27 + src/app/core/basic-datatypes/entity-array/edit-entity/edit-entity.component.ts + 36 context Add User(s) Placeholder for input to add entities @@ -2699,7 +2744,7 @@ link to other records (multi-select) src/app/core/basic-datatypes/entity-array/entity-array.datatype.ts - 35 + 34 datatype-label @@ -2737,7 +2782,7 @@ link to another record src/app/core/basic-datatypes/entity/entity.datatype.ts - 37 + 36 datatype-label @@ -2777,23 +2822,31 @@ Add option src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html - 52 + 65 e.g. Add option My new Option Label for adding an option in a dropdown + + remove + + src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html + 112 + + tooltip for remove icon on chips of dropdown item + Create new option src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.ts - 213 + 274 Do you want to create the new option ""? src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.ts - 214 + 275 @@ -2928,6 +2981,13 @@ 24 + + Add or remove visible fields + + src/app/core/common-components/entity-fields-menu/entity-fields-menu.component.html + 4 + + Must be greater than @@ -2984,18 +3044,20 @@ 200 - - Current user is not permitted to save these changes + + Could not save : src/app/core/common-components/entity-form/entity-form.service.ts - 245 + 253 - - Could not save : + + Current user is not permitted to save these changes: src/app/core/common-components/entity-form/entity-form.service.ts - 256 + 281,283 @@ -3020,19 +3082,11 @@ form field validation error - - remove - - src/app/core/common-components/entity-select/entity-select.component.html - 33 - - tooltip for remove icon-button - - - Also show inactive + + Also show inactive src/app/core/common-components/entity-select/entity-select.component.html - 67,69 + 28,29 e.g. include inactive children Label for checkbox @@ -3041,7 +3095,7 @@ loading... src/app/core/common-components/entity-select/entity-select.component.ts - 54 + 51 A placeholder for the input element when select options are not loaded yet @@ -3881,6 +3935,14 @@ src/app/core/entity-details/entity-details/entity-details.component.html 41 + + src/app/core/entity-list/entity-list/entity-list.component.html + 232 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 232 + Save the new record to create it before accessing other details @@ -4115,33 +4177,33 @@ Actions on selected records: src/app/core/entity-list/entity-list/entity-list.component.html - 228 + 240 src/app/core/entity-list/entity-list/entity-list.component.html - 228 + 240 Select rows for an action on multiple records src/app/core/entity-list/entity-list/entity-list.component.html - 232 + 244 src/app/core/entity-list/entity-list/entity-list.component.html - 232 + 244 Archive src/app/core/entity-list/entity-list/entity-list.component.html - 241,243 + 253,255 src/app/core/entity-list/entity-list/entity-list.component.html - 241,243 + 253,255 bulk action button @@ -4149,11 +4211,11 @@ Anonymize src/app/core/entity-list/entity-list/entity-list.component.html - 250,252 + 262,264 src/app/core/entity-list/entity-list/entity-list.component.html - 250,252 + 262,264 bulk action button @@ -4161,11 +4223,11 @@ Delete src/app/core/entity-list/entity-list/entity-list.component.html - 259,261 + 271,273 src/app/core/entity-list/entity-list/entity-list.component.html - 259,261 + 271,273 bulk action button @@ -4173,11 +4235,11 @@ Duplicate src/app/core/entity-list/entity-list/entity-list.component.html - 268,270 + 280,282 src/app/core/entity-list/entity-list/entity-list.component.html - 268,270 + 280,282 bulk action button @@ -4185,11 +4247,11 @@ Cancel src/app/core/entity-list/entity-list/entity-list.component.html - 272,274 + 284,286 src/app/core/entity-list/entity-list/entity-list.component.html - 272,274 + 284,286 @@ -5386,6 +5448,22 @@ button to enable a user + + Save + + src/app/core/user/user-security/user-security.component.html + 60,62 + + Save button for forms + + + Cancel + + src/app/core/user/user-security/user-security.component.html + 69,71 + + Cancel button for forms + User is currently disabled and will not be able to login to the app @@ -6671,7 +6749,7 @@ Overdue src/app/features/todos/todo-list/todo-list.component.ts - 162 + 171 Filter-option for todos @@ -6679,7 +6757,7 @@ Completed src/app/features/todos/todo-list/todo-list.component.ts - 167 + 176 Filter-option for todos @@ -6687,7 +6765,7 @@ All Open src/app/features/todos/todo-list/todo-list.component.ts - 172 + 181 Filter-option for todos @@ -6695,21 +6773,21 @@ Any src/app/features/todos/todo-list/todo-list.component.ts - 175 + 184 Tasks due src/app/features/todos/todo-list/todo-list.component.ts - 177 + 186 Currently Active src/app/features/todos/todo-list/todo-list.component.ts - 196 + 205 Filter-option for todos From a62aec4b4c95cf4d653ccd351a8abeb7c1a878c6 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Wed, 17 Apr 2024 14:58:45 +0200 Subject: [PATCH 53/58] small ui adaptions --- .../admin-entity-details.component.html | 6 +++ .../admin-entity/admin-entity.component.ts | 2 +- .../setup-wizard/setup-wizard.component.html | 38 +++++++++++-------- .../setup-wizard/setup-wizard.component.ts | 8 +++- 4 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html index f5f258e264..b3a2ca4c16 100644 --- a/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html +++ b/src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html @@ -1,6 +1,12 @@ <Name of displayed {{ this.entityConstructor?.label }}> +

+ You can edit how users will see the details of a single record of this type. + Drag and drop fields and sections in this preview of a profile view and group + them as appropriate. We recommend to keep things simple: Only add fields that + you really need for your work. +

diff --git a/src/app/core/admin/admin-entity/admin-entity.component.ts b/src/app/core/admin/admin-entity/admin-entity.component.ts index ac96277bb7..30b85d4164 100644 --- a/src/app/core/admin/admin-entity/admin-entity.component.ts +++ b/src/app/core/admin/admin-entity/admin-entity.component.ts @@ -66,7 +66,7 @@ export class AdminEntityComponent implements OnInit { configListView: EntityListConfig; configEntitySettings: EntityConfig; - protected mode: "details" | "list" | "general" = "list"; + protected mode: "details" | "list" | "general" = "details"; @ContentChild(TemplateRef) templateRef: TemplateRef; diff --git a/src/app/core/admin/setup-wizard/setup-wizard.component.html b/src/app/core/admin/setup-wizard/setup-wizard.component.html index 135110d26b..3179970e4c 100644 --- a/src/app/core/admin/setup-wizard/setup-wizard.component.html +++ b/src/app/core/admin/setup-wizard/setup-wizard.component.html @@ -1,4 +1,12 @@ - + + + + {{ index + 1 }} + + + {{ index + 1 }} + +

Herzlich willkommen bei codo!

codo hilft dir dabei ...

@@ -15,7 +23,7 @@
- +

codo ist als Software bereits genau auf die Betreuung von Patenschaften zugeschnitten. Unsere langjährige Erfahrungen der BürgerStiftung Hamburg @@ -45,32 +53,32 @@ - +

- Falls ihr bestehende Daten bisheriger Patenschaften habt, könnt ihr diese - einfach importieren. Dazu müssen diese aus Excel im ".csv"-Format - abgespeichert werden. Das Import-Modul von codo hilft euch dabei, die - Tabellen den passenden Datenfeldern zuzuordnen. + Ihr könnt in codo sehr einfach als Team zusammenarbeiten. Die Daten sind + für alle synchronisiert und auf dem aktuellsten Stand. Weitere + Nutzer-Accounts könnt ihr jederzeit selbst erstellen.

- +
- +

- Ihr könnt in codo sehr einfach als Team zusammenarbeiten. Die Daten sind - für alle synchronisiert und auf dem aktuellsten Stand. Weitere - Nutzer-Accounts könnt ihr jederzeit selbst erstellen. + Falls ihr bestehende Daten bisheriger Patenschaften habt, könnt ihr diese + einfach importieren. Dazu müssen diese aus Excel im ".csv"-Format + abgespeichert werden. Das Import-Modul von codo hilft euch dabei, die + Tabellen den passenden Datenfeldern zuzuordnen.

- +
diff --git a/src/app/core/admin/setup-wizard/setup-wizard.component.ts b/src/app/core/admin/setup-wizard/setup-wizard.component.ts index 27e2af3e1a..43968dd63c 100644 --- a/src/app/core/admin/setup-wizard/setup-wizard.component.ts +++ b/src/app/core/admin/setup-wizard/setup-wizard.component.ts @@ -1,6 +1,11 @@ import { Component } from "@angular/core"; import { CommonModule } from "@angular/common"; -import { MatStep, MatStepper, MatStepperNext } from "@angular/material/stepper"; +import { + MatStep, + MatStepper, + MatStepperIcon, + MatStepperNext, +} from "@angular/material/stepper"; import { MatActionList, MatListItem } from "@angular/material/list"; import { RouterLink } from "@angular/router"; import { MatButton } from "@angular/material/button"; @@ -17,6 +22,7 @@ import { MatButton } from "@angular/material/button"; RouterLink, MatButton, MatStepperNext, + MatStepperIcon, ], templateUrl: "./setup-wizard.component.html", styleUrl: "./setup-wizard.component.scss", From 19019bdbce16d7c001a0e465496587be2eb61b20 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Thu, 18 Apr 2024 18:38:58 +0200 Subject: [PATCH 54/58] make configurable and formatted with markdown --- .../admin/setup-wizard/setup-wizard-config.ts | 94 ++++++++++++++++ .../setup-wizard/setup-wizard.component.html | 102 +++--------------- .../setup-wizard/setup-wizard.component.ts | 18 +++- .../config/demo-config-generator.service.ts | 9 +- src/app/core/ui/navigation/menu-item.ts | 2 +- 5 files changed, 135 insertions(+), 90 deletions(-) create mode 100644 src/app/core/admin/setup-wizard/setup-wizard-config.ts diff --git a/src/app/core/admin/setup-wizard/setup-wizard-config.ts b/src/app/core/admin/setup-wizard/setup-wizard-config.ts new file mode 100644 index 0000000000..f58c23fc7e --- /dev/null +++ b/src/app/core/admin/setup-wizard/setup-wizard-config.ts @@ -0,0 +1,94 @@ +import { MenuItem } from "../../ui/navigation/menu-item"; + +export const CONFIG_SETUP_WIZARD_ID = "Config:SetupWizard"; + +export interface SetupWizardConfig { + steps: SetupWizardStep[]; +} + +export interface SetupWizardStep { + title: string; + text: string; + actions?: MenuItem[]; +} + +export const defaultSetupWizardConfig: SetupWizardConfig = { + steps: [ + { + title: "Willkommen", + text: ` +# Herzlich willkommen bei codo! +codo hilft dir dabei ... + +Die folgenden Schritten leiten dich durch die wichtigsten Einstellungen, +um codo optimal auf euer Projekt anzupassen. Du kannst schon nach wenigen +Minuten loslegen und die ersten Daten erfassen. + +Du kannst jederzeit über den Button unten im Menü links zu diesen +Einrichtungsassistenten zurückkehren, wenn du zunächst die Anwendung +erkunden möchtest.`, + }, + { + title: "Profile & Felder anpassen", + text: ` +codo ist als Software bereits genau auf die Betreuung von Patenschaften +zugeschnitten. Unsere langjährige Erfahrungen der BürgerStiftung Hamburg +und Stiftung Bürgermut in der Betreuung solcher Projekte sind die Basis +für codo und das System wurde in enger Zusammenarbeit mit einer +Fokusgruppe von Projekten entwickelt. + +Damit codo optimal auf euer Projekt passt, könnt ihr innerhalb der +vorhandenen Datenstrukturen zusätzliche Felder und Formularbereiche +individuell anpassen.`, + actions: [ + { + label: "Mentor:innen-Profile anpassen", + link: "/admin/entity/School", + }, + { + label: "Mentee-Profile anpassen", + link: "/admin/entity/Child", + }, + { + label: "Patenschafts-Daten anpassen", + link: "/admin/entity/ChildSchoolRelation", + }, + ], + }, + { + title: "Nutzer:innen hinzufügen", + text: ` +Ihr könnt in codo sehr einfach als Team zusammenarbeiten. Die Daten sind +für alle synchronisiert und auf dem aktuellsten Stand. Weitere +Nutzer-Accounts könnt ihr jederzeit selbst erstellen.`, + actions: [ + { + label: "Nutzer-Accounts verwalten", + link: "/user", + }, + ], + }, + { + title: "Daten importieren", + text: ` +Falls ihr bestehende Daten bisheriger Patenschaften habt, könnt ihr diese +einfach importieren. Dazu müssen diese aus Excel im ".csv"-Format +abgespeichert werden. Das Import-Modul von codo hilft euch dabei, die +Tabellen den passenden Datenfeldern zuzuordnen.`, + actions: [ + { + label: "Daten importieren", + link: "/import", + }, + ], + }, + { + title: "Fertig", + text: ` +Mehr gibt es eigentlich nicht zu beachten. Ihr könnt jetzt loslegen und +codo ausprobieren. Bei Fragen oder Problemen wendet euch gerne an xxx.de + +Ein paar Tipps und mögliche erste Schritte zum Abschluss: ...`, + }, + ], +}; diff --git a/src/app/core/admin/setup-wizard/setup-wizard.component.html b/src/app/core/admin/setup-wizard/setup-wizard.component.html index 3179970e4c..cf36e2ab54 100644 --- a/src/app/core/admin/setup-wizard/setup-wizard.component.html +++ b/src/app/core/admin/setup-wizard/setup-wizard.component.html @@ -7,91 +7,19 @@ {{ index + 1 }}
- -

Herzlich willkommen bei codo!

-

codo hilft dir dabei ...

-

...

-

- Die folgenden Schritten leiten dich durch die wichtigsten Einstellungen, - um codo optimal auf euer Projekt anzupassen. Du kannst schon nach wenigen - Minuten loslegen und die ersten Daten erfassen.
- Du kannst jederzeit über den Button unten im Menü links zu diesen - Einrichtungsassistenten zurückkehren, wenn du zunächst die Anwendung - erkunden möchtest. -

- - -
- - -

- codo ist als Software bereits genau auf die Betreuung von Patenschaften - zugeschnitten. Unsere langjährige Erfahrungen der BürgerStiftung Hamburg - und Stiftung Bürgermut in der Betreuung solcher Projekte sind die Basis - für codo und das System wurde in enger Zusammenarbeit mit einer - Fokusgruppe von Projekten entwickelt.
- Damit codo optimal auf euer Projekt passt, könnt ihr innerhalb der - vorhandenen Datenstrukturen zusätzliche Felder und Formularbereiche - individuell anpassen. -

- - - - - - - - -
- - -

- Ihr könnt in codo sehr einfach als Team zusammenarbeiten. Die Daten sind - für alle synchronisiert und auf dem aktuellsten Stand. Weitere - Nutzer-Accounts könnt ihr jederzeit selbst erstellen. -

- -
- -
- - -
- - -

- Falls ihr bestehende Daten bisheriger Patenschaften habt, könnt ihr diese - einfach importieren. Dazu müssen diese aus Excel im ".csv"-Format - abgespeichert werden. Das Import-Modul von codo hilft euch dabei, die - Tabellen den passenden Datenfeldern zuzuordnen. -

- -
- -
- - -
- - -

- Mehr gibt es eigentlich nicht zu beachten. Ihr könnt jetzt loslegen und - codo ausprobieren. Bei Fragen oder Problemen wendet euch gerne an xxx.de -

- -

Ein paar Tipps und mögliche erste Schritte zum Abschluss: ...

- - -
+ @for (step of config.steps; track step) { + + {{ step.text }} + + + @for (action of step.actions; track action.link) { + + } + + + + + } diff --git a/src/app/core/admin/setup-wizard/setup-wizard.component.ts b/src/app/core/admin/setup-wizard/setup-wizard.component.ts index 43968dd63c..64d6867dae 100644 --- a/src/app/core/admin/setup-wizard/setup-wizard.component.ts +++ b/src/app/core/admin/setup-wizard/setup-wizard.component.ts @@ -9,6 +9,13 @@ import { import { MatActionList, MatListItem } from "@angular/material/list"; import { RouterLink } from "@angular/router"; import { MatButton } from "@angular/material/button"; +import { EntityMapperService } from "../../entity/entity-mapper/entity-mapper.service"; +import { Config } from "../../config/config"; +import { + CONFIG_SETUP_WIZARD_ID, + SetupWizardConfig, +} from "./setup-wizard-config"; +import { MarkdownComponent } from "ngx-markdown"; @Component({ selector: "app-setup-wizard", @@ -23,8 +30,17 @@ import { MatButton } from "@angular/material/button"; MatButton, MatStepperNext, MatStepperIcon, + MarkdownComponent, ], templateUrl: "./setup-wizard.component.html", styleUrl: "./setup-wizard.component.scss", }) -export class SetupWizardComponent {} +export class SetupWizardComponent { + config: SetupWizardConfig; + + constructor(entityMapper: EntityMapperService) { + entityMapper + .load(Config, CONFIG_SETUP_WIZARD_ID) + .then((r: Config) => (this.config = r.data)); + } +} diff --git a/src/app/core/config/demo-config-generator.service.ts b/src/app/core/config/demo-config-generator.service.ts index baea66e329..f1a3dcae23 100644 --- a/src/app/core/config/demo-config-generator.service.ts +++ b/src/app/core/config/demo-config-generator.service.ts @@ -2,6 +2,10 @@ import { Injectable } from "@angular/core"; import { DemoDataGenerator } from "../demo-data/demo-data-generator"; import { Config } from "./config"; import { defaultJsonConfig } from "./config-fix"; +import { + CONFIG_SETUP_WIZARD_ID, + defaultSetupWizardConfig, +} from "../admin/setup-wizard/setup-wizard-config"; @Injectable() export class DemoConfigGeneratorService extends DemoDataGenerator { @@ -16,6 +20,9 @@ export class DemoConfigGeneratorService extends DemoDataGenerator { protected generateEntities(): Config[] { const defaultConfig = JSON.parse(JSON.stringify(defaultJsonConfig)); - return [new Config(Config.CONFIG_KEY, defaultConfig)]; + return [ + new Config(Config.CONFIG_KEY, defaultConfig), + new Config(CONFIG_SETUP_WIZARD_ID, defaultSetupWizardConfig), + ]; } } diff --git a/src/app/core/ui/navigation/menu-item.ts b/src/app/core/ui/navigation/menu-item.ts index f3194f6f66..cf6f8187df 100644 --- a/src/app/core/ui/navigation/menu-item.ts +++ b/src/app/core/ui/navigation/menu-item.ts @@ -9,7 +9,7 @@ export interface MenuItem { /** * The icon to be displayed left of the label. */ - icon: string; + icon?: string; /** * The url fragment to which the item will route to (e.g. '/dashboard') */ From 34274daf89ab3831e9b08fc280f5d84ae0dfd7ba Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Fri, 19 Apr 2024 11:38:22 +0200 Subject: [PATCH 55/58] save progress and dismissal of setup wizard --- src/app/core/admin/admin/admin.component.html | 4 ++ .../setup-wizard-button.component.html | 13 ++++++ .../setup-wizard-button.component.scss | 7 +++ .../setup-wizard-button.component.spec.ts | 27 ++++++++++++ .../setup-wizard-button.component.ts | 44 +++++++++++++++++++ .../admin/setup-wizard/setup-wizard-config.ts | 9 ++++ .../setup-wizard/setup-wizard.component.html | 28 ++++++++++-- .../setup-wizard.component.spec.ts | 20 +++++---- .../setup-wizard/setup-wizard.component.ts | 27 ++++++++++-- src/app/core/ui/ui/ui.component.html | 10 +---- src/app/core/ui/ui/ui.component.ts | 2 + 11 files changed, 166 insertions(+), 25 deletions(-) create mode 100644 src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.html create mode 100644 src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.scss create mode 100644 src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.spec.ts create mode 100644 src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.ts diff --git a/src/app/core/admin/admin/admin.component.html b/src/app/core/admin/admin/admin.component.html index a76c8c9547..9d2e94b90a 100644 --- a/src/app/core/admin/admin/admin.component.html +++ b/src/app/core/admin/admin/admin.component.html @@ -16,6 +16,10 @@

Shortcuts

Database Conflicts + + + Setup Wizard +
diff --git a/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.html b/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.html new file mode 100644 index 0000000000..4e8d2af291 --- /dev/null +++ b/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.html @@ -0,0 +1,13 @@ +@if (showSetupWizard) { + +} diff --git a/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.scss b/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.scss new file mode 100644 index 0000000000..89a33b0577 --- /dev/null +++ b/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.scss @@ -0,0 +1,7 @@ + +.button { + border-top: solid 1px rgba(0, 0, 0, 0.12); + border-radius: 0; + overflow: hidden; + width: 100%; +} diff --git a/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.spec.ts b/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.spec.ts new file mode 100644 index 0000000000..7ec16b384f --- /dev/null +++ b/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.spec.ts @@ -0,0 +1,27 @@ +import { ComponentFixture, TestBed } from "@angular/core/testing"; + +import { SetupWizardButtonComponent } from "./setup-wizard-button.component"; +import { EntityMapperService } from "../../../entity/entity-mapper/entity-mapper.service"; +import { mockEntityMapper } from "../../../entity/entity-mapper/mock-entity-mapper-service"; + +describe("SetupWizardButtonComponent", () => { + let component: SetupWizardButtonComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [SetupWizardButtonComponent], + providers: [ + { provide: EntityMapperService, useValue: mockEntityMapper() }, + ], + }).compileComponents(); + + fixture = TestBed.createComponent(SetupWizardButtonComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.ts b/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.ts new file mode 100644 index 0000000000..82831340be --- /dev/null +++ b/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.ts @@ -0,0 +1,44 @@ +import { Component } from "@angular/core"; +import { FaIconComponent } from "@fortawesome/angular-fontawesome"; +import { MatButton } from "@angular/material/button"; +import { RouterLink } from "@angular/router"; +import { EntityMapperService } from "../../../entity/entity-mapper/entity-mapper.service"; +import { Config } from "../../../config/config"; +import { + CONFIG_SETUP_WIZARD_ID, + SetupWizardConfig, +} from "../setup-wizard-config"; +import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; +import { filter } from "rxjs/operators"; + +@UntilDestroy() +@Component({ + selector: "app-setup-wizard-button", + standalone: true, + imports: [FaIconComponent, MatButton, RouterLink], + templateUrl: "./setup-wizard-button.component.html", + styleUrls: ["./setup-wizard-button.component.scss"], +}) +export class SetupWizardButtonComponent { + showSetupWizard: boolean; + + constructor(entityMapper: EntityMapperService) { + entityMapper + .load(Config, CONFIG_SETUP_WIZARD_ID) + .then((r: Config) => { + this.updateStatus(r.data); + }); + + entityMapper + .receiveUpdates>(Config) + .pipe( + untilDestroyed(this), + filter(({ entity }) => entity.getId() === CONFIG_SETUP_WIZARD_ID), + ) + .subscribe((update) => this.updateStatus(update.entity.data)); + } + + private updateStatus(config: SetupWizardConfig) { + this.showSetupWizard = !config.finished; + } +} diff --git a/src/app/core/admin/setup-wizard/setup-wizard-config.ts b/src/app/core/admin/setup-wizard/setup-wizard-config.ts index f58c23fc7e..58af64cf8d 100644 --- a/src/app/core/admin/setup-wizard/setup-wizard-config.ts +++ b/src/app/core/admin/setup-wizard/setup-wizard-config.ts @@ -3,6 +3,12 @@ import { MenuItem } from "../../ui/navigation/menu-item"; export const CONFIG_SETUP_WIZARD_ID = "Config:SetupWizard"; export interface SetupWizardConfig { + /** index of the current (last visited) step, to be opened when user returns to the wizard **/ + currentStep?: number; + + /** whether the wizard has been completed overall and should be hidden */ + finished?: boolean; + steps: SetupWizardStep[]; } @@ -10,6 +16,9 @@ export interface SetupWizardStep { title: string; text: string; actions?: MenuItem[]; + + /** whether the user(s) have completed this step yet */ + completed?: boolean; } export const defaultSetupWizardConfig: SetupWizardConfig = { diff --git a/src/app/core/admin/setup-wizard/setup-wizard.component.html b/src/app/core/admin/setup-wizard/setup-wizard.component.html index cf36e2ab54..66caffde84 100644 --- a/src/app/core/admin/setup-wizard/setup-wizard.component.html +++ b/src/app/core/admin/setup-wizard/setup-wizard.component.html @@ -1,4 +1,4 @@ - + {{ index + 1 }} @@ -7,8 +7,8 @@ {{ index + 1 }} - @for (step of config.steps; track step) { - + @for (step of config?.steps; track step; let last = $last) { + {{ step.text }} @@ -19,7 +19,27 @@ } - + @if (!last) { + + } @else { + + } } diff --git a/src/app/core/admin/setup-wizard/setup-wizard.component.spec.ts b/src/app/core/admin/setup-wizard/setup-wizard.component.spec.ts index 9d21bad33e..620badf94b 100644 --- a/src/app/core/admin/setup-wizard/setup-wizard.component.spec.ts +++ b/src/app/core/admin/setup-wizard/setup-wizard.component.spec.ts @@ -1,23 +1,27 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { SetupWizardComponent } from './setup-wizard.component'; +import { SetupWizardComponent } from "./setup-wizard.component"; +import { EntityMapperService } from "../../entity/entity-mapper/entity-mapper.service"; +import { mockEntityMapper } from "../../entity/entity-mapper/mock-entity-mapper-service"; -describe('SetupWizardComponent', () => { +describe("SetupWizardComponent", () => { let component: SetupWizardComponent; let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [SetupWizardComponent] - }) - .compileComponents(); - + imports: [SetupWizardComponent], + providers: [ + { provide: EntityMapperService, useValue: mockEntityMapper() }, + ], + }).compileComponents(); + fixture = TestBed.createComponent(SetupWizardComponent); component = fixture.componentInstance; fixture.detectChanges(); }); - it('should create', () => { + it("should create", () => { expect(component).toBeTruthy(); }); }); diff --git a/src/app/core/admin/setup-wizard/setup-wizard.component.ts b/src/app/core/admin/setup-wizard/setup-wizard.component.ts index 64d6867dae..c669b67723 100644 --- a/src/app/core/admin/setup-wizard/setup-wizard.component.ts +++ b/src/app/core/admin/setup-wizard/setup-wizard.component.ts @@ -1,4 +1,4 @@ -import { Component } from "@angular/core"; +import { Component, OnDestroy } from "@angular/core"; import { CommonModule } from "@angular/common"; import { MatStep, @@ -16,6 +16,7 @@ import { SetupWizardConfig, } from "./setup-wizard-config"; import { MarkdownComponent } from "ngx-markdown"; +import { MatTooltip } from "@angular/material/tooltip"; @Component({ selector: "app-setup-wizard", @@ -31,16 +32,34 @@ import { MarkdownComponent } from "ngx-markdown"; MatStepperNext, MatStepperIcon, MarkdownComponent, + MatTooltip, ], templateUrl: "./setup-wizard.component.html", styleUrl: "./setup-wizard.component.scss", }) -export class SetupWizardComponent { +export class SetupWizardComponent implements OnDestroy { config: SetupWizardConfig; + currentStep: number; - constructor(entityMapper: EntityMapperService) { + private configEntity: Config; + + constructor(private entityMapper: EntityMapperService) { entityMapper .load(Config, CONFIG_SETUP_WIZARD_ID) - .then((r: Config) => (this.config = r.data)); + .then((r: Config) => { + this.configEntity = r; + this.config = r.data; + this.currentStep = this.config.currentStep; + }); + } + + ngOnDestroy(): void { + if (!this.config) { + return; + } + + this.config.currentStep = this.currentStep; + this.configEntity.data = this.config; + this.entityMapper.save(this.configEntity); } } diff --git a/src/app/core/ui/ui/ui.component.html b/src/app/core/ui/ui/ui.component.html index b4f0c6c4cf..ee9fa0e877 100644 --- a/src/app/core/ui/ui/ui.component.html +++ b/src/app/core/ui/ui/ui.component.html @@ -82,15 +82,7 @@
- + diff --git a/src/app/core/ui/ui/ui.component.ts b/src/app/core/ui/ui/ui.component.ts index c9b50b3a50..377a3e5cb9 100644 --- a/src/app/core/ui/ui/ui.component.ts +++ b/src/app/core/ui/ui/ui.component.ts @@ -38,6 +38,7 @@ import { SiteSettings } from "../../site-settings/site-settings"; import { LoginStateSubject } from "../../session/session-type"; import { LoginState } from "../../session/session-states/login-state.enum"; import { SessionManagerService } from "../../session/session-service/session-manager.service"; +import { SetupWizardButtonComponent } from "../../admin/setup-wizard/setup-wizard-button/setup-wizard-button.component"; /** * The main user interface component as root element for the app structure @@ -65,6 +66,7 @@ import { SessionManagerService } from "../../session/session-service/session-man RouterOutlet, PrimaryActionComponent, DisplayImgComponent, + SetupWizardButtonComponent, ], standalone: true, }) From d784b459c0f5c1ebd6a1e07c825aff4dad30638a Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Fri, 19 Apr 2024 12:58:12 +0200 Subject: [PATCH 56/58] translations --- ...min-entity-general-settings.component.html | 12 +- .../admin/setup-wizard/setup-wizard-config.ts | 93 +-- src/assets/locale/messages.de.xlf | 698 ++++++++++++++---- src/assets/locale/messages.fr.xlf | 696 +++++++++++++---- src/assets/locale/messages.it.xlf | 696 +++++++++++++---- src/assets/locale/messages.xlf | 640 ++++++++++++---- 6 files changed, 2166 insertions(+), 669 deletions(-) diff --git a/src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html b/src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html index ca313dc70d..1c92a8208a 100644 --- a/src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html +++ b/src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html @@ -15,8 +15,8 @@

General Settings of "{{ entityConstructor.label }}" Records

- - Label (Plural) + + Label (Plural) General Settings of "{{ entityConstructor.label }}" Records - - Icon + + Icon General Settings of "{{ entityConstructor.label }}" Records
- - Generated Title of Record + + Generated Title of Record src/app/core/config/config-fix.ts - 300 + 305 src/app/core/config/config-fix.ts - 775 + 780 @@ -1180,7 +1180,7 @@ Download note details as CSV src/app/child-dev-project/notes/note-details/note-details.component.html - 84 + 71 @@ -1476,12 +1476,12 @@ Add new Neu erstellen + e.g. Add new My new Option + Label for adding an option in a dropdown src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html - 63 + 80 - e.g. Add new My new Option - Label for adding an option in a dropdown Imported values @@ -2265,7 +2265,7 @@ src/app/core/config/config-fix.ts - 586 + 591 @@ -2401,7 +2401,7 @@ Title for notes overview src/app/core/config/config-fix.ts - 165 + 164 @@ -2410,11 +2410,11 @@ Translated name of default column group src/app/core/config/config-fix.ts - 169 + 168 src/app/core/config/config-fix.ts - 173 + 172 @@ -2423,19 +2423,19 @@ Translated name of mobile column group src/app/core/config/config-fix.ts - 170 + 169 src/app/core/config/config-fix.ts - 183 + 182 src/app/core/config/config-fix.ts - 404 + 409 src/app/core/config/config-fix.ts - 457 + 462 @@ -2451,7 +2451,7 @@ App-Einstellungen src/app/core/admin/admin.routing.ts - 39 + 44 @@ -2472,13 +2472,22 @@ admin menu item + + Setup Wizard + Setup-Assistent + + src/app/core/admin/admin/admin.component.html + 20,22 + + admin menu item + User Information Übersicht Panel title src/app/core/config/config-fix.ts - 257 + 262 @@ -2487,7 +2496,7 @@ Panel title src/app/core/config/config-fix.ts - 272 + 277 @@ -2496,7 +2505,7 @@ Filename of markdown help page (make sure the filename you enter as a translation actually exists on the server!) src/app/core/config/config-fix.ts - 285 + 290 @@ -2505,15 +2514,15 @@ Panel title src/app/core/config/config-fix.ts - 318 + 323 src/app/core/config/config-fix.ts - 491 + 496 src/app/core/config/config-fix.ts - 731 + 736 @@ -2522,7 +2531,7 @@ Panel title src/app/core/config/config-fix.ts - 335 + 340 @@ -2531,7 +2540,7 @@ Panel title src/app/core/config/config-fix.ts - 344 + 349 @@ -2540,7 +2549,7 @@ Column label for age of child src/app/core/config/config-fix.ts - 367 + 372 @@ -2549,7 +2558,7 @@ Column label for school attendance of child src/app/core/config/config-fix.ts - 385 + 390 @@ -2558,7 +2567,7 @@ Column label for coaching attendance of child src/app/core/config/config-fix.ts - 394 + 399 @@ -2567,11 +2576,11 @@ Translated name of default column group src/app/core/config/config-fix.ts - 403 + 408 src/app/core/config/config-fix.ts - 407 + 412 @@ -2580,7 +2589,7 @@ Column group name src/app/core/config/config-fix.ts - 420 + 425 @@ -2589,11 +2598,11 @@ Column group name src/app/core/config/config-fix.ts - 443 + 448 src/app/core/config/config-fix.ts - 608 + 613 @@ -2602,7 +2611,7 @@ Header for form section src/app/core/config/config-fix.ts - 501 + 506 @@ -2611,7 +2620,7 @@ Header for form section src/app/core/config/config-fix.ts - 505 + 510 @@ -2620,7 +2629,7 @@ Header for form section src/app/core/config/config-fix.ts - 509 + 514 @@ -2629,7 +2638,7 @@ Panel title src/app/core/config/config-fix.ts - 517 + 522 @@ -2638,7 +2647,7 @@ Title inside a panel src/app/core/config/config-fix.ts - 520 + 525 @@ -2647,7 +2656,7 @@ Title inside a panel src/app/core/config/config-fix.ts - 540 + 545 @@ -2656,7 +2665,7 @@ Child details section title src/app/core/config/config-fix.ts - 574 + 579 @@ -2665,7 +2674,7 @@ Panel title src/app/core/config/config-fix.ts - 595 + 600 @@ -2674,7 +2683,7 @@ description section src/app/core/config/config-fix.ts - 618 + 623 @@ -2683,7 +2692,7 @@ Title inside a panel src/app/core/config/config-fix.ts - 626 + 631 @@ -2692,7 +2701,7 @@ Panel title src/app/core/config/config-fix.ts - 647 + 652 @@ -2701,7 +2710,7 @@ Panel title src/app/core/config/config-fix.ts - 672 + 677 @@ -2719,7 +2728,7 @@ Panel title src/app/core/config/config-fix.ts - 759 + 764 @@ -2928,7 +2937,7 @@ src/app/core/config/config-fix.ts - 691 + 696 @@ -2941,7 +2950,7 @@ src/app/core/config/config-fix.ts - 825 + 830 @@ -3184,11 +3193,11 @@ src/app/core/config/config-fix.ts - 362 + 367 src/app/core/config/config-fix.ts - 809 + 814 src/app/features/reporting/demo-report-config-generator.service.ts @@ -3235,7 +3244,7 @@ src/app/core/config/config-fix.ts - 833 + 838 @@ -3445,6 +3454,16 @@ 39 + + You can edit how users will see the details of a single record of this type. Drag and drop fields and sections in this preview of a profile view and group them as appropriate. We recommend to keep things simple: Only add fields that you really need for your work. + + Sie können anpassen, wie Nutzer:innen die Details eines einzelnen Datensatzes dieses Typs sehen. Verschieben Sie Felder und Bereiche per "drag & drop" in dieser Vorschau und gruppieren Sie Felder. Weniger ist mehr: Aus unserer Erfahrung empfehlen wir, nur Felder die Sie wirklich aktuell benötigen anzulegen. + + + src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html + 4,9 + + Sektion hinzufügen src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html - 39,45 + 45 @@ -3482,6 +3501,10 @@ src/app/core/admin/admin-entity-details/admin-entity-field/admin-entity-field.component.html 13 + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 9 + Optionally you can define an additional shorter label to be displayed in table headers and other places where space is limited. @@ -3684,6 +3707,80 @@ 80 + + General Settings of "" Records + Allgemeine Einstellungen für ""-Datensätze + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 1 + + + + The settings here apply to the entity type overall and take effect everywhere the entity is displayed, including lists, forms and other views. + + Die Einstellungen hier betreffen den Datensatz-Typ insgesamt und wirken sich überall aus, wo ein Datensatz angezeigt wird (z.B. Listen, Formular und sonstige Ansichten). + + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 2,5 + + + + Label (Plural) + Label (Plural) + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 19 + + + + Optionally you can define how multiple records of this entity should be called, e.g. in lists. + Optional können Sie definieren, wie mehrere Datensätze dieses Typs bezeichnet werden, z.B. in Listen. + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 22 + + + + Icon + Icon + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 35 + + + + The icon to represent this entity type, e.g. when displaying records as a small preview block. [see fontawesome.com/icons] + Das Symbol, das diesen Typ repräsentiert, z.B. in Vorschau-Blöcken eines Datensatzes. [verfügbare Icons siehe fontawesome.com/icons] + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 38 + + + + Generated Title of Record + Generierter Titel eines Datensatzes + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 53 + + + + Select the fields that should be used (in that order) to generate a simple name/title for a record. This generated title is used in previews, search and for form fields that allow to select a record of this type. (Only text fields can be used here) + Die Werte der ausgewählten Felder werden (in dieser Reihenfolge) genutzt um eine Bezeichnung für einen konkreten Datensatz zu erzeugen. (Nur Felder vom Typ "Text" sind hierfür verfügbar) + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 56 + + + + Configure PII / Anonymization + Anonymisierung konfigurieren + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 77 + + Editing data structure for "" records Datenstruktur für ""-Einträge anpassen @@ -3733,16 +3830,219 @@ neuen Tab hinzufügen src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.html - 30 + 47 + + + + Setup Wizard + Setup-Assistent + + src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.html + 10,12 + + + + Welcome + Willkommen + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 27 + + Setup Wizard Step Title + + + +# Welcome to Aam Digital! +We are here to help you manage your participants' or beneficiaries' details +and your team's interactions with them. + +The Aam Digital platform is very flexible and you can customize the structures and views +to exactly fit your project needs. +The following steps guide you through the most important configuration options for this. +And you can start working with your data within a few minutes already. + +We also have some short video guides for you: [Aam Digital Video Guides (YouTube)](https://www.youtube.com/channel/UCZSFOX_MBa8zz5Mtfv_qlnA/videos) + +Feel free to leave this setup wizard in between to explore the existing system first. +You can always come back to this view through the "Setup Wizard" button at the bottom of the main menu on the left. +To dismiss and hide this wizard, go to the last step of the wizard and "finish" the setup process. + +# Willkommen bei Aam Digital! + Wir sind hier, um Ihnen bei der Verwaltung der Daten rund um Teilnehmende und Ihrer Interaktionen mit ihnen zu helfen. + + Die Aam Digital Plattform ist sehr flexibel und Sie können die Strukturen und Ansichten genau auf Ihr Projekt zuschneiden. + Die folgenden Schritte führen Sie durch die wichtigsten Konfigurationsmöglichkeiten dafür. + Dann können Sie bereits innerhalb weniger Minuten mit der Arbeit mit Ihren Daten beginnen. + + Für weitere Erklärungen existieren einige kurze Videoanleitungen: [Aam Digital Video Guides (YouTube)](https://www.youtube.com/channel/UCZSFOX_MBa8zz5Mtfv_qlnA/videos) + + Sie können diesen Einrichtungsassistenten zwischendurch gerne verlassen, um zunächst das System zu erkunden. + Über die Schaltfläche „Setup-Assistent“ unten im Hauptmenü auf der linken Seite können Sie jederzeit zu dieser Ansicht zurückkehren. + Um diesen Assistenten zu schließen und auszublenden, gehen Sie zum letzten Schritt des Assistenten und „schließen“ Sie den Einrichtungsvorgang ab. + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 28,42 + + Setup Wizard Step Text + + + Profiles & Fields + Profile & Felder + Setup Wizard Step Title + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 45 + + +The system already holds some basic structures for your case management. +You can adapt the fields and how the details are displayed. + +If you have further requirements, don't hesitate to reach out to us at [support@aam-digital.com](mailto:support@aam-digital.com). + +_Please note that the setup wizard and form builder is still under active development ("beta" version). +Some advanced configuration options are not available here yet for you to configure yourself and may need assistance from the tech support team. +We are currently extending and optimizing the user interfaces for these steps._ + + +Das System umfasst schon einige typische grundlegende Felder. +Sie können die Profile weiter anpassen, sodass Sie alle relevanten Informationen dokumentieren können. + +Wenn Sie weitergehende Anforderungen haben, kontaktieren Sie uns gerne unter [support@aam-digital.com](mailto:support@aam-digital.com). + +_Der Einrichtungs-Assistent und Formular-Editor sind noch in der Entwicklung ("beta" Version). +Einige Einstellungen lassen sich noch nicht von Ihnen selbst anpassen und müssen ggf. durch unser Support-Team aktiviert werden. +Wir arbeiten momentan daran diese Funktionen zu erweitern und zu optimieren._ + + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 46,55 + + Setup Wizard Step Text + + + Customize Child profile + Kinder-Profil anpassen + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 58 + + Setup Wizard Step Action + + + Customize School profile + Schul-Profil anpassen + Setup Wizard Step Action + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 62 + + + + User Accounts + Nutzer-Accounts + Setup Wizard Step Title + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 68 + + + + +You can collaborate on Aam Digital as a team. +Data is synced and all users have access to the latest information. + +Sie können mit Hilfe von Aam Digital sehr einfach als Team zusammenarbeiten. +Daten werden automatisch synchronisiert und alle Nutzer:innen haben Zugriff auf den aktuellsten Stand der Informationen. + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 69,71 + + Setup Wizard Step Text + + + Manage User Accounts + Nutzer-Accounts verwalten + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 74 + + Setup Wizard Step Action + + + Import Data + Daten importieren + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 80 + + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 88 + + Setup Wizard Step Title + + + +If you have exising data from a previous system, you can easily import it. +Save the data in ".csv" format (e.g. from MS Excel). +You do not need any specific column names in your file to be imported. +The Import Module helps your map your spreadsheet data to the relevant fields in your Aam Digital profiles. + +Wenn Sie bestehende Daten aus einem anderen System haben, können Sie diese einfach importieren. +Speichern Sie die Daten dafür im ".csv"-Format (z.B. in MS Excel). +Die Tabellen-Spalten benötigen keine spezielle Struktur oder Benennung. +Das Import-Modul hilft Ihnen dabei die Daten aus dem Tabellenformat in die passenden Felder der Aam Digital Profile zu importieren. + + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 81,85 + + Setup Wizard Step Text + + + Done! + Fertig! + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 94 + + Setup Wizard Step Title + + + +That's it. You are ready to explore your system and start work! + +You can always adapt your setup further, after you started using it. +We recommend to keep things simple in the beginning, +start using it for some of your tasks +and then add further fields and adjust your setup. + +Feel free to reach out to us with your questions or feedback: [support@aam-digital.com](mailto:support@aam-digital.com) + +Das war's. Sie können ihr System jetzt ausprobieren und mit der Arbeit beginnen! + +Natürlich können Sie die Konfiguration jederzeit weiter anpassen. +Unserer Erfahrung nach hat es sich bewährt, mit einem einfachem Setup zu starten +und möglichst schnell für einige Aufgaben die tägliche Nutzung zu beginnen. +Anschließend lassen sich mit den ersten Erfahrungen daraus einfach weitere Anpassungen machen +und zusätzliche Felder konfigurieren. + +Zögern Sie nicht uns mit Fragen und Feedback zu kontaktieren: [support@aam-digital.com](mailto:support@aam-digital.com) + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 95,103 + + Setup Wizard Step Text + Configuration updated Konfiguration aktualisiert Save config confirmation message src/app/core/admin/admin-entity/admin-entity.component.ts - 132 + 141 @@ -3835,7 +4135,7 @@ src/app/core/config/config-fix.ts - 373 + 378 @@ -3985,11 +4285,11 @@ src/app/core/config/config-fix.ts - 378 + 383 src/app/core/config/config-fix.ts - 473 + 478 @@ -4117,7 +4417,7 @@ src/app/core/config/config-fix.ts - 746 + 751 src/app/features/reporting/demo-report-config-generator.service.ts @@ -4223,7 +4523,7 @@ src/app/core/config/config-fix.ts - 433 + 438 @@ -4272,7 +4572,7 @@ src/app/core/config/config-fix.ts - 774 + 779 @@ -4281,7 +4581,7 @@ Table header, Short for Body Mass Index src/app/core/config/config-fix.ts - 637 + 642 @@ -4290,7 +4590,7 @@ Tooltip for BMI info src/app/core/config/config-fix.ts - 639 + 644 @@ -4476,11 +4776,15 @@ Label - Bezeichnung + Label src/app/core/admin/admin-entity-details/admin-entity-field/admin-entity-field.component.html 17 + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 13 + src/app/features/dashboard-widgets/progress-dashboard-widget/progress-dashboard/progress-dashboard.component.html 35 @@ -4535,11 +4839,11 @@ Label for the address of a child src/app/core/config/config-fix.ts - 780 + 785 src/app/core/config/config-fix.ts - 821 + 826 @@ -4548,7 +4852,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 784 + 789 @@ -4557,7 +4861,7 @@ Label for the religion of a child src/app/core/config/config-fix.ts - 788 + 793 @@ -4566,7 +4870,7 @@ Label for the mother tongue of a child src/app/core/config/config-fix.ts - 792 + 797 @@ -4575,7 +4879,7 @@ Tooltip description for the mother tongue of a child src/app/core/config/config-fix.ts - 793 + 798 @@ -4584,7 +4888,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 797 + 802 @@ -4593,7 +4897,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 801 + 806 @@ -4601,11 +4905,11 @@ Privatschule src/app/core/config/config-fix.ts - 307 + 312 src/app/core/config/config-fix.ts - 813 + 818 @@ -4614,7 +4918,7 @@ Label for the language of a school src/app/core/config/config-fix.ts - 817 + 822 @@ -4623,7 +4927,7 @@ Label for the timing of a school src/app/core/config/config-fix.ts - 829 + 834 @@ -4632,7 +4936,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 842 + 847 @@ -4641,7 +4945,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 843 + 848 @@ -4650,7 +4954,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 848 + 853 @@ -4659,7 +4963,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 849 + 854 @@ -4668,7 +4972,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 854 + 859 @@ -4677,7 +4981,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 855 + 860 @@ -4686,7 +4990,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 860 + 865 @@ -4695,7 +4999,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 861 + 866 @@ -4704,7 +5008,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 866 + 871 @@ -4713,7 +5017,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 867 + 872 @@ -4722,7 +5026,7 @@ Label of user phone src/app/core/config/config-fix.ts - 875 + 880 @@ -4831,56 +5135,56 @@ Archive Archivieren + entity context menu src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 69 + 74 - entity context menu Mark the record as inactive, hiding it from lists by default while keeping the data. Datensatz als "inaktiv" markieren, um diesen für Listen standardmäßig auszublenden. Die Daten bleiben dabei aber erhalten. + entity context menu tooltip src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 70 + 75 - entity context menu tooltip Anonymize Anonymisieren + entity context menu src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 77 + 83 - entity context menu Remove all personal data and keep an archived basic record for statistical reporting. Alle persönlichen Daten entfernen und nur einen archivierten Basis-Datensatz für statistische Auswertungen behalten. + entity context menu tooltip src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 78 + 84 - entity context menu tooltip Delete Löschen + entity context menu src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 85 + 91 - entity context menu Remove the record completely from the database. Datensatz vollständig aus der Datenbank entfernen. + entity context menu tooltip src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 86 + 92 - entity context menu tooltip Archived @@ -4914,30 +5218,33 @@ 19,22 - + Adding new Neuer Eintrag - An entity is a child, note, school, etc. - Title when adding a new entity src/app/core/entity-details/entity-details/entity-details.component.html - 27 + 6,8 + Title when adding a new entity Edit Data Structure Datenstruktur anpassen src/app/core/entity-details/entity-details/entity-details.component.html - 41 + 29 src/app/core/entity-list/entity-list/entity-list.component.html - 232 + 233 src/app/core/entity-list/entity-list/entity-list.component.html - 232 + 233 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 233 @@ -4946,7 +5253,7 @@ Tooltip explaining disabled sections when creating new entity src/app/core/entity-details/entity-details/entity-details.component.html - 60 + 45 @@ -4958,7 +5265,7 @@ src/app/core/common-components/view-title/view-title.component.html - 6 + 8 @@ -5030,7 +5337,7 @@ Speichern von fehlgeschlagen: src/app/core/common-components/entity-form/entity-form.service.ts - 253 + 258 @@ -5042,7 +5349,7 @@ )"/> src/app/core/common-components/entity-form/entity-form.service.ts - 281,283 + 286 @@ -5372,11 +5679,15 @@ Examples of things to filter src/app/core/entity-list/entity-list/entity-list.component.html - 88 + 87 src/app/core/entity-list/entity-list/entity-list.component.html - 88 + 87 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 87 @@ -5385,11 +5696,15 @@ Add a new entity to a list of multiple entities src/app/core/entity-list/entity-list/entity-list.component.html - 141 + 140 src/app/core/entity-list/entity-list/entity-list.component.html - 141 + 140 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 140 @@ -5398,11 +5713,15 @@ Show filter options popup for list src/app/core/entity-list/entity-list/entity-list.component.html - 153 + 152 src/app/core/entity-list/entity-list/entity-list.component.html - 153 + 152 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 152 @@ -5411,11 +5730,15 @@ Download list contents as CSV src/app/core/entity-list/entity-list/entity-list.component.html - 172 + 171 src/app/core/entity-list/entity-list/entity-list.component.html - 172 + 171 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 171 @@ -5424,11 +5747,15 @@ Download list contents as CSV src/app/core/entity-list/entity-list/entity-list.component.html - 190 + 189 src/app/core/entity-list/entity-list/entity-list.component.html - 190 + 189 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 189 @@ -5438,11 +5765,15 @@ Filter placeholder src/app/core/entity-list/entity-list/entity-list.component.html - 82 + 81 src/app/core/entity-list/entity-list/entity-list.component.html - 82 + 81 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 81 @@ -5450,11 +5781,15 @@ Datei importieren src/app/core/entity-list/entity-list/entity-list.component.html - 206 + 205 src/app/core/entity-list/entity-list/entity-list.component.html - 206 + 205 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 205 @@ -5462,11 +5797,15 @@ Wählen Sie mehrere Datensätze aus, um gemeinsame Aktionen für alle auszuführen (z.B. Duplizieren oder Löschen) src/app/core/entity-list/entity-list/entity-list.component.html - 212 + 211 src/app/core/entity-list/entity-list/entity-list.component.html - 212 + 211 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 211 @@ -5474,11 +5813,15 @@ Massen-Bearbeitung src/app/core/entity-list/entity-list/entity-list.component.html - 220 + 219 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 219 src/app/core/entity-list/entity-list/entity-list.component.html - 220 + 219 @@ -5486,11 +5829,15 @@ Aktionen auf allen markierten Datensätzen: src/app/core/entity-list/entity-list/entity-list.component.html - 240 + 241 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 241 src/app/core/entity-list/entity-list/entity-list.component.html - 240 + 241 @@ -5498,11 +5845,15 @@ Zeilen auswählen, um Aktion auf mehreren Datensätzen auszuführen src/app/core/entity-list/entity-list/entity-list.component.html - 244 + 245 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 245 src/app/core/entity-list/entity-list/entity-list.component.html - 244 + 245 @@ -5511,11 +5862,15 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 253 + 254 src/app/core/entity-list/entity-list/entity-list.component.html - 253 + 254 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 254 @@ -5524,11 +5879,15 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 262 + 263 src/app/core/entity-list/entity-list/entity-list.component.html - 262 + 263 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 263 @@ -5537,11 +5896,15 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 271 + 272 src/app/core/entity-list/entity-list/entity-list.component.html - 271 + 272 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 272 @@ -5550,11 +5913,15 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 280 + 281 src/app/core/entity-list/entity-list/entity-list.component.html - 280 + 281 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 281 @@ -5562,11 +5929,15 @@ Abbrechen src/app/core/entity-list/entity-list/entity-list.component.html - 284 + 285 src/app/core/entity-list/entity-list/entity-list.component.html - 284 + 285 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 285 @@ -5607,22 +5978,22 @@ Cancel Abbrechen + Form cancel button src/app/core/form-dialog/dialog-buttons/dialog-buttons.component.html - 21,23 + 22 - Form cancel button Go to details Gehe zu Details + Form button to navigate to details page of entity src/app/core/form-dialog/dialog-buttons/dialog-buttons.component.html - 32,34 + 33 - Form button to navigate to details page of entity Select file @@ -5702,7 +6073,7 @@ Slider that allows a user to also include events src/app/child-dev-project/notes/notes-manager/notes-manager.component.html - 22 + 28 @@ -5849,7 +6220,7 @@ tooltip for remove icon on chips of dropdown item src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html - 110 + 127 @@ -6275,7 +6646,7 @@ Navigate to user profile page src/app/core/ui/ui/ui.component.html - 95 + 97 @@ -6286,7 +6657,7 @@ Sign out of the app src/app/core/ui/ui/ui.component.html - 105 + 107 @@ -6752,7 +7123,10 @@ Continue Weiter - import next step button + + src/app/core/admin/setup-wizard/setup-wizard.component.html + 28 + src/app/core/import/import/import.component.html 27 @@ -6766,6 +7140,22 @@ 132 + + We will hide the setup wizard from the main menu as you finish it here. You can still access it from the admin screen. + Der Setup-Assistent wird im Hauptmenü versteckt, nachdem Sie den Prozess hiermit abschließen. Sie können diesen Bildschirm aber weiterhin über dem Admin-Bereich aufrufen. + + src/app/core/admin/setup-wizard/setup-wizard.component.html + 36 + + + + Finish + Abschließen + + src/app/core/admin/setup-wizard/setup-wizard.component.html + 39,41 + + Select Import Type(s) Import Datentyp wählen @@ -7379,7 +7769,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 205 + 206 @@ -7388,7 +7778,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 171 + 172 @@ -7397,7 +7787,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 176 + 177 @@ -7406,7 +7796,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 181 + 182 @@ -7414,7 +7804,7 @@ Alle src/app/features/todos/todo-list/todo-list.component.ts - 184 + 185 @@ -7422,7 +7812,7 @@ fällige Aufgaben src/app/features/todos/todo-list/todo-list.component.ts - 186 + 187 diff --git a/src/assets/locale/messages.fr.xlf b/src/assets/locale/messages.fr.xlf index f778097182..7672a450c5 100644 --- a/src/assets/locale/messages.fr.xlf +++ b/src/assets/locale/messages.fr.xlf @@ -85,7 +85,7 @@ src/app/core/config/config-fix.ts - 833 + 838 @@ -777,11 +777,11 @@ src/app/core/config/config-fix.ts - 378 + 383 src/app/core/config/config-fix.ts - 473 + 478 @@ -909,7 +909,7 @@ src/app/core/config/config-fix.ts - 746 + 751 src/app/features/reporting/demo-report-config-generator.service.ts @@ -1018,7 +1018,7 @@ src/app/core/config/config-fix.ts - 691 + 696 @@ -1137,11 +1137,11 @@ src/app/core/config/config-fix.ts - 362 + 367 src/app/core/config/config-fix.ts - 809 + 814 src/app/features/reporting/demo-report-config-generator.service.ts @@ -1225,7 +1225,7 @@ src/app/core/config/config-fix.ts - 433 + 438 @@ -1274,7 +1274,7 @@ src/app/core/config/config-fix.ts - 825 + 830 @@ -1287,7 +1287,7 @@ src/app/core/config/config-fix.ts - 774 + 779 @@ -1300,7 +1300,7 @@ src/app/core/config/config-fix.ts - 373 + 378 @@ -1586,7 +1586,7 @@ Table header, Short for Body Mass Index src/app/core/config/config-fix.ts - 637 + 642 @@ -1595,7 +1595,7 @@ Tooltip for BMI info src/app/core/config/config-fix.ts - 639 + 644 @@ -2114,11 +2114,11 @@ src/app/core/config/config-fix.ts - 300 + 305 src/app/core/config/config-fix.ts - 775 + 780 @@ -2200,7 +2200,7 @@ Download note details as CSV src/app/child-dev-project/notes/note-details/note-details.component.html - 84 + 71 @@ -2359,6 +2359,10 @@ src/app/core/admin/admin-entity-details/admin-entity-field/admin-entity-field.component.html 17 + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 13 + src/app/features/dashboard-widgets/progress-dashboard-widget/progress-dashboard/progress-dashboard.component.html 35 @@ -2639,12 +2643,12 @@ Add new Add new + e.g. Add new My new Option + Label for adding an option in a dropdown src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html - 63 + 80 - e.g. Add new My new Option - Label for adding an option in a dropdown Imported values @@ -2936,6 +2940,16 @@ 39 + + You can edit how users will see the details of a single record of this type. Drag and drop fields and sections in this preview of a profile view and group them as appropriate. We recommend to keep things simple: Only add fields that you really need for your work. + + You can edit how users will see the details of a single record of this type. Drag and drop fields and sections in this preview of a profile view and group them as appropriate. We recommend to keep things simple: Only add fields that you really need for your work. + + + src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html + 4,9 + + Add Section src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html - 39,45 + 45 @@ -2973,6 +2987,10 @@ src/app/core/admin/admin-entity-details/admin-entity-field/admin-entity-field.component.html 13 + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 9 + Optionally you can define an additional shorter label to be displayed in table headers and other places where space is limited. @@ -3175,6 +3193,80 @@ 80 + + General Settings of "" Records + General Settings of "" Records + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 1 + + + + The settings here apply to the entity type overall and take effect everywhere the entity is displayed, including lists, forms and other views. + + The settings here apply to the entity type overall and take effect everywhere the entity is displayed, including lists, forms and other views. + + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 2,5 + + + + Label (Plural) + Label (Plural) + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 19 + + + + Optionally you can define how multiple records of this entity should be called, e.g. in lists. + Optionally you can define how multiple records of this entity should be called, e.g. in lists. + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 22 + + + + Icon + Icon + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 35 + + + + The icon to represent this entity type, e.g. when displaying records as a small preview block. [see fontawesome.com/icons] + The icon to represent this entity type, e.g. when displaying records as a small preview block. [see fontawesome.com/icons] + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 38 + + + + Generated Title of Record + Generated Title of Record + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 53 + + + + Select the fields that should be used (in that order) to generate a simple name/title for a record. This generated title is used in previews, search and for form fields that allow to select a record of this type. (Only text fields can be used here) + Select the fields that should be used (in that order) to generate a simple name/title for a record. This generated title is used in previews, search and for form fields that allow to select a record of this type. (Only text fields can be used here) + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 56 + + + + Configure PII / Anonymization + Configure PII / Anonymization + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 77 + + Editing data structure for "" records Editing data structure for "" records @@ -3224,16 +3316,219 @@ add a new tab src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.html - 30 + 47 + + Setup Wizard + Setup Wizard + + src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.html + 10,12 + + + + Welcome + Welcome + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 27 + + Setup Wizard Step Title + + + +# Welcome to Aam Digital! +We are here to help you manage your participants' or beneficiaries' details +and your team's interactions with them. + +The Aam Digital platform is very flexible and you can customize the structures and views +to exactly fit your project needs. +The following steps guide you through the most important configuration options for this. +And you can start working with your data within a few minutes already. + +We also have some short video guides for you: [Aam Digital Video Guides (YouTube)](https://www.youtube.com/channel/UCZSFOX_MBa8zz5Mtfv_qlnA/videos) + +Feel free to leave this setup wizard in between to explore the existing system first. +You can always come back to this view through the "Setup Wizard" button at the bottom of the main menu on the left. +To dismiss and hide this wizard, go to the last step of the wizard and "finish" the setup process. + +# Welcome to Aam Digital! +We are here to help you manage your participants' or beneficiaries' details +and your team's interactions with them. + +The Aam Digital platform is very flexible and you can customize the structures and views +to exactly fit your project needs. +The following steps guide you through the most important configuration options for this. +And you can start working with your data within a few minutes already. + +We also have some short video guides for you: [Aam Digital Video Guides (YouTube)](https://www.youtube.com/channel/UCZSFOX_MBa8zz5Mtfv_qlnA/videos) + +Feel free to leave this setup wizard in between to explore the existing system first. +You can always come back to this view through the "Setup Wizard" button at the bottom of the main menu on the left. +To dismiss and hide this wizard, go to the last step of the wizard and "finish" the setup process. + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 28,42 + + Setup Wizard Step Text + + + Profiles & Fields + Profiles & Fields + Setup Wizard Step Title + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 45 + + + + +The system already holds some basic structures for your case management. +You can adapt the fields and how the details are displayed. + +If you have further requirements, don't hesitate to reach out to us at [support@aam-digital.com](mailto:support@aam-digital.com). + +_Please note that the setup wizard and form builder is still under active development ("beta" version). +Some advanced configuration options are not available here yet for you to configure yourself and may need assistance from the tech support team. +We are currently extending and optimizing the user interfaces for these steps._ + + +The system already holds some basic structures for your case management. +You can adapt the fields and how the details are displayed. + +If you have further requirements, don't hesitate to reach out to us at [support@aam-digital.com](mailto:support@aam-digital.com). + +_Please note that the setup wizard and form builder is still under active development ("beta" version). +Some advanced configuration options are not available here yet for you to configure yourself and may need assistance from the tech support team. +We are currently extending and optimizing the user interfaces for these steps._ + + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 46,55 + + Setup Wizard Step Text + + + Customize Child profile + Customize Child profile + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 58 + + Setup Wizard Step Action + + + Customize School profile + Customize School profile + Setup Wizard Step Action + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 62 + + + + User Accounts + User Accounts + Setup Wizard Step Title + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 68 + + + + +You can collaborate on Aam Digital as a team. +Data is synced and all users have access to the latest information. + +You can collaborate on Aam Digital as a team. +Data is synced and all users have access to the latest information. + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 69,71 + + Setup Wizard Step Text + + + Manage User Accounts + Manage User Accounts + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 74 + + Setup Wizard Step Action + + + Import Data + Import Data + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 80 + + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 88 + + Setup Wizard Step Title + + + +If you have exising data from a previous system, you can easily import it. +Save the data in ".csv" format (e.g. from MS Excel). +You do not need any specific column names in your file to be imported. +The Import Module helps your map your spreadsheet data to the relevant fields in your Aam Digital profiles. + +If you have exising data from a previous system, you can easily import it. +Save the data in ".csv" format (e.g. from MS Excel). +You do not need any specific column names in your file to be imported. +The Import Module helps your map your spreadsheet data to the relevant fields in your Aam Digital profiles. + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 81,85 + + Setup Wizard Step Text + + + Done! + Done! + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 94 + + Setup Wizard Step Title + + + +That's it. You are ready to explore your system and start work! + +You can always adapt your setup further, after you started using it. +We recommend to keep things simple in the beginning, +start using it for some of your tasks +and then add further fields and adjust your setup. + +Feel free to reach out to us with your questions or feedback: [support@aam-digital.com](mailto:support@aam-digital.com) + +That's it. You are ready to explore your system and start work! + +You can always adapt your setup further, after you started using it. +We recommend to keep things simple in the beginning, +start using it for some of your tasks +and then add further fields and adjust your setup. + +Feel free to reach out to us with your questions or feedback: [support@aam-digital.com](mailto:support@aam-digital.com) + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 95,103 + + Setup Wizard Step Text + Configuration updated Configuration updated Save config confirmation message src/app/core/admin/admin-entity/admin-entity.component.ts - 132 + 141 @@ -3650,7 +3945,7 @@ Title for notes overview src/app/core/config/config-fix.ts - 165 + 164 @@ -3659,11 +3954,11 @@ Translated name of default column group src/app/core/config/config-fix.ts - 169 + 168 src/app/core/config/config-fix.ts - 173 + 172 @@ -3672,19 +3967,19 @@ Translated name of mobile column group src/app/core/config/config-fix.ts - 170 + 169 src/app/core/config/config-fix.ts - 183 + 182 src/app/core/config/config-fix.ts - 404 + 409 src/app/core/config/config-fix.ts - 457 + 462 @@ -3700,7 +3995,7 @@ Site Settings src/app/core/admin/admin.routing.ts - 39 + 44 @@ -3721,13 +4016,22 @@ admin menu item + + Setup Wizard + Setup Wizard + + src/app/core/admin/admin/admin.component.html + 20,22 + + admin menu item + User Information User Information Panel title src/app/core/config/config-fix.ts - 257 + 262 @@ -3736,7 +4040,7 @@ Panel title src/app/core/config/config-fix.ts - 272 + 277 @@ -3745,7 +4049,7 @@ Filename of markdown help page (make sure the filename you enter as a translation actually exists on the server!) src/app/core/config/config-fix.ts - 285 + 290 @@ -3753,11 +4057,11 @@ École privée src/app/core/config/config-fix.ts - 307 + 312 src/app/core/config/config-fix.ts - 813 + 818 @@ -3766,15 +4070,15 @@ Panel title src/app/core/config/config-fix.ts - 318 + 323 src/app/core/config/config-fix.ts - 491 + 496 src/app/core/config/config-fix.ts - 731 + 736 @@ -3783,7 +4087,7 @@ Panel title src/app/core/config/config-fix.ts - 335 + 340 @@ -3792,7 +4096,7 @@ Panel title src/app/core/config/config-fix.ts - 344 + 349 @@ -3801,7 +4105,7 @@ Column label for age of child src/app/core/config/config-fix.ts - 367 + 372 @@ -3810,7 +4114,7 @@ Column label for school attendance of child src/app/core/config/config-fix.ts - 385 + 390 @@ -3819,7 +4123,7 @@ Column label for coaching attendance of child src/app/core/config/config-fix.ts - 394 + 399 @@ -3828,7 +4132,7 @@ Column group name src/app/core/config/config-fix.ts - 420 + 425 @@ -3837,11 +4141,11 @@ Translated name of default column group src/app/core/config/config-fix.ts - 403 + 408 src/app/core/config/config-fix.ts - 407 + 412 @@ -3850,11 +4154,11 @@ Column group name src/app/core/config/config-fix.ts - 443 + 448 src/app/core/config/config-fix.ts - 608 + 613 @@ -3863,7 +4167,7 @@ Header for form section src/app/core/config/config-fix.ts - 501 + 506 @@ -3872,7 +4176,7 @@ Header for form section src/app/core/config/config-fix.ts - 505 + 510 @@ -3881,7 +4185,7 @@ Header for form section src/app/core/config/config-fix.ts - 509 + 514 @@ -3890,7 +4194,7 @@ Panel title src/app/core/config/config-fix.ts - 517 + 522 @@ -3899,7 +4203,7 @@ Title inside a panel src/app/core/config/config-fix.ts - 520 + 525 @@ -3908,7 +4212,7 @@ Title inside a panel src/app/core/config/config-fix.ts - 540 + 545 @@ -3917,7 +4221,7 @@ Child details section title src/app/core/config/config-fix.ts - 574 + 579 @@ -3926,7 +4230,7 @@ Panel title src/app/core/config/config-fix.ts - 595 + 600 @@ -3935,7 +4239,7 @@ description section src/app/core/config/config-fix.ts - 618 + 623 @@ -3948,7 +4252,7 @@ src/app/core/config/config-fix.ts - 586 + 591 @@ -3970,7 +4274,7 @@ Title inside a panel src/app/core/config/config-fix.ts - 626 + 631 @@ -3979,7 +4283,7 @@ Panel title src/app/core/config/config-fix.ts - 647 + 652 @@ -3988,7 +4292,7 @@ Panel title src/app/core/config/config-fix.ts - 672 + 677 @@ -3997,7 +4301,7 @@ Panel title src/app/core/config/config-fix.ts - 759 + 764 @@ -4141,11 +4445,11 @@ Label for the address of a child src/app/core/config/config-fix.ts - 780 + 785 src/app/core/config/config-fix.ts - 821 + 826 @@ -4154,7 +4458,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 784 + 789 @@ -4163,7 +4467,7 @@ Label for the religion of a child src/app/core/config/config-fix.ts - 788 + 793 @@ -4172,7 +4476,7 @@ Label for the mother tongue of a child src/app/core/config/config-fix.ts - 792 + 797 @@ -4181,7 +4485,7 @@ Tooltip description for the mother tongue of a child src/app/core/config/config-fix.ts - 793 + 798 @@ -4190,7 +4494,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 797 + 802 @@ -4199,7 +4503,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 801 + 806 @@ -4208,7 +4512,7 @@ Label for the language of a school src/app/core/config/config-fix.ts - 817 + 822 @@ -4217,7 +4521,7 @@ Label for the timing of a school src/app/core/config/config-fix.ts - 829 + 834 @@ -4226,7 +4530,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 842 + 847 @@ -4235,7 +4539,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 843 + 848 @@ -4244,7 +4548,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 848 + 853 @@ -4253,7 +4557,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 849 + 854 @@ -4262,7 +4566,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 854 + 859 @@ -4271,7 +4575,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 855 + 860 @@ -4280,7 +4584,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 860 + 865 @@ -4289,7 +4593,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 861 + 866 @@ -4298,7 +4602,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 866 + 871 @@ -4307,7 +4611,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 867 + 872 @@ -4316,7 +4620,7 @@ Label of user phone src/app/core/config/config-fix.ts - 875 + 880 @@ -4561,56 +4865,56 @@ Archive Archive + entity context menu src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 69 + 74 - entity context menu Mark the record as inactive, hiding it from lists by default while keeping the data. Mark the record as inactive, hiding it from lists by default while keeping the data. + entity context menu tooltip src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 70 + 75 - entity context menu tooltip Anonymize Anonymize + entity context menu src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 77 + 83 - entity context menu Remove all personal data and keep an archived basic record for statistical reporting. Remove all personal data and keep an archived basic record for statistical reporting. + entity context menu tooltip src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 78 + 84 - entity context menu tooltip Delete Supprimer + entity context menu src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 85 + 91 - entity context menu Remove the record completely from the database. Remove the record completely from the database. + entity context menu tooltip src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 86 + 92 - entity context menu tooltip Archived @@ -4644,30 +4948,33 @@ 19,22 - + Adding new Ajout d'un(e) - An entity is a child, note, school, etc. - Title when adding a new entity src/app/core/entity-details/entity-details/entity-details.component.html - 27 + 6,8 + Title when adding a new entity Edit Data Structure Edit Data Structure src/app/core/entity-details/entity-details/entity-details.component.html - 41 + 29 src/app/core/entity-list/entity-list/entity-list.component.html - 232 + 233 src/app/core/entity-list/entity-list/entity-list.component.html - 232 + 233 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 233 @@ -4676,7 +4983,7 @@ Tooltip explaining disabled sections when creating new entity src/app/core/entity-details/entity-details/entity-details.component.html - 60 + 45 @@ -4688,7 +4995,7 @@ src/app/core/common-components/view-title/view-title.component.html - 6 + 8 @@ -4760,7 +5067,7 @@ Echec pour sauvegarder : src/app/core/common-components/entity-form/entity-form.service.ts - 253 + 258 @@ -4772,7 +5079,7 @@ )"/> src/app/core/common-components/entity-form/entity-form.service.ts - 281,283 + 286 @@ -4807,11 +5114,15 @@ Examples of things to filter src/app/core/entity-list/entity-list/entity-list.component.html - 88 + 87 src/app/core/entity-list/entity-list/entity-list.component.html - 88 + 87 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 87 @@ -4820,11 +5131,15 @@ Add a new entity to a list of multiple entities src/app/core/entity-list/entity-list/entity-list.component.html - 141 + 140 src/app/core/entity-list/entity-list/entity-list.component.html - 141 + 140 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 140 @@ -4833,11 +5148,15 @@ Show filter options popup for list src/app/core/entity-list/entity-list/entity-list.component.html - 153 + 152 src/app/core/entity-list/entity-list/entity-list.component.html - 153 + 152 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 152 @@ -4846,11 +5165,15 @@ Download list contents as CSV src/app/core/entity-list/entity-list/entity-list.component.html - 172 + 171 src/app/core/entity-list/entity-list/entity-list.component.html - 172 + 171 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 171 @@ -4859,11 +5182,15 @@ Download list contents as CSV src/app/core/entity-list/entity-list/entity-list.component.html - 190 + 189 src/app/core/entity-list/entity-list/entity-list.component.html - 190 + 189 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 189 @@ -4873,11 +5200,15 @@ Filter placeholder src/app/core/entity-list/entity-list/entity-list.component.html - 82 + 81 src/app/core/entity-list/entity-list/entity-list.component.html - 82 + 81 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 81 @@ -4885,11 +5216,15 @@ Import from file src/app/core/entity-list/entity-list/entity-list.component.html - 206 + 205 src/app/core/entity-list/entity-list/entity-list.component.html - 206 + 205 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 205 @@ -4897,11 +5232,15 @@ Select multiple records for bulk actions like duplicating or deleting src/app/core/entity-list/entity-list/entity-list.component.html - 212 + 211 src/app/core/entity-list/entity-list/entity-list.component.html - 212 + 211 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 211 @@ -4909,11 +5248,15 @@ Bulk Actions src/app/core/entity-list/entity-list/entity-list.component.html - 220 + 219 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 219 src/app/core/entity-list/entity-list/entity-list.component.html - 220 + 219 @@ -4921,11 +5264,15 @@ Actions on selected records: src/app/core/entity-list/entity-list/entity-list.component.html - 240 + 241 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 241 src/app/core/entity-list/entity-list/entity-list.component.html - 240 + 241 @@ -4933,11 +5280,15 @@ Select rows for an action on multiple records src/app/core/entity-list/entity-list/entity-list.component.html - 244 + 245 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 245 src/app/core/entity-list/entity-list/entity-list.component.html - 244 + 245 @@ -4946,11 +5297,15 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 253 + 254 src/app/core/entity-list/entity-list/entity-list.component.html - 253 + 254 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 254 @@ -4959,11 +5314,15 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 262 + 263 src/app/core/entity-list/entity-list/entity-list.component.html - 262 + 263 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 263 @@ -4972,11 +5331,15 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 271 + 272 src/app/core/entity-list/entity-list/entity-list.component.html - 271 + 272 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 272 @@ -4985,11 +5348,15 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 280 + 281 src/app/core/entity-list/entity-list/entity-list.component.html - 280 + 281 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 281 @@ -4997,11 +5364,15 @@ Annuler src/app/core/entity-list/entity-list/entity-list.component.html - 284 + 285 src/app/core/entity-list/entity-list/entity-list.component.html - 284 + 285 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 285 @@ -5042,22 +5413,22 @@ Cancel Annuler + Form cancel button src/app/core/form-dialog/dialog-buttons/dialog-buttons.component.html - 21,23 + 22 - Form cancel button Go to details Go to details + Form button to navigate to details page of entity src/app/core/form-dialog/dialog-buttons/dialog-buttons.component.html - 32,34 + 33 - Form button to navigate to details page of entity Select file @@ -5128,7 +5499,7 @@ Slider that allows a user to also include events src/app/child-dev-project/notes/notes-manager/notes-manager.component.html - 22 + 28 @@ -5188,7 +5559,7 @@ tooltip for remove icon on chips of dropdown item src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html - 110 + 127 @@ -5942,7 +6313,7 @@ Navigate to user profile page src/app/core/ui/ui/ui.component.html - 95 + 97 @@ -5953,7 +6324,7 @@ Sign out of the app src/app/core/ui/ui/ui.component.html - 105 + 107 @@ -6419,7 +6790,10 @@ Continue Continue - import next step button + + src/app/core/admin/setup-wizard/setup-wizard.component.html + 28 + src/app/core/import/import/import.component.html 27 @@ -6433,6 +6807,22 @@ 132 + + We will hide the setup wizard from the main menu as you finish it here. You can still access it from the admin screen. + We will hide the setup wizard from the main menu as you finish it here. You can still access it from the admin screen. + + src/app/core/admin/setup-wizard/setup-wizard.component.html + 36 + + + + Finish + Finish + + src/app/core/admin/setup-wizard/setup-wizard.component.html + 39,41 + + Select Import Type(s) Select Import Type(s) @@ -7451,7 +7841,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 205 + 206 @@ -7460,7 +7850,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 171 + 172 @@ -7469,7 +7859,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 176 + 177 @@ -7478,7 +7868,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 181 + 182 @@ -7486,7 +7876,7 @@ Any src/app/features/todos/todo-list/todo-list.component.ts - 184 + 185 @@ -7494,7 +7884,7 @@ Tasks due src/app/features/todos/todo-list/todo-list.component.ts - 186 + 187 diff --git a/src/assets/locale/messages.it.xlf b/src/assets/locale/messages.it.xlf index cc00916ad7..4b06afa54d 100644 --- a/src/assets/locale/messages.it.xlf +++ b/src/assets/locale/messages.it.xlf @@ -702,7 +702,7 @@ src/app/core/config/config-fix.ts - 746 + 751 src/app/features/reporting/demo-report-config-generator.service.ts @@ -823,7 +823,7 @@ src/app/core/config/config-fix.ts - 833 + 838 @@ -992,7 +992,7 @@ src/app/core/config/config-fix.ts - 691 + 696 @@ -1278,7 +1278,7 @@ Table header, Short for Body Mass Index src/app/core/config/config-fix.ts - 637 + 642 @@ -1287,7 +1287,7 @@ Tooltip for BMI info src/app/core/config/config-fix.ts - 639 + 644 @@ -1331,11 +1331,11 @@ src/app/core/config/config-fix.ts - 362 + 367 src/app/core/config/config-fix.ts - 809 + 814 src/app/features/reporting/demo-report-config-generator.service.ts @@ -1419,7 +1419,7 @@ src/app/core/config/config-fix.ts - 433 + 438 @@ -1468,7 +1468,7 @@ src/app/core/config/config-fix.ts - 825 + 830 @@ -1481,7 +1481,7 @@ src/app/core/config/config-fix.ts - 774 + 779 @@ -1502,11 +1502,11 @@ src/app/core/config/config-fix.ts - 378 + 383 src/app/core/config/config-fix.ts - 473 + 478 @@ -1519,7 +1519,7 @@ src/app/core/config/config-fix.ts - 373 + 378 @@ -2135,11 +2135,11 @@ src/app/core/config/config-fix.ts - 300 + 305 src/app/core/config/config-fix.ts - 775 + 780 @@ -2221,7 +2221,7 @@ Download note details as CSV src/app/child-dev-project/notes/note-details/note-details.component.html - 84 + 71 @@ -2266,7 +2266,7 @@ Slider that allows a user to also include events src/app/child-dev-project/notes/notes-manager/notes-manager.component.html - 22 + 28 @@ -2409,6 +2409,16 @@ 39 + + You can edit how users will see the details of a single record of this type. Drag and drop fields and sections in this preview of a profile view and group them as appropriate. We recommend to keep things simple: Only add fields that you really need for your work. + + You can edit how users will see the details of a single record of this type. Drag and drop fields and sections in this preview of a profile view and group them as appropriate. We recommend to keep things simple: Only add fields that you really need for your work. + + + src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html + 4,9 + + Add Section src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html - 39,45 + 45 @@ -2446,6 +2456,10 @@ src/app/core/admin/admin-entity-details/admin-entity-field/admin-entity-field.component.html 13 + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 9 + Optionally you can define an additional shorter label to be displayed in table headers and other places where space is limited. @@ -2648,6 +2662,80 @@ 80 + + General Settings of "" Records + General Settings of "" Records + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 1 + + + + The settings here apply to the entity type overall and take effect everywhere the entity is displayed, including lists, forms and other views. + + The settings here apply to the entity type overall and take effect everywhere the entity is displayed, including lists, forms and other views. + + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 2,5 + + + + Label (Plural) + Label (Plural) + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 19 + + + + Optionally you can define how multiple records of this entity should be called, e.g. in lists. + Optionally you can define how multiple records of this entity should be called, e.g. in lists. + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 22 + + + + Icon + Icon + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 35 + + + + The icon to represent this entity type, e.g. when displaying records as a small preview block. [see fontawesome.com/icons] + The icon to represent this entity type, e.g. when displaying records as a small preview block. [see fontawesome.com/icons] + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 38 + + + + Generated Title of Record + Generated Title of Record + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 53 + + + + Select the fields that should be used (in that order) to generate a simple name/title for a record. This generated title is used in previews, search and for form fields that allow to select a record of this type. (Only text fields can be used here) + Select the fields that should be used (in that order) to generate a simple name/title for a record. This generated title is used in previews, search and for form fields that allow to select a record of this type. (Only text fields can be used here) + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 56 + + + + Configure PII / Anonymization + Configure PII / Anonymization + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 77 + + Editing data structure for "" records Editing data structure for "" records @@ -2697,8 +2785,211 @@ add a new tab src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.html - 30 + 47 + + + + Setup Wizard + Setup Wizard + + src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.html + 10,12 + + + + Welcome + Welcome + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 27 + Setup Wizard Step Title + + + +# Welcome to Aam Digital! +We are here to help you manage your participants' or beneficiaries' details +and your team's interactions with them. + +The Aam Digital platform is very flexible and you can customize the structures and views +to exactly fit your project needs. +The following steps guide you through the most important configuration options for this. +And you can start working with your data within a few minutes already. + +We also have some short video guides for you: [Aam Digital Video Guides (YouTube)](https://www.youtube.com/channel/UCZSFOX_MBa8zz5Mtfv_qlnA/videos) + +Feel free to leave this setup wizard in between to explore the existing system first. +You can always come back to this view through the "Setup Wizard" button at the bottom of the main menu on the left. +To dismiss and hide this wizard, go to the last step of the wizard and "finish" the setup process. + +# Welcome to Aam Digital! +We are here to help you manage your participants' or beneficiaries' details +and your team's interactions with them. + +The Aam Digital platform is very flexible and you can customize the structures and views +to exactly fit your project needs. +The following steps guide you through the most important configuration options for this. +And you can start working with your data within a few minutes already. + +We also have some short video guides for you: [Aam Digital Video Guides (YouTube)](https://www.youtube.com/channel/UCZSFOX_MBa8zz5Mtfv_qlnA/videos) + +Feel free to leave this setup wizard in between to explore the existing system first. +You can always come back to this view through the "Setup Wizard" button at the bottom of the main menu on the left. +To dismiss and hide this wizard, go to the last step of the wizard and "finish" the setup process. + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 28,42 + + Setup Wizard Step Text + + + Profiles & Fields + Profiles & Fields + Setup Wizard Step Title + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 45 + + + + +The system already holds some basic structures for your case management. +You can adapt the fields and how the details are displayed. + +If you have further requirements, don't hesitate to reach out to us at [support@aam-digital.com](mailto:support@aam-digital.com). + +_Please note that the setup wizard and form builder is still under active development ("beta" version). +Some advanced configuration options are not available here yet for you to configure yourself and may need assistance from the tech support team. +We are currently extending and optimizing the user interfaces for these steps._ + + +The system already holds some basic structures for your case management. +You can adapt the fields and how the details are displayed. + +If you have further requirements, don't hesitate to reach out to us at [support@aam-digital.com](mailto:support@aam-digital.com). + +_Please note that the setup wizard and form builder is still under active development ("beta" version). +Some advanced configuration options are not available here yet for you to configure yourself and may need assistance from the tech support team. +We are currently extending and optimizing the user interfaces for these steps._ + + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 46,55 + + Setup Wizard Step Text + + + Customize Child profile + Customize Child profile + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 58 + + Setup Wizard Step Action + + + Customize School profile + Customize School profile + Setup Wizard Step Action + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 62 + + + + User Accounts + User Accounts + Setup Wizard Step Title + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 68 + + + + +You can collaborate on Aam Digital as a team. +Data is synced and all users have access to the latest information. + +You can collaborate on Aam Digital as a team. +Data is synced and all users have access to the latest information. + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 69,71 + + Setup Wizard Step Text + + + Manage User Accounts + Manage User Accounts + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 74 + + Setup Wizard Step Action + + + Import Data + Import Data + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 80 + + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 88 + + Setup Wizard Step Title + + + +If you have exising data from a previous system, you can easily import it. +Save the data in ".csv" format (e.g. from MS Excel). +You do not need any specific column names in your file to be imported. +The Import Module helps your map your spreadsheet data to the relevant fields in your Aam Digital profiles. + +If you have exising data from a previous system, you can easily import it. +Save the data in ".csv" format (e.g. from MS Excel). +You do not need any specific column names in your file to be imported. +The Import Module helps your map your spreadsheet data to the relevant fields in your Aam Digital profiles. + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 81,85 + + Setup Wizard Step Text + + + Done! + Done! + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 94 + + Setup Wizard Step Title + + + +That's it. You are ready to explore your system and start work! + +You can always adapt your setup further, after you started using it. +We recommend to keep things simple in the beginning, +start using it for some of your tasks +and then add further fields and adjust your setup. + +Feel free to reach out to us with your questions or feedback: [support@aam-digital.com](mailto:support@aam-digital.com) + +That's it. You are ready to explore your system and start work! + +You can always adapt your setup further, after you started using it. +We recommend to keep things simple in the beginning, +start using it for some of your tasks +and then add further fields and adjust your setup. + +Feel free to reach out to us with your questions or feedback: [support@aam-digital.com](mailto:support@aam-digital.com) + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 95,103 + + Setup Wizard Step Text Configuration updated @@ -2706,7 +2997,7 @@ Save config confirmation message src/app/core/admin/admin-entity/admin-entity.component.ts - 132 + 141 @@ -2987,7 +3278,7 @@ src/app/core/config/config-fix.ts - 586 + 591 @@ -3124,7 +3415,7 @@ Title for notes overview src/app/core/config/config-fix.ts - 165 + 164 @@ -3133,11 +3424,11 @@ Translated name of default column group src/app/core/config/config-fix.ts - 169 + 168 src/app/core/config/config-fix.ts - 173 + 172 @@ -3146,19 +3437,19 @@ Translated name of mobile column group src/app/core/config/config-fix.ts - 170 + 169 src/app/core/config/config-fix.ts - 183 + 182 src/app/core/config/config-fix.ts - 404 + 409 src/app/core/config/config-fix.ts - 457 + 462 @@ -3174,7 +3465,7 @@ Site Settings src/app/core/admin/admin.routing.ts - 39 + 44 @@ -3195,13 +3486,22 @@ admin menu item + + Setup Wizard + Setup Wizard + + src/app/core/admin/admin/admin.component.html + 20,22 + + admin menu item + User Information User Information Panel title src/app/core/config/config-fix.ts - 257 + 262 @@ -3210,7 +3510,7 @@ Panel title src/app/core/config/config-fix.ts - 272 + 277 @@ -3219,7 +3519,7 @@ Filename of markdown help page (make sure the filename you enter as a translation actually exists on the server!) src/app/core/config/config-fix.ts - 285 + 290 @@ -3228,15 +3528,15 @@ Panel title src/app/core/config/config-fix.ts - 318 + 323 src/app/core/config/config-fix.ts - 491 + 496 src/app/core/config/config-fix.ts - 731 + 736 @@ -3245,7 +3545,7 @@ Panel title src/app/core/config/config-fix.ts - 335 + 340 @@ -3254,7 +3554,7 @@ Panel title src/app/core/config/config-fix.ts - 344 + 349 @@ -3263,7 +3563,7 @@ Column label for age of child src/app/core/config/config-fix.ts - 367 + 372 @@ -3272,7 +3572,7 @@ Column label for school attendance of child src/app/core/config/config-fix.ts - 385 + 390 @@ -3281,7 +3581,7 @@ Column label for coaching attendance of child src/app/core/config/config-fix.ts - 394 + 399 @@ -3290,11 +3590,11 @@ Translated name of default column group src/app/core/config/config-fix.ts - 403 + 408 src/app/core/config/config-fix.ts - 407 + 412 @@ -3303,7 +3603,7 @@ Column group name src/app/core/config/config-fix.ts - 420 + 425 @@ -3312,11 +3612,11 @@ Column group name src/app/core/config/config-fix.ts - 443 + 448 src/app/core/config/config-fix.ts - 608 + 613 @@ -3325,7 +3625,7 @@ Header for form section src/app/core/config/config-fix.ts - 501 + 506 @@ -3334,7 +3634,7 @@ Header for form section src/app/core/config/config-fix.ts - 505 + 510 @@ -3343,7 +3643,7 @@ Header for form section src/app/core/config/config-fix.ts - 509 + 514 @@ -3352,7 +3652,7 @@ Panel title src/app/core/config/config-fix.ts - 517 + 522 @@ -3361,7 +3661,7 @@ Title inside a panel src/app/core/config/config-fix.ts - 520 + 525 @@ -3370,7 +3670,7 @@ Title inside a panel src/app/core/config/config-fix.ts - 540 + 545 @@ -3379,7 +3679,7 @@ Child details section title src/app/core/config/config-fix.ts - 574 + 579 @@ -3388,7 +3688,7 @@ Panel title src/app/core/config/config-fix.ts - 595 + 600 @@ -3397,7 +3697,7 @@ description section src/app/core/config/config-fix.ts - 618 + 623 @@ -3406,7 +3706,7 @@ Title inside a panel src/app/core/config/config-fix.ts - 626 + 631 @@ -3415,7 +3715,7 @@ Panel title src/app/core/config/config-fix.ts - 647 + 652 @@ -3424,7 +3724,7 @@ Panel title src/app/core/config/config-fix.ts - 672 + 677 @@ -3442,7 +3742,7 @@ Panel title src/app/core/config/config-fix.ts - 759 + 764 @@ -3645,11 +3945,11 @@ Label for the address of a child src/app/core/config/config-fix.ts - 780 + 785 src/app/core/config/config-fix.ts - 821 + 826 @@ -3658,7 +3958,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 784 + 789 @@ -3667,7 +3967,7 @@ Label for the religion of a child src/app/core/config/config-fix.ts - 788 + 793 @@ -3676,7 +3976,7 @@ Label for the mother tongue of a child src/app/core/config/config-fix.ts - 792 + 797 @@ -3685,7 +3985,7 @@ Tooltip description for the mother tongue of a child src/app/core/config/config-fix.ts - 793 + 798 @@ -3694,7 +3994,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 797 + 802 @@ -3703,7 +4003,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 801 + 806 @@ -3711,11 +4011,11 @@ Private School src/app/core/config/config-fix.ts - 307 + 312 src/app/core/config/config-fix.ts - 813 + 818 @@ -3724,7 +4024,7 @@ Label for the language of a school src/app/core/config/config-fix.ts - 817 + 822 @@ -3733,7 +4033,7 @@ Label for the timing of a school src/app/core/config/config-fix.ts - 829 + 834 @@ -3742,7 +4042,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 842 + 847 @@ -3751,7 +4051,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 843 + 848 @@ -3760,7 +4060,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 848 + 853 @@ -3769,7 +4069,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 849 + 854 @@ -3778,7 +4078,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 854 + 859 @@ -3787,7 +4087,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 855 + 860 @@ -3796,7 +4096,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 860 + 865 @@ -3805,7 +4105,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 861 + 866 @@ -3814,7 +4114,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 866 + 871 @@ -3823,7 +4123,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 867 + 872 @@ -3832,7 +4132,7 @@ Label of user phone src/app/core/config/config-fix.ts - 875 + 880 @@ -4026,56 +4326,56 @@ Archive Archive + entity context menu src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 69 + 74 - entity context menu Mark the record as inactive, hiding it from lists by default while keeping the data. Mark the record as inactive, hiding it from lists by default while keeping the data. + entity context menu tooltip src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 70 + 75 - entity context menu tooltip Anonymize Anonymize + entity context menu src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 77 + 83 - entity context menu Remove all personal data and keep an archived basic record for statistical reporting. Remove all personal data and keep an archived basic record for statistical reporting. + entity context menu tooltip src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 78 + 84 - entity context menu tooltip Delete Elimina + entity context menu src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 85 + 91 - entity context menu Remove the record completely from the database. Remove the record completely from the database. + entity context menu tooltip src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 86 + 92 - entity context menu tooltip Archived @@ -4109,30 +4409,33 @@ 19,22 - + Adding new Nuovo - An entity is a child, note, school, etc. - Title when adding a new entity src/app/core/entity-details/entity-details/entity-details.component.html - 27 + 6,8 + Title when adding a new entity Edit Data Structure Edit Data Structure src/app/core/entity-details/entity-details/entity-details.component.html - 41 + 29 src/app/core/entity-list/entity-list/entity-list.component.html - 232 + 233 src/app/core/entity-list/entity-list/entity-list.component.html - 232 + 233 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 233 @@ -4141,7 +4444,7 @@ Tooltip explaining disabled sections when creating new entity src/app/core/entity-details/entity-details/entity-details.component.html - 60 + 45 @@ -4213,7 +4516,7 @@ Could not save : src/app/core/common-components/entity-form/entity-form.service.ts - 253 + 258 @@ -4225,7 +4528,7 @@ )"/> src/app/core/common-components/entity-form/entity-form.service.ts - 281,283 + 286 @@ -4269,11 +4572,15 @@ Examples of things to filter src/app/core/entity-list/entity-list/entity-list.component.html - 88 + 87 src/app/core/entity-list/entity-list/entity-list.component.html - 88 + 87 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 87 @@ -4282,11 +4589,15 @@ Add a new entity to a list of multiple entities src/app/core/entity-list/entity-list/entity-list.component.html - 141 + 140 src/app/core/entity-list/entity-list/entity-list.component.html - 141 + 140 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 140 @@ -4295,11 +4606,15 @@ Show filter options popup for list src/app/core/entity-list/entity-list/entity-list.component.html - 153 + 152 src/app/core/entity-list/entity-list/entity-list.component.html - 153 + 152 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 152 @@ -4308,11 +4623,15 @@ Download list contents as CSV src/app/core/entity-list/entity-list/entity-list.component.html - 172 + 171 src/app/core/entity-list/entity-list/entity-list.component.html - 172 + 171 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 171 @@ -4321,11 +4640,15 @@ Download list contents as CSV src/app/core/entity-list/entity-list/entity-list.component.html - 190 + 189 src/app/core/entity-list/entity-list/entity-list.component.html - 190 + 189 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 189 @@ -4335,11 +4658,15 @@ Filter placeholder src/app/core/entity-list/entity-list/entity-list.component.html - 82 + 81 src/app/core/entity-list/entity-list/entity-list.component.html - 82 + 81 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 81 @@ -4347,11 +4674,15 @@ Import from file src/app/core/entity-list/entity-list/entity-list.component.html - 206 + 205 src/app/core/entity-list/entity-list/entity-list.component.html - 206 + 205 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 205 @@ -4359,11 +4690,15 @@ Select multiple records for bulk actions like duplicating or deleting src/app/core/entity-list/entity-list/entity-list.component.html - 212 + 211 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 211 src/app/core/entity-list/entity-list/entity-list.component.html - 212 + 211 @@ -4371,11 +4706,15 @@ Bulk Actions src/app/core/entity-list/entity-list/entity-list.component.html - 220 + 219 src/app/core/entity-list/entity-list/entity-list.component.html - 220 + 219 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 219 @@ -4383,11 +4722,15 @@ Actions on selected records: src/app/core/entity-list/entity-list/entity-list.component.html - 240 + 241 src/app/core/entity-list/entity-list/entity-list.component.html - 240 + 241 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 241 @@ -4395,11 +4738,15 @@ Select rows for an action on multiple records src/app/core/entity-list/entity-list/entity-list.component.html - 244 + 245 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 245 src/app/core/entity-list/entity-list/entity-list.component.html - 244 + 245 @@ -4408,11 +4755,15 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 253 + 254 src/app/core/entity-list/entity-list/entity-list.component.html - 253 + 254 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 254 @@ -4421,11 +4772,15 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 262 + 263 src/app/core/entity-list/entity-list/entity-list.component.html - 262 + 263 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 263 @@ -4434,11 +4789,15 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 271 + 272 src/app/core/entity-list/entity-list/entity-list.component.html - 271 + 272 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 272 @@ -4447,11 +4806,15 @@ bulk action button src/app/core/entity-list/entity-list/entity-list.component.html - 280 + 281 src/app/core/entity-list/entity-list/entity-list.component.html - 280 + 281 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 281 @@ -4459,11 +4822,15 @@ Cancella src/app/core/entity-list/entity-list/entity-list.component.html - 284 + 285 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 285 src/app/core/entity-list/entity-list/entity-list.component.html - 284 + 285 @@ -4504,22 +4871,22 @@ Cancel Cancella + Form cancel button src/app/core/form-dialog/dialog-buttons/dialog-buttons.component.html - 21,23 + 22 - Form cancel button Go to details Go to details + Form button to navigate to details page of entity src/app/core/form-dialog/dialog-buttons/dialog-buttons.component.html - 32,34 + 33 - Form button to navigate to details page of entity Select file @@ -4614,7 +4981,7 @@ tooltip for remove icon on chips of dropdown item src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html - 110 + 127 @@ -4681,7 +5048,7 @@ src/app/core/common-components/view-title/view-title.component.html - 6 + 8 @@ -5594,7 +5961,7 @@ Navigate to user profile page src/app/core/ui/ui/ui.component.html - 95 + 97 @@ -5605,7 +5972,7 @@ Sign out of the app src/app/core/ui/ui/ui.component.html - 105 + 107 @@ -6071,7 +6438,10 @@ Continue Continue - import next step button + + src/app/core/admin/setup-wizard/setup-wizard.component.html + 28 + src/app/core/import/import/import.component.html 27 @@ -6085,6 +6455,22 @@ 132 + + We will hide the setup wizard from the main menu as you finish it here. You can still access it from the admin screen. + We will hide the setup wizard from the main menu as you finish it here. You can still access it from the admin screen. + + src/app/core/admin/setup-wizard/setup-wizard.component.html + 36 + + + + Finish + Finish + + src/app/core/admin/setup-wizard/setup-wizard.component.html + 39,41 + + Select Import Type(s) Select Import Type(s) @@ -6917,12 +7303,12 @@ Add new Add new + e.g. Add new My new Option + Label for adding an option in a dropdown src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html - 63 + 80 - e.g. Add new My new Option - Label for adding an option in a dropdown Imported values @@ -7056,6 +7442,10 @@ src/app/core/admin/admin-entity-details/admin-entity-field/admin-entity-field.component.html 17 + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 13 + src/app/features/dashboard-widgets/progress-dashboard-widget/progress-dashboard/progress-dashboard.component.html 35 @@ -7639,7 +8029,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 205 + 206 @@ -7648,7 +8038,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 171 + 172 @@ -7657,7 +8047,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 176 + 177 @@ -7666,7 +8056,7 @@ Filter-option for todos src/app/features/todos/todo-list/todo-list.component.ts - 181 + 182 @@ -7674,7 +8064,7 @@ Any src/app/features/todos/todo-list/todo-list.component.ts - 184 + 185 @@ -7682,7 +8072,7 @@ Tasks due src/app/features/todos/todo-list/todo-list.component.ts - 186 + 187 diff --git a/src/assets/locale/messages.xlf b/src/assets/locale/messages.xlf index 9c8404d5de..2e214d1df6 100644 --- a/src/assets/locale/messages.xlf +++ b/src/assets/locale/messages.xlf @@ -98,7 +98,7 @@ src/app/core/common-components/view-title/view-title.component.html - 6 + 8 @@ -655,7 +655,7 @@ src/app/core/config/config-fix.ts - 746 + 751 src/app/features/reporting/demo-report-config-generator.service.ts @@ -767,7 +767,7 @@ src/app/core/config/config-fix.ts - 833 + 838 Label for the remarks of a ASER result @@ -868,7 +868,7 @@ src/app/core/config/config-fix.ts - 691 + 696 Child status @@ -1156,11 +1156,11 @@ src/app/core/config/config-fix.ts - 362 + 367 src/app/core/config/config-fix.ts - 809 + 814 src/app/features/reporting/demo-report-config-generator.service.ts @@ -1236,7 +1236,7 @@ src/app/core/config/config-fix.ts - 433 + 438 Label for the status of a child @@ -1280,7 +1280,7 @@ src/app/core/config/config-fix.ts - 825 + 830 Label for the phone number of a child @@ -1292,7 +1292,7 @@ src/app/core/config/config-fix.ts - 774 + 779 Label for the child of a relation @@ -1312,11 +1312,11 @@ src/app/core/config/config-fix.ts - 378 + 383 src/app/core/config/config-fix.ts - 473 + 478 Label for the school of a relation @@ -1328,7 +1328,7 @@ src/app/core/config/config-fix.ts - 373 + 378 Label for the class of a relation @@ -1848,11 +1848,11 @@ src/app/core/config/config-fix.ts - 300 + 305 src/app/core/config/config-fix.ts - 775 + 780 Label for the children of a note @@ -1907,7 +1907,7 @@ Download details src/app/child-dev-project/notes/note-details/note-details.component.html - 84 + 71 Download note details as CSV @@ -1918,7 +1918,7 @@ >"/> Include events src/app/child-dev-project/notes/notes-manager/notes-manager.component.html - 22,27 + 28,33 events are related to a child @@ -2010,6 +2010,14 @@ Label warning level + + You can edit how users will see the details of a single record of this type. Drag and drop fields and sections in this preview of a profile view and group them as appropriate. We recommend to keep things simple: Only add fields that you really need for your work. + + + src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html + 4,9 + + Add Section src/app/core/admin/admin-entity-details/admin-entity-details/admin-entity-details.component.html - 39,45 + 45,51 @@ -2049,6 +2057,10 @@ src/app/core/admin/admin-entity-details/admin-entity-field/admin-entity-field.component.html 13 + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 9 + Label @@ -2056,6 +2068,10 @@ src/app/core/admin/admin-entity-details/admin-entity-field/admin-entity-field.component.html 17 + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 13 + src/app/features/dashboard-widgets/progress-dashboard-widget/progress-dashboard/progress-dashboard.component.html 35 @@ -2288,6 +2304,70 @@ 80,89 + + General Settings of "" Records + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 1 + + + + The settings here apply to the entity type overall and take effect everywhere the entity is displayed, including lists, forms and other views. + + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 2,5 + + + + Label (Plural) + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 19 + + + + Optionally you can define how multiple records of this entity should be called, e.g. in lists. + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 22 + + + + Icon + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 35 + + + + The icon to represent this entity type, e.g. when displaying records as a small preview block. [see fontawesome.com/icons] + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 38 + + + + Generated Title of Record + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 53 + + + + Select the fields that should be used (in that order) to generate a simple name/title for a record. This generated title is used in previews, search and for form fields that allow to select a record of this type. (Only text fields can be used here) + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 56 + + + + Configure PII / Anonymization + + src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html + 77 + + Editing data structure for "" records @@ -2331,7 +2411,7 @@ Configuration updated src/app/core/admin/admin-entity/admin-entity.component.ts - 132 + 141 Save config confirmation message @@ -2339,7 +2419,7 @@ Site Settings src/app/core/admin/admin.routing.ts - 39 + 44 @@ -2358,6 +2438,14 @@ admin menu item + + Setup Wizard + + src/app/core/admin/admin/admin.component.html + 20,22 + + admin menu item + (no title) @@ -2386,7 +2474,192 @@ add a new tab src/app/core/admin/building-blocks/admin-tabs/admin-tabs.component.html - 30 + 47 + + + + Setup Wizard + + src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.html + 10,12 + + + + Welcome + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 27 + + Setup Wizard Step Title + + + +# Welcome to Aam Digital! +We are here to help you manage your participants' or beneficiaries' details +and your team's interactions with them. + +The Aam Digital platform is very flexible and you can customize the structures and views +to exactly fit your project needs. +The following steps guide you through the most important configuration options for this. +And you can start working with your data within a few minutes already. + +We also have some short video guides for you: [Aam Digital Video Guides (YouTube)](https://www.youtube.com/channel/UCZSFOX_MBa8zz5Mtfv_qlnA/videos) + +Feel free to leave this setup wizard in between to explore the existing system first. +You can always come back to this view through the "Setup Wizard" button at the bottom of the main menu on the left. +To dismiss and hide this wizard, go to the last step of the wizard and "finish" the setup process. + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 28,42 + + Setup Wizard Step Text + + + Profiles & Fields + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 45 + + Setup Wizard Step Title + + + +The system already holds some basic structures for your case management. +You can adapt the fields and how the details are displayed. + +If you have further requirements, don't hesitate to reach out to us at [support@aam-digital.com](mailto:support@aam-digital.com). + +_Please note that the setup wizard and form builder is still under active development ("beta" version). +Some advanced configuration options are not available here yet for you to configure yourself and may need assistance from the tech support team. +We are currently extending and optimizing the user interfaces for these steps._ + + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 46,55 + + Setup Wizard Step Text + + + Customize Child profile + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 58 + + Setup Wizard Step Action + + + Customize School profile + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 62 + + Setup Wizard Step Action + + + User Accounts + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 68 + + Setup Wizard Step Title + + + +You can collaborate on Aam Digital as a team. +Data is synced and all users have access to the latest information. + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 69,71 + + Setup Wizard Step Text + + + Manage User Accounts + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 74 + + Setup Wizard Step Action + + + Import Data + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 80 + + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 88 + + Setup Wizard Step Title + + + +If you have exising data from a previous system, you can easily import it. +Save the data in ".csv" format (e.g. from MS Excel). +You do not need any specific column names in your file to be imported. +The Import Module helps your map your spreadsheet data to the relevant fields in your Aam Digital profiles. + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 81,85 + + Setup Wizard Step Text + + + Done! + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 94 + + Setup Wizard Step Title + + + +That's it. You are ready to explore your system and start work! + +You can always adapt your setup further, after you started using it. +We recommend to keep things simple in the beginning, +start using it for some of your tasks +and then add further fields and adjust your setup. + +Feel free to reach out to us with your questions or feedback: [support@aam-digital.com](mailto:support@aam-digital.com) + + src/app/core/admin/setup-wizard/setup-wizard-config.ts + 95,103 + + Setup Wizard Step Text + + + Continue + + src/app/core/admin/setup-wizard/setup-wizard.component.html + 28,30 + + + src/app/core/import/import/import.component.html + 27,29 + + + src/app/core/import/import/import.component.html + 75,77 + + + src/app/core/import/import/import.component.html + 132,134 + + + + We will hide the setup wizard from the main menu as you finish it here. You can still access it from the admin screen. + + src/app/core/admin/setup-wizard/setup-wizard.component.html + 36 + + + + Finish + + src/app/core/admin/setup-wizard/setup-wizard.component.html + 39,41 @@ -2801,7 +3074,7 @@ Add new src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html - 63 + 80 e.g. Add new My new Option Label for adding an option in a dropdown @@ -2810,7 +3083,7 @@ remove src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html - 110 + 127 tooltip for remove icon on chips of dropdown item @@ -3013,7 +3286,7 @@ Could not save : src/app/core/common-components/entity-form/entity-form.service.ts - 253 + 258 @@ -3022,7 +3295,7 @@ )"/> src/app/core/common-components/entity-form/entity-form.service.ts - 281,283 + 286,288 @@ -3100,7 +3373,7 @@ src/app/core/config/config-fix.ts - 586 + 591 Menu item @@ -3215,7 +3488,7 @@ Notes & Reports src/app/core/config/config-fix.ts - 165 + 164 Title for notes overview @@ -3223,11 +3496,11 @@ Standard src/app/core/config/config-fix.ts - 169 + 168 src/app/core/config/config-fix.ts - 173 + 172 Translated name of default column group @@ -3235,19 +3508,19 @@ Mobile src/app/core/config/config-fix.ts - 170 + 169 src/app/core/config/config-fix.ts - 183 + 182 src/app/core/config/config-fix.ts - 404 + 409 src/app/core/config/config-fix.ts - 457 + 462 Translated name of mobile column group @@ -3255,7 +3528,7 @@ User Information src/app/core/config/config-fix.ts - 257 + 262 Panel title @@ -3263,7 +3536,7 @@ Security src/app/core/config/config-fix.ts - 272 + 277 Panel title @@ -3271,7 +3544,7 @@ assets/help/help.en.md src/app/core/config/config-fix.ts - 285 + 290 Filename of markdown help page (make sure the filename you enter as a translation actually exists on the server!) @@ -3279,26 +3552,26 @@ Private School src/app/core/config/config-fix.ts - 307 + 312 src/app/core/config/config-fix.ts - 813 + 818 Basic Information src/app/core/config/config-fix.ts - 318 + 323 src/app/core/config/config-fix.ts - 491 + 496 src/app/core/config/config-fix.ts - 731 + 736 Panel title @@ -3306,7 +3579,7 @@ Students src/app/core/config/config-fix.ts - 335 + 340 Panel title @@ -3314,7 +3587,7 @@ Activities src/app/core/config/config-fix.ts - 344 + 349 Panel title @@ -3322,7 +3595,7 @@ Age src/app/core/config/config-fix.ts - 367 + 372 Column label for age of child @@ -3330,7 +3603,7 @@ Attendance (School) src/app/core/config/config-fix.ts - 385 + 390 Column label for school attendance of child @@ -3338,7 +3611,7 @@ Attendance (Coaching) src/app/core/config/config-fix.ts - 394 + 399 Column label for coaching attendance of child @@ -3346,11 +3619,11 @@ Basic Info src/app/core/config/config-fix.ts - 403 + 408 src/app/core/config/config-fix.ts - 407 + 412 Translated name of default column group @@ -3358,7 +3631,7 @@ School Info src/app/core/config/config-fix.ts - 420 + 425 Column group name @@ -3366,11 +3639,11 @@ Health src/app/core/config/config-fix.ts - 443 + 448 src/app/core/config/config-fix.ts - 608 + 613 Column group name @@ -3378,7 +3651,7 @@ Personal Information src/app/core/config/config-fix.ts - 501 + 506 Header for form section @@ -3386,7 +3659,7 @@ Additional src/app/core/config/config-fix.ts - 505 + 510 Header for form section @@ -3394,7 +3667,7 @@ Scholar activities src/app/core/config/config-fix.ts - 509 + 514 Header for form section @@ -3402,7 +3675,7 @@ Education src/app/core/config/config-fix.ts - 517 + 522 Panel title @@ -3410,7 +3683,7 @@ School History src/app/core/config/config-fix.ts - 520 + 525 Title inside a panel @@ -3418,7 +3691,7 @@ ASER Results src/app/core/config/config-fix.ts - 540 + 545 Title inside a panel @@ -3426,7 +3699,7 @@ Find a suitable new school src/app/core/config/config-fix.ts - 574 + 579 Child details section title @@ -3434,7 +3707,7 @@ Notes & Tasks src/app/core/config/config-fix.ts - 595 + 600 Panel title @@ -3442,7 +3715,7 @@ Health checkups are to be done regularly, at least every 6 months according to the program guidelines. src/app/core/config/config-fix.ts - 618 + 623 description section @@ -3450,7 +3723,7 @@ Height & Weight Tracking src/app/core/config/config-fix.ts - 626 + 631 Title inside a panel @@ -3458,7 +3731,7 @@ BMI src/app/core/config/config-fix.ts - 637 + 642 Table header, Short for Body Mass Index @@ -3466,7 +3739,7 @@ This is calculated using the height and the weight measure src/app/core/config/config-fix.ts - 639 + 644 Tooltip for BMI info @@ -3474,7 +3747,7 @@ Educational Materials src/app/core/config/config-fix.ts - 647 + 652 Panel title @@ -3482,7 +3755,7 @@ Observations src/app/core/config/config-fix.ts - 672 + 677 Panel title @@ -3490,7 +3763,7 @@ Events & Attendance src/app/core/config/config-fix.ts - 759 + 764 Panel title @@ -3498,11 +3771,11 @@ Address src/app/core/config/config-fix.ts - 780 + 785 src/app/core/config/config-fix.ts - 821 + 826 Label for the address of a child @@ -3510,7 +3783,7 @@ Blood Group src/app/core/config/config-fix.ts - 784 + 789 Label for a child attribute @@ -3518,7 +3791,7 @@ Religion src/app/core/config/config-fix.ts - 788 + 793 Label for the religion of a child @@ -3526,7 +3799,7 @@ Mother Tongue src/app/core/config/config-fix.ts - 792 + 797 Label for the mother tongue of a child @@ -3534,7 +3807,7 @@ The primary language spoken at home src/app/core/config/config-fix.ts - 793 + 798 Tooltip description for the mother tongue of a child @@ -3542,7 +3815,7 @@ Last Dental Check-Up src/app/core/config/config-fix.ts - 797 + 802 Label for a child attribute @@ -3550,7 +3823,7 @@ Birth certificate src/app/core/config/config-fix.ts - 801 + 806 Label for a child attribute @@ -3558,7 +3831,7 @@ Language src/app/core/config/config-fix.ts - 817 + 822 Label for the language of a school @@ -3566,7 +3839,7 @@ School Timing src/app/core/config/config-fix.ts - 829 + 834 Label for the timing of a school @@ -3574,7 +3847,7 @@ Motivated src/app/core/config/config-fix.ts - 842 + 847 Label for a child attribute @@ -3582,7 +3855,7 @@ The child is motivated during the class. src/app/core/config/config-fix.ts - 843 + 848 Description for a child attribute @@ -3590,7 +3863,7 @@ Participating src/app/core/config/config-fix.ts - 848 + 853 Label for a child attribute @@ -3598,7 +3871,7 @@ The child is actively participating in the class. src/app/core/config/config-fix.ts - 849 + 854 Description for a child attribute @@ -3606,7 +3879,7 @@ Interacting src/app/core/config/config-fix.ts - 854 + 859 Label for a child attribute @@ -3614,7 +3887,7 @@ The child interacts with other students during the class. src/app/core/config/config-fix.ts - 855 + 860 Description for a child attribute @@ -3622,7 +3895,7 @@ Homework src/app/core/config/config-fix.ts - 860 + 865 Label for a child attribute @@ -3630,7 +3903,7 @@ The child does its homework. src/app/core/config/config-fix.ts - 861 + 866 Description for a child attribute @@ -3638,7 +3911,7 @@ Asking Questions src/app/core/config/config-fix.ts - 866 + 871 Label for a child attribute @@ -3646,7 +3919,7 @@ The child is asking questions during the class. src/app/core/config/config-fix.ts - 867 + 872 Description for a child attribute @@ -3654,7 +3927,7 @@ Contact src/app/core/config/config-fix.ts - 875 + 880 Label of user phone @@ -3813,7 +4086,7 @@ Archive src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 69 + 74 entity context menu @@ -3821,7 +4094,7 @@ Mark the record as inactive, hiding it from lists by default while keeping the data. src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 70 + 75 entity context menu tooltip @@ -3829,7 +4102,7 @@ Anonymize src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 77 + 83 entity context menu @@ -3837,7 +4110,7 @@ Remove all personal data and keep an archived basic record for statistical reporting. src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 78 + 84 entity context menu tooltip @@ -3845,7 +4118,7 @@ Delete src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 85 + 91 entity context menu @@ -3853,7 +4126,7 @@ Remove the record completely from the database. src/app/core/entity-details/entity-actions-menu/entity-actions-menu.component.ts - 86 + 92 entity context menu tooltip @@ -3885,35 +4158,38 @@ 19,22 - + Adding new src/app/core/entity-details/entity-details/entity-details.component.html - 27,29 + 6,8 - An entity is a child, note, school, etc. - Title when adding a new entity + Title when adding a new entity Edit Data Structure src/app/core/entity-details/entity-details/entity-details.component.html - 41 + 29 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 233 src/app/core/entity-list/entity-list/entity-list.component.html - 232 + 233 src/app/core/entity-list/entity-list/entity-list.component.html - 232 + 233 Save the new record to create it before accessing other details src/app/core/entity-details/entity-details/entity-details.component.html - 60 + 45 Tooltip explaining disabled sections when creating new entity @@ -4036,11 +4312,15 @@ Filter src/app/core/entity-list/entity-list/entity-list.component.html - 82,83 + 81,82 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 81,82 src/app/core/entity-list/entity-list/entity-list.component.html - 82,83 + 81,82 Allows the user to filter through entities Filter placeholder @@ -4049,11 +4329,15 @@ e.g. name, age src/app/core/entity-list/entity-list/entity-list.component.html - 88 + 87 src/app/core/entity-list/entity-list/entity-list.component.html - 88 + 87 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 87 Examples of things to filter @@ -4061,11 +4345,15 @@ Add New src/app/core/entity-list/entity-list/entity-list.component.html - 141,143 + 140,142 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 140,142 src/app/core/entity-list/entity-list/entity-list.component.html - 141,143 + 140,142 Add a new entity to a list of multiple entities @@ -4073,11 +4361,15 @@ Filter options src/app/core/entity-list/entity-list/entity-list.component.html - 153 + 152 src/app/core/entity-list/entity-list/entity-list.component.html - 153 + 152 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 152 Show filter options popup for list @@ -4085,11 +4377,15 @@ Download all data (.csv) src/app/core/entity-list/entity-list/entity-list.component.html - 172 + 171 src/app/core/entity-list/entity-list/entity-list.component.html - 172 + 171 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 171 Download list contents as CSV @@ -4097,11 +4393,15 @@ Download current (.csv) src/app/core/entity-list/entity-list/entity-list.component.html - 190 + 189 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 189 src/app/core/entity-list/entity-list/entity-list.component.html - 190 + 189 Download list contents as CSV @@ -4109,66 +4409,90 @@ Import from file src/app/core/entity-list/entity-list/entity-list.component.html - 206 + 205 src/app/core/entity-list/entity-list/entity-list.component.html - 206 + 205 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 205 Select multiple records for bulk actions like duplicating or deleting src/app/core/entity-list/entity-list/entity-list.component.html - 212 + 211 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 211 src/app/core/entity-list/entity-list/entity-list.component.html - 212 + 211 Bulk Actions src/app/core/entity-list/entity-list/entity-list.component.html - 220 + 219 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 219 src/app/core/entity-list/entity-list/entity-list.component.html - 220 + 219 Actions on selected records: src/app/core/entity-list/entity-list/entity-list.component.html - 240 + 241 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 241 src/app/core/entity-list/entity-list/entity-list.component.html - 240 + 241 Select rows for an action on multiple records src/app/core/entity-list/entity-list/entity-list.component.html - 244 + 245 src/app/core/entity-list/entity-list/entity-list.component.html - 244 + 245 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 245 Archive src/app/core/entity-list/entity-list/entity-list.component.html - 253,255 + 254,256 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 254,256 src/app/core/entity-list/entity-list/entity-list.component.html - 253,255 + 254,256 bulk action button @@ -4176,11 +4500,15 @@ Anonymize src/app/core/entity-list/entity-list/entity-list.component.html - 262,264 + 263,265 src/app/core/entity-list/entity-list/entity-list.component.html - 262,264 + 263,265 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 263,265 bulk action button @@ -4188,11 +4516,15 @@ Delete src/app/core/entity-list/entity-list/entity-list.component.html - 271,273 + 272,274 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 272,274 src/app/core/entity-list/entity-list/entity-list.component.html - 271,273 + 272,274 bulk action button @@ -4200,11 +4532,15 @@ Duplicate src/app/core/entity-list/entity-list/entity-list.component.html - 280,282 + 281,283 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 281,283 src/app/core/entity-list/entity-list/entity-list.component.html - 280,282 + 281,283 bulk action button @@ -4212,11 +4548,15 @@ Cancel src/app/core/entity-list/entity-list/entity-list.component.html - 284,286 + 285,287 src/app/core/entity-list/entity-list/entity-list.component.html - 284,286 + 285,287 + + + src/app/core/entity-list/entity-list/entity-list.component.html + 285,287 @@ -4453,7 +4793,7 @@ src/app/core/form-dialog/dialog-buttons/dialog-buttons.component.html - 21,23 + 22,24 Form cancel button @@ -4462,7 +4802,7 @@ src/app/core/form-dialog/dialog-buttons/dialog-buttons.component.html - 32,34 + 33,35 Form button to navigate to details page of entity @@ -4742,22 +5082,6 @@ Import Step - upload - sub-label - - Continue - - src/app/core/import/import/import.component.html - 27,29 - - - src/app/core/import/import/import.component.html - 75,77 - - - src/app/core/import/import/import.component.html - 132,134 - - import next step button - Select Import Type(s) @@ -5333,7 +5657,7 @@ <button"/> Profile src/app/core/ui/ui/ui.component.html - 95,97 + 97,99 Navigate to user profile page @@ -5343,7 +5667,7 @@ </button>"/> Sign out src/app/core/ui/ui/ui.component.html - 105,107 + 107,109 Sign out of the app @@ -6726,7 +7050,7 @@ Overdue src/app/features/todos/todo-list/todo-list.component.ts - 171 + 172 Filter-option for todos @@ -6734,7 +7058,7 @@ Completed src/app/features/todos/todo-list/todo-list.component.ts - 176 + 177 Filter-option for todos @@ -6742,7 +7066,7 @@ All Open src/app/features/todos/todo-list/todo-list.component.ts - 181 + 182 Filter-option for todos @@ -6750,21 +7074,21 @@ Any src/app/features/todos/todo-list/todo-list.component.ts - 184 + 185 Tasks due src/app/features/todos/todo-list/todo-list.component.ts - 186 + 187 Currently Active src/app/features/todos/todo-list/todo-list.component.ts - 205 + 206 Filter-option for todos From 35d2f80f13d1a9b1fe7d13c253a062d4448c50f1 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Fri, 19 Apr 2024 13:02:52 +0200 Subject: [PATCH 57/58] handle missing config --- .../setup-wizard-button/setup-wizard-button.component.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.ts b/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.ts index 82831340be..ac1a354e1b 100644 --- a/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.ts +++ b/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.ts @@ -10,6 +10,7 @@ import { } from "../setup-wizard-config"; import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; import { filter } from "rxjs/operators"; +import { LoggingService } from "../../../logging/logging.service"; @UntilDestroy() @Component({ @@ -22,12 +23,13 @@ import { filter } from "rxjs/operators"; export class SetupWizardButtonComponent { showSetupWizard: boolean; - constructor(entityMapper: EntityMapperService) { + constructor(entityMapper: EntityMapperService, logger: LoggingService) { entityMapper .load(Config, CONFIG_SETUP_WIZARD_ID) .then((r: Config) => { this.updateStatus(r.data); - }); + }) + .catch((e) => logger.debug("No Setup Wizard Config found")); entityMapper .receiveUpdates>(Config) From da225f50ede614ca2524fd11e3824af566f459d2 Mon Sep 17 00:00:00 2001 From: Sebastian Leidig Date: Thu, 25 Apr 2024 11:32:52 +0200 Subject: [PATCH 58/58] add tests --- .../setup-wizard-button.component.spec.ts | 25 ++++++++- .../setup-wizard-button.component.ts | 15 +++-- .../setup-wizard.component.spec.ts | 56 ++++++++++++++++++- .../setup-wizard/setup-wizard.component.ts | 19 +++++-- 4 files changed, 102 insertions(+), 13 deletions(-) diff --git a/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.spec.ts b/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.spec.ts index 7ec16b384f..8f7a76ef83 100644 --- a/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.spec.ts +++ b/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.spec.ts @@ -1,8 +1,15 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { + ComponentFixture, + fakeAsync, + TestBed, + tick, +} from "@angular/core/testing"; import { SetupWizardButtonComponent } from "./setup-wizard-button.component"; import { EntityMapperService } from "../../../entity/entity-mapper/entity-mapper.service"; import { mockEntityMapper } from "../../../entity/entity-mapper/mock-entity-mapper-service"; +import { SetupWizardConfig } from "../setup-wizard-config"; +import { Config } from "../../../config/config"; describe("SetupWizardButtonComponent", () => { let component: SetupWizardButtonComponent; @@ -24,4 +31,20 @@ describe("SetupWizardButtonComponent", () => { it("should create", () => { expect(component).toBeTruthy(); }); + + it("should hide if SetupWizardConfig completed", fakeAsync(() => { + const testWizardConfig: SetupWizardConfig = { + steps: [], + finished: true, + }; + spyOn(TestBed.inject(EntityMapperService), "load").and.resolveTo( + new Config("", testWizardConfig), + ); + + // @ts-ignore + component.init(); + tick(); + + expect(component.showSetupWizard).toBeFalse(); + })); }); diff --git a/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.ts b/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.ts index ac1a354e1b..c73af3e8ab 100644 --- a/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.ts +++ b/src/app/core/admin/setup-wizard/setup-wizard-button/setup-wizard-button.component.ts @@ -23,15 +23,22 @@ import { LoggingService } from "../../../logging/logging.service"; export class SetupWizardButtonComponent { showSetupWizard: boolean; - constructor(entityMapper: EntityMapperService, logger: LoggingService) { - entityMapper + constructor( + private entityMapper: EntityMapperService, + private logger: LoggingService, + ) { + this.init(); + } + + private init() { + this.entityMapper .load(Config, CONFIG_SETUP_WIZARD_ID) .then((r: Config) => { this.updateStatus(r.data); }) - .catch((e) => logger.debug("No Setup Wizard Config found")); + .catch((e) => this.logger.debug("No Setup Wizard Config found")); - entityMapper + this.entityMapper .receiveUpdates>(Config) .pipe( untilDestroyed(this), diff --git a/src/app/core/admin/setup-wizard/setup-wizard.component.spec.ts b/src/app/core/admin/setup-wizard/setup-wizard.component.spec.ts index 620badf94b..7584c29698 100644 --- a/src/app/core/admin/setup-wizard/setup-wizard.component.spec.ts +++ b/src/app/core/admin/setup-wizard/setup-wizard.component.spec.ts @@ -1,8 +1,22 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { + ComponentFixture, + fakeAsync, + TestBed, + tick, +} from "@angular/core/testing"; import { SetupWizardComponent } from "./setup-wizard.component"; import { EntityMapperService } from "../../entity/entity-mapper/entity-mapper.service"; -import { mockEntityMapper } from "../../entity/entity-mapper/mock-entity-mapper-service"; +import { + mockEntityMapper, + MockEntityMapperService, +} from "../../entity/entity-mapper/mock-entity-mapper-service"; +import { + CONFIG_SETUP_WIZARD_ID, + defaultSetupWizardConfig, + SetupWizardConfig, +} from "./setup-wizard-config"; +import { Config } from "../../config/config"; describe("SetupWizardComponent", () => { let component: SetupWizardComponent; @@ -24,4 +38,42 @@ describe("SetupWizardComponent", () => { it("should create", () => { expect(component).toBeTruthy(); }); + + it("should not save progress if no config was originally loaded", fakeAsync(() => { + const entityMapperSpy = spyOn(TestBed.inject(EntityMapperService), "save"); + + component.ngOnDestroy(); + tick(); + + expect(entityMapperSpy).not.toHaveBeenCalled(); + })); + + it("should load config on init and save progress upon leaving component", fakeAsync(() => { + const testConfig: SetupWizardConfig = JSON.parse( + JSON.stringify(defaultSetupWizardConfig), + ); + testConfig.currentStep = 2; + + const entityMapper: MockEntityMapperService = TestBed.inject( + EntityMapperService, + ) as MockEntityMapperService; + entityMapper.add(new Config(CONFIG_SETUP_WIZARD_ID, testConfig)); + const entityMapperSaveSpy = spyOn(entityMapper, "save"); + + component.ngOnInit(); + tick(); + expect(component.config).toEqual(testConfig); + expect(component.currentStep).toBe(2); + + component.currentStep = 3; + component.config.finished = true; + component.ngOnDestroy(); + tick(); + + expect(entityMapperSaveSpy).toHaveBeenCalled(); + const actualSavedConfig = entityMapperSaveSpy.calls.mostRecent() + .args[0] as Config; + expect(actualSavedConfig.data.finished).toBe(true); + expect(actualSavedConfig.data.currentStep).toBe(3); + })); }); diff --git a/src/app/core/admin/setup-wizard/setup-wizard.component.ts b/src/app/core/admin/setup-wizard/setup-wizard.component.ts index c669b67723..14ebb659e1 100644 --- a/src/app/core/admin/setup-wizard/setup-wizard.component.ts +++ b/src/app/core/admin/setup-wizard/setup-wizard.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy } from "@angular/core"; +import { Component, OnDestroy, OnInit } from "@angular/core"; import { CommonModule } from "@angular/common"; import { MatStep, @@ -17,6 +17,7 @@ import { } from "./setup-wizard-config"; import { MarkdownComponent } from "ngx-markdown"; import { MatTooltip } from "@angular/material/tooltip"; +import { LoggingService } from "../../logging/logging.service"; @Component({ selector: "app-setup-wizard", @@ -37,24 +38,30 @@ import { MatTooltip } from "@angular/material/tooltip"; templateUrl: "./setup-wizard.component.html", styleUrl: "./setup-wizard.component.scss", }) -export class SetupWizardComponent implements OnDestroy { +export class SetupWizardComponent implements OnInit, OnDestroy { config: SetupWizardConfig; currentStep: number; private configEntity: Config; - constructor(private entityMapper: EntityMapperService) { - entityMapper + constructor( + private entityMapper: EntityMapperService, + private logger: LoggingService, + ) {} + + ngOnInit() { + this.entityMapper .load(Config, CONFIG_SETUP_WIZARD_ID) .then((r: Config) => { this.configEntity = r; this.config = r.data; this.currentStep = this.config.currentStep; - }); + }) + .catch((e) => this.logger.debug("no setup wizard config loaded", e)); } ngOnDestroy(): void { - if (!this.config) { + if (!this.configEntity) { return; }