From e6e0a2cd337355506bb7916fd60abb58277b762e Mon Sep 17 00:00:00 2001 From: Schottkyc137 <45085299+Schottkyc137@users.noreply.github.com> Date: Thu, 21 Oct 2021 11:27:00 +0200 Subject: [PATCH 01/21] fix: Colors for highest ASER level are correctly displayed closes #993 --- .../child-dev-project/aser/model/aser.spec.ts | 20 ++++++++-- src/app/child-dev-project/aser/model/aser.ts | 37 +++++++++++-------- .../aser/model/mathLevels.ts | 14 ++++--- .../aser/model/readingLevels.ts | 14 ++++--- .../configurable-enum.interface.ts | 5 +++ 5 files changed, 60 insertions(+), 30 deletions(-) diff --git a/src/app/child-dev-project/aser/model/aser.spec.ts b/src/app/child-dev-project/aser/model/aser.spec.ts index 63ed13cebb..b5172ffbf0 100644 --- a/src/app/child-dev-project/aser/model/aser.spec.ts +++ b/src/app/child-dev-project/aser/model/aser.spec.ts @@ -16,7 +16,6 @@ */ import { Aser } from "./aser"; -import { waitForAsync } from "@angular/core/testing"; import { Entity } from "../../../core/entity/model/entity"; import { EntitySchemaService } from "../../../core/entity/schema/entity-schema.service"; import { mathLevels } from "./mathLevels"; @@ -27,8 +26,6 @@ describe("Aser", () => { const ENTITY_TYPE = "Aser"; const entitySchemaService = new EntitySchemaService(); - beforeEach(waitForAsync(() => {})); - it("has correct _id and entityId and type", function () { const id = "test1"; const entity = new Aser(id); @@ -90,4 +87,21 @@ describe("Aser", () => { expect(entity.getWarningLevel()).toBe(WarningLevel.WARNING); }); + + it("has a warning level of OK if english is at it's highest level", () => { + const entity = new Aser(); + entity.english = readingLevels[readingLevels.length - 1]; + + expect(entity.getWarningLevel()).toBe(WarningLevel.OK); + }); + + it("has a warning level of OK if all values are at it's highest level", () => { + const entity = new Aser(); + entity.math = mathLevels[mathLevels.length - 1]; + entity.english = readingLevels[readingLevels.length - 1]; + entity.hindi = readingLevels[readingLevels.length - 1]; + entity.bengali = readingLevels[readingLevels.length - 1]; + + expect(entity.getWarningLevel()).toBe(WarningLevel.OK); + }); }); diff --git a/src/app/child-dev-project/aser/model/aser.ts b/src/app/child-dev-project/aser/model/aser.ts index 41ac3366cd..c672b3593c 100644 --- a/src/app/child-dev-project/aser/model/aser.ts +++ b/src/app/child-dev-project/aser/model/aser.ts @@ -18,27 +18,34 @@ import { Entity } from "../../../core/entity/model/entity"; import { DatabaseField } from "../../../core/entity/database-field.decorator"; import { DatabaseEntity } from "../../../core/entity/database-entity.decorator"; -import { ConfigurableEnumValue } from "../../../core/configurable-enum/configurable-enum.interface"; -import { mathLevels } from "./mathLevels"; -import { readingLevels } from "./readingLevels"; +import { + ConfigurableEnumConfig, + ConfigurableEnumValue, +} from "../../../core/configurable-enum/configurable-enum.interface"; +import { MathLevel, mathLevels } from "./mathLevels"; +import { ReadingLevel, readingLevels } from "./readingLevels"; import { WarningLevel } from "../../../core/entity/model/warning-level"; @DatabaseEntity("Aser") export class Aser extends Entity { - static isReadingPassedOrNA(level: ConfigurableEnumValue) { - if (!level || level.id === "") { - // not applicable - return true; - } - return level === readingLevels.find((it) => it.id === "read_paragraph"); + static isReadingPassedOrNA(level: ConfigurableEnumValue): boolean { + return this.isHighestLevelOrNA(level, readingLevels); + } + + static isMathPassedOrNA(level: ConfigurableEnumValue): boolean { + return this.isHighestLevelOrNA(level, mathLevels); } - static isMathPassedOrNA(level: ConfigurableEnumValue) { + static isHighestLevelOrNA( + level: ConfigurableEnumValue, + source: ConfigurableEnumConfig + ): boolean { if (!level || level.id === "") { // not applicable return true; } - return level === mathLevels.find((it) => it.id === "division"); + const index = source.findIndex((cEnumValue) => cEnumValue.id === level.id); + return index === source.length - 1; } @DatabaseField() child: string; // id of Child entity @@ -51,25 +58,25 @@ export class Aser extends Entity { dataType: "configurable-enum", innerDataType: "reading-levels", }) - hindi: ConfigurableEnumValue; + hindi: ReadingLevel; @DatabaseField({ label: $localize`:Label of the Bengali ASER result:Bengali`, dataType: "configurable-enum", innerDataType: "reading-levels", }) - bengali: ConfigurableEnumValue; + bengali: ReadingLevel; @DatabaseField({ label: $localize`:Label of the English ASER result:English`, dataType: "configurable-enum", innerDataType: "reading-levels", }) - english: ConfigurableEnumValue; + english: ReadingLevel; @DatabaseField({ label: $localize`:Label of the Math ASER result:Math`, dataType: "configurable-enum", innerDataType: "math-levels", }) - math: ConfigurableEnumValue; + math: MathLevel; @DatabaseField({ label: $localize`:Label for the remarks of a ASER result:Remarks`, }) diff --git a/src/app/child-dev-project/aser/model/mathLevels.ts b/src/app/child-dev-project/aser/model/mathLevels.ts index b88fe930a5..00af8d1eb5 100644 --- a/src/app/child-dev-project/aser/model/mathLevels.ts +++ b/src/app/child-dev-project/aser/model/mathLevels.ts @@ -1,10 +1,12 @@ -import { ConfigurableEnumValue } from "../../../core/configurable-enum/configurable-enum.interface"; +import { + ConfigurableEnumConfig, + ConfigurableEnumValue, + EMPTY, +} from "../../../core/configurable-enum/configurable-enum.interface"; -export const mathLevels: ConfigurableEnumValue[] = [ - { - id: "", - label: "", - }, +export type MathLevel = ConfigurableEnumValue; +export const mathLevels: ConfigurableEnumConfig = [ + EMPTY, { id: "Nothing", label: $localize`:Label math level:Nothing`, diff --git a/src/app/child-dev-project/aser/model/readingLevels.ts b/src/app/child-dev-project/aser/model/readingLevels.ts index c594316cfb..577f7a0f44 100644 --- a/src/app/child-dev-project/aser/model/readingLevels.ts +++ b/src/app/child-dev-project/aser/model/readingLevels.ts @@ -1,10 +1,12 @@ -import { ConfigurableEnumValue } from "../../../core/configurable-enum/configurable-enum.interface"; +import { + ConfigurableEnumConfig, + ConfigurableEnumValue, + EMPTY, +} from "../../../core/configurable-enum/configurable-enum.interface"; -export const readingLevels: ConfigurableEnumValue[] = [ - { - id: "", - label: "", - }, +export type ReadingLevel = ConfigurableEnumValue; +export const readingLevels: ConfigurableEnumConfig = [ + EMPTY, { id: "Nothing", label: $localize`:Label reading level:Nothing`, diff --git a/src/app/core/configurable-enum/configurable-enum.interface.ts b/src/app/core/configurable-enum/configurable-enum.interface.ts index 6ca3054b5b..c269d2ac58 100644 --- a/src/app/core/configurable-enum/configurable-enum.interface.ts +++ b/src/app/core/configurable-enum/configurable-enum.interface.ts @@ -32,6 +32,11 @@ export interface ConfigurableEnumValue { [x: string]: any; } +export const EMPTY: ConfigurableEnumValue = { + id: "", + label: "", +}; + /** * The prefix of all enum collection entries in the config database. * From e1918cac461dbd21270a419607ff5420c1fda61d Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 21 Oct 2021 11:52:44 +0200 Subject: [PATCH 02/21] test: Using mock of HttpModule to prevent tests from failing --- src/app/app.component.spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 4259024ce3..4a8d20dcf3 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -33,6 +33,7 @@ import { EntityMapperService } from "./core/entity/entity-mapper.service"; import { Config } from "./core/config/config"; import { USAGE_ANALYTICS_CONFIG_ID } from "./core/analytics/usage-analytics-config"; import { environment } from "../environments/environment"; +import { HttpClientTestingModule } from "@angular/common/http/testing"; describe("AppComponent", () => { let component: AppComponent; @@ -49,7 +50,7 @@ describe("AppComponent", () => { AppConfig.settings = mockAppSettings; TestBed.configureTestingModule({ - imports: [AppModule], + imports: [AppModule, HttpClientTestingModule], providers: [ { provide: AppConfig, useValue: jasmine.createSpyObj(["load"]) }, ], From 00f696a0087ca1bb0c857796911258dbca38a4f7 Mon Sep 17 00:00:00 2001 From: Schottkyc137 <45085299+Schottkyc137@users.noreply.github.com> Date: Thu, 21 Oct 2021 12:06:31 +0200 Subject: [PATCH 03/21] refactor: prevent error log when no interaction type is selected closes #971 --- .../note-details/note-details.component.html | 4 ++-- .../note-details.component.spec.ts | 19 +++++++++++++++++++ .../note-details/note-details.component.ts | 4 ++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/app/child-dev-project/notes/note-details/note-details.component.html b/src/app/child-dev-project/notes/note-details/note-details.component.html index 04c440825b..45c194d251 100644 --- a/src/app/child-dev-project/notes/note-details/note-details.component.html +++ b/src/app/child-dev-project/notes/note-details/note-details.component.html @@ -137,7 +137,7 @@

{{ entity.date?.toLocaleDateString() }}: {{ entity.subject }}

[(selection)]="entity.children" (selectionChange)="entityForm.form.markAsDirty()" [additionalFilter]="filterInactiveChildren" - [showEntities]="!entity.category.isMeeting" + [showEntities]="!isMeeting" label="Participants" i18n-label="Participants of a note" placeholder="Add participant ..." @@ -155,7 +155,7 @@

{{ entity.date?.toLocaleDateString() }}: {{ entity.subject }}

-
+
{ it("should create", () => { expect(component).toBeTruthy(); }); + + it("should show the child meeting note attendance component when the event is a meeting", () => { + component.entity.category.isMeeting = true; + const element = fixture.debugElement.query( + By.directive(ChildMeetingNoteAttendanceComponent) + ); + expect(element).toBeTruthy(); + }); + + it("should not show the child meeting note attendance component when the event's category is undefined", () => { + component.entity.category = undefined; + fixture.detectChanges(); + const element = fixture.debugElement.query( + By.directive(ChildMeetingNoteAttendanceComponent) + ); + expect(element).toBeFalsy(); + }); }); diff --git a/src/app/child-dev-project/notes/note-details/note-details.component.ts b/src/app/child-dev-project/notes/note-details/note-details.component.ts index e0fbb66b0d..e538e13eb0 100644 --- a/src/app/child-dev-project/notes/note-details/note-details.component.ts +++ b/src/app/child-dev-project/notes/note-details/note-details.component.ts @@ -51,4 +51,8 @@ export class NoteDetailsComponent implements ShowsEntity { .beforeClosed() .subscribe(() => this.matDialogRef.close(entity)); } + + get isMeeting(): boolean { + return this.entity.category?.isMeeting || false; + } } From 711a30d60db186eff89cc6df65418f976423852b Mon Sep 17 00:00:00 2001 From: Simon <33730997+TheSlimvReal@users.noreply.github.com> Date: Mon, 25 Oct 2021 10:16:06 +0200 Subject: [PATCH 04/21] fix: not displaying school in child block if no school info is available (#1034) --- .../children/child-block/child-block.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/child-dev-project/children/child-block/child-block.component.html b/src/app/child-dev-project/children/child-block/child-block.component.html index cec854c1f8..73dfebd3c5 100644 --- a/src/app/child-dev-project/children/child-block/child-block.component.html +++ b/src/app/child-dev-project/children/child-block/child-block.component.html @@ -26,7 +26,7 @@

{{ entity?.name }}

{{ entity?.phone }}

- +

,

@@ -36,7 +36,7 @@

{{ entity?.name }}

[linkDisabled]="true" >, - + class {{ entity?.schoolClass }}

From 05274289eb2a0485be0397bfafe63f2902a080ba Mon Sep 17 00:00:00 2001 From: Schottkyc137 <45085299+Schottkyc137@users.noreply.github.com> Date: Mon, 25 Oct 2021 15:16:30 +0200 Subject: [PATCH 05/21] refactor: entities are automatically registered in a static map closes #597 --- src/app/app.component.spec.ts | 5 + src/app/app.component.ts | 23 +-- .../core/admin/admin/admin.component.spec.ts | 5 + .../config/config-migration.service.spec.ts | 4 + .../core/config/config-migration.service.ts | 7 +- .../entity-details.component.ts | 26 +-- .../filter-generator.service.spec.ts | 4 + .../entity-list/filter-generator.service.ts | 16 +- .../edit-single-entity.component.ts | 13 +- .../entity-select.component.spec.ts | 4 + .../entity-select/entity-select.component.ts | 14 +- .../display-entity-array.component.spec.ts | 8 +- .../display-entity-array.component.ts | 14 +- .../display-entity.component.spec.ts | 8 +- .../display-entity.component.ts | 13 +- .../core/entity/database-entity.decorator.ts | 3 + .../entity/dynamic-entity.service.spec.ts | 158 ++++++++++++++++++ src/app/core/entity/dynamic-entity.service.ts | 128 ++++++++++++++ .../core/entity/entity-config.service.spec.ts | 105 +++++++++++- src/app/core/entity/entity-config.service.ts | 88 +++++++++- src/app/core/entity/model/entity.ts | 4 +- .../form-dialog-wrapper.component.spec.ts | 8 +- .../primary-action.component.spec.ts | 3 + .../core/ui/search/search.component.spec.ts | 4 + src/app/core/ui/search/search.component.ts | 19 +-- 25 files changed, 576 insertions(+), 108 deletions(-) create mode 100644 src/app/core/entity/dynamic-entity.service.spec.ts create mode 100644 src/app/core/entity/dynamic-entity.service.ts diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 4a8d20dcf3..1573391fb8 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -34,6 +34,7 @@ import { Config } from "./core/config/config"; import { USAGE_ANALYTICS_CONFIG_ID } from "./core/analytics/usage-analytics-config"; import { environment } from "../environments/environment"; import { HttpClientTestingModule } from "@angular/common/http/testing"; +import { DynamicEntityService } from "./core/entity/dynamic-entity.service"; describe("AppComponent", () => { let component: AppComponent; @@ -55,6 +56,10 @@ describe("AppComponent", () => { { provide: AppConfig, useValue: jasmine.createSpyObj(["load"]) }, ], }).compileComponents(); + + // Otherwise multiple registrations throw an error + spyOn(DynamicEntityService, "registerNewEntity"); + TestBed.inject(ApplicationInitStatus); // This ensures that the AppConfig is loaded before test execution }) ); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 7805c36641..602a97c16b 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -24,18 +24,14 @@ import { EntityMapperService } from "./core/entity/entity-mapper.service"; import { ConfigService } from "./core/config/config.service"; import { RouterService } from "./core/view/dynamic-routing/router.service"; import { EntityConfigService } from "./core/entity/entity-config.service"; -import { Child } from "./child-dev-project/children/model/child"; import { SessionService } from "./core/session/session-service/session.service"; import { SyncState } from "./core/session/session-states/sync-state.enum"; import { ActivatedRoute, Router } from "@angular/router"; -import { RecurringActivity } from "./child-dev-project/attendance/model/recurring-activity"; -import { School } from "./child-dev-project/schools/model/school"; -import { HistoricalEntityData } from "./features/historical-data/historical-entity-data"; -import { Note } from "./child-dev-project/notes/model/note"; -import { EventNote } from "./child-dev-project/attendance/model/event-note"; import { waitForChangeTo } from "./core/session/session-states/session-utils"; import { environment } from "../environments/environment"; -import { ChildSchoolRelation } from "./child-dev-project/children/model/childSchoolRelation"; +import { DynamicEntityService } from "./core/entity/dynamic-entity.service"; +import { Child } from "./child-dev-project/children/model/child"; +import { School } from "./child-dev-project/schools/model/school"; @Component({ selector: "app-root", @@ -62,6 +58,11 @@ export class AppComponent implements OnInit { } private async initBasicServices() { + // TODO: remove this with issue #886 + // This needs to be in the app module (as opposed to the dynamic entity service) + // to prevent circular dependencies + DynamicEntityService.registerNewEntity("Participant", Child); + DynamicEntityService.registerNewEntity("Team", School); // first register to events // Reload config once the database is synced @@ -76,13 +77,7 @@ export class AppComponent implements OnInit { // These functions will be executed whenever a new config is available this.configService.configUpdates.subscribe(() => { this.routerService.initRouting(); - this.entityConfigService.addConfigAttributes(Child); - this.entityConfigService.addConfigAttributes(School); - this.entityConfigService.addConfigAttributes(RecurringActivity); - this.entityConfigService.addConfigAttributes(HistoricalEntityData); - this.entityConfigService.addConfigAttributes(Note); - this.entityConfigService.addConfigAttributes(EventNote); - this.entityConfigService.addConfigAttributes(ChildSchoolRelation); + this.entityConfigService.setupEntitiesFromConfig(); }); // If loading the config earlier (in a module constructor or through APP_INITIALIZER) a runtime error occurs. diff --git a/src/app/core/admin/admin/admin.component.spec.ts b/src/app/core/admin/admin/admin.component.spec.ts index 56e31ccfa3..a93f13e0e7 100644 --- a/src/app/core/admin/admin/admin.component.spec.ts +++ b/src/app/core/admin/admin/admin.component.spec.ts @@ -24,6 +24,7 @@ import { NotesMigrationService } from "../../../child-dev-project/notes/notes-mi import { AttendanceMigrationService } from "../../../child-dev-project/attendance/attendance-migration/attendance-migration.service"; import { ChildrenMigrationService } from "../../../child-dev-project/children/child-photo-service/children-migration.service"; import { PermissionsMigrationService } from "../../permissions/permissions-migration.service"; +import { ConfigMigrationService } from "../../config/config-migration.service"; describe("AdminComponent", () => { let component: AdminComponent; @@ -118,6 +119,10 @@ describe("AdminComponent", () => { provide: PermissionsMigrationService, useValue: {}, }, + { + provide: ConfigMigrationService, + useValue: {}, + }, ], }).compileComponents(); }) diff --git a/src/app/core/config/config-migration.service.spec.ts b/src/app/core/config/config-migration.service.spec.ts index 1e61306687..02720984b5 100644 --- a/src/app/core/config/config-migration.service.spec.ts +++ b/src/app/core/config/config-migration.service.spec.ts @@ -16,6 +16,8 @@ import { genders } from "../../child-dev-project/children/model/genders"; import { EntitySchemaField } from "../entity/schema/entity-schema-field"; import { Child } from "../../child-dev-project/children/model/child"; import { HistoricalEntityData } from "../../features/historical-data/historical-entity-data"; +import { DynamicEntityService } from "../entity/dynamic-entity.service"; +import { EntitySchemaService } from "../entity/schema/entity-schema.service"; describe("ConfigMigrationService", () => { let service: ConfigMigrationService; @@ -344,6 +346,8 @@ describe("ConfigMigrationService", () => { providers: [ EntityConfigService, ConfigService, + EntitySchemaService, + DynamicEntityService, { provide: EntityMapperService, useValue: mockEntityMapper }, ], }); diff --git a/src/app/core/config/config-migration.service.ts b/src/app/core/config/config-migration.service.ts index e6ecb494c3..28539db7fd 100644 --- a/src/app/core/config/config-migration.service.ts +++ b/src/app/core/config/config-migration.service.ts @@ -9,7 +9,6 @@ import { FilterConfig, } from "../entity-components/entity-list/EntityListConfig"; import { FormFieldConfig } from "../entity-components/entity-form/entity-form/FormConfig"; -import { ENTITY_MAP } from "../entity-components/entity-details/entity-details.component"; import { Entity, EntityConstructor } from "../entity/model/entity"; import { EntityConfig, @@ -33,6 +32,7 @@ import { } from "../configurable-enum/configurable-enum.interface"; import { warningLevels } from "../../child-dev-project/warning-levels"; import { User } from "../user/user"; +import { DynamicEntityService } from "../entity/dynamic-entity.service"; @Injectable({ providedIn: "root", @@ -41,7 +41,8 @@ export class ConfigMigrationService { private config: Config; constructor( private configService: ConfigService, - private entityMapper: EntityMapperService + private entityMapper: EntityMapperService, + private dynamicEntityService: DynamicEntityService ) {} async migrateConfig(): Promise { @@ -92,7 +93,7 @@ export class ConfigMigrationService { .split("-") .map((s) => s.charAt(0).toUpperCase() + s.slice(1)) .join(""); - return ENTITY_MAP.get(entityType); + return this.dynamicEntityService.getEntityConstructor(entityType); } private migrateEntityListConfig( diff --git a/src/app/core/entity-components/entity-details/entity-details.component.ts b/src/app/core/entity-components/entity-details/entity-details.component.ts index 8972a24256..69a2ce2b54 100644 --- a/src/app/core/entity-components/entity-details/entity-details.component.ts +++ b/src/app/core/entity-components/entity-details/entity-details.component.ts @@ -7,18 +7,13 @@ import { PanelComponent, PanelConfig, } from "./EntityDetailsConfig"; -import { Entity, EntityConstructor } from "../../entity/model/entity"; -import { School } from "../../../child-dev-project/schools/model/school"; +import { Entity } from "../../entity/model/entity"; import { EntityMapperService } from "../../entity/entity-mapper.service"; import { getUrlWithoutParams } from "../../../utils/utils"; -import { Child } from "../../../child-dev-project/children/model/child"; -import { RecurringActivity } from "../../../child-dev-project/attendance/model/recurring-activity"; import { EntityPermissionsService, OperationType, } from "../../permissions/entity-permissions.service"; -import { User } from "../../user/user"; -import { Note } from "../../../child-dev-project/notes/model/note"; import { UntilDestroy } from "@ngneat/until-destroy"; import { RouteData } from "../../view/dynamic-routing/view-config.interface"; import { AnalyticsService } from "../../analytics/analytics.service"; @@ -26,19 +21,7 @@ import { EntityRemoveService, RemoveResult, } from "../../entity/entity-remove.service"; - -export const ENTITY_MAP: Map> = new Map< - string, - EntityConstructor ->([ - ["Child", Child], - ["Participant", Child], - ["School", School], - ["Team", School], - ["RecurringActivity", RecurringActivity], - ["Note", Note], - ["User", User], -]); +import { DynamicEntityService } from "../../entity/dynamic-entity.service"; /** * This component can be used to display a entity in more detail. @@ -69,7 +52,8 @@ export class EntityDetailsComponent { private location: Location, private analyticsService: AnalyticsService, private permissionService: EntityPermissionsService, - private entityRemoveService: EntityRemoveService + private entityRemoveService: EntityRemoveService, + private dynamicEntityService: DynamicEntityService ) { this.route.data.subscribe((data: RouteData) => { this.config = data.config; @@ -81,7 +65,7 @@ export class EntityDetailsComponent { } private loadEntity(id: string) { - const constr: EntityConstructor = ENTITY_MAP.get( + const constr = this.dynamicEntityService.getEntityConstructor( this.config.entity ); if (id === "new") { diff --git a/src/app/core/entity-components/entity-list/filter-generator.service.spec.ts b/src/app/core/entity-components/entity-list/filter-generator.service.spec.ts index 17b3ef0a76..638c0a04c3 100644 --- a/src/app/core/entity-components/entity-list/filter-generator.service.spec.ts +++ b/src/app/core/entity-components/entity-list/filter-generator.service.spec.ts @@ -12,6 +12,8 @@ import { ChildSchoolRelation } from "../../../child-dev-project/children/model/c import { Child } from "../../../child-dev-project/children/model/child"; import moment from "moment"; import { EntityConfigService } from "app/core/entity/entity-config.service"; +import { EntitySchemaService } from "../../entity/schema/entity-schema.service"; +import { DynamicEntityService } from "../../entity/dynamic-entity.service"; describe("FilterGeneratorService", () => { let service: FilterGeneratorService; @@ -23,7 +25,9 @@ describe("FilterGeneratorService", () => { TestBed.configureTestingModule({ providers: [ ConfigService, + EntitySchemaService, { provide: EntityMapperService, useValue: mockEntityMapper }, + DynamicEntityService, LoggingService, EntityConfigService, ], diff --git a/src/app/core/entity-components/entity-list/filter-generator.service.ts b/src/app/core/entity-components/entity-list/filter-generator.service.ts index 68a77d9850..a7324a7aa5 100644 --- a/src/app/core/entity-components/entity-list/filter-generator.service.ts +++ b/src/app/core/entity-components/entity-list/filter-generator.service.ts @@ -8,7 +8,6 @@ import { FilterConfig, PrebuiltFilterConfig, } from "./EntityListConfig"; -import { ENTITY_MAP } from "../entity-details/entity-details.component"; import { Entity, EntityConstructor } from "../../entity/model/entity"; import { CONFIGURABLE_ENUM_CONFIG_PREFIX, @@ -16,9 +15,9 @@ import { } from "../../configurable-enum/configurable-enum.interface"; import { ConfigService } from "../../config/config.service"; import { LoggingService } from "../../logging/logging.service"; -import { EntityMapperService } from "../../entity/entity-mapper.service"; import { EntitySchemaField } from "../../entity/schema/entity-schema-field"; import { FilterComponentSettings } from "./filter-component.settings"; +import { DynamicEntityService } from "../../entity/dynamic-entity.service"; @Injectable({ providedIn: "root", @@ -27,7 +26,7 @@ export class FilterGeneratorService { constructor( private configService: ConfigService, private loggingService: LoggingService, - private entityMapperService: EntityMapperService + private dynamicEntityService: DynamicEntityService ) {} /** @@ -97,8 +96,10 @@ export class FilterGeneratorService { schema.innerDataType ); } else if ( - ENTITY_MAP.has(config.type) || - ENTITY_MAP.has(schema.additional) + this.dynamicEntityService.hasAnyRegisteredEntity( + config.type, + schema.additional + ) ) { return await this.createEntityFilterOption( config.id, @@ -159,10 +160,7 @@ export class FilterGeneratorService { property: string, entityType: string ): Promise[]> { - const entityConstructor = ENTITY_MAP.get(entityType); - const filterEntities = await this.entityMapperService.loadType( - entityConstructor - ); + const filterEntities = await this.dynamicEntityService.loadType(entityType); const options = [ { diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.ts index 46e4b44141..8d6632b959 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.ts +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.ts @@ -1,12 +1,11 @@ import { Component, ElementRef, ViewChild } from "@angular/core"; import { EditComponent, EditPropertyConfig } from "../edit-component"; -import { ENTITY_MAP } from "../../../entity-details/entity-details.component"; -import { EntityMapperService } from "../../../../entity/entity-mapper.service"; import { Entity } from "../../../../entity/model/entity"; import { Observable } from "rxjs"; import { filter, map } from "rxjs/operators"; import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; import { FormControl } from "@angular/forms"; +import { DynamicEntityService } from "../../../../entity/dynamic-entity.service"; @UntilDestroy() @Component({ @@ -24,7 +23,7 @@ export class EditSingleEntityComponent extends EditComponent { @ViewChild("inputElement") input: ElementRef; - constructor(private entityMapper: EntityMapperService) { + constructor(private dynamicEntityService: DynamicEntityService) { super(); this.filteredEntities = this.entityNameFormControl.valueChanges.pipe( untilDestroyed(this), @@ -49,12 +48,8 @@ export class EditSingleEntityComponent extends EditComponent { this.placeholder = $localize`:Placeholder for input to set an entity|context Select User:Select ${this.label}`; const entityType: string = config.formFieldConfig.additional || config.propertySchema.additional; - const entityConstructor = ENTITY_MAP.get(entityType); - if (!entityConstructor) { - throw new Error(`Entity-Type ${entityType} not in EntityMap`); - } - this.entities = await this.entityMapper - .loadType(entityConstructor) + this.entities = await this.dynamicEntityService + .loadType(entityType) .then((entities) => entities.sort((e1, e2) => e1.toString().localeCompare(e2.toString())) ); diff --git a/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.spec.ts b/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.spec.ts index e0f16f6d15..ad7d1dbe0d 100644 --- a/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.spec.ts +++ b/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.spec.ts @@ -17,6 +17,8 @@ import { User } from "../../../user/user"; import { Child } from "../../../../child-dev-project/children/model/child"; import { FlexLayoutModule } from "@angular/flex-layout"; import { Subscription } from "rxjs"; +import { EntitySchemaService } from "../../../entity/schema/entity-schema.service"; +import { DynamicEntityService } from "../../../entity/dynamic-entity.service"; describe("EntitySelectComponent", () => { let component: EntitySelectComponent; @@ -38,6 +40,8 @@ describe("EntitySelectComponent", () => { provide: EntityMapperService, useValue: mockEntityMapper(testUsers.concat(otherEntities)), }, + EntitySchemaService, + DynamicEntityService, ], imports: [ MatAutocompleteModule, diff --git a/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.ts b/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.ts index e600a8817f..4418f435f1 100644 --- a/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.ts +++ b/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.ts @@ -9,15 +9,14 @@ import { ViewChild, } from "@angular/core"; import { COMMA, ENTER } from "@angular/cdk/keycodes"; -import { Entity, EntityConstructor } from "../../../entity/model/entity"; -import { EntityMapperService } from "../../../entity/entity-mapper.service"; +import { Entity } from "../../../entity/model/entity"; import { BehaviorSubject, Observable } from "rxjs"; import { FormControl } from "@angular/forms"; import { filter, map } from "rxjs/operators"; import { MatChipInputEvent } from "@angular/material/chips"; import { MatAutocompleteTrigger } from "@angular/material/autocomplete"; -import { ENTITY_MAP } from "../../entity-details/entity-details.component"; import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; +import { DynamicEntityService } from "../../../entity/dynamic-entity.service"; @Component({ selector: "app-entity-select", @@ -31,18 +30,13 @@ export class EntitySelectComponent implements OnChanges { /** * The entity-type (e.g. 'Child', 'School', e.t.c.) to set. - * The entity-type has to be inside {@link ENTITY_MAP} * @param type The ENTITY_TYPE of a Entity. This affects the entities which will be loaded and the component * that displays the entities. * @throws Error when `type` is not in the entity-map */ @Input() set entityType(type: string) { - const entityConstructor = ENTITY_MAP.get(type) as EntityConstructor; - if (!entityConstructor) { - throw new Error(`Entity-Type ${type} not in EntityMap`); - } this.loading.next(true); - this.entityMapperService.loadType(entityConstructor).then((entities) => { + this.dynamicEntityService.loadType(type).then((entities) => { this.allEntities = entities; this.loading.next(false); this.formControl.setValue(null); @@ -149,7 +143,7 @@ export class EntitySelectComponent implements OnChanges { @ViewChild("inputField") inputField: ElementRef; @ViewChild(MatAutocompleteTrigger) autocomplete: MatAutocompleteTrigger; - constructor(private entityMapperService: EntityMapperService) { + constructor(private dynamicEntityService: DynamicEntityService) { this.filteredEntities = this.formControl.valueChanges.pipe( untilDestroyed(this), filter((value) => value === null || typeof value === "string"), // sometimes produces entities diff --git a/src/app/core/entity-components/entity-utils/view-components/display-entity-array/display-entity-array.component.spec.ts b/src/app/core/entity-components/entity-utils/view-components/display-entity-array/display-entity-array.component.spec.ts index db9b184dec..677de7870e 100644 --- a/src/app/core/entity-components/entity-utils/view-components/display-entity-array/display-entity-array.component.spec.ts +++ b/src/app/core/entity-components/entity-utils/view-components/display-entity-array/display-entity-array.component.spec.ts @@ -4,6 +4,8 @@ import { DisplayEntityArrayComponent } from "./display-entity-array.component"; import { EntityMapperService } from "../../../../entity/entity-mapper.service"; import { Child } from "../../../../../child-dev-project/children/model/child"; import { Note } from "../../../../../child-dev-project/notes/model/note"; +import { EntitySchemaService } from "../../../../entity/schema/entity-schema.service"; +import { DynamicEntityService } from "../../../../entity/dynamic-entity.service"; describe("DisplayEntityArrayComponent", () => { let component: DisplayEntityArrayComponent; @@ -15,7 +17,11 @@ describe("DisplayEntityArrayComponent", () => { mockEntityMapper.load.and.resolveTo(new Child()); await TestBed.configureTestingModule({ declarations: [DisplayEntityArrayComponent], - providers: [{ provide: EntityMapperService, useValue: mockEntityMapper }], + providers: [ + { provide: EntityMapperService, useValue: mockEntityMapper }, + EntitySchemaService, + DynamicEntityService, + ], }).compileComponents(); }); diff --git a/src/app/core/entity-components/entity-utils/view-components/display-entity-array/display-entity-array.component.ts b/src/app/core/entity-components/entity-utils/view-components/display-entity-array/display-entity-array.component.ts index 706fd772e7..e066cd99b3 100644 --- a/src/app/core/entity-components/entity-utils/view-components/display-entity-array/display-entity-array.component.ts +++ b/src/app/core/entity-components/entity-utils/view-components/display-entity-array/display-entity-array.component.ts @@ -3,7 +3,7 @@ import { Entity } from "../../../../entity/model/entity"; import { EntityMapperService } from "../../../../entity/entity-mapper.service"; import { ViewComponent } from "../view-component"; import { ViewPropertyConfig } from "../../../entity-list/EntityListConfig"; -import { ENTITY_MAP } from "../../../entity-details/entity-details.component"; +import { DynamicEntityService } from "../../../../entity/dynamic-entity.service"; @Component({ selector: "app-display-entity-array", @@ -13,7 +13,10 @@ import { ENTITY_MAP } from "../../../entity-details/entity-details.component"; export class DisplayEntityArrayComponent extends ViewComponent { readonly aggregationThreshold = 5; entities: Entity[]; - constructor(private entityMapper: EntityMapperService) { + constructor( + private entityMapper: EntityMapperService, + private dynamicEntityService: DynamicEntityService + ) { super(); } @@ -22,10 +25,9 @@ export class DisplayEntityArrayComponent extends ViewComponent { const entityIds: string[] = this.entity[this.property] || []; if (entityIds.length < this.aggregationThreshold) { const entityType = this.entity.getSchema().get(this.property).additional; - const entityConstructor = ENTITY_MAP.get(entityType); - if (!entityConstructor) { - throw new Error(`Could not find type ${entityType} in ENTITY_MAP`); - } + const entityConstructor = this.dynamicEntityService.getEntityConstructor( + entityType + ); const entityPromises = entityIds.map((entityId) => this.entityMapper.load(entityConstructor, entityId) ); diff --git a/src/app/core/entity-components/entity-utils/view-components/display-entity/display-entity.component.spec.ts b/src/app/core/entity-components/entity-utils/view-components/display-entity/display-entity.component.spec.ts index 70434fcbbc..5497a56c05 100644 --- a/src/app/core/entity-components/entity-utils/view-components/display-entity/display-entity.component.spec.ts +++ b/src/app/core/entity-components/entity-utils/view-components/display-entity/display-entity.component.spec.ts @@ -10,6 +10,8 @@ import { EntityMapperService } from "../../../../entity/entity-mapper.service"; import { Child } from "../../../../../child-dev-project/children/model/child"; import { ChildSchoolRelation } from "../../../../../child-dev-project/children/model/childSchoolRelation"; import { School } from "../../../../../child-dev-project/schools/model/school"; +import { EntitySchemaService } from "../../../../entity/schema/entity-schema.service"; +import { DynamicEntityService } from "../../../../entity/dynamic-entity.service"; describe("DisplayEntityComponent", () => { let component: DisplayEntityComponent; @@ -21,7 +23,11 @@ describe("DisplayEntityComponent", () => { mockEntityMapper.load.and.resolveTo(new Child()); await TestBed.configureTestingModule({ declarations: [DisplayEntityComponent], - providers: [{ provide: EntityMapperService, useValue: mockEntityMapper }], + providers: [ + { provide: EntityMapperService, useValue: mockEntityMapper }, + EntitySchemaService, + DynamicEntityService, + ], }).compileComponents(); }); diff --git a/src/app/core/entity-components/entity-utils/view-components/display-entity/display-entity.component.ts b/src/app/core/entity-components/entity-utils/view-components/display-entity/display-entity.component.ts index b57e7bbe74..890aa324bc 100644 --- a/src/app/core/entity-components/entity-utils/view-components/display-entity/display-entity.component.ts +++ b/src/app/core/entity-components/entity-utils/view-components/display-entity/display-entity.component.ts @@ -1,9 +1,8 @@ import { Component, Input, OnInit } from "@angular/core"; import { Entity } from "../../../../entity/model/entity"; import { ViewPropertyConfig } from "../../../entity-list/EntityListConfig"; -import { EntityMapperService } from "../../../../entity/entity-mapper.service"; -import { ENTITY_MAP } from "../../../entity-details/entity-details.component"; import { ViewComponent } from "../view-component"; +import { DynamicEntityService } from "../../../../entity/dynamic-entity.service"; @Component({ selector: "app-display-entity", @@ -14,7 +13,7 @@ export class DisplayEntityComponent extends ViewComponent implements OnInit { @Input() entityToDisplay: Entity; @Input() linkDisabled = false; entityBlockComponent: string; - constructor(private entityMapper: EntityMapperService) { + constructor(private dynamicEntityService: DynamicEntityService) { super(); } @@ -31,12 +30,8 @@ export class DisplayEntityComponent extends ViewComponent implements OnInit { if (this.entity[this.property]) { const type = config.config || this.entity.getSchema().get(this.property).additional; - const entityConstructor = ENTITY_MAP.get(type); - if (!entityConstructor) { - throw new Error(`Could not find type ${type} in ENTITY_MAP`); - } - this.entityToDisplay = await this.entityMapper - .load(entityConstructor, this.entity[this.property]) + this.entityToDisplay = await this.dynamicEntityService + .loadEntity(type, this.entity[this.property]) .catch(() => undefined); this.ngOnInit(); } diff --git a/src/app/core/entity/database-entity.decorator.ts b/src/app/core/entity/database-entity.decorator.ts index 526e131491..249c97d1a0 100644 --- a/src/app/core/entity/database-entity.decorator.ts +++ b/src/app/core/entity/database-entity.decorator.ts @@ -5,8 +5,11 @@ * * @param entityType The string key for this Entity Type, used as id prefix. */ +import { DynamicEntityService } from "./dynamic-entity.service"; + export function DatabaseEntity(entityType: string) { return (constructor) => { + DynamicEntityService.registerNewEntity(entityType, constructor); constructor.ENTITY_TYPE = entityType; // append parent schema definitions diff --git a/src/app/core/entity/dynamic-entity.service.spec.ts b/src/app/core/entity/dynamic-entity.service.spec.ts new file mode 100644 index 0000000000..7f02ae7a66 --- /dev/null +++ b/src/app/core/entity/dynamic-entity.service.spec.ts @@ -0,0 +1,158 @@ +import { EntityMapperService } from "./entity-mapper.service"; +import { TestBed } from "@angular/core/testing"; +import { EntitySchemaService } from "./schema/entity-schema.service"; +import { DynamicEntityService } from "./dynamic-entity.service"; +import { DatabaseEntity } from "./database-entity.decorator"; +import { Entity, EntityConstructor } from "./model/entity"; +import { DatabaseField } from "./database-field.decorator"; +import { + mockEntityMapper, + MockEntityMapperService, +} from "./mock-entity-mapper-service"; + +describe("DynamicEntityService", () => { + let service: DynamicEntityService; + let mockedEntityMapper: MockEntityMapperService; + + beforeEach(() => { + mockedEntityMapper = mockEntityMapper(); + TestBed.configureTestingModule({ + providers: [ + { provide: EntityMapperService, useValue: mockedEntityMapper }, + EntitySchemaService, + ], + }); + service = TestBed.inject(DynamicEntityService); + }); + + it("should be created", () => { + expect(service).toBeTruthy(); + }); + + it("contains the new entity-definition when registered", () => { + const mockEntityName = "Mock"; + DynamicEntityService.registerNewEntity( + mockEntityName, + EntityWithoutDecorator + ); + expect(service.isRegisteredEntity(mockEntityName)).toBeTrue(); + }); + + it("contains entity-definitions when they have the 'DatabaseEntity' decorator", () => { + expect(service.isRegisteredEntity(ENTITY_WITH_DECORATOR_TYPE)).toBeTrue(); + }); + + it("throws when trying to define a duplicate entity", () => { + const registerNewEntity = () => { + DynamicEntityService.registerNewEntity( + ENTITY_WITH_DECORATOR_TYPE, + EntityWithDecorator + ); + }; + expect(registerNewEntity).toThrowError(); + }); + + it("throws when trying to set a constructor that is not an entity-constructor", () => { + const registerNonEntity = () => { + DynamicEntityService.registerNewEntity( + NON_ENTITY_CLASS_TYPE, + NonEntityClass as EntityConstructor + ); + }; + expect(registerNonEntity).toThrowError(); + }); + + it("returns the entity-constructor of a defined entity", () => { + const ctor = service.getEntityConstructor(ENTITY_WITH_DECORATOR_TYPE); + expect(ctor).toEqual(EntityWithDecorator); + }); + + it("throws when trying to get an entity-constructor that doesn't exist", () => { + expect(() => service.getEntityConstructor("IDoNotExist")).toThrowError(); + }); + + it("Instantiates an entity", () => { + const instance = service.instantiateEntity(ENTITY_WITH_PARAMETERS_TYPE); + expect(instance.getType()).toEqual(ENTITY_WITH_PARAMETERS_TYPE); + expect(instance).toBeInstanceOf(Entity); + expect(instance).toBeInstanceOf(EntityWithParameters); + }); + + it("Instantiates an entity with given id", () => { + const idName = "id"; + const instance = service.instantiateEntity( + ENTITY_WITH_PARAMETERS_TYPE, + idName + ); + expect(instance.getId()).toEqual(idName); + expect(instance.getType()).toEqual(ENTITY_WITH_PARAMETERS_TYPE); + }); + + it("instantiates an entity with given initial raw parameters", () => { + const idName = "id"; + const params = { + x: "Hello, World!", + y: 42, + }; + const instance = service.instantiateEntity( + ENTITY_WITH_PARAMETERS_TYPE, + idName, + params + ); + expect(instance.x).toEqual(params.x); + expect(instance.y).toEqual(params.y); + }); + + it("returns true when any entity is registered from a set of given types", () => { + expect( + service.hasAnyRegisteredEntity(ENTITY_WITH_DECORATOR_TYPE, "IDoNotExist") + ).toBeTrue(); + }); + + it("returns false when no entity is registered from a set of given types", () => { + expect( + service.hasAnyRegisteredEntity("IDoNotExist", "MeNeither") + ).toBeFalse(); + }); + + it("loads an entity by it's type", () => { + const entityId = "id"; + const mockEntity = new EntityWithParameters(entityId); + mockEntity.x = "Hello, World!"; + mockEntity.y = 42; + mockedEntityMapper.add(mockEntity); + const entity = service.loadEntity(ENTITY_WITH_PARAMETERS_TYPE, entityId); + return expectAsync(entity).toBeResolvedTo(mockEntity); + }); + + it("loads an array of entities by their type", () => { + const mockEntities = ["id1", "id2"].map( + (id) => new EntityWithParameters(id) + ); + mockedEntityMapper.addAll(mockEntities); + const entities = service.loadType(ENTITY_WITH_PARAMETERS_TYPE); + return expectAsync(entities).toBeResolvedTo(mockEntities); + }); +}); + +const ENTITY_WITH_DECORATOR_TYPE = "EntityWithDecorator"; + +@DatabaseEntity(ENTITY_WITH_DECORATOR_TYPE) +class EntityWithDecorator extends Entity {} + +const ENTITY_WITH_PARAMETERS_TYPE = "EntityWithParameters"; + +@DatabaseEntity(ENTITY_WITH_PARAMETERS_TYPE) +class EntityWithParameters extends Entity { + @DatabaseField() + x?: string; + + @DatabaseField() + y?: number; +} + +class EntityWithoutDecorator extends Entity {} + +const NON_ENTITY_CLASS_TYPE = "NonEntityClass"; + +class NonEntityClass {} diff --git a/src/app/core/entity/dynamic-entity.service.ts b/src/app/core/entity/dynamic-entity.service.ts new file mode 100644 index 0000000000..decd24abf8 --- /dev/null +++ b/src/app/core/entity/dynamic-entity.service.ts @@ -0,0 +1,128 @@ +import { Entity, EntityConstructor } from "./model/entity"; +import { Injectable } from "@angular/core"; +import { EntityMapperService } from "./entity-mapper.service"; +import { EntitySchemaService } from "./schema/entity-schema.service"; + +/** + * A service that can be used to get the entity-constructors (see {@link EntityConstructor}) + * from their string-types. + * This also contains utility methods that deal with creating, loading, + * checking on the existence and instantiating entities based on the string-types + */ +@Injectable({ + providedIn: "root", +}) +export class DynamicEntityService { + private static ENTITY_MAP = new Map>(); + + /** + * Registers a new entity so that it can be used using this service. + * This method should generally never be used other than from the + * {@link DatabaseEntity}-Decorator + * + * @param type The entity-type as string + * @param constructor The constructor of the entity + */ + static registerNewEntity( + type: string, + constructor: EntityConstructor + ) { + if (!(new constructor() instanceof Entity)) { + throw Error( + `Tried to register an entity-type that is not a subclass of Entity\n` + + `type: ${type}; constructor: ${constructor}` + ); + } + if (this.ENTITY_MAP.has(type)) { + throw Error( + `Duplicate entity definition: ${type} is already registered with constructor ${this.ENTITY_MAP.get( + type + )}` + ); + } + this.ENTITY_MAP.set(type, constructor); + } + + constructor( + private entityMapper: EntityMapperService, + private entitySchemaService: EntitySchemaService + ) {} + + /** + * returns the entity-constructor for a given string-name (i.e. the type) + * of the entity. If the name is not registered, this method throws an error + * @param entityType The type to get the entity from + */ + getEntityConstructor( + entityType: string + ): EntityConstructor { + const ctor = DynamicEntityService.ENTITY_MAP.get(entityType); + if (!ctor) { + throw new Error(`Entity-type ${entityType} does not exist!`); + } + return ctor as EntityConstructor; + } + + /** + * Utility method to instantiate an entity using initial, raw parameters as they + * would appear in the database + * @param entityType The type to instantiate an entity by + * @param id The id that the entity should have + * @param initialParameters The initial parameters as they would appear in the database + */ + instantiateEntity( + entityType: string, + id?: string, + initialParameters?: object + ): E { + const ctor = this.getEntityConstructor(entityType); + const entity = id ? new ctor(id) : new ctor(); + if (initialParameters) { + this.entitySchemaService.loadDataIntoEntity(entity, initialParameters); + } + return entity; + } + + /** + * returns {@code true}, when the entity is registered and could thus be + * instantiated. Use this method when you don't want to use the throwing + * {@link getEntityConstructor} or similar throwing methods + * @param entityType The type to look up + */ + isRegisteredEntity(entityType: string): boolean { + return DynamicEntityService.ENTITY_MAP.has(entityType); + } + + /** + * returns {@code true}, when any of the given entities are registered + * and could be instantiated + * @param entityTypes The types of entities to look up + */ + hasAnyRegisteredEntity(...entityTypes: string[]): boolean { + return entityTypes.some((type) => this.isRegisteredEntity(type)); + } + + /** + * Load an entity dynamically using the name instead of the constructor + * like one would in the {@link EntityMapperService} + * @param entityType The type of the entity to load + * @param entityId The id of the entity to load + */ + async loadEntity( + entityType: string, + entityId: string + ): Promise { + const ctor = this.getEntityConstructor(entityType); + return this.entityMapper.load(ctor, entityId); + } + + /** + * Load all entities of a certain type using the name of the entity-type + * instead of the constructor + * @param entityType The entity-type to load + */ + async loadType(entityType: string): Promise { + const ctor = this.getEntityConstructor(entityType); + return this.entityMapper.loadType(ctor); + } +} diff --git a/src/app/core/entity/entity-config.service.spec.ts b/src/app/core/entity/entity-config.service.spec.ts index a2012c1e1e..4845baf9e8 100644 --- a/src/app/core/entity/entity-config.service.spec.ts +++ b/src/app/core/entity/entity-config.service.spec.ts @@ -5,21 +5,63 @@ import { DatabaseEntity } from "./database-entity.decorator"; import { DatabaseField } from "./database-field.decorator"; import { Entity } from "./model/entity"; import { ConfigService } from "../config/config.service"; +import { DynamicEntityService } from "./dynamic-entity.service"; +import { LoggingService } from "../logging/logging.service"; +import { EntitySchemaService } from "./schema/entity-schema.service"; +import { EntityMapperService } from "./entity-mapper.service"; +import { mockEntityMapper } from "./mock-entity-mapper-service"; + +declare global { + namespace jasmine { + interface Matchers { + toContainKey(key: any); + } + } +} describe("EntityConfigService", () => { let service: EntityConfigService; - const mockConfigService: jasmine.SpyObj = jasmine.createSpyObj( - "mockConfigService", - ["getConfig"] - ); + let mockConfigService: jasmine.SpyObj; + let mockLogger: jasmine.SpyObj; const testConfig: EntityConfig = { attributes: [{ name: "testAttribute", schema: { dataType: "string" } }], }; + beforeAll(() => { + jasmine.addMatchers({ + toContainKey: () => { + return { + compare: (actual: Map, expected: T) => { + if (actual.has(expected)) { + return { + pass: true, + }; + } else { + return { + pass: false, + message: `Expected Map ${[...actual].join( + "," + )} to contain key '${expected}'`, + }; + } + }, + }; + }, + }); + }); + beforeEach(() => { + mockConfigService = jasmine.createSpyObj(["getConfig", "getAllConfigs"]); + mockLogger = jasmine.createSpyObj(["error"]); mockConfigService.getConfig.and.returnValue(testConfig); TestBed.configureTestingModule({ - providers: [{ provide: ConfigService, useValue: mockConfigService }], + providers: [ + { provide: ConfigService, useValue: mockConfigService }, + { provide: LoggingService, useValue: mockLogger }, + { provide: EntityMapperService, useValue: mockEntityMapper() }, + DynamicEntityService, + EntitySchemaService, + ], }); service = TestBed.inject(EntityConfigService); }); @@ -31,8 +73,8 @@ describe("EntityConfigService", () => { it("should add attributes to a entity class schema", () => { expect(Test.schema.has("name")).toBeTrue(); service.addConfigAttributes(Test); - expect(Test.schema.has("testAttribute")).toBeTrue(); - expect(Test.schema.has("name")).toBeTrue(); + expect(Test.schema).toContainKey("testAttribute"); + expect(Test.schema).toContainKey("name"); }); it("should assign the correct schema", () => { @@ -47,9 +89,58 @@ describe("EntityConfigService", () => { expect(mockConfigService.getConfig).toHaveBeenCalledWith("entity:Test"); expect(result).toBe(config); }); + + it("warns when trying to setting the entities up from config and they are not registered", () => { + const configWithInvalidEntities: (EntityConfig & { _id: string })[] = [ + { + _id: "entity:IDoNotExist", + permissions: {}, + }, + ]; + mockConfigService.getAllConfigs.and.returnValue(configWithInvalidEntities); + service.setupEntitiesFromConfig(); + expect(mockLogger.error).toHaveBeenCalled(); + }); + + it("appends custom definitions for each entity from the config", () => { + const ATTRIBUTE_1_NAME = "test1Attribute"; + const ATTRIBUTE_2_NAME = "test2Attribute"; + const mockEntityConfigs: (EntityConfig & { _id: string })[] = [ + { + _id: "entity:Test", + attributes: [ + { + name: ATTRIBUTE_1_NAME, + schema: { + dataType: "string", + }, + }, + ], + }, + { + _id: "entity:Test2", + attributes: [ + { + name: ATTRIBUTE_2_NAME, + schema: { + dataType: "number", + }, + }, + ], + }, + ]; + mockConfigService.getAllConfigs.and.returnValue(mockEntityConfigs); + service.setupEntitiesFromConfig(); + expect(mockLogger.error).not.toHaveBeenCalled(); + expect(Test.schema).toContainKey(ATTRIBUTE_1_NAME); + expect(Test2.schema).toContainKey(ATTRIBUTE_2_NAME); + }); }); @DatabaseEntity("Test") class Test extends Entity { @DatabaseField() name: string; } + +@DatabaseEntity("Test2") +class Test2 extends Entity {} diff --git a/src/app/core/entity/entity-config.service.ts b/src/app/core/entity/entity-config.service.ts index 64987d8f62..5bbbdc1197 100644 --- a/src/app/core/entity/entity-config.service.ts +++ b/src/app/core/entity/entity-config.service.ts @@ -1,20 +1,44 @@ import { Injectable } from "@angular/core"; -import { Entity, EntityConstructor } from "./model/entity"; +import { + Entity, + ENTITY_CONFIG_PREFIX, + EntityConstructor, +} from "./model/entity"; import { ConfigService } from "../config/config.service"; import { EntitySchemaField } from "./schema/entity-schema-field"; import { addPropertySchema } from "./database-field.decorator"; import { OperationType } from "../permissions/entity-permissions.service"; +import { DynamicEntityService } from "./dynamic-entity.service"; +import { LoggingService } from "../logging/logging.service"; +/** + * A service that allows to work with configuration-objects + * related to entities such as assigning dynamic attributes + * and their schemas to existing entities + */ @Injectable({ providedIn: "root", }) export class EntityConfigService { static readonly PREFIX_ENTITY_CONFIG = "entity:"; - constructor(private configService: ConfigService) {} + constructor( + private configService: ConfigService, + private dynamicEntityService: DynamicEntityService, + private loggingService: LoggingService + ) {} - public addConfigAttributes(entityType: typeof Entity) { - const entityConfig = this.getEntityConfig(entityType); + /** + * Appends the given (dynamic) attributes to the schema of the provided Entity. + * If no arguments are provided, they will be loaded from the config + * @param entityType The type to add the attributes to + * @param configAttributes The attributes to add + */ + public addConfigAttributes( + entityType: EntityConstructor, + configAttributes?: EntityConfig + ) { + const entityConfig = configAttributes || this.getEntityConfig(entityType); if (entityConfig?.attributes) { entityConfig.attributes.forEach((attribute) => addPropertySchema( @@ -26,14 +50,66 @@ export class EntityConfigService { } } - public getEntityConfig(entityType: EntityConstructor): EntityConfig { + /** + * Returns the `EntityConfig` from the config service that contains additional + * fields for a certain entity + * @param entityType The type to get the config for + */ + public getEntityConfig(entityType: EntityConstructor): EntityConfig { const configName = EntityConfigService.PREFIX_ENTITY_CONFIG + entityType.ENTITY_TYPE; return this.configService.getConfig(configName); } + + /** + * Assigns additional schema-fields to all entities that are + * defined inside the config. Entities that are not registered + * using the {@link DatabaseEntity}-Decorator won't work and will + * trigger an error message + */ + setupEntitiesFromConfig() { + const entitiesNotFound: string[] = []; + for (const config of this.configService.getAllConfigs< + EntityConfig & { _id: string } + >(ENTITY_CONFIG_PREFIX)) { + const id = config._id.substring(ENTITY_CONFIG_PREFIX.length); + try { + const ctor = this.dynamicEntityService.getEntityConstructor(id); + this.addConfigAttributes(ctor, config); + } catch (err) { + entitiesNotFound.push(id); + } + } + if (entitiesNotFound.length > 0) { + this.loggingService.error( + `The following entities were defined in the config but are not registered properly: ${entitiesNotFound.join( + ", " + )}.\n` + + `Make sure they exist as a class and are properly registered (see the how-to guides for more info on this topic)` + ); + } + } } +/** + * Dynamic configuration for a entity. + * This allows to change entity metadata based on the configuration. + */ export interface EntityConfig { permissions?: { [key in OperationType]?: string[] }; - attributes?: { name: string; schema: EntitySchemaField }[]; + + /** + * A list of attributes that will be dynamically added/overwritten to the entity. + */ + attributes?: { + /** + * The name of the attribute (class variable) to be added/overwritten. + */ + name: string; + + /** + * The (new) schema configuration for this attribute. + */ + schema: EntitySchemaField; + }[]; } diff --git a/src/app/core/entity/model/entity.ts b/src/app/core/entity/model/entity.ts index 6a7c10cc4b..37c6bcbb3d 100644 --- a/src/app/core/entity/model/entity.ts +++ b/src/app/core/entity/model/entity.ts @@ -26,7 +26,9 @@ import { getWarningLevelColor, WarningLevel } from "./warning-level"; * It can also be used to check the ENTITY_TYPE of a class * For example usage check the {@link EntityMapperService}. */ -export type EntityConstructor = (new (id?: string) => T) & +export type EntityConstructor = (new ( + id?: string +) => T) & typeof Entity; export const ENTITY_CONFIG_PREFIX = "entity:"; diff --git a/src/app/core/form-dialog/form-dialog-wrapper/form-dialog-wrapper.component.spec.ts b/src/app/core/form-dialog/form-dialog-wrapper/form-dialog-wrapper.component.spec.ts index 78c77dbb58..e87a5e8473 100644 --- a/src/app/core/form-dialog/form-dialog-wrapper/form-dialog-wrapper.component.spec.ts +++ b/src/app/core/form-dialog/form-dialog-wrapper/form-dialog-wrapper.component.spec.ts @@ -9,6 +9,8 @@ import { MatDialogRef } from "@angular/material/dialog"; import { Subject } from "rxjs"; import { MatSnackBarModule } from "@angular/material/snack-bar"; import { MockSessionModule } from "../../session/mock-session.module"; +import { DynamicEntityService } from "../../entity/dynamic-entity.service"; +import { EntitySchemaService } from "../../entity/schema/entity-schema.service"; describe("FormDialogWrapperComponent", () => { let component: FormDialogWrapperComponent; @@ -26,7 +28,11 @@ describe("FormDialogWrapperComponent", () => { MatSnackBarModule, MockSessionModule.withState(), ], - providers: [{ provide: MatDialogRef, useValue: {} }], + providers: [ + { provide: MatDialogRef, useValue: {} }, + DynamicEntityService, + EntitySchemaService, + ], }).compileComponents(); saveEntitySpy = spyOn(TestBed.inject(EntityMapperService), "save"); diff --git a/src/app/core/ui/primary-action/primary-action.component.spec.ts b/src/app/core/ui/primary-action/primary-action.component.spec.ts index 117ef104a7..0ed5517138 100644 --- a/src/app/core/ui/primary-action/primary-action.component.spec.ts +++ b/src/app/core/ui/primary-action/primary-action.component.spec.ts @@ -7,6 +7,8 @@ import { FormDialogModule } from "../../form-dialog/form-dialog.module"; import { PermissionsModule } from "../../permissions/permissions.module"; import { MockSessionModule } from "../../session/mock-session.module"; import { FontAwesomeTestingModule } from "@fortawesome/angular-fontawesome/testing"; +import { DynamicEntityService } from "../../entity/dynamic-entity.service"; +import { EntitySchemaService } from "../../entity/schema/entity-schema.service"; describe("PrimaryActionComponent", () => { let component: PrimaryActionComponent; @@ -23,6 +25,7 @@ describe("PrimaryActionComponent", () => { FontAwesomeTestingModule, MockSessionModule.withState(), ], + providers: [DynamicEntityService, EntitySchemaService], }).compileComponents(); }); diff --git a/src/app/core/ui/search/search.component.spec.ts b/src/app/core/ui/search/search.component.spec.ts index 4ec78aa878..fbed06f921 100644 --- a/src/app/core/ui/search/search.component.spec.ts +++ b/src/app/core/ui/search/search.component.spec.ts @@ -18,6 +18,8 @@ import { DatabaseIndexingService } from "../../entity/database-indexing/database import { EntityUtilsModule } from "../../entity-components/entity-utils/entity-utils.module"; import { Subscription } from "rxjs"; import { Entity } from "../../entity/model/entity"; +import { DynamicEntityService } from "../../entity/dynamic-entity.service"; +import { EntityMapperService } from "../../entity/entity-mapper.service"; describe("SearchComponent", () => { let component: SearchComponent; @@ -52,6 +54,8 @@ describe("SearchComponent", () => { providers: [ { provide: EntitySchemaService, useValue: entitySchemaService }, { provide: DatabaseIndexingService, useValue: mockIndexService }, + { provide: EntityMapperService, useValue: {} }, + DynamicEntityService, ], declarations: [SearchComponent], }).compileComponents(); diff --git a/src/app/core/ui/search/search.component.ts b/src/app/core/ui/search/search.component.ts index 5d944583b2..0428c95010 100644 --- a/src/app/core/ui/search/search.component.ts +++ b/src/app/core/ui/search/search.component.ts @@ -1,13 +1,12 @@ import { Component } from "@angular/core"; -import { Entity, EntityConstructor } from "../../entity/model/entity"; -import { EntitySchemaService } from "../../entity/schema/entity-schema.service"; +import { Entity } from "../../entity/model/entity"; import { Observable } from "rxjs"; import { concatMap, debounceTime, skipUntil, tap } from "rxjs/operators"; import { DatabaseIndexingService } from "../../entity/database-indexing/database-indexing.service"; import { Router } from "@angular/router"; -import { ENTITY_MAP } from "../../entity-components/entity-details/entity-details.component"; import { fromPromise } from "rxjs/internal-compatibility"; import { FormControl } from "@angular/forms"; +import { DynamicEntityService } from "../../entity/dynamic-entity.service"; /** * General search box that provides results out of any kind of entities from the system @@ -39,8 +38,8 @@ export class SearchComponent { constructor( private indexingService: DatabaseIndexingService, - private entitySchemaService: EntitySchemaService, - private router: Router + private router: Router, + private dynamicEntityService: DynamicEntityService ) { this.results = this.formControl.valueChanges.pipe( debounceTime(this.INPUT_DEBOUNCE_TIME_MS), @@ -157,10 +156,10 @@ export class SearchComponent { id: string; doc: object; }): Entity { - const ctor: EntityConstructor = - ENTITY_MAP.get(Entity.extractTypeFromId(doc.id)) || Entity; - const entity = new ctor(doc.id); - this.entitySchemaService.loadDataIntoEntity(entity, doc.doc); - return entity; + return this.dynamicEntityService.instantiateEntity( + Entity.extractTypeFromId(doc.id), + doc.id, + doc.doc + ); } } From b5136a098e47b5d41b8e2d5b741b45b850576282 Mon Sep 17 00:00:00 2001 From: Snyk bot Date: Fri, 29 Oct 2021 12:04:57 +0200 Subject: [PATCH 06/21] refactor: upgrade @sentry/browser from 6.13.2 to 6.13.3 (#1037) --- package-lock.json | 126 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/package-lock.json b/package-lock.json index 18e191cc99..c681f2cf56 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,7 @@ "@fortawesome/free-regular-svg-icons": "^5.15.2", "@fortawesome/free-solid-svg-icons": "^5.15.4", "@ngneat/until-destroy": "^8.1.4", - "@sentry/browser": "^6.13.2", + "@sentry/browser": "^6.13.3", "angulartics2": "^10.0.0", "crypto-js": "^4.1.1", "deep-object-diff": "^1.1.0", @@ -4669,13 +4669,13 @@ "dev": true }, "node_modules/@sentry/browser": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.13.2.tgz", - "integrity": "sha512-bkFXK4vAp2UX/4rQY0pj2Iky55Gnwr79CtveoeeMshoLy5iDgZ8gvnLNAz7om4B9OQk1u7NzLEa4IXAmHTUyag==", + "version": "6.13.3", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.13.3.tgz", + "integrity": "sha512-jwlpsk2/u1cofvfYsjmqcnx50JJtf/T6HTgdW+ih8+rqWC5ABEZf4IiB/H+KAyjJ3wVzCOugMq5irL83XDCfqQ==", "dependencies": { - "@sentry/core": "6.13.2", - "@sentry/types": "6.13.2", - "@sentry/utils": "6.13.2", + "@sentry/core": "6.13.3", + "@sentry/types": "6.13.3", + "@sentry/utils": "6.13.3", "tslib": "^1.9.3" }, "engines": { @@ -4688,14 +4688,14 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/core": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.13.2.tgz", - "integrity": "sha512-snXNNFLwlS7yYxKTX4DBXebvJK+6ikBWN6noQ1CHowvM3ReFBlrdrs0Z0SsSFEzXm2S4q7f6HHbm66GSQZ/8FQ==", - "dependencies": { - "@sentry/hub": "6.13.2", - "@sentry/minimal": "6.13.2", - "@sentry/types": "6.13.2", - "@sentry/utils": "6.13.2", + "version": "6.13.3", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.13.3.tgz", + "integrity": "sha512-obm3SjgCk8A7nB37b2AU1eq1q7gMoJRrGMv9VRIyfcG0Wlz/5lJ9O3ohUk+YZaaVfZMxXn6hFtsBiOWmlv7IIA==", + "dependencies": { + "@sentry/hub": "6.13.3", + "@sentry/minimal": "6.13.3", + "@sentry/types": "6.13.3", + "@sentry/utils": "6.13.3", "tslib": "^1.9.3" }, "engines": { @@ -4708,12 +4708,12 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/hub": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.13.2.tgz", - "integrity": "sha512-sppSuJdNMiMC/vFm/dQowCBh11uTrmvks00fc190YWgxHshodJwXMdpc+pN61VSOmy2QA4MbQ5aMAgHzPzel3A==", + "version": "6.13.3", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.13.3.tgz", + "integrity": "sha512-eYppBVqvhs5cvm33snW2sxfcw6G20/74RbBn+E4WDo15hozis89kU7ZCJDOPkXuag3v1h9igns/kM6PNBb41dw==", "dependencies": { - "@sentry/types": "6.13.2", - "@sentry/utils": "6.13.2", + "@sentry/types": "6.13.3", + "@sentry/utils": "6.13.3", "tslib": "^1.9.3" }, "engines": { @@ -4726,12 +4726,12 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/minimal": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.13.2.tgz", - "integrity": "sha512-6iJfEvHzzpGBHDfLxSHcGObh73XU1OSQKWjuhDOe7UQDyI4BQmTfcXAC+Fr8sm8C/tIsmpVi/XJhs8cubFdSMw==", + "version": "6.13.3", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.13.3.tgz", + "integrity": "sha512-63MlYYRni3fs5Bh8XBAfVZ+ctDdWg0fapSTP1ydIC37fKvbE+5zhyUqwrEKBIiclEApg1VKX7bkKxVdu/vsFdw==", "dependencies": { - "@sentry/hub": "6.13.2", - "@sentry/types": "6.13.2", + "@sentry/hub": "6.13.3", + "@sentry/types": "6.13.3", "tslib": "^1.9.3" }, "engines": { @@ -4744,19 +4744,19 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/types": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.13.2.tgz", - "integrity": "sha512-6WjGj/VjjN8LZDtqJH5ikeB1o39rO1gYS6anBxiS3d0sXNBb3Ux0pNNDFoBxQpOhmdDHXYS57MEptX9EV82gmg==", + "version": "6.13.3", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.13.3.tgz", + "integrity": "sha512-Vrz5CdhaTRSvCQjSyIFIaV9PodjAVFkzJkTRxyY7P77RcegMsRSsG1yzlvCtA99zG9+e6MfoJOgbOCwuZids5A==", "engines": { "node": ">=6" } }, "node_modules/@sentry/utils": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.13.2.tgz", - "integrity": "sha512-foF4PbxqPMWNbuqdXkdoOmKm3quu3PP7Q7j/0pXkri4DtCuvF/lKY92mbY0V9rHS/phCoj+3/Se5JvM2ymh2/w==", + "version": "6.13.3", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.13.3.tgz", + "integrity": "sha512-zYFuFH3MaYtBZTeJ4Yajg7pDf0pM3MWs3+9k5my9Fd+eqNcl7dYQYJbT9gyC0HXK1QI4CAMNNlHNl4YXhF91ag==", "dependencies": { - "@sentry/types": "6.13.2", + "@sentry/types": "6.13.3", "tslib": "^1.9.3" }, "engines": { @@ -35221,13 +35221,13 @@ } }, "@sentry/browser": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.13.2.tgz", - "integrity": "sha512-bkFXK4vAp2UX/4rQY0pj2Iky55Gnwr79CtveoeeMshoLy5iDgZ8gvnLNAz7om4B9OQk1u7NzLEa4IXAmHTUyag==", + "version": "6.13.3", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.13.3.tgz", + "integrity": "sha512-jwlpsk2/u1cofvfYsjmqcnx50JJtf/T6HTgdW+ih8+rqWC5ABEZf4IiB/H+KAyjJ3wVzCOugMq5irL83XDCfqQ==", "requires": { - "@sentry/core": "6.13.2", - "@sentry/types": "6.13.2", - "@sentry/utils": "6.13.2", + "@sentry/core": "6.13.3", + "@sentry/types": "6.13.3", + "@sentry/utils": "6.13.3", "tslib": "^1.9.3" }, "dependencies": { @@ -35239,14 +35239,14 @@ } }, "@sentry/core": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.13.2.tgz", - "integrity": "sha512-snXNNFLwlS7yYxKTX4DBXebvJK+6ikBWN6noQ1CHowvM3ReFBlrdrs0Z0SsSFEzXm2S4q7f6HHbm66GSQZ/8FQ==", - "requires": { - "@sentry/hub": "6.13.2", - "@sentry/minimal": "6.13.2", - "@sentry/types": "6.13.2", - "@sentry/utils": "6.13.2", + "version": "6.13.3", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.13.3.tgz", + "integrity": "sha512-obm3SjgCk8A7nB37b2AU1eq1q7gMoJRrGMv9VRIyfcG0Wlz/5lJ9O3ohUk+YZaaVfZMxXn6hFtsBiOWmlv7IIA==", + "requires": { + "@sentry/hub": "6.13.3", + "@sentry/minimal": "6.13.3", + "@sentry/types": "6.13.3", + "@sentry/utils": "6.13.3", "tslib": "^1.9.3" }, "dependencies": { @@ -35258,12 +35258,12 @@ } }, "@sentry/hub": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.13.2.tgz", - "integrity": "sha512-sppSuJdNMiMC/vFm/dQowCBh11uTrmvks00fc190YWgxHshodJwXMdpc+pN61VSOmy2QA4MbQ5aMAgHzPzel3A==", + "version": "6.13.3", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.13.3.tgz", + "integrity": "sha512-eYppBVqvhs5cvm33snW2sxfcw6G20/74RbBn+E4WDo15hozis89kU7ZCJDOPkXuag3v1h9igns/kM6PNBb41dw==", "requires": { - "@sentry/types": "6.13.2", - "@sentry/utils": "6.13.2", + "@sentry/types": "6.13.3", + "@sentry/utils": "6.13.3", "tslib": "^1.9.3" }, "dependencies": { @@ -35275,12 +35275,12 @@ } }, "@sentry/minimal": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.13.2.tgz", - "integrity": "sha512-6iJfEvHzzpGBHDfLxSHcGObh73XU1OSQKWjuhDOe7UQDyI4BQmTfcXAC+Fr8sm8C/tIsmpVi/XJhs8cubFdSMw==", + "version": "6.13.3", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.13.3.tgz", + "integrity": "sha512-63MlYYRni3fs5Bh8XBAfVZ+ctDdWg0fapSTP1ydIC37fKvbE+5zhyUqwrEKBIiclEApg1VKX7bkKxVdu/vsFdw==", "requires": { - "@sentry/hub": "6.13.2", - "@sentry/types": "6.13.2", + "@sentry/hub": "6.13.3", + "@sentry/types": "6.13.3", "tslib": "^1.9.3" }, "dependencies": { @@ -35292,16 +35292,16 @@ } }, "@sentry/types": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.13.2.tgz", - "integrity": "sha512-6WjGj/VjjN8LZDtqJH5ikeB1o39rO1gYS6anBxiS3d0sXNBb3Ux0pNNDFoBxQpOhmdDHXYS57MEptX9EV82gmg==" + "version": "6.13.3", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.13.3.tgz", + "integrity": "sha512-Vrz5CdhaTRSvCQjSyIFIaV9PodjAVFkzJkTRxyY7P77RcegMsRSsG1yzlvCtA99zG9+e6MfoJOgbOCwuZids5A==" }, "@sentry/utils": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.13.2.tgz", - "integrity": "sha512-foF4PbxqPMWNbuqdXkdoOmKm3quu3PP7Q7j/0pXkri4DtCuvF/lKY92mbY0V9rHS/phCoj+3/Se5JvM2ymh2/w==", + "version": "6.13.3", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.13.3.tgz", + "integrity": "sha512-zYFuFH3MaYtBZTeJ4Yajg7pDf0pM3MWs3+9k5my9Fd+eqNcl7dYQYJbT9gyC0HXK1QI4CAMNNlHNl4YXhF91ag==", "requires": { - "@sentry/types": "6.13.2", + "@sentry/types": "6.13.3", "tslib": "^1.9.3" }, "dependencies": { diff --git a/package.json b/package.json index 1fae8252e3..752bfd3b70 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "@fortawesome/free-regular-svg-icons": "^5.15.2", "@fortawesome/free-solid-svg-icons": "^5.15.4", "@ngneat/until-destroy": "^8.1.4", - "@sentry/browser": "^6.13.2", + "@sentry/browser": "^6.13.3", "angulartics2": "^10.0.0", "crypto-js": "^4.1.1", "deep-object-diff": "^1.1.0", From bdbcb63b98778c6d54cd6a50ca4ee96001986afe Mon Sep 17 00:00:00 2001 From: Snyk bot Date: Mon, 15 Nov 2021 04:48:35 +0100 Subject: [PATCH 07/21] refactor: upgrade idb from 6.1.4 to 6.1.5 (#1039) --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index c681f2cf56..66d0706856 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "deep-object-diff": "^1.1.0", "faker": "^5.5.3", "flag-icon-css": "^3.5.0", - "idb": "^6.1.2", + "idb": "^6.1.5", "json-query": "^2.2.2", "lodash": "^4.17.21", "md5": "^2.3.0", @@ -16220,9 +16220,9 @@ } }, "node_modules/idb": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/idb/-/idb-6.1.4.tgz", - "integrity": "sha512-DshI5yxIB3NYc47cPpfipYX8MSIgQPqVR+WoaGI9EDq6cnLGgGYR1fp6z8/Bq9vMS8Jq1bS3eWUgXpFO5+ypSA==" + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/idb/-/idb-6.1.5.tgz", + "integrity": "sha512-IJtugpKkiVXQn5Y+LteyBCNk1N8xpGV3wWZk9EVtZWH8DYkjBn0bX1XnGP9RkyZF0sAcywa6unHqSWKe7q4LGw==" }, "node_modules/ieee754": { "version": "1.2.1", @@ -44386,9 +44386,9 @@ "requires": {} }, "idb": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/idb/-/idb-6.1.4.tgz", - "integrity": "sha512-DshI5yxIB3NYc47cPpfipYX8MSIgQPqVR+WoaGI9EDq6cnLGgGYR1fp6z8/Bq9vMS8Jq1bS3eWUgXpFO5+ypSA==" + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/idb/-/idb-6.1.5.tgz", + "integrity": "sha512-IJtugpKkiVXQn5Y+LteyBCNk1N8xpGV3wWZk9EVtZWH8DYkjBn0bX1XnGP9RkyZF0sAcywa6unHqSWKe7q4LGw==" }, "ieee754": { "version": "1.2.1", diff --git a/package.json b/package.json index 752bfd3b70..10d6a2cad3 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "deep-object-diff": "^1.1.0", "faker": "^5.5.3", "flag-icon-css": "^3.5.0", - "idb": "^6.1.2", + "idb": "^6.1.5", "json-query": "^2.2.2", "lodash": "^4.17.21", "md5": "^2.3.0", From d8fef4b7f74f74bf5fb16fbd6a8647bb7a05412c Mon Sep 17 00:00:00 2001 From: Snyk bot Date: Wed, 17 Nov 2021 10:32:12 +0100 Subject: [PATCH 08/21] refactor: upgrade angulartics2 from 10.0.0 to 10.1.0 --- package-lock.json | 14 +++++++------- package.json | 2 +- src/app/app.component.spec.ts | 4 ++-- src/app/app.module.ts | 4 ++-- .../core/analytics/analytics.service.spec.ts | 17 ++++++++--------- src/app/core/analytics/analytics.service.ts | 19 ++++++++++++------- 6 files changed, 32 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index 66d0706856..cdc23930ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,7 @@ "@fortawesome/free-solid-svg-icons": "^5.15.4", "@ngneat/until-destroy": "^8.1.4", "@sentry/browser": "^6.13.3", - "angulartics2": "^10.0.0", + "angulartics2": "^10.1.0", "crypto-js": "^4.1.1", "deep-object-diff": "^1.1.0", "faker": "^5.5.3", @@ -8249,9 +8249,9 @@ } }, "node_modules/angulartics2": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/angulartics2/-/angulartics2-10.0.0.tgz", - "integrity": "sha512-ebn4uZb74WtG5S/OI69eY1J1MLyvIOXpUo64nYHAL7nUqp0PSbz+djPSaWsHKu4ga9G8lMmURzfxZ/EY1X+lmg==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/angulartics2/-/angulartics2-10.1.0.tgz", + "integrity": "sha512-MnwQxRXJkfbBF7417Cs7L/SIuTRNWHCOBnGolZXHFz5ogw1e51KdCKUaUkfgBogR7JpXP279FU9UDkzerIS3xw==", "dependencies": { "tslib": "^2.0.0" }, @@ -37991,9 +37991,9 @@ "optional": true }, "angulartics2": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/angulartics2/-/angulartics2-10.0.0.tgz", - "integrity": "sha512-ebn4uZb74WtG5S/OI69eY1J1MLyvIOXpUo64nYHAL7nUqp0PSbz+djPSaWsHKu4ga9G8lMmURzfxZ/EY1X+lmg==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/angulartics2/-/angulartics2-10.1.0.tgz", + "integrity": "sha512-MnwQxRXJkfbBF7417Cs7L/SIuTRNWHCOBnGolZXHFz5ogw1e51KdCKUaUkfgBogR7JpXP279FU9UDkzerIS3xw==", "requires": { "tslib": "^2.0.0" } diff --git a/package.json b/package.json index 10d6a2cad3..b29bf57f21 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "@fortawesome/free-solid-svg-icons": "^5.15.4", "@ngneat/until-destroy": "^8.1.4", "@sentry/browser": "^6.13.3", - "angulartics2": "^10.0.0", + "angulartics2": "^10.1.0", "crypto-js": "^4.1.1", "deep-object-diff": "^1.1.0", "faker": "^5.5.3", diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 1573391fb8..617bffc9fa 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -28,7 +28,7 @@ import { ApplicationInitStatus } from "@angular/core"; import { AppModule } from "./app.module"; import { AppConfig } from "./core/app-config/app-config"; import { IAppConfig } from "./core/app-config/app-config.model"; -import { Angulartics2Piwik } from "angulartics2/piwik"; +import { Angulartics2Matomo } from "angulartics2/matomo"; import { EntityMapperService } from "./core/entity/entity-mapper.service"; import { Config } from "./core/config/config"; import { USAGE_ANALYTICS_CONFIG_ID } from "./core/analytics/usage-analytics-config"; @@ -90,7 +90,7 @@ describe("AppComponent", () => { }; const entityMapper = TestBed.inject(EntityMapperService); spyOn(entityMapper, "load").and.resolveTo(new Config(testConfig)); - const angulartics = TestBed.inject(Angulartics2Piwik); + const angulartics = TestBed.inject(Angulartics2Matomo); const startTrackingSpy = spyOn(angulartics, "startTracking"); createComponent(); diff --git a/src/app/app.module.ts b/src/app/app.module.ts index b065887774..b14cce8e77 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -57,7 +57,7 @@ import { FormDialogModule } from "./core/form-dialog/form-dialog.module"; import { LoggingService } from "./core/logging/logging.service"; import { Angulartics2Module } from "angulartics2"; import { AnalyticsService } from "./core/analytics/analytics.service"; -import { Angulartics2Piwik } from "angulartics2/piwik"; +import { Angulartics2Matomo } from "angulartics2/matomo"; import { ViewModule } from "./core/view/view.module"; import { DashboardModule } from "./core/dashboard/dashboard.module"; import { EntityDetailsModule } from "./core/entity-components/entity-details/entity-details.module"; @@ -156,7 +156,7 @@ import { far } from "@fortawesome/free-regular-svg-icons"; { provide: ErrorHandler, useClass: LoggingErrorHandler }, { provide: MatPaginatorIntl, useValue: TranslatableMatPaginator() }, AnalyticsService, - Angulartics2Piwik, + Angulartics2Matomo, ], bootstrap: [AppComponent], }) diff --git a/src/app/core/analytics/analytics.service.spec.ts b/src/app/core/analytics/analytics.service.spec.ts index 4d0d839067..2f837820e8 100644 --- a/src/app/core/analytics/analytics.service.spec.ts +++ b/src/app/core/analytics/analytics.service.spec.ts @@ -6,7 +6,7 @@ import { RouterTestingModule } from "@angular/router/testing"; import { MockSessionModule } from "../session/mock-session.module"; import { ConfigService } from "../config/config.service"; import { UsageAnalyticsConfig } from "./usage-analytics-config"; -import { Angulartics2Piwik } from "angulartics2/piwik"; +import { Angulartics2Matomo } from "angulartics2/matomo"; import { AppConfig } from "../app-config/app-config"; import { IAppConfig } from "../app-config/app-config.model"; @@ -14,17 +14,16 @@ describe("AnalyticsService", () => { let service: AnalyticsService; let mockConfigService: jasmine.SpyObj; - let mockAngulartics: jasmine.SpyObj; + let mockMatomo: jasmine.SpyObj; beforeEach(() => { AppConfig.settings = { site_name: "unit-testing" } as IAppConfig; mockConfigService = jasmine.createSpyObj("mockConfigService", [ "getConfig", ]); - mockAngulartics = jasmine.createSpyObj("mockAngulartics", [ - "startTracking", - "setUserProperties", + mockMatomo = jasmine.createSpyObj("mockMatomo", [ "setUsername", + "startTracking", ]); TestBed.configureTestingModule({ @@ -36,7 +35,7 @@ describe("AnalyticsService", () => { providers: [ AnalyticsService, { provide: ConfigService, useValue: mockConfigService }, - { provide: Angulartics2Piwik, useValue: mockAngulartics }, + { provide: Angulartics2Matomo, useValue: mockMatomo }, ], }); service = TestBed.inject(AnalyticsService); @@ -52,13 +51,13 @@ describe("AnalyticsService", () => { it("should not track if no url or site_id", () => { mockConfigService.getConfig.and.returnValue({}); service.init(); - expect(mockAngulartics.startTracking).not.toHaveBeenCalled(); + expect(mockMatomo.startTracking).not.toHaveBeenCalled(); }); it("should not track if no usage analytics config", () => { mockConfigService.getConfig.and.returnValue(undefined); service.init(); - expect(mockAngulartics.startTracking).not.toHaveBeenCalled(); + expect(mockMatomo.startTracking).not.toHaveBeenCalled(); }); it("should track correct site_id", () => { @@ -70,7 +69,7 @@ describe("AnalyticsService", () => { service.init(); - expect(mockAngulartics.startTracking).toHaveBeenCalledTimes(1); + expect(mockMatomo.startTracking).toHaveBeenCalledTimes(1); expect(window["_paq"]).toContain([ "setSiteId", testAnalyticsConfig.site_id, diff --git a/src/app/core/analytics/analytics.service.ts b/src/app/core/analytics/analytics.service.ts index 547f681163..437e4c4294 100644 --- a/src/app/core/analytics/analytics.service.ts +++ b/src/app/core/analytics/analytics.service.ts @@ -1,5 +1,5 @@ import { Injectable } from "@angular/core"; -import { Angulartics2Piwik } from "angulartics2/piwik"; +import { Angulartics2Matomo } from "angulartics2/matomo"; import { environment } from "../../../environments/environment"; import { AppConfig } from "../app-config/app-config"; import { ConfigService } from "../config/config.service"; @@ -9,6 +9,7 @@ import { USAGE_ANALYTICS_CONFIG_ID, UsageAnalyticsConfig, } from "./usage-analytics-config"; +import { Angulartics2 } from "angulartics2"; const md5 = require("md5"); @@ -26,7 +27,8 @@ export class AnalyticsService { } constructor( - private angulartics2Piwik: Angulartics2Piwik, + private angulartics2: Angulartics2, + private angulartics2Matomo: Angulartics2Matomo, private configService: ConfigService, private sessionService: SessionService ) { @@ -34,19 +36,19 @@ export class AnalyticsService { } private setUser(username: string): void { - this.angulartics2Piwik.setUsername( + this.angulartics2Matomo.setUsername( AnalyticsService.getUserHash(username ?? "") ); } private setVersion(): void { - this.angulartics2Piwik.setUserProperties({ + this.angulartics2.setUserProperties.next({ dimension1: "ndb-core@" + environment.appVersion, }); } private setOrganization(orgName: string): void { - this.angulartics2Piwik.setUserProperties({ + this.angulartics2.setUserProperties.next({ dimension2: orgName, }); } @@ -80,7 +82,7 @@ export class AnalyticsService { this.setOrganization(AppConfig.settings.site_name); this.setUser(undefined); - this.angulartics2Piwik.startTracking(); + this.angulartics2Matomo.startTracking(); } /** @@ -138,6 +140,9 @@ export class AnalyticsService { label: "no_label", } ): void { - this.angulartics2Piwik.eventTrack(action, properties); + this.angulartics2.eventTrack.next({ + action: action, + properties: properties, + }); } } From d0e366e244f9530c56d6de67c2daa09e5bca1a05 Mon Sep 17 00:00:00 2001 From: Simon <33730997+TheSlimvReal@users.noreply.github.com> Date: Fri, 19 Nov 2021 18:08:36 +0530 Subject: [PATCH 09/21] fix: Added strict type checking for angular compiler --- .../child-block/child-block.component.html | 3 - .../demo-child-generator.service.ts | 5 ++ .../child-dev-project/children/model/child.ts | 5 ++ .../school-block/school-block.component.html | 12 +--- .../school-block/school-block.component.ts | 15 ----- src/app/core/admin/admin/admin.component.html | 4 +- .../core/admin/admin/admin.component.spec.ts | 4 +- src/app/core/admin/admin/admin.component.ts | 15 +++-- src/app/core/config/config-fix.ts | 1 + .../edit-configurable-enum.component.spec.ts | 4 +- .../list-paginator.component.spec.ts | 4 +- .../list-paginator.component.ts | 6 +- .../edit-age/edit-age.component.spec.ts | 9 +-- .../edit-boolean.component.spec.ts | 9 +-- .../edit-component.spec.ts | 23 ++++++++ .../dynamic-form-components/edit-component.ts | 6 +- .../edit-date/edit-date.component.spec.ts | 9 +-- .../edit-entity-array.component.spec.ts | 4 +- .../edit-entity-array.component.ts | 5 +- .../edit-long-text.component.spec.ts | 9 +-- .../edit-number/edit-number.component.spec.ts | 11 +--- .../edit-percentage.component.spec.ts | 14 ++--- .../edit-photo/edit-photo.component.spec.ts | 8 +-- .../edit-single-entity.component.spec.ts | 5 +- .../edit-text/edit-text.component.spec.ts | 9 +-- .../entity-select.component.html | 2 +- .../entity-select.component.spec.ts | 41 +++++++------- .../entity-select/entity-select.component.ts | 56 +++++++------------ .../data-import/data-import.component.html | 2 +- .../data-import/data-import.component.spec.ts | 2 +- .../data-import/data-import.component.ts | 5 +- tsconfig.json | 3 + 32 files changed, 140 insertions(+), 170 deletions(-) create mode 100644 src/app/core/entity-components/entity-utils/dynamic-form-components/edit-component.spec.ts diff --git a/src/app/child-dev-project/children/child-block/child-block.component.html b/src/app/child-dev-project/children/child-block/child-block.component.html index 73dfebd3c5..ef87a9a93e 100644 --- a/src/app/child-dev-project/children/child-block/child-block.component.html +++ b/src/app/child-dev-project/children/child-block/child-block.component.html @@ -27,9 +27,6 @@

{{ entity?.name }}

{{ entity?.phone }}

-

- , -

{ child.dateOfBirth = faker.dateOfBirth(5, 20); child["motherTongue"] = faker.random.arrayElement(languages); child.center = faker.random.arrayElement(centersWithProbability); + child.phone = + "+" + + faker.datatype.number({ min: 10, max: 99 }) + + " " + + faker.datatype.number({ min: 10000000, max: 99999999 }); child.admissionDate = faker.date.past(child.age - 4); diff --git a/src/app/child-dev-project/children/model/child.ts b/src/app/child-dev-project/children/model/child.ts index 7bcb584ccb..466625a8e5 100644 --- a/src/app/child-dev-project/children/model/child.ts +++ b/src/app/child-dev-project/children/model/child.ts @@ -100,6 +100,11 @@ export class Child extends Entity { }) photo: Photo; + @DatabaseField({ + label: $localize`:Label for the phone number of a child:Phone Number`, + }) + phone: string; + get age(): number { return this.dateOfBirth ? calculateAge(this.dateOfBirth) : null; } diff --git a/src/app/child-dev-project/schools/school-block/school-block.component.html b/src/app/child-dev-project/schools/school-block/school-block.component.html index f201ad2e44..d62b8c88f6 100644 --- a/src/app/child-dev-project/schools/school-block/school-block.component.html +++ b/src/app/child-dev-project/schools/school-block/school-block.component.html @@ -1,14 +1,4 @@ - + {{ entity?.name }} - -

-
-
{{ entity?.language || entity?.medium}}
-
-
diff --git a/src/app/child-dev-project/schools/school-block/school-block.component.ts b/src/app/child-dev-project/schools/school-block/school-block.component.ts index 542449053f..d5e5d23242 100644 --- a/src/app/child-dev-project/schools/school-block/school-block.component.ts +++ b/src/app/child-dev-project/schools/school-block/school-block.component.ts @@ -22,8 +22,6 @@ export class SchoolBlockComponent implements OnInitDynamicComponent, OnChanges { @Input() entity: School = new School(""); @Input() entityId: string; @Input() linkDisabled: boolean; - tooltip = false; - tooltipTimeout; constructor( private router: Router, @@ -57,19 +55,6 @@ export class SchoolBlockComponent implements OnInitDynamicComponent, OnChanges { this.entity = await this.entityMapper.load(School, this.entityId); } - showTooltip() { - if (this.tooltipTimeout) { - clearTimeout(this.tooltipTimeout); - } - this.tooltipTimeout = setTimeout(() => (this.tooltip = true), 1000); - } - hideTooltip() { - if (this.tooltipTimeout) { - clearTimeout(this.tooltipTimeout); - } - this.tooltipTimeout = setTimeout(() => (this.tooltip = false), 150); - } - @HostListener("click") onClick() { this.showDetailsPage(); } diff --git a/src/app/core/admin/admin/admin.component.html b/src/app/core/admin/admin/admin.component.html index fae1db1ac8..9f6e8c8437 100644 --- a/src/app/core/admin/admin/admin.component.html +++ b/src/app/core/admin/admin/admin.component.html @@ -71,7 +71,7 @@

Backup

#backupImport type="file" style="display: none" - (change)="loadBackup($event.target.files[0])" + (change)="loadBackup($event)" />

@@ -113,7 +113,7 @@

Application Configuration

#configImport type="file" style="display: none" - (change)="uploadConfigFile($event.target.files[0])" + (change)="uploadConfigFile($event)" />

diff --git a/src/app/core/admin/admin/admin.component.spec.ts b/src/app/core/admin/admin/admin.component.spec.ts index a93f13e0e7..212aaf60ae 100644 --- a/src/app/core/admin/admin/admin.component.spec.ts +++ b/src/app/core/admin/admin/admin.component.spec.ts @@ -167,7 +167,7 @@ describe("AdminComponent", () => { it("should save and apply new configuration", fakeAsync(() => { const mockFileReader = createFileReaderMock("{}"); mockConfigService.saveConfig.and.returnValue(Promise.resolve(null)); - component.uploadConfigFile(null); + component.uploadConfigFile({ target: { files: [] } } as any); tick(); expect(mockFileReader.readAsText).toHaveBeenCalled(); expect(mockConfigService.saveConfig).toHaveBeenCalled(); @@ -178,7 +178,7 @@ describe("AdminComponent", () => { mockBackupService.getJsonExport.and.returnValue(Promise.resolve("[]")); createDialogMock(); - component.loadBackup(null); + component.loadBackup({ target: { files: [] } } as any); expect(mockBackupService.getJsonExport).toHaveBeenCalled(); tick(); expect(mockFileReader.readAsText).toHaveBeenCalled(); diff --git a/src/app/core/admin/admin/admin.component.ts b/src/app/core/admin/admin/admin.component.ts index a41631c6a2..72efa2788d 100644 --- a/src/app/core/admin/admin/admin.component.ts +++ b/src/app/core/admin/admin/admin.component.ts @@ -97,8 +97,8 @@ export class AdminComponent implements OnInit { this.startDownload(configString, "text/json", "config.json"); } - async uploadConfigFile(file: Blob) { - const loadedFile = await readFile(file); + async uploadConfigFile(inputEvent: Event) { + const loadedFile = await readFile(this.getFileFromInputEvent(inputEvent)); await this.configService.saveConfig( this.entityMapper, JSON.parse(loadedFile) @@ -116,11 +116,11 @@ export class AdminComponent implements OnInit { /** * Reset the database to the state from the loaded backup file. - * @param file The file object of the backup to be restored + * @param inputEvent for the input where a file has been selected */ - async loadBackup(file) { + async loadBackup(inputEvent: Event) { const restorePoint = await this.backupService.getJsonExport(); - const newData = await readFile(file); + const newData = await readFile(this.getFileFromInputEvent(inputEvent)); const dialogRef = this.confirmationDialog.openDialog( $localize`Overwrite complete database?`, @@ -154,6 +154,11 @@ export class AdminComponent implements OnInit { }); } + private getFileFromInputEvent(inputEvent: Event): Blob { + const target = inputEvent.target as HTMLInputElement; + return target.files[0]; + } + /** * Reset the database removing all entities except user accounts. */ diff --git a/src/app/core/config/config-fix.ts b/src/app/core/config/config-fix.ts index a403182eff..cc7904a5ec 100644 --- a/src/app/core/config/config-fix.ts +++ b/src/app/core/config/config-fix.ts @@ -530,6 +530,7 @@ export const defaultJsonConfig = { "center", "status", "address", + "phone" ], ] } diff --git a/src/app/core/configurable-enum/edit-configurable-enum/edit-configurable-enum.component.spec.ts b/src/app/core/configurable-enum/edit-configurable-enum/edit-configurable-enum.component.spec.ts index 3c1760e04e..d0b22a059f 100644 --- a/src/app/core/configurable-enum/edit-configurable-enum/edit-configurable-enum.component.spec.ts +++ b/src/app/core/configurable-enum/edit-configurable-enum/edit-configurable-enum.component.spec.ts @@ -8,6 +8,8 @@ import { ConfigService } from "../../config/config.service"; import { MatFormFieldModule } from "@angular/material/form-field"; import { MatSelectModule } from "@angular/material/select"; import { ConfigurableEnumModule } from "../configurable-enum.module"; +import { TypedFormControl } from "../../entity-components/entity-utils/dynamic-form-components/edit-component"; +import { ConfigurableEnumValue } from "../configurable-enum.interface"; describe("EditConfigurableEnumComponent", () => { let component: EditConfigurableEnumComponent; @@ -38,7 +40,7 @@ describe("EditConfigurableEnumComponent", () => { const formControl = new FormControl(); const formGroup = new FormGroup({}); component.formControlName = "testControl"; - component.formControl = formControl; + component.formControl = formControl as TypedFormControl; formGroup.registerControl(component.formControlName, formControl); component.enumId = ""; fixture.detectChanges(); diff --git a/src/app/core/entity-components/entity-subrecord/list-paginator/list-paginator.component.spec.ts b/src/app/core/entity-components/entity-subrecord/list-paginator/list-paginator.component.spec.ts index aad7eb4089..f63aeb66cf 100644 --- a/src/app/core/entity-components/entity-subrecord/list-paginator/list-paginator.component.spec.ts +++ b/src/app/core/entity-components/entity-subrecord/list-paginator/list-paginator.component.spec.ts @@ -15,8 +15,8 @@ import { MockSessionModule } from "../../../session/mock-session.module"; import { EntityMapperService } from "../../../entity/entity-mapper.service"; describe("ListPaginatorComponent", () => { - let component: ListPaginatorComponent; - let fixture: ComponentFixture>; + let component: ListPaginatorComponent; + let fixture: ComponentFixture; beforeEach( waitForAsync(() => { diff --git a/src/app/core/entity-components/entity-subrecord/list-paginator/list-paginator.component.ts b/src/app/core/entity-components/entity-subrecord/list-paginator/list-paginator.component.ts index 71b51c97fc..c453565bcb 100644 --- a/src/app/core/entity-components/entity-subrecord/list-paginator/list-paginator.component.ts +++ b/src/app/core/entity-components/entity-subrecord/list-paginator/list-paginator.component.ts @@ -6,7 +6,6 @@ import { SimpleChanges, AfterViewInit, } from "@angular/core"; -import { Entity } from "../../../entity/model/entity"; import { MatPaginator, PageEvent } from "@angular/material/paginator"; import { MatTableDataSource } from "@angular/material/table"; import { User } from "../../../user/user"; @@ -21,12 +20,11 @@ import { filter } from "rxjs/operators"; templateUrl: "./list-paginator.component.html", styleUrls: ["./list-paginator.component.scss"], }) -export class ListPaginatorComponent - implements OnChanges, AfterViewInit { +export class ListPaginatorComponent implements OnChanges, AfterViewInit { readonly pageSizeOptions = [10, 20, 50]; readonly defaultPageSize = 10; - @Input() dataSource: MatTableDataSource; + @Input() dataSource: MatTableDataSource; @Input() idForSavingPagination: string; @ViewChild(MatPaginator) paginator: MatPaginator; diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-age/edit-age.component.spec.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-age/edit-age.component.spec.ts index e14f6b9835..a0e2053699 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-age/edit-age.component.spec.ts +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-age/edit-age.component.spec.ts @@ -1,7 +1,7 @@ import { ComponentFixture, TestBed } from "@angular/core/testing"; import { EditAgeComponent } from "./edit-age.component"; -import { FormControl, FormGroup, ReactiveFormsModule } from "@angular/forms"; +import { ReactiveFormsModule } from "@angular/forms"; import { NoopAnimationsModule } from "@angular/platform-browser/animations"; import { MatFormFieldModule } from "@angular/material/form-field"; import { MatDatepickerModule } from "@angular/material/datepicker"; @@ -9,6 +9,7 @@ import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; import { MatNativeDateModule } from "@angular/material/core"; import { FontAwesomeTestingModule } from "@fortawesome/angular-fontawesome/testing"; import { MatInputModule } from "@angular/material/input"; +import { setupEditComponent } from "../edit-component.spec"; describe("EditAgeComponent", () => { let component: EditAgeComponent; @@ -33,11 +34,7 @@ describe("EditAgeComponent", () => { beforeEach(() => { fixture = TestBed.createComponent(EditAgeComponent); component = fixture.componentInstance; - const formControl = new FormControl(); - const formGroup = new FormGroup({}); - component.formControlName = "testControl"; - component.formControl = formControl; - formGroup.registerControl(component.formControlName, formControl); + setupEditComponent(component); fixture.detectChanges(); }); diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/edit-boolean.component.spec.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/edit-boolean.component.spec.ts index d8e6be9445..90e62306b0 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/edit-boolean.component.spec.ts +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/edit-boolean.component.spec.ts @@ -1,9 +1,10 @@ import { ComponentFixture, TestBed } from "@angular/core/testing"; import { EditBooleanComponent } from "./edit-boolean.component"; -import { FormControl, FormGroup, ReactiveFormsModule } from "@angular/forms"; +import { ReactiveFormsModule } from "@angular/forms"; import { NoopAnimationsModule } from "@angular/platform-browser/animations"; import { MatCheckboxModule } from "@angular/material/checkbox"; +import { setupEditComponent } from "../edit-component.spec"; describe("EditBooleanComponent", () => { let component: EditBooleanComponent; @@ -19,11 +20,7 @@ describe("EditBooleanComponent", () => { beforeEach(() => { fixture = TestBed.createComponent(EditBooleanComponent); component = fixture.componentInstance; - const formControl = new FormControl(); - const formGroup = new FormGroup({}); - component.formControlName = "testControl"; - component.formControl = formControl; - formGroup.registerControl(component.formControlName, formControl); + setupEditComponent(component); fixture.detectChanges(); }); diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-component.spec.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-component.spec.ts new file mode 100644 index 0000000000..e05c441ceb --- /dev/null +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-component.spec.ts @@ -0,0 +1,23 @@ +import { EditComponent } from "./edit-component"; +import { FormControl, FormGroup } from "@angular/forms"; + +/** + * A simple helper class that sets up a EditComponent with the required FormGroup + * @param component that extends EditComponent + * @param propertyName (optional) the name of the property for which the edit component is created + */ +export function setupEditComponent( + component: EditComponent, + propertyName = "testProperty" +): FormGroup { + const formControl = new FormControl(); + const fromGroupConfig = {}; + fromGroupConfig[propertyName] = formControl; + const formGroup = new FormGroup(fromGroupConfig); + component.onInitFromDynamicConfig({ + formControl: formControl, + propertySchema: {}, + formFieldConfig: { id: propertyName }, + }); + return formGroup; +} diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-component.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-component.ts index 4c50b498b0..0f53ad4d33 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-component.ts +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-component.ts @@ -1,5 +1,5 @@ import { OnInitDynamicComponent } from "../../../view/dynamic-components/on-init-dynamic-component.interface"; -import { AbstractControl, FormControl } from "@angular/forms"; +import { AbstractControl, FormControl, FormGroup } from "@angular/forms"; import { FormFieldConfig } from "../../entity-form/entity-form/FormConfig"; import { EntitySchemaField } from "../../../entity/schema/entity-schema-field"; @@ -40,6 +40,10 @@ export class TypedFormControl extends FormControl { ) { super.setValue(value, options); } + + get parent(): FormGroup { + return super.parent as FormGroup; + } } /** diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-date/edit-date.component.spec.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-date/edit-date.component.spec.ts index 45fa70584f..7d4da5c27a 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-date/edit-date.component.spec.ts +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-date/edit-date.component.spec.ts @@ -1,12 +1,13 @@ import { ComponentFixture, TestBed } from "@angular/core/testing"; import { EditDateComponent } from "./edit-date.component"; -import { FormControl, FormGroup, ReactiveFormsModule } from "@angular/forms"; +import { ReactiveFormsModule } from "@angular/forms"; import { NoopAnimationsModule } from "@angular/platform-browser/animations"; import { MatFormFieldModule } from "@angular/material/form-field"; import { MatDatepickerModule } from "@angular/material/datepicker"; import { MatInputModule } from "@angular/material/input"; import { MatNativeDateModule } from "@angular/material/core"; +import { setupEditComponent } from "../edit-component.spec"; describe("EditDateComponent", () => { let component: EditDateComponent; @@ -29,11 +30,7 @@ describe("EditDateComponent", () => { beforeEach(() => { fixture = TestBed.createComponent(EditDateComponent); component = fixture.componentInstance; - const formControl = new FormControl(); - const formGroup = new FormGroup({}); - component.formControlName = "testControl"; - component.formControl = formControl; - formGroup.registerControl(component.formControlName, formControl); + setupEditComponent(component); fixture.detectChanges(); }); diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-entity-array/edit-entity-array.component.spec.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-entity-array/edit-entity-array.component.spec.ts index ab761f23d4..b0756516fd 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-entity-array/edit-entity-array.component.spec.ts +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-entity-array/edit-entity-array.component.spec.ts @@ -1,12 +1,12 @@ import { ComponentFixture, TestBed } from "@angular/core/testing"; import { EditEntityArrayComponent } from "./edit-entity-array.component"; -import { FormControl } from "@angular/forms"; import { EntityMapperService } from "../../../../entity/entity-mapper.service"; import { Child } from "../../../../../child-dev-project/children/model/child"; import { NoopAnimationsModule } from "@angular/platform-browser/animations"; import { EntityUtilsModule } from "../../entity-utils.module"; import { EntitySchemaService } from "../../../../entity/schema/entity-schema.service"; +import { setupEditComponent } from "../edit-component.spec"; describe("EditEntityArrayComponent", () => { let component: EditEntityArrayComponent; @@ -29,7 +29,7 @@ describe("EditEntityArrayComponent", () => { beforeEach(() => { fixture = TestBed.createComponent(EditEntityArrayComponent); component = fixture.componentInstance; - component.formControl = new FormControl(); + setupEditComponent(component); component.entityName = Child.ENTITY_TYPE; fixture.detectChanges(); }); diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-entity-array/edit-entity-array.component.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-entity-array/edit-entity-array.component.ts index 67a081bcf8..1b1b9c2dcf 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-entity-array/edit-entity-array.component.ts +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-entity-array/edit-entity-array.component.ts @@ -1,15 +1,12 @@ import { Component } from "@angular/core"; import { EditComponent, EditPropertyConfig } from "../edit-component"; -import { Entity } from "../../../../entity/model/entity"; @Component({ selector: "app-edit-entity-array", templateUrl: "./edit-entity-array.component.html", styleUrls: ["./edit-entity-array.component.scss"], }) -export class EditEntityArrayComponent extends EditComponent< - (string | Entity)[] -> { +export class EditEntityArrayComponent extends EditComponent { placeholder: string; entityName: string; onInitFromDynamicConfig(config: EditPropertyConfig) { diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-long-text/edit-long-text.component.spec.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-long-text/edit-long-text.component.spec.ts index 3bd63009d7..d3bf505e84 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-long-text/edit-long-text.component.spec.ts +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-long-text/edit-long-text.component.spec.ts @@ -2,9 +2,10 @@ import { ComponentFixture, TestBed } from "@angular/core/testing"; import { EditLongTextComponent } from "./edit-long-text.component"; import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { FormControl, FormGroup, ReactiveFormsModule } from "@angular/forms"; +import { ReactiveFormsModule } from "@angular/forms"; import { MatFormFieldModule } from "@angular/material/form-field"; import { MatInputModule } from "@angular/material/input"; +import { setupEditComponent } from "../edit-component.spec"; describe("EditLongTextComponent", () => { let component: EditLongTextComponent; @@ -25,11 +26,7 @@ describe("EditLongTextComponent", () => { beforeEach(() => { fixture = TestBed.createComponent(EditLongTextComponent); component = fixture.componentInstance; - const formControl = new FormControl(); - const formGroup = new FormGroup({}); - component.formControlName = "testControl"; - component.formControl = formControl; - formGroup.registerControl(component.formControlName, formControl); + setupEditComponent(component); fixture.detectChanges(); }); diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-number/edit-number.component.spec.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-number/edit-number.component.spec.ts index 010fe838a0..569b63251b 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-number/edit-number.component.spec.ts +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-number/edit-number.component.spec.ts @@ -1,10 +1,11 @@ import { ComponentFixture, TestBed } from "@angular/core/testing"; import { EditNumberComponent } from "./edit-number.component"; -import { FormControl, FormGroup, ReactiveFormsModule } from "@angular/forms"; +import { FormGroup, ReactiveFormsModule } from "@angular/forms"; import { MatFormFieldModule } from "@angular/material/form-field"; import { MatInputModule } from "@angular/material/input"; import { NoopAnimationsModule } from "@angular/platform-browser/animations"; +import { setupEditComponent } from "../edit-component.spec"; describe("EditNumberComponent", () => { let component: EditNumberComponent; @@ -26,13 +27,7 @@ describe("EditNumberComponent", () => { beforeEach(() => { fixture = TestBed.createComponent(EditNumberComponent); component = fixture.componentInstance; - const formControl = new FormControl(); - formGroup = new FormGroup({ testProperty: formControl }); - component.onInitFromDynamicConfig({ - formControl: formControl, - propertySchema: {}, - formFieldConfig: { id: "testProperty" }, - }); + formGroup = setupEditComponent(component); fixture.detectChanges(); }); diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-percentage/edit-percentage.component.spec.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-percentage/edit-percentage.component.spec.ts index 9980967174..587f6eaba5 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-percentage/edit-percentage.component.spec.ts +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-percentage/edit-percentage.component.spec.ts @@ -10,11 +10,13 @@ import { } from "@angular/forms"; import { MatInputModule } from "@angular/material/input"; import { NoopAnimationsModule } from "@angular/platform-browser/animations"; +import { setupEditComponent } from "../edit-component.spec"; describe("EditPercentageComponent", () => { let component: EditPercentageComponent; let fixture: ComponentFixture; let formGroup: FormGroup; + const propertyName = "percentageProperty"; beforeEach(async () => { await TestBed.configureTestingModule({ @@ -31,13 +33,7 @@ describe("EditPercentageComponent", () => { beforeEach(() => { fixture = TestBed.createComponent(EditPercentageComponent); component = fixture.componentInstance; - const formControl = new FormControl(); - formGroup = new FormGroup({ testProperty: formControl }); - component.onInitFromDynamicConfig({ - formControl: formControl, - propertySchema: {}, - formFieldConfig: { id: "testProperty" }, - }); + formGroup = setupEditComponent(component, propertyName); fixture.detectChanges(); }); @@ -74,11 +70,11 @@ describe("EditPercentageComponent", () => { expect(formGroup.valid).toBeTrue(); const control = new FormControl(0, [Validators.required]); - formGroup.setControl("testProperty", control); + formGroup.setControl(propertyName, control); component.onInitFromDynamicConfig({ formControl: control, propertySchema: {}, - formFieldConfig: { id: "testProperty" }, + formFieldConfig: { id: propertyName }, }); component.formControl.setValue(null); diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-photo/edit-photo.component.spec.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-photo/edit-photo.component.spec.ts index 30b5e1851f..d06bc8a274 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-photo/edit-photo.component.spec.ts +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-photo/edit-photo.component.spec.ts @@ -2,8 +2,8 @@ import { ComponentFixture, TestBed } from "@angular/core/testing"; import { EditPhotoComponent } from "./edit-photo.component"; import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { FormControl, FormGroup } from "@angular/forms"; import { SessionService } from "../../../../session/session-service/session.service"; +import { setupEditComponent } from "../edit-component.spec"; describe("EditPhotoComponent", () => { let component: EditPhotoComponent; @@ -22,11 +22,7 @@ describe("EditPhotoComponent", () => { beforeEach(() => { fixture = TestBed.createComponent(EditPhotoComponent); component = fixture.componentInstance; - const formControl = new FormControl(); - const formGroup = new FormGroup({}); - component.formControlName = "testControl"; - component.formControl = formControl; - formGroup.registerControl(component.formControlName, formControl); + setupEditComponent(component); fixture.detectChanges(); }); diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.spec.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.spec.ts index 172ea9dcaa..db8cbd61d5 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.spec.ts +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.spec.ts @@ -7,7 +7,7 @@ import { import { EditSingleEntityComponent } from "./edit-single-entity.component"; import { EntityMapperService } from "../../../../entity/entity-mapper.service"; -import { FormControl, Validators } from "@angular/forms"; +import { Validators } from "@angular/forms"; import { EntitySchemaService } from "../../../../entity/schema/entity-schema.service"; import { EntityFormService } from "../../../entity-form/entity-form.service"; import { NoopAnimationsModule } from "@angular/platform-browser/animations"; @@ -15,6 +15,7 @@ import { ChildSchoolRelation } from "../../../../../child-dev-project/children/m import { School } from "../../../../../child-dev-project/schools/model/school"; import { EntityUtilsModule } from "../../entity-utils.module"; import { Child } from "../../../../../child-dev-project/children/model/child"; +import { TypedFormControl } from "../edit-component"; describe("EditSingleEntityComponent", () => { let component: EditSingleEntityComponent; @@ -42,7 +43,7 @@ describe("EditSingleEntityComponent", () => { const entityFormService = TestBed.inject(EntityFormService); component.formControl = entityFormService .createFormGroup([{ id: "schoolId" }], new ChildSchoolRelation()) - .get("schoolId") as FormControl; + .get("schoolId") as TypedFormControl; component.formControlName = "schoolId"; fixture.detectChanges(); }); diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-text/edit-text.component.spec.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-text/edit-text.component.spec.ts index 7e6c04e2b0..953688500a 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-text/edit-text.component.spec.ts +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-text/edit-text.component.spec.ts @@ -1,10 +1,11 @@ import { ComponentFixture, TestBed } from "@angular/core/testing"; import { EditTextComponent } from "./edit-text.component"; -import { FormControl, FormGroup, ReactiveFormsModule } from "@angular/forms"; +import { ReactiveFormsModule } from "@angular/forms"; import { NoopAnimationsModule } from "@angular/platform-browser/animations"; import { MatFormFieldModule } from "@angular/material/form-field"; import { MatInputModule } from "@angular/material/input"; +import { setupEditComponent } from "../edit-component.spec"; describe("EditTextComponent", () => { let component: EditTextComponent; @@ -25,11 +26,7 @@ describe("EditTextComponent", () => { beforeEach(() => { fixture = TestBed.createComponent(EditTextComponent); component = fixture.componentInstance; - const formControl = new FormControl(); - const formGroup = new FormGroup({}); - component.formControlName = "testControl"; - component.formControl = formControl; - formGroup.registerControl(component.formControlName, formControl); + setupEditComponent(component); fixture.detectChanges(); }); diff --git a/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.html b/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.html index 894ee4994d..0db4135273 100644 --- a/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.html +++ b/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.html @@ -17,7 +17,7 @@ diff --git a/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.spec.ts b/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.spec.ts index ad7d1dbe0d..d7ead594fe 100644 --- a/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.spec.ts +++ b/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.spec.ts @@ -90,47 +90,44 @@ describe("EntitySelectComponent", () => { fixture.detectChanges(); }); - it("contains the initial selection when passed as entity-arguments", fakeAsync(() => { + it("contains the initial selection as entities", fakeAsync(() => { component.entityType = User.ENTITY_TYPE; - fixture.detectChanges(); - tick(); - component.selectionInputType = "entity"; - const expectation = testUsers.slice(2, 3); - component.selection = expectation; - expect(component.selection_).toEqual(expectation); - })); + const expectation = testUsers.slice(2, 3).map((user) => user.getId()); - it("contains the initial selection when passed as id-arguments", fakeAsync(() => { - component.entityType = User.ENTITY_TYPE; - component.selectionInputType = "id"; - const expectation = testUsers.slice(2, 3).map((child) => child.getId()); component.selection = expectation; fixture.detectChanges(); tick(); - expect(component.selection_.every((s) => typeof s === "object")).toBeTrue(); - expect(component.selection_.map((s) => s.getId())).toEqual(expectation); + + component.selectedEntities.forEach((s) => expect(s).toBeInstanceOf(User)); + expect(component.selectedEntities.map((s) => s.getId())).toEqual( + expectation + ); })); it("emits whenever a new entity is selected", fakeAsync(() => { spyOn(component.selectionChange, "emit"); component.entityType = User.ENTITY_TYPE; tick(); - component.selectionInputType = "entity"; + component.selectEntity(testUsers[0]); - expect(component.selectionChange.emit).toHaveBeenCalledWith([testUsers[0]]); + expect(component.selectionChange.emit).toHaveBeenCalledWith([ + testUsers[0].getId(), + ]); + component.selectEntity(testUsers[1]); expect(component.selectionChange.emit).toHaveBeenCalledWith([ - testUsers[0], - testUsers[1], + testUsers[0].getId(), + testUsers[1].getId(), ]); tick(); })); it("emits whenever a selected entity is removed", () => { spyOn(component.selectionChange, "emit"); - component.selection_ = [...testUsers]; - component.selectionInputType = "id"; + component.selectedEntities = [...testUsers]; + component.unselectEntity(testUsers[0]); + const remainingChildren = testUsers .filter((c) => c.getId() !== testUsers[0].getId()) .map((c) => c.getId()); @@ -142,13 +139,13 @@ describe("EntitySelectComponent", () => { it("adds a new entity if it matches a known entity", () => { component.allEntities = testUsers; component.select({ input: null, value: testUsers[0]["name"] }); - expect(component.selection_).toEqual([testUsers[0]]); + expect(component.selectedEntities).toEqual([testUsers[0]]); }); it("does not add anything if a new entity doesn't match", () => { component.allEntities = testUsers; component.select({ input: null, value: "ZZ" }); - expect(component.selection_).toEqual([]); + expect(component.selectedEntities).toEqual([]); }); it("autocompletes with the default accessor", (done) => { diff --git a/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.ts b/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.ts index 4418f435f1..22b2ea636b 100644 --- a/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.ts +++ b/src/app/core/entity-components/entity-utils/entity-select/entity-select.component.ts @@ -45,45 +45,33 @@ export class EntitySelectComponent implements OnChanges { /** * The (initial) selection. Can be used in combination with {@link selectionChange} - * to enable two-way binding to either an array of entities or an array of strings - * corresponding to the id's of the entities. - * The type (id's or entities) will be determined by the setting of the - * {@link selectionInputType} + * to enable two-way binding to an array of strings corresponding to the id's of the entities. * @param sel The initial selection */ - @Input() set selection(sel: (string | E)[]) { + @Input() set selection(sel: string[]) { if (!Array.isArray(sel)) { - this.selection_ = []; + this.selectedEntities = []; return; } - if (this.selectionInputType === "id") { - this.loading - .pipe( - untilDestroyed(this), - filter((isLoading) => !isLoading) - ) - .subscribe((_) => { - this.selection_ = this.allEntities.filter((e) => - sel.find((s) => s === e.getId()) - ); - }); - } else { - this.selection_ = sel as E[]; - } + this.loading + .pipe( + untilDestroyed(this), + filter((isLoading) => !isLoading) + ) + .subscribe((_) => { + this.selectedEntities = this.allEntities.filter((e) => + sel.find((s) => s === e.getId()) + ); + }); } /** Underlying data-array */ - selection_: E[] = []; - /** - * The type to publish and receive; either string-id's or entities - * Defaults to string-id's - */ - @Input() selectionInputType: "id" | "entity" = "id"; + selectedEntities: E[] = []; /** * called whenever the selection changes. * This happens when a new entity is being added or an existing * one is removed */ - @Output() selectionChange = new EventEmitter<(string | E)[]>(); + @Output() selectionChange = new EventEmitter(); /** * The label is what is seen above the list. For example when used * in the note-details-view, this is "Children" @@ -178,7 +166,7 @@ export class EntitySelectComponent implements OnChanges { * @param entity the entity to select */ selectEntity(entity: E) { - this.selection_.push(entity); + this.selectedEntities.push(entity); this.emitChange(); this.inputField.nativeElement.value = ""; this.formControl.setValue(null); @@ -230,11 +218,11 @@ export class EntitySelectComponent implements OnChanges { * @param entity The entity to remove */ unselectEntity(entity: E) { - const index = this.selection_.findIndex( + const index = this.selectedEntities.findIndex( (e) => e.getId() === entity.getId() ); if (index !== -1) { - this.selection_.splice(index, 1); + this.selectedEntities.splice(index, 1); this.emitChange(); // Update the form control to re-run the filter function this.formControl.updateValueAndValidity(); @@ -242,14 +230,10 @@ export class EntitySelectComponent implements OnChanges { } private emitChange() { - if (this.selectionInputType === "id") { - this.selectionChange.emit(this.selection_.map((e) => e.getId())); - } else { - this.selectionChange.emit(this.selection_); - } + this.selectionChange.emit(this.selectedEntities.map((e) => e.getId())); } private isSelected(entity: E): boolean { - return this.selection_.some((e) => e.getId() === entity.getId()); + return this.selectedEntities.some((e) => e.getId() === entity.getId()); } } diff --git a/src/app/features/data-import/data-import/data-import.component.html b/src/app/features/data-import/data-import/data-import.component.html index be9982043a..8a03d1c983 100644 --- a/src/app/features/data-import/data-import/data-import.component.html +++ b/src/app/features/data-import/data-import/data-import.component.html @@ -9,5 +9,5 @@ #csvImport type="file" style="display: none" - (change)="importCsvFile($event.target.files[0])" + (change)="importCsvFile($event)" /> diff --git a/src/app/features/data-import/data-import/data-import.component.spec.ts b/src/app/features/data-import/data-import/data-import.component.spec.ts index b420b73e54..5017615f66 100644 --- a/src/app/features/data-import/data-import/data-import.component.spec.ts +++ b/src/app/features/data-import/data-import/data-import.component.spec.ts @@ -36,7 +36,7 @@ describe("DataImportComponent", () => { }); it("should call handleCsvImport() in DataImportService", () => { - component.importCsvFile(mockCsvFile); + component.importCsvFile({ target: { files: [mockCsvFile] } } as any); expect(mockDataImportService.handleCsvImport).toHaveBeenCalledWith( mockCsvFile ); diff --git a/src/app/features/data-import/data-import/data-import.component.ts b/src/app/features/data-import/data-import/data-import.component.ts index a07ed36e5c..7647e9da92 100644 --- a/src/app/features/data-import/data-import/data-import.component.ts +++ b/src/app/features/data-import/data-import/data-import.component.ts @@ -12,7 +12,8 @@ import { DataImportService } from "../data-import.service"; export class DataImportComponent { constructor(private dataImportService: DataImportService) {} - importCsvFile(file: Blob): void { - this.dataImportService.handleCsvImport(file); + importCsvFile(inputEvent: Event): void { + const target = inputEvent.target as HTMLInputElement; + this.dataImportService.handleCsvImport(target.files[0]); } } diff --git a/tsconfig.json b/tsconfig.json index ef05cba779..eebe99d4f4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,5 +19,8 @@ "dom" ], "resolveJsonModule": true + }, + "angularCompilerOptions": { + "strictTemplates": true } } From 3d0014d8b0f3ed2134c3525ff2258cca13558b33 Mon Sep 17 00:00:00 2001 From: SuttArt <77150155+SuttArt@users.noreply.github.com> Date: Tue, 23 Nov 2021 11:44:24 +0100 Subject: [PATCH 10/21] test: added cypress and an example e2e test --- .gitignore | 4 + README.md | 6 +- angular.json | 144 +- cypress.json | 10 + e2e/app.e2e-spec.ts | 31 - e2e/app.po.ts | 28 - e2e/fixtures/example.json | 5 + .../LinkingChildToSchool.ts | 61 + e2e/plugins/index.ts | 3 + e2e/support/commands.ts | 43 + e2e/support/index.ts | 17 + e2e/tsconfig.e2e.json | 12 - e2e/tsconfig.json | 8 + package-lock.json | 2975 ++++++++--------- package.json | 10 +- protractor.conf.js | 45 - 16 files changed, 1785 insertions(+), 1617 deletions(-) create mode 100644 cypress.json delete mode 100644 e2e/app.e2e-spec.ts delete mode 100644 e2e/app.po.ts create mode 100644 e2e/fixtures/example.json create mode 100644 e2e/integration/LinkingChildToSchool/LinkingChildToSchool.ts create mode 100644 e2e/plugins/index.ts create mode 100644 e2e/support/commands.ts create mode 100644 e2e/support/index.ts delete mode 100644 e2e/tsconfig.e2e.json create mode 100644 e2e/tsconfig.json delete mode 100644 protractor.conf.js diff --git a/.gitignore b/.gitignore index 9acd6f5f69..ed21cb0ff9 100644 --- a/.gitignore +++ b/.gitignore @@ -192,3 +192,7 @@ fabric.properties ### VisualStudioCode template .vs/* .vscode/* + +# video and screenshot of the tests from Cypress +./e2e/screenshots +./e2e/videos diff --git a/README.md b/README.md index cf9c7079e3..3ebdc5c032 100644 --- a/README.md +++ b/README.md @@ -97,8 +97,10 @@ Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github. ### Running end-to-end tests -Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). -Before running the tests make sure you are serving the app via `ng serve`. +Run `npm run e2e` to execute the end-to-end tests via [Cypress](http://www.cypress.io/) in the terminal. + +Run `npm run e2e-open` to execute the end-to-end tests via Cypress own User Interface. + ### Build a docker image locally Deployment on a server can be done through a docker image, our [ndb-setup project](https://github.com/Aam-Digital/ndb-setup) provides tools and a starting point to run the system using docker. diff --git a/angular.json b/angular.json index 95fc8d588a..1a0ab839e6 100644 --- a/angular.json +++ b/angular.json @@ -63,7 +63,10 @@ "serviceWorker": true }, "localized": { - "localize": ["de", "en-US"] + "localize": [ + "de", + "en-US" + ] } } }, @@ -119,24 +122,151 @@ }, "ndb-core-e2e": { "root": "", - "sourceRoot": "", + "sourceRoot": "src", "projectType": "application", + "i18n": { + "sourceLocale": "en-US", + "locales": { + "de": "src/locale/messages.de.xlf" + } + }, "architect": { - "e2e": { - "builder": "@angular-devkit/build-angular:protractor", + "build": { + "builder": "@angular-devkit/build-angular:browser", "options": { - "protractorConfig": "./protractor.conf.js", - "devServerTarget": "ndb-core:serve" + "aot": true, + "outputPath": "dist", + "index": "src/index.html", + "main": "src/main.ts", + "tsConfig": "src/tsconfig.app.json", + "polyfills": "src/polyfills.ts", + "i18nMissingTranslation": "warning", + "assets": [ + "src/assets", + "src/favicon.ico", + "src/manifest.json" + ], + "styles": [ + "src/ndb-theme.scss", + "src/styles.scss", + "node_modules/flag-icon-css/css/flag-icon.min.css" + ], + "scripts": [ + "node_modules/marked/lib/marked.js" + ] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "anyComponentStyle", + "maximumWarning": "6kb" + } + ], + "optimization": true, + "outputHashing": "all", + "sourceMap": true, + "namedChunks": false, + "aot": true, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true, + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "serviceWorker": true + }, + "localized": { + "localize": [ + "de", + "en-US" + ] + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "ndb-core-e2e:build" + }, + "configurations": { + "production": { + "browserTarget": "ndb-core-e2e:build:production" + } + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "ndb-core-e2e:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "karmaConfig": "./karma.conf.js", + "polyfills": "src/polyfills.ts", + "tsConfig": "src/tsconfig.spec.json", + "scripts": [ + "node_modules/marked/lib/marked.js" + ], + "styles": [ + "src/ndb-theme.scss", + "src/styles.scss" + ], + "assets": [ + "src/assets", + "src/favicon.ico", + "src/manifest.json" + ] } }, "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { "tsConfig": [ - "e2e/tsconfig.e2e.json" + "src/tsconfig.app.json", + "src/tsconfig.spec.json", + "e2e/tsconfig.json" ], "exclude": [] } + }, + "cypress-run": { + "builder": "@cypress/schematic:cypress", + "options": { + "devServerTarget": "ndb-core-e2e:serve" + }, + "configurations": { + "production": { + "devServerTarget": "ndb-core-e2e:serve:production" + } + } + }, + "cypress-open": { + "builder": "@cypress/schematic:cypress", + "options": { + "watch": true, + "headless": false, + "devServerTarget": "ndb-core-e2e:serve" + } + }, + "e2e": { + "builder": "@cypress/schematic:cypress", + "options": { + "devServerTarget": "ndb-core-e2e:serve", + "watch": false, + "headless": true + }, + "configurations": { + "production": { + "devServerTarget": "ndb-core-e2e:serve:production" + } + } } } } diff --git a/cypress.json b/cypress.json new file mode 100644 index 0000000000..ca6554bbef --- /dev/null +++ b/cypress.json @@ -0,0 +1,10 @@ +{ + "integrationFolder": "e2e/integration", + "supportFile": "e2e/support/index.ts", + "videosFolder": "e2e/videos", + "screenshotsFolder": "e2e/screenshots", + "pluginsFile": "e2e/plugins/index.ts", + "fixturesFolder": "e2e/fixtures", + "baseUrl": "http://localhost:4200", + "video": false +} diff --git a/e2e/app.e2e-spec.ts b/e2e/app.e2e-spec.ts deleted file mode 100644 index 1a006594a3..0000000000 --- a/e2e/app.e2e-spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of ndb-core. - * - * ndb-core is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ndb-core is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ndb-core. If not, see . - */ - -import { NdbCorePage } from "./app.po"; - -describe("ndb-core App", () => { - let page: NdbCorePage; - - beforeEach(() => { - page = new NdbCorePage(); - }); - - it("should display message saying app works", () => { - page.navigateTo(); - // expect(page.getParagraphText()).toEqual("app works!"); - }); -}); diff --git a/e2e/app.po.ts b/e2e/app.po.ts deleted file mode 100644 index ea45250cbb..0000000000 --- a/e2e/app.po.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of ndb-core. - * - * ndb-core is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ndb-core is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ndb-core. If not, see . - */ - -import { browser, by, element } from "protractor"; - -export class NdbCorePage { - navigateTo() { - return browser.get("/"); - } - - getParagraphText() { - return element(by.css("app-root h1")).getText(); - } -} diff --git a/e2e/fixtures/example.json b/e2e/fixtures/example.json new file mode 100644 index 0000000000..02e4254378 --- /dev/null +++ b/e2e/fixtures/example.json @@ -0,0 +1,5 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" +} diff --git a/e2e/integration/LinkingChildToSchool/LinkingChildToSchool.ts b/e2e/integration/LinkingChildToSchool/LinkingChildToSchool.ts new file mode 100644 index 0000000000..61b8d3d7e5 --- /dev/null +++ b/e2e/integration/LinkingChildToSchool/LinkingChildToSchool.ts @@ -0,0 +1,61 @@ +describe("Scenario: Linking a child to a school - E2E test", () => { + before(() => { + // GIVEN I am on the details page of a child + cy.wrap("Aaditya School").as("schoolName"); + // cy.wrap(0).as('studentsCount') + cy.visit("http://localhost:4200/child/1"); + cy.wait(10000); + + cy.get(".page-header > .ng-star-inserted").invoke("text").as("studentName"); + }); + + // WHEN I add an entry in the 'Previous Schools' section with a specific school + // (with todays date - that might be added to this e2e test later) + it("Add an entry in the Previous School section", function () { + // get the Education button and click on it + cy.get("#mat-expansion-panel-header-1 > .mat-content") + .should("contain", "Education") + .click(); + // get the Show All button and toggle it, forcing the click is needed because the element has a hidden feature + cy.get( + "#mat-slide-toggle-1 > .mat-slide-toggle-label > .mat-slide-toggle-bar > .mat-slide-toggle-thumb-container > .mat-slide-toggle-thumb" + ).click({ force: true }); + // get the Add School button and click on it + cy.get( + "app-previous-schools.ng-star-inserted > app-entity-subrecord > .container > .mat-table > thead > .mat-header-row > .cdk-column-actions > .mat-focus-indicator" + ).click(); + + // choose the school to add + cy.get('[ng-reflect-placeholder="Select School"]') + .type(this.schoolName) + .click(); + // save school in child profile + cy.contains("button", "Save").click(); + }); + + // THEN I can see that child in the 'Children Overview' of the details page of this school + it("Check for child in Children Overview of specific school", function () { + // Go to the school overview page + cy.contains("mat-list-item", "Schools").click(); + + // Choose the school that was added to the child profile + cy.contains( + "tbody > :nth-child(1) > .cdk-column-name", + this.schoolName + ).click(); + // Open the students overview + cy.contains("mat-expansion-panel-header", "Students").click(); + + // Here a wait function is implemented because cypress is faster then the website + cy.wait(2000); + + // Toggle 'Show All' switch to display all students + cy.get(".mat-slide-toggle-content").click({ force: true }); + + // Check if student is in the school students list + cy.contains( + "#cdk-accordion-child-10 > .mat-expansion-panel-body", + this.studentName + ); + }); +}); diff --git a/e2e/plugins/index.ts b/e2e/plugins/index.ts new file mode 100644 index 0000000000..edf74d3186 --- /dev/null +++ b/e2e/plugins/index.ts @@ -0,0 +1,3 @@ +// Plugins enable you to tap into, modify, or extend the internal behavior of Cypress +// For more info, visit https://on.cypress.io/plugins-api +module.exports = (on, config) => {}; diff --git a/e2e/support/commands.ts b/e2e/support/commands.ts new file mode 100644 index 0000000000..af1f44a0fc --- /dev/null +++ b/e2e/support/commands.ts @@ -0,0 +1,43 @@ +// *********************************************** +// This example namespace declaration will help +// with Intellisense and code completion in your +// IDE or Text Editor. +// *********************************************** +// declare namespace Cypress { +// interface Chainable { +// customCommand(param: any): typeof customCommand; +// } +// } +// +// function customCommand(param: any): void { +// console.warn(param); +// } +// +// NOTE: You can use it like so: +// Cypress.Commands.add('customCommand', customCommand); +// +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add("login", (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/e2e/support/index.ts b/e2e/support/index.ts new file mode 100644 index 0000000000..ac293b6165 --- /dev/null +++ b/e2e/support/index.ts @@ -0,0 +1,17 @@ +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// When a command from ./commands is ready to use, import with `import './commands'` syntax +// import './commands'; diff --git a/e2e/tsconfig.e2e.json b/e2e/tsconfig.e2e.json deleted file mode 100644 index e2a9a2fc77..0000000000 --- a/e2e/tsconfig.e2e.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "outDir": "../out-tsc/e2e", - "module": "commonjs", - "target": "es5", - "types": [ - "jasmine", - "node" - ] - } -} diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json new file mode 100644 index 0000000000..d046303b59 --- /dev/null +++ b/e2e/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../tsconfig.json", + "include": ["**/*.ts"], + "compilerOptions": { + "sourceMap": false, + "types": ["cypress", "node"] + } +} diff --git a/package-lock.json b/package-lock.json index cdc23930ed..65da73ba37 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,6 +59,7 @@ "@angular/compiler-cli": "^11.2.4", "@babel/core": "^7.13.8", "@compodoc/compodoc": "1.1.11", + "@cypress/schematic": "^1.5.1", "@schematics/angular": "^11.2.14", "@storybook/addon-actions": "^6.1.21", "@storybook/addon-essentials": "^6.1.21", @@ -73,6 +74,7 @@ "@types/pouchdb": "^6.4.0", "babel-loader": "^8.2.2", "codelyzer": "6.0.1", + "cypress": "8.5.0", "husky": "^5.1.3", "jasmine-core": "^3.8.0", "jasmine-spec-reporter": "^6.0.0", @@ -86,7 +88,6 @@ "lint-staged": "^10.5.4", "ngx-i18nsupport": "^0.17.1", "prettier": "~2.2.1", - "protractor": "~7.0.0", "ts-node": "^9.1.1", "tslint": "^6.1.3", "tslint-config-prettier": "^1.18.0", @@ -102,13 +103,12 @@ "dev": true }, "node_modules/@angular-devkit/architect": { - "version": "0.1202.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1202.6.tgz", - "integrity": "sha512-DQHK5VGfPof1TuSmRmt2Usw2BuNVLzxKSSy7+tEJbYzqf8N/wQO+1M67ye8qf8gAU88xGo378dD9++DFc/PJZA==", + "version": "0.1200.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1200.5.tgz", + "integrity": "sha512-222VZ4OeaDK3vON8V5m+w15SRWfUs5uOb4H9ij/H9/6tyHD83uWfCDoOGg+ax4wJVdWEFJIS+Vn4ijGcZCq9WQ==", "dev": true, - "peer": true, "dependencies": { - "@angular-devkit/core": "12.2.6", + "@angular-devkit/core": "12.0.5", "rxjs": "6.6.7" }, "engines": { @@ -117,6 +117,25 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@angular-devkit/architect/node_modules/@angular-devkit/core": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.0.5.tgz", + "integrity": "sha512-zVSQV+8/vjUjsUKGlj8Kf5LioA6AXJTGI0yhHW9q1dFX4dPpbW63k0R1UoIB2wJ0F/AbYVgpnPGPe9BBm2fvZA==", + "dev": true, + "dependencies": { + "ajv": "8.2.0", + "ajv-formats": "2.0.2", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.7", + "source-map": "0.7.3" + }, + "engines": { + "node": "^12.14.1 || >=14.0.0", + "npm": "^6.11.0 || ^7.5.6", + "yarn": ">= 1.13.0" + } + }, "node_modules/@angular-devkit/build-angular": { "version": "0.1102.14", "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.1102.14.tgz", @@ -1021,11 +1040,10 @@ "dev": true }, "node_modules/@angular-devkit/core": { - "version": "12.2.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.2.6.tgz", - "integrity": "sha512-E+OhY34Vmwyy1/PaX/nzao40XM70wOr7Urh00sAtV8sPLXMLeW0gHk4DUchCKohxQkrIL0AxYt1aeUVgIc7bSA==", + "version": "12.2.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.2.7.tgz", + "integrity": "sha512-WeLlDZaudpx10OGDPfVcWu/CaEWiWzAaLTUQz0Ww/yM+01FxR/P8yeH1sYAV1MS6d6KHvXGw7Lpf8PV7IA/zHA==", "dev": true, - "peer": true, "dependencies": { "ajv": "8.6.2", "ajv-formats": "2.1.0", @@ -1040,6 +1058,39 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@angular-devkit/core/node_modules/ajv": { + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz", + "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@angular-devkit/core/node_modules/ajv-formats": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.0.tgz", + "integrity": "sha512-USH2jBb+C/hIpwD2iRjp0pe0k+MvzG0mlSn/FIdCgQhUb9ALPRjt2KIQdfZDS9r0ZIeUAg7gOu9KL0PFqGqr5Q==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, "node_modules/@angular-devkit/schematics": { "version": "11.2.14", "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-11.2.14.tgz", @@ -3575,6 +3626,199 @@ "node": ">= 10.0.0" } }, + "node_modules/@cypress/request": { + "version": "2.88.6", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.6.tgz", + "integrity": "sha512-z0UxBE/+qaESAHY9p9sM2h8Y4XqtsbDCt0/DPOrqA/RZgKi4PkxdpXyK4wCCnSk1xHqWHZZAE+gV6aDAR6+caQ==", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@cypress/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/@cypress/request/node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/@cypress/schematic": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@cypress/schematic/-/schematic-1.5.1.tgz", + "integrity": "sha512-Ak8teyJ2rzwWMxxhNBmJvW+pJrXb27pJ267yS3Gi0OJ/l2sp1fb+zb58VQot4zj3HrWaL2GbcwbmjeA8Sj7X9g==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "^0.1200.0", + "@angular-devkit/core": "^12.0.0", + "@angular-devkit/schematics": "^12.0.0", + "@schematics/angular": "^12.0.0", + "jsonc-parser": "^3.0.0", + "rxjs": "~6.6.0" + } + }, + "node_modules/@cypress/schematic/node_modules/@angular-devkit/schematics": { + "version": "12.2.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-12.2.7.tgz", + "integrity": "sha512-E0hCFyyfbixjerf0Okt4ynC6F1dsT2Wl7MwAePe+wzPTHCnKIRTa2PQTxJzdWeTlSkQMkSK6ft2iyWOD/FODng==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "12.2.7", + "ora": "5.4.1", + "rxjs": "6.6.7" + }, + "engines": { + "node": "^12.14.1 || >=14.0.0", + "npm": "^6.11.0 || ^7.5.6", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@cypress/schematic/node_modules/@schematics/angular": { + "version": "12.2.7", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-12.2.7.tgz", + "integrity": "sha512-wGqp0jC545Fwf0ydBkeoJHx9snFW+uqn40WwVqs/27Nh4AEHB5uzwzLY7Ykae95Zn802a61KPqSNWpez2fWWGA==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "12.2.7", + "@angular-devkit/schematics": "12.2.7", + "jsonc-parser": "3.0.0" + }, + "engines": { + "node": "^12.14.1 || >=14.0.0", + "npm": "^6.11.0 || ^7.5.6", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@cypress/schematic/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@cypress/schematic/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@cypress/schematic/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@cypress/schematic/node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@cypress/schematic/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@cypress/xvfb": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", + "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", + "dev": true, + "dependencies": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + } + }, + "node_modules/@cypress/xvfb/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz", @@ -7670,12 +7914,6 @@ "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", "dev": true }, - "node_modules/@types/q": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", - "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=", - "dev": true - }, "node_modules/@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", @@ -7723,10 +7961,16 @@ "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", "dev": true }, - "node_modules/@types/selenium-webdriver": { - "version": "3.0.19", - "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.19.tgz", - "integrity": "sha512-OFUilxQg+rWL2FMxtmIgCkUDlJB6pskkpvmew7yeXfzzsOBb5rc+y2+DjHm+r3r1ZPPcJefK3DveNSYWGiy68g==", + "node_modules/@types/sinonjs__fake-timers": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.4.tgz", + "integrity": "sha512-IFQTJARgMUBF+xVd2b+hIgXWrZEjND3vJtRCvIelcFB5SIXfjV4bOHbHJ0eXKh+0COrBRc8MqteKAz/j88rE0A==", + "dev": true + }, + "node_modules/@types/sizzle": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", + "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", "dev": true }, "node_modules/@types/source-list-map": { @@ -7826,6 +8070,16 @@ "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, + "node_modules/@types/yauzl": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", + "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@webassemblyjs/ast": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", @@ -8115,15 +8369,6 @@ "node": ">=8.9" } }, - "node_modules/adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", - "dev": true, - "engines": { - "node": ">=0.3.0" - } - }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -8189,11 +8434,10 @@ } }, "node_modules/ajv": { - "version": "8.6.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz", - "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.2.0.tgz", + "integrity": "sha512-WSNGFuyWd//XO8n/m/EaOlNLtO0yL8EXT/74LqT4khdhpZjP7lkj/kT5uwRmGitKEVp/Oj7ZUHeGfPtgHhQ5CA==", "dev": true, - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -8215,11 +8459,10 @@ } }, "node_modules/ajv-formats": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.0.tgz", - "integrity": "sha512-USH2jBb+C/hIpwD2iRjp0pe0k+MvzG0mlSn/FIdCgQhUb9ALPRjt2KIQdfZDS9r0ZIeUAg7gOu9KL0PFqGqr5Q==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.0.2.tgz", + "integrity": "sha512-Brah4Uo5/U8v76c6euTwtjVFFaVishwnJrQBYpev1JRh4vjA1F4HY3UzQez41YUCszUCXKagG8v6eVRBHV1gkw==", "dev": true, - "peer": true, "dependencies": { "ajv": "^8.0.0" }, @@ -8502,6 +8745,26 @@ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/are-we-there-yet": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", @@ -9454,20 +9717,11 @@ "node": ">= 6" } }, - "node_modules/blocking-proxy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-1.0.1.tgz", - "integrity": "sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "blocking-proxy": "built/lib/bin.js" - }, - "engines": { - "node": ">=6.9.x" - } + "node_modules/blob-util": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", + "dev": true }, "node_modules/bluebird": { "version": "3.7.2", @@ -9837,49 +10091,6 @@ "url": "https://opencollective.com/browserslist" } }, - "node_modules/browserstack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.6.1.tgz", - "integrity": "sha512-GxtFjpIaKdbAyzHfFDKixKO8IBT7wR3NjbzrGc78nNs/Ciys9wU3/nBtsqsWv5nDSrdI5tz0peKuzCPuNXNUiw==", - "dev": true, - "dependencies": { - "https-proxy-agent": "^2.2.1" - } - }, - "node_modules/browserstack/node_modules/agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "dev": true, - "dependencies": { - "es6-promisify": "^5.0.0" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/browserstack/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/browserstack/node_modules/https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "dev": true, - "dependencies": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - }, - "engines": { - "node": ">= 4.5.0" - } - }, "node_modules/bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", @@ -9912,6 +10123,15 @@ "ieee754": "^1.1.13" } }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/buffer-equal": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", @@ -10016,6 +10236,15 @@ "node": ">=0.10.0" } }, + "node_modules/cachedir": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", + "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -10225,6 +10454,15 @@ "node": "*" } }, + "node_modules/check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/cheerio": { "version": "1.0.0-rc.10", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", @@ -10768,6 +11006,15 @@ "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", "dev": true }, + "node_modules/common-tags": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", + "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -12148,6 +12395,228 @@ "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", "dev": true }, + "node_modules/cypress": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-8.5.0.tgz", + "integrity": "sha512-MMkXIS+Ro2KETn4gAlG3tIc/7FiljuuCZP0zpd9QsRG6MZSyZW/l1J3D4iQM6WHsVxuX4rFChn5jPFlC2tNSvQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@cypress/request": "^2.88.6", + "@cypress/xvfb": "^1.2.4", + "@types/node": "^14.14.31", + "@types/sinonjs__fake-timers": "^6.0.2", + "@types/sizzle": "^2.3.2", + "arch": "^2.2.0", + "blob-util": "^2.0.2", + "bluebird": "^3.7.2", + "cachedir": "^2.3.0", + "chalk": "^4.1.0", + "check-more-types": "^2.24.0", + "cli-cursor": "^3.1.0", + "cli-table3": "~0.6.0", + "commander": "^5.1.0", + "common-tags": "^1.8.0", + "dayjs": "^1.10.4", + "debug": "^4.3.2", + "enquirer": "^2.3.6", + "eventemitter2": "^6.4.3", + "execa": "4.1.0", + "executable": "^4.1.1", + "extract-zip": "2.0.1", + "figures": "^3.2.0", + "fs-extra": "^9.1.0", + "getos": "^3.2.1", + "is-ci": "^3.0.0", + "is-installed-globally": "~0.4.0", + "lazy-ass": "^1.6.0", + "listr2": "^3.8.3", + "lodash": "^4.17.21", + "log-symbols": "^4.0.0", + "minimist": "^1.2.5", + "ospath": "^1.2.2", + "pretty-bytes": "^5.6.0", + "proxy-from-env": "1.0.0", + "ramda": "~0.27.1", + "request-progress": "^3.0.0", + "supports-color": "^8.1.1", + "tmp": "~0.2.1", + "untildify": "^4.0.0", + "url": "^0.11.0", + "yauzl": "^2.10.0" + }, + "bin": { + "cypress": "bin/cypress" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/cypress/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cypress/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cypress/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cypress/node_modules/ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, + "node_modules/cypress/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/cypress/node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/cypress/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cypress/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cypress/node_modules/is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "dependencies": { + "ci-info": "^3.1.1" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/cypress/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/cypress/node_modules/ramda": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", + "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==", + "dev": true + }, + "node_modules/cypress/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/cypress/node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/cypress/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/d": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", @@ -12191,6 +12660,12 @@ "node": ">=4.0" } }, + "node_modules/dayjs": { + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz", + "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==", + "dev": true + }, "node_modules/debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -12457,83 +12932,6 @@ "node": ">=0.10.0" } }, - "node_modules/del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "dependencies": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del/node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del/node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del/node_modules/globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "dependencies": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -13326,21 +13724,6 @@ "event-emitter": "~0.3.5" } }, - "node_modules/es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "node_modules/es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "dev": true, - "dependencies": { - "es6-promise": "^4.0.3" - } - }, "node_modules/es6-set": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", @@ -13555,6 +13938,12 @@ "through": "~2.3.1" } }, + "node_modules/eventemitter2": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.4.tgz", + "integrity": "sha512-HLU3NDY6wARrLCEwyGKRBvuWYyvW6mHYv72SJJAH3iJN3a6eVUvkjFkcxah1bcTgGVBBrFdIopBJPhCQFMLyXw==", + "dev": true + }, "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -13621,13 +14010,25 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "node_modules/executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", "dev": true, + "dependencies": { + "pify": "^2.2.0" + }, "engines": { - "node": ">= 0.8.0" + "node": ">=4" + } + }, + "node_modules/executable/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, "node_modules/expand-brackets": { @@ -13932,6 +14333,26 @@ "node": ">=0.10.0" } }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -14065,6 +14486,15 @@ "bser": "2.1.1" } }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, "node_modules/figgy-pudding": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", @@ -14787,6 +15217,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -14996,6 +15427,21 @@ "node": ">=0.10.0" } }, + "node_modules/getos": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", + "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", + "dev": true, + "dependencies": { + "async": "^3.2.0" + } + }, + "node_modules/getos/node_modules/async": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.1.tgz", + "integrity": "sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg==", + "dev": true + }, "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -15116,6 +15562,21 @@ "process": "^0.11.10" } }, + "node_modules/global-dirs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", + "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", + "dev": true, + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -15307,27 +15768,6 @@ "node": ">= 0.4.0" } }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/has-bigints": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", @@ -16909,6 +17349,22 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -16995,37 +17451,13 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "dependencies": { - "is-path-inside": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, - "dependencies": { - "path-is-inside": "^1.0.1" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/is-plain-obj": { @@ -17444,20 +17876,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jasmine": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", - "integrity": "sha1-awicChFXax8W3xG4AUbZHU6Lij4=", - "dev": true, - "dependencies": { - "exit": "^0.1.2", - "glob": "^7.0.6", - "jasmine-core": "~2.8.0" - }, - "bin": { - "jasmine": "bin/jasmine.js" - } - }, "node_modules/jasmine-core": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.9.0.tgz", @@ -17473,21 +17891,6 @@ "colors": "1.4.0" } }, - "node_modules/jasmine/node_modules/jasmine-core": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", - "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=", - "dev": true - }, - "node_modules/jasminewd2": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/jasminewd2/-/jasminewd2-2.2.0.tgz", - "integrity": "sha1-43zwsX8ZnM4jvqcbIDk5Uka07E4=", - "dev": true, - "engines": { - "node": ">= 6.9.x" - } - }, "node_modules/jest-docblock": { "version": "21.2.0", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz", @@ -17721,8 +18124,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "peer": true + "dev": true }, "node_modules/json-stringify-safe": { "version": "5.0.1", @@ -17788,18 +18190,6 @@ "verror": "1.10.0" } }, - "node_modules/jszip": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.7.1.tgz", - "integrity": "sha512-ghL0tz1XG9ZEmRMcEN2vt7xabrDdqHHeykgARpmZ0BiIctWxM47Vt63ZO2dnp4QYt/xJVLLy5Zv1l/xRdh2byg==", - "dev": true, - "dependencies": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "set-immediate-shim": "~1.0.1" - } - }, "node_modules/junk": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", @@ -18053,6 +18443,15 @@ "resolved": "https://registry.npmjs.org/layerr/-/layerr-0.1.2.tgz", "integrity": "sha512-ob5kTd9H3S4GOG2nVXyQhOu9O8nBgP555XxWPkJI0tR0JeRilfyTp8WtPdIJHLXBmHMSdEq5+KMxiYABeScsIQ==" }, + "node_modules/lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", + "dev": true, + "engines": { + "node": "> 0.8" + } + }, "node_modules/lazy-universal-dotenv": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/lazy-universal-dotenv/-/lazy-universal-dotenv-3.0.1.tgz", @@ -18341,21 +18740,6 @@ "source-map": "~0.6.1" } }, - "node_modules/lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "dev": true, - "dependencies": { - "immediate": "~3.0.5" - } - }, - "node_modules/lie/node_modules/immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", - "dev": true - }, "node_modules/linebreak": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/linebreak/-/linebreak-1.0.2.tgz", @@ -18666,6 +19050,43 @@ "fsevents": "^1.2.7" } }, + "node_modules/live-server/node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/live-server/node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/live-server/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/live-server/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, "node_modules/live-server/node_modules/fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -18803,6 +19224,33 @@ "node": ">=0.10.0" } }, + "node_modules/live-server/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/live-server/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "node_modules/live-server/node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/live-server/node_modules/readdirp": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", @@ -18817,6 +19265,30 @@ "node": ">=0.10" } }, + "node_modules/live-server/node_modules/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/live-server/node_modules/to-regex-range": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", @@ -18885,6 +19357,12 @@ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", + "dev": true + }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -21027,6 +21505,12 @@ "node": ">=0.10.0" } }, + "node_modules/ospath": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", + "integrity": "sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs=", + "dev": true + }, "node_modules/overlayscrollbars": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/overlayscrollbars/-/overlayscrollbars-1.13.1.tgz", @@ -21539,6 +22023,12 @@ "node": ">=0.10.0" } }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -22806,284 +23296,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/protractor": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/protractor/-/protractor-7.0.0.tgz", - "integrity": "sha512-UqkFjivi4GcvUQYzqGYNe0mLzfn5jiLmO8w9nMhQoJRLhy2grJonpga2IWhI6yJO30LibWXJJtA4MOIZD2GgZw==", - "dev": true, - "dependencies": { - "@types/q": "^0.0.32", - "@types/selenium-webdriver": "^3.0.0", - "blocking-proxy": "^1.0.0", - "browserstack": "^1.5.1", - "chalk": "^1.1.3", - "glob": "^7.0.3", - "jasmine": "2.8.0", - "jasminewd2": "^2.1.0", - "q": "1.4.1", - "saucelabs": "^1.5.0", - "selenium-webdriver": "3.6.0", - "source-map-support": "~0.4.0", - "webdriver-js-extender": "2.1.0", - "webdriver-manager": "^12.1.7", - "yargs": "^15.3.1" - }, - "bin": { - "protractor": "bin/protractor", - "webdriver-manager": "bin/webdriver-manager" - }, - "engines": { - "node": ">=10.13.x" - } - }, - "node_modules/protractor/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/protractor/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/protractor/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/protractor/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/protractor/node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/protractor/node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/protractor/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/protractor/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/protractor/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/protractor/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/protractor/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/protractor/node_modules/source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "dependencies": { - "source-map": "^0.5.6" - } - }, - "node_modules/protractor/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/protractor/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/protractor/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/protractor/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/protractor/node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/protractor/node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/protractor/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/protractor/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/protractor/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -23097,6 +23309,12 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", + "dev": true + }, "node_modules/proxy-middleware": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz", @@ -23177,16 +23395,6 @@ "node": ">=6" } }, - "node_modules/q": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", - "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=", - "dev": true, - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, "node_modules/qjobs": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", @@ -24363,6 +24571,15 @@ "node": ">= 6" } }, + "node_modules/request-progress": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", + "integrity": "sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4=", + "dev": true, + "dependencies": { + "throttleit": "^1.0.0" + } + }, "node_modules/request/node_modules/form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", @@ -24409,7 +24626,6 @@ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -25111,52 +25327,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/saucelabs": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz", - "integrity": "sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==", - "dev": true, - "dependencies": { - "https-proxy-agent": "^2.2.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/saucelabs/node_modules/agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "dev": true, - "dependencies": { - "es6-promisify": "^5.0.0" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/saucelabs/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/saucelabs/node_modules/https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "dev": true, - "dependencies": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - }, - "engines": { - "node": ">= 4.5.0" - } - }, "node_modules/sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -25243,45 +25413,6 @@ "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", "dev": true }, - "node_modules/selenium-webdriver": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz", - "integrity": "sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==", - "dev": true, - "dependencies": { - "jszip": "^3.1.3", - "rimraf": "^2.5.4", - "tmp": "0.0.30", - "xml2js": "^0.4.17" - }, - "engines": { - "node": ">= 6.9.0" - } - }, - "node_modules/selenium-webdriver/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/selenium-webdriver/node_modules/tmp": { - "version": "0.0.30", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", - "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.1" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/selfsigned": { "version": "1.10.11", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.11.tgz", @@ -25523,15 +25654,6 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, - "node_modules/set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", @@ -27501,6 +27623,12 @@ "node": ">=10" } }, + "node_modules/throttleit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", + "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", + "dev": true + }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -28963,6 +29091,15 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/upath": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", @@ -29704,126 +29841,6 @@ "url-parse": "^1.5.3" } }, - "node_modules/webdriver-js-extender": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz", - "integrity": "sha512-lcUKrjbBfCK6MNsh7xaY2UAUmZwe+/ib03AjVOpFobX4O7+83BUveSrLfU0Qsyb1DaKJdQRbuU+kM9aZ6QUhiQ==", - "dev": true, - "dependencies": { - "@types/selenium-webdriver": "^3.0.0", - "selenium-webdriver": "^3.0.1" - }, - "engines": { - "node": ">=6.9.x" - } - }, - "node_modules/webdriver-manager": { - "version": "12.1.8", - "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.8.tgz", - "integrity": "sha512-qJR36SXG2VwKugPcdwhaqcLQOD7r8P2Xiv9sfNbfZrKBnX243iAkOueX1yAmeNgIKhJ3YAT/F2gq6IiEZzahsg==", - "dev": true, - "dependencies": { - "adm-zip": "^0.4.9", - "chalk": "^1.1.1", - "del": "^2.2.0", - "glob": "^7.0.3", - "ini": "^1.3.4", - "minimist": "^1.2.0", - "q": "^1.4.1", - "request": "^2.87.0", - "rimraf": "^2.5.2", - "semver": "^5.3.0", - "xml2js": "^0.4.17" - }, - "bin": { - "webdriver-manager": "bin/webdriver-manager" - }, - "engines": { - "node": ">=6.9.x" - } - }, - "node_modules/webdriver-manager/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webdriver-manager/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webdriver-manager/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webdriver-manager/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/webdriver-manager/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/webdriver-manager/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/webdriver-manager/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webdriver-manager/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/webpack": { "version": "4.46.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", @@ -31698,28 +31715,6 @@ } } }, - "node_modules/xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dev": true, - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/xmldoc": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.1.2.tgz", @@ -31795,6 +31790,16 @@ "node": ">=10" } }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", @@ -31843,14 +31848,29 @@ "dev": true }, "@angular-devkit/architect": { - "version": "0.1202.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1202.6.tgz", - "integrity": "sha512-DQHK5VGfPof1TuSmRmt2Usw2BuNVLzxKSSy7+tEJbYzqf8N/wQO+1M67ye8qf8gAU88xGo378dD9++DFc/PJZA==", + "version": "0.1200.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1200.5.tgz", + "integrity": "sha512-222VZ4OeaDK3vON8V5m+w15SRWfUs5uOb4H9ij/H9/6tyHD83uWfCDoOGg+ax4wJVdWEFJIS+Vn4ijGcZCq9WQ==", "dev": true, - "peer": true, "requires": { - "@angular-devkit/core": "12.2.6", + "@angular-devkit/core": "12.0.5", "rxjs": "6.6.7" + }, + "dependencies": { + "@angular-devkit/core": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.0.5.tgz", + "integrity": "sha512-zVSQV+8/vjUjsUKGlj8Kf5LioA6AXJTGI0yhHW9q1dFX4dPpbW63k0R1UoIB2wJ0F/AbYVgpnPGPe9BBm2fvZA==", + "dev": true, + "requires": { + "ajv": "8.2.0", + "ajv-formats": "2.0.2", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.7", + "source-map": "0.7.3" + } + } } }, "@angular-devkit/build-angular": { @@ -32546,11 +32566,10 @@ } }, "@angular-devkit/core": { - "version": "12.2.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.2.6.tgz", - "integrity": "sha512-E+OhY34Vmwyy1/PaX/nzao40XM70wOr7Urh00sAtV8sPLXMLeW0gHk4DUchCKohxQkrIL0AxYt1aeUVgIc7bSA==", + "version": "12.2.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.2.7.tgz", + "integrity": "sha512-WeLlDZaudpx10OGDPfVcWu/CaEWiWzAaLTUQz0Ww/yM+01FxR/P8yeH1sYAV1MS6d6KHvXGw7Lpf8PV7IA/zHA==", "dev": true, - "peer": true, "requires": { "ajv": "8.6.2", "ajv-formats": "2.1.0", @@ -32558,6 +32577,29 @@ "magic-string": "0.25.7", "rxjs": "6.6.7", "source-map": "0.7.3" + }, + "dependencies": { + "ajv": { + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz", + "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-formats": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.0.tgz", + "integrity": "sha512-USH2jBb+C/hIpwD2iRjp0pe0k+MvzG0mlSn/FIdCgQhUb9ALPRjt2KIQdfZDS9r0ZIeUAg7gOu9KL0PFqGqr5Q==", + "dev": true, + "requires": { + "ajv": "^8.0.0" + } + } } }, "@angular-devkit/schematics": { @@ -34362,6 +34404,162 @@ } } }, + "@cypress/request": { + "version": "2.88.6", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.6.tgz", + "integrity": "sha512-z0UxBE/+qaESAHY9p9sM2h8Y4XqtsbDCt0/DPOrqA/RZgKi4PkxdpXyK4wCCnSk1xHqWHZZAE+gV6aDAR6+caQ==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^8.3.2" + }, + "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + } + } + }, + "@cypress/schematic": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@cypress/schematic/-/schematic-1.5.1.tgz", + "integrity": "sha512-Ak8teyJ2rzwWMxxhNBmJvW+pJrXb27pJ267yS3Gi0OJ/l2sp1fb+zb58VQot4zj3HrWaL2GbcwbmjeA8Sj7X9g==", + "dev": true, + "requires": { + "@angular-devkit/architect": "^0.1200.0", + "@angular-devkit/core": "^12.0.0", + "@angular-devkit/schematics": "^12.0.0", + "@schematics/angular": "^12.0.0", + "jsonc-parser": "^3.0.0", + "rxjs": "~6.6.0" + }, + "dependencies": { + "@angular-devkit/schematics": { + "version": "12.2.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-12.2.7.tgz", + "integrity": "sha512-E0hCFyyfbixjerf0Okt4ynC6F1dsT2Wl7MwAePe+wzPTHCnKIRTa2PQTxJzdWeTlSkQMkSK6ft2iyWOD/FODng==", + "dev": true, + "requires": { + "@angular-devkit/core": "12.2.7", + "ora": "5.4.1", + "rxjs": "6.6.7" + } + }, + "@schematics/angular": { + "version": "12.2.7", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-12.2.7.tgz", + "integrity": "sha512-wGqp0jC545Fwf0ydBkeoJHx9snFW+uqn40WwVqs/27Nh4AEHB5uzwzLY7Ykae95Zn802a61KPqSNWpez2fWWGA==", + "dev": true, + "requires": { + "@angular-devkit/core": "12.2.7", + "@angular-devkit/schematics": "12.2.7", + "jsonc-parser": "3.0.0" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "requires": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@cypress/xvfb": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", + "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, "@discoveryjs/json-ext": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz", @@ -37461,12 +37659,6 @@ "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", "dev": true }, - "@types/q": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", - "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=", - "dev": true - }, "@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", @@ -37516,10 +37708,16 @@ "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", "dev": true }, - "@types/selenium-webdriver": { - "version": "3.0.19", - "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.19.tgz", - "integrity": "sha512-OFUilxQg+rWL2FMxtmIgCkUDlJB6pskkpvmew7yeXfzzsOBb5rc+y2+DjHm+r3r1ZPPcJefK3DveNSYWGiy68g==", + "@types/sinonjs__fake-timers": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.4.tgz", + "integrity": "sha512-IFQTJARgMUBF+xVd2b+hIgXWrZEjND3vJtRCvIelcFB5SIXfjV4bOHbHJ0eXKh+0COrBRc8MqteKAz/j88rE0A==", + "dev": true + }, + "@types/sizzle": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", + "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", "dev": true }, "@types/source-list-map": { @@ -37617,6 +37815,16 @@ "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, + "@types/yauzl": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", + "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", + "dev": true, + "optional": true, + "requires": { + "@types/node": "*" + } + }, "@webassemblyjs/ast": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", @@ -37886,12 +38094,6 @@ "regex-parser": "^2.2.11" } }, - "adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", - "dev": true - }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -37948,11 +38150,10 @@ } }, "ajv": { - "version": "8.6.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz", - "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.2.0.tgz", + "integrity": "sha512-WSNGFuyWd//XO8n/m/EaOlNLtO0yL8EXT/74LqT4khdhpZjP7lkj/kT5uwRmGitKEVp/Oj7ZUHeGfPtgHhQ5CA==", "dev": true, - "peer": true, "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -37968,11 +38169,10 @@ "requires": {} }, "ajv-formats": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.0.tgz", - "integrity": "sha512-USH2jBb+C/hIpwD2iRjp0pe0k+MvzG0mlSn/FIdCgQhUb9ALPRjt2KIQdfZDS9r0ZIeUAg7gOu9KL0PFqGqr5Q==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.0.2.tgz", + "integrity": "sha512-Brah4Uo5/U8v76c6euTwtjVFFaVishwnJrQBYpev1JRh4vjA1F4HY3UzQez41YUCszUCXKagG8v6eVRBHV1gkw==", "dev": true, - "peer": true, "requires": { "ajv": "^8.0.0" } @@ -38176,6 +38376,12 @@ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true }, + "arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true + }, "are-we-there-yet": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", @@ -38937,14 +39143,11 @@ } } }, - "blocking-proxy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-1.0.1.tgz", - "integrity": "sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } + "blob-util": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", + "dev": true }, "bluebird": { "version": "3.7.2", @@ -39261,45 +39464,6 @@ "node-releases": "^1.1.75" } }, - "browserstack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.6.1.tgz", - "integrity": "sha512-GxtFjpIaKdbAyzHfFDKixKO8IBT7wR3NjbzrGc78nNs/Ciys9wU3/nBtsqsWv5nDSrdI5tz0peKuzCPuNXNUiw==", - "dev": true, - "requires": { - "https-proxy-agent": "^2.2.1" - }, - "dependencies": { - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "dev": true, - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - } - } - }, "bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", @@ -39318,6 +39482,12 @@ "ieee754": "^1.1.13" } }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, "buffer-equal": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", @@ -39407,6 +39577,12 @@ "unset-value": "^1.0.0" } }, + "cachedir": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", + "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", + "dev": true + }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -39563,6 +39739,12 @@ "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" }, + "check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=", + "dev": true + }, "cheerio": { "version": "1.0.0-rc.10", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", @@ -39979,6 +40161,12 @@ "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", "dev": true }, + "common-tags": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", + "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", + "dev": true + }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -41095,6 +41283,176 @@ "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", "dev": true }, + "cypress": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-8.5.0.tgz", + "integrity": "sha512-MMkXIS+Ro2KETn4gAlG3tIc/7FiljuuCZP0zpd9QsRG6MZSyZW/l1J3D4iQM6WHsVxuX4rFChn5jPFlC2tNSvQ==", + "dev": true, + "requires": { + "@cypress/request": "^2.88.6", + "@cypress/xvfb": "^1.2.4", + "@types/node": "^14.14.31", + "@types/sinonjs__fake-timers": "^6.0.2", + "@types/sizzle": "^2.3.2", + "arch": "^2.2.0", + "blob-util": "^2.0.2", + "bluebird": "^3.7.2", + "cachedir": "^2.3.0", + "chalk": "^4.1.0", + "check-more-types": "^2.24.0", + "cli-cursor": "^3.1.0", + "cli-table3": "~0.6.0", + "commander": "^5.1.0", + "common-tags": "^1.8.0", + "dayjs": "^1.10.4", + "debug": "^4.3.2", + "enquirer": "^2.3.6", + "eventemitter2": "^6.4.3", + "execa": "4.1.0", + "executable": "^4.1.1", + "extract-zip": "2.0.1", + "figures": "^3.2.0", + "fs-extra": "^9.1.0", + "getos": "^3.2.1", + "is-ci": "^3.0.0", + "is-installed-globally": "~0.4.0", + "lazy-ass": "^1.6.0", + "listr2": "^3.8.3", + "lodash": "^4.17.21", + "log-symbols": "^4.0.0", + "minimist": "^1.2.5", + "ospath": "^1.2.2", + "pretty-bytes": "^5.6.0", + "proxy-from-env": "1.0.0", + "ramda": "~0.27.1", + "request-progress": "^3.0.0", + "supports-color": "^8.1.1", + "tmp": "~0.2.1", + "untildify": "^4.0.0", + "url": "^0.11.0", + "yauzl": "^2.10.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "ramda": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", + "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "requires": { + "rimraf": "^3.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, "d": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", @@ -41132,6 +41490,12 @@ "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==", "dev": true }, + "dayjs": { + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz", + "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==", + "dev": true + }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -41340,67 +41704,6 @@ "isobject": "^3.0.1" } }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -42076,21 +42379,6 @@ "event-emitter": "~0.3.5" } }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "dev": true, - "requires": { - "es6-promise": "^4.0.3" - } - }, "es6-set": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", @@ -42262,6 +42550,12 @@ "through": "~2.3.1" } }, + "eventemitter2": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.4.tgz", + "integrity": "sha512-HLU3NDY6wARrLCEwyGKRBvuWYyvW6mHYv72SJJAH3iJN3a6eVUvkjFkcxah1bcTgGVBBrFdIopBJPhCQFMLyXw==", + "dev": true + }, "eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -42316,11 +42610,22 @@ "strip-final-newline": "^2.0.0" } }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true + "executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "requires": { + "pify": "^2.2.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } }, "expand-brackets": { "version": "2.1.4", @@ -42582,6 +42887,18 @@ } } }, + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + } + }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -42692,6 +43009,15 @@ "bser": "2.1.1" } }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, "figgy-pudding": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", @@ -43267,6 +43593,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "optional": true }, "function-bind": { @@ -43420,6 +43747,23 @@ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", "dev": true }, + "getos": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", + "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", + "dev": true, + "requires": { + "async": "^3.2.0" + }, + "dependencies": { + "async": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.1.tgz", + "integrity": "sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg==", + "dev": true + } + } + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -43518,6 +43862,15 @@ "process": "^0.11.10" } }, + "global-dirs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", + "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", + "dev": true, + "requires": { + "ini": "2.0.0" + } + }, "global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -43666,23 +44019,6 @@ "function-bind": "^1.1.1" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - } - } - }, "has-bigints": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", @@ -44885,6 +45221,16 @@ "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", "dev": true }, + "is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "requires": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + } + }, "is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -44941,29 +45287,11 @@ "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", "dev": true }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "requires": { - "is-path-inside": "^1.0.0" - } - }, "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true }, "is-plain-obj": { "version": "2.1.0", @@ -45268,25 +45596,6 @@ "iterate-iterator": "^1.0.1" } }, - "jasmine": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", - "integrity": "sha1-awicChFXax8W3xG4AUbZHU6Lij4=", - "dev": true, - "requires": { - "exit": "^0.1.2", - "glob": "^7.0.6", - "jasmine-core": "~2.8.0" - }, - "dependencies": { - "jasmine-core": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", - "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=", - "dev": true - } - } - }, "jasmine-core": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.9.0.tgz", @@ -45302,12 +45611,6 @@ "colors": "1.4.0" } }, - "jasminewd2": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/jasminewd2/-/jasminewd2-2.2.0.tgz", - "integrity": "sha1-43zwsX8ZnM4jvqcbIDk5Uka07E4=", - "dev": true - }, "jest-docblock": { "version": "21.2.0", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz", @@ -45489,8 +45792,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "peer": true + "dev": true }, "json-stringify-safe": { "version": "5.0.1", @@ -45544,18 +45846,6 @@ "verror": "1.10.0" } }, - "jszip": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.7.1.tgz", - "integrity": "sha512-ghL0tz1XG9ZEmRMcEN2vt7xabrDdqHHeykgARpmZ0BiIctWxM47Vt63ZO2dnp4QYt/xJVLLy5Zv1l/xRdh2byg==", - "dev": true, - "requires": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "set-immediate-shim": "~1.0.1" - } - }, "junk": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", @@ -45754,6 +46044,12 @@ "resolved": "https://registry.npmjs.org/layerr/-/layerr-0.1.2.tgz", "integrity": "sha512-ob5kTd9H3S4GOG2nVXyQhOu9O8nBgP555XxWPkJI0tR0JeRilfyTp8WtPdIJHLXBmHMSdEq5+KMxiYABeScsIQ==" }, + "lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", + "dev": true + }, "lazy-universal-dotenv": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/lazy-universal-dotenv/-/lazy-universal-dotenv-3.0.1.tgz", @@ -45976,23 +46272,6 @@ } } }, - "lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "dev": true, - "requires": { - "immediate": "~3.0.5" - }, - "dependencies": { - "immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", - "dev": true - } - } - }, "linebreak": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/linebreak/-/linebreak-1.0.2.tgz", @@ -46236,6 +46515,39 @@ "upath": "^1.1.1" } }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -46347,6 +46659,24 @@ "to-regex": "^3.0.2" } }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, "readdirp": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", @@ -46358,6 +46688,27 @@ "readable-stream": "^2.0.2" } }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + } + }, "to-regex-range": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", @@ -46413,6 +46764,12 @@ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", + "dev": true + }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -48106,6 +48463,12 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, + "ospath": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", + "integrity": "sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs=", + "dev": true + }, "overlayscrollbars": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/overlayscrollbars/-/overlayscrollbars-1.13.1.tgz", @@ -48534,6 +48897,12 @@ } } }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -49461,223 +49830,6 @@ "xtend": "^4.0.0" } }, - "protractor": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/protractor/-/protractor-7.0.0.tgz", - "integrity": "sha512-UqkFjivi4GcvUQYzqGYNe0mLzfn5jiLmO8w9nMhQoJRLhy2grJonpga2IWhI6yJO30LibWXJJtA4MOIZD2GgZw==", - "dev": true, - "requires": { - "@types/q": "^0.0.32", - "@types/selenium-webdriver": "^3.0.0", - "blocking-proxy": "^1.0.0", - "browserstack": "^1.5.1", - "chalk": "^1.1.3", - "glob": "^7.0.3", - "jasmine": "2.8.0", - "jasminewd2": "^2.1.0", - "q": "1.4.1", - "saucelabs": "^1.5.0", - "selenium-webdriver": "3.6.0", - "source-map-support": "~0.4.0", - "webdriver-js-extender": "2.1.0", - "webdriver-manager": "^12.1.7", - "yargs": "^15.3.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -49688,6 +49840,12 @@ "ipaddr.js": "1.9.1" } }, + "proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", + "dev": true + }, "proxy-middleware": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz", @@ -49766,12 +49924,6 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, - "q": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", - "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=", - "dev": true - }, "qjobs": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", @@ -50719,6 +50871,15 @@ } } }, + "request-progress": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", + "integrity": "sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4=", + "dev": true, + "requires": { + "throttleit": "^1.0.0" + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -50728,8 +50889,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "peer": true + "dev": true }, "require-main-filename": { "version": "2.0.0", @@ -51248,45 +51408,6 @@ } } }, - "saucelabs": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz", - "integrity": "sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==", - "dev": true, - "requires": { - "https-proxy-agent": "^2.2.1" - }, - "dependencies": { - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "dev": true, - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - } - } - }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -51362,38 +51483,6 @@ "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", "dev": true }, - "selenium-webdriver": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz", - "integrity": "sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==", - "dev": true, - "requires": { - "jszip": "^3.1.3", - "rimraf": "^2.5.4", - "tmp": "0.0.30", - "xml2js": "^0.4.17" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "tmp": { - "version": "0.0.30", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", - "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.1" - } - } - } - }, "selfsigned": { "version": "1.10.11", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.11.tgz", @@ -51614,12 +51703,6 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true - }, "set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", @@ -53196,6 +53279,12 @@ "integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==", "dev": true }, + "throttleit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", + "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", + "dev": true + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -54332,6 +54421,12 @@ } } }, + "untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true + }, "upath": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", @@ -54933,98 +55028,6 @@ "url-parse": "^1.5.3" } }, - "webdriver-js-extender": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz", - "integrity": "sha512-lcUKrjbBfCK6MNsh7xaY2UAUmZwe+/ib03AjVOpFobX4O7+83BUveSrLfU0Qsyb1DaKJdQRbuU+kM9aZ6QUhiQ==", - "dev": true, - "requires": { - "@types/selenium-webdriver": "^3.0.0", - "selenium-webdriver": "^3.0.1" - } - }, - "webdriver-manager": { - "version": "12.1.8", - "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.8.tgz", - "integrity": "sha512-qJR36SXG2VwKugPcdwhaqcLQOD7r8P2Xiv9sfNbfZrKBnX243iAkOueX1yAmeNgIKhJ3YAT/F2gq6IiEZzahsg==", - "dev": true, - "requires": { - "adm-zip": "^0.4.9", - "chalk": "^1.1.1", - "del": "^2.2.0", - "glob": "^7.0.3", - "ini": "^1.3.4", - "minimist": "^1.2.0", - "q": "^1.4.1", - "request": "^2.87.0", - "rimraf": "^2.5.2", - "semver": "^5.3.0", - "xml2js": "^0.4.17" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, "webpack": { "version": "4.46.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", @@ -56514,22 +56517,6 @@ "dev": true, "requires": {} }, - "xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dev": true, - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - }, - "xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "dev": true - }, "xmldoc": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.1.2.tgz", @@ -56586,6 +56573,16 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/package.json b/package.json index b29bf57f21..9fffb999ca 100644 --- a/package.json +++ b/package.json @@ -11,12 +11,15 @@ "test-ci": "ng test --code-coverage --karmaConfig=build/karma-ci.conf.js ", "lint": "ng lint ndb-core --type-check", "e2e": "ng e2e", + "e2e-open": "ng run ndb-core-e2e:cypress-open", "compodoc": "npx compodoc -c doc/compodoc_sources/.compodocrc.json", "postinstall": "ngcc && node patch-webpack.js", "docs:json": "compodoc -p ./tsconfig.json -e json -d .", "storybook": "npm run docs:json && start-storybook -p 6006", "build-storybook": "npm run docs:json && build-storybook", - "extract-i18n": "ng extract-i18n --output-path ./src/locale/ && xliffmerge --profile xliffmerge.json" + "extract-i18n": "ng extract-i18n --output-path ./src/locale/ && xliffmerge --profile xliffmerge.json", + "cypress:open": "e2e open", + "cypress:run": "e2e run" }, "private": true, "dependencies": { @@ -69,6 +72,7 @@ "@angular/compiler-cli": "^11.2.4", "@babel/core": "^7.13.8", "@compodoc/compodoc": "1.1.11", + "@cypress/schematic": "^1.5.1", "@schematics/angular": "^11.2.14", "@storybook/addon-actions": "^6.1.21", "@storybook/addon-essentials": "^6.1.21", @@ -96,13 +100,13 @@ "lint-staged": "^10.5.4", "ngx-i18nsupport": "^0.17.1", "prettier": "~2.2.1", - "protractor": "~7.0.0", "ts-node": "^9.1.1", "tslint": "^6.1.3", "tslint-config-prettier": "^1.18.0", "tslint-plugin-prettier": "^2.3.0", "typescript": "~4.1.6", - "webpack": "^4.6.0" + "webpack": "^4.6.0", + "cypress": "8.5.0" }, "browser": { "crypto": false diff --git a/protractor.conf.js b/protractor.conf.js deleted file mode 100644 index 786d3b8686..0000000000 --- a/protractor.conf.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of ndb-core. - * - * ndb-core is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ndb-core is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ndb-core. If not, see . - */ - -// Protractor configuration file, see link for more information -// https://github.com/angular/protractor/blob/master/lib/config.ts - -const { SpecReporter } = require('jasmine-spec-reporter'); - -exports.config = { - allScriptsTimeout: 11000, - specs: [ - './e2e/**/*.e2e-spec.ts' - ], - capabilities: { - 'browserName': 'chrome' - }, - directConnect: true, - baseUrl: 'http://localhost:4200/', - framework: 'jasmine', - jasmineNodeOpts: { - showColors: true, - defaultTimeoutInterval: 30000, - print: function() {} - }, - onPrepare() { - require('ts-node').register({ - project: 'e2e/tsconfig.e2e.json' - }); - jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); - } -}; From 93f03e86ff17e41d9c9dcfb1835e36ce5c416525 Mon Sep 17 00:00:00 2001 From: Snyk bot Date: Fri, 26 Nov 2021 07:52:26 +0100 Subject: [PATCH 11/21] refactor: upgrade @sentry/browser from 6.13.3 to 6.14.0 (#1042) --- package-lock.json | 128 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 64 insertions(+), 66 deletions(-) diff --git a/package-lock.json b/package-lock.json index 65da73ba37..22ab4bd414 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,7 @@ "@fortawesome/free-regular-svg-icons": "^5.15.2", "@fortawesome/free-solid-svg-icons": "^5.15.4", "@ngneat/until-destroy": "^8.1.4", - "@sentry/browser": "^6.13.3", + "@sentry/browser": "^6.14.0", "angulartics2": "^10.1.0", "crypto-js": "^4.1.1", "deep-object-diff": "^1.1.0", @@ -4913,13 +4913,13 @@ "dev": true }, "node_modules/@sentry/browser": { - "version": "6.13.3", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.13.3.tgz", - "integrity": "sha512-jwlpsk2/u1cofvfYsjmqcnx50JJtf/T6HTgdW+ih8+rqWC5ABEZf4IiB/H+KAyjJ3wVzCOugMq5irL83XDCfqQ==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.14.0.tgz", + "integrity": "sha512-tdLTvgBwBuHhGG2iABdoRf5pUbS99xVapkHXKp9977slMGnUznMUrLUAVenitPx9fGoyYDZc8ukMfabAblfDyA==", "dependencies": { - "@sentry/core": "6.13.3", - "@sentry/types": "6.13.3", - "@sentry/utils": "6.13.3", + "@sentry/core": "6.14.0", + "@sentry/types": "6.14.0", + "@sentry/utils": "6.14.0", "tslib": "^1.9.3" }, "engines": { @@ -4932,14 +4932,14 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/core": { - "version": "6.13.3", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.13.3.tgz", - "integrity": "sha512-obm3SjgCk8A7nB37b2AU1eq1q7gMoJRrGMv9VRIyfcG0Wlz/5lJ9O3ohUk+YZaaVfZMxXn6hFtsBiOWmlv7IIA==", - "dependencies": { - "@sentry/hub": "6.13.3", - "@sentry/minimal": "6.13.3", - "@sentry/types": "6.13.3", - "@sentry/utils": "6.13.3", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.14.0.tgz", + "integrity": "sha512-GKs1A3yjcVB5ST4Mx9Eq4Z1yQaeq+AN1eJO1pnJhkOUnBXbmLGXvEp039W3Qn9iq9QuQmVRQz2C0+9GbrWmx9A==", + "dependencies": { + "@sentry/hub": "6.14.0", + "@sentry/minimal": "6.14.0", + "@sentry/types": "6.14.0", + "@sentry/utils": "6.14.0", "tslib": "^1.9.3" }, "engines": { @@ -4952,12 +4952,12 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/hub": { - "version": "6.13.3", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.13.3.tgz", - "integrity": "sha512-eYppBVqvhs5cvm33snW2sxfcw6G20/74RbBn+E4WDo15hozis89kU7ZCJDOPkXuag3v1h9igns/kM6PNBb41dw==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.14.0.tgz", + "integrity": "sha512-27ZN0YOxxy+2BV8VyelCejeeVJXy3Bs91bF6ICv3fekfL6cpyGswVMFltmSxraZOMxS4+Xz2HEgjlddgtd8yDQ==", "dependencies": { - "@sentry/types": "6.13.3", - "@sentry/utils": "6.13.3", + "@sentry/types": "6.14.0", + "@sentry/utils": "6.14.0", "tslib": "^1.9.3" }, "engines": { @@ -4970,12 +4970,12 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/minimal": { - "version": "6.13.3", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.13.3.tgz", - "integrity": "sha512-63MlYYRni3fs5Bh8XBAfVZ+ctDdWg0fapSTP1ydIC37fKvbE+5zhyUqwrEKBIiclEApg1VKX7bkKxVdu/vsFdw==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.14.0.tgz", + "integrity": "sha512-LLw2xwCxfnVToYZQQYqVb5ZGYW5nzZWXT/HlnHObwy1IJLTuGsHzFNxwfrTDVe9bsmAFGTo+2yHF+1bdYIfiCQ==", "dependencies": { - "@sentry/hub": "6.13.3", - "@sentry/types": "6.13.3", + "@sentry/hub": "6.14.0", + "@sentry/types": "6.14.0", "tslib": "^1.9.3" }, "engines": { @@ -4988,19 +4988,19 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/types": { - "version": "6.13.3", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.13.3.tgz", - "integrity": "sha512-Vrz5CdhaTRSvCQjSyIFIaV9PodjAVFkzJkTRxyY7P77RcegMsRSsG1yzlvCtA99zG9+e6MfoJOgbOCwuZids5A==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.14.0.tgz", + "integrity": "sha512-7t1YyKO69lLru2WZVGWik6f59qf8J75wSg41Sk5SySvsd7hjcxbj1PWz61/5ndRStvbZmabiVcn76nI2JKyD5A==", "engines": { "node": ">=6" } }, "node_modules/@sentry/utils": { - "version": "6.13.3", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.13.3.tgz", - "integrity": "sha512-zYFuFH3MaYtBZTeJ4Yajg7pDf0pM3MWs3+9k5my9Fd+eqNcl7dYQYJbT9gyC0HXK1QI4CAMNNlHNl4YXhF91ag==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.14.0.tgz", + "integrity": "sha512-uEpQ2sjvS2bSj/QNIRWbXFXgk2+rWmw+QXbvVCIiYB7LK7Y7kry6StTt42UumMHlVLFLgXVKlTa50XrIblr60g==", "dependencies": { - "@sentry/types": "6.13.3", + "@sentry/types": "6.14.0", "tslib": "^1.9.3" }, "engines": { @@ -15217,7 +15217,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -35419,13 +35418,13 @@ } }, "@sentry/browser": { - "version": "6.13.3", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.13.3.tgz", - "integrity": "sha512-jwlpsk2/u1cofvfYsjmqcnx50JJtf/T6HTgdW+ih8+rqWC5ABEZf4IiB/H+KAyjJ3wVzCOugMq5irL83XDCfqQ==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.14.0.tgz", + "integrity": "sha512-tdLTvgBwBuHhGG2iABdoRf5pUbS99xVapkHXKp9977slMGnUznMUrLUAVenitPx9fGoyYDZc8ukMfabAblfDyA==", "requires": { - "@sentry/core": "6.13.3", - "@sentry/types": "6.13.3", - "@sentry/utils": "6.13.3", + "@sentry/core": "6.14.0", + "@sentry/types": "6.14.0", + "@sentry/utils": "6.14.0", "tslib": "^1.9.3" }, "dependencies": { @@ -35437,14 +35436,14 @@ } }, "@sentry/core": { - "version": "6.13.3", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.13.3.tgz", - "integrity": "sha512-obm3SjgCk8A7nB37b2AU1eq1q7gMoJRrGMv9VRIyfcG0Wlz/5lJ9O3ohUk+YZaaVfZMxXn6hFtsBiOWmlv7IIA==", - "requires": { - "@sentry/hub": "6.13.3", - "@sentry/minimal": "6.13.3", - "@sentry/types": "6.13.3", - "@sentry/utils": "6.13.3", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.14.0.tgz", + "integrity": "sha512-GKs1A3yjcVB5ST4Mx9Eq4Z1yQaeq+AN1eJO1pnJhkOUnBXbmLGXvEp039W3Qn9iq9QuQmVRQz2C0+9GbrWmx9A==", + "requires": { + "@sentry/hub": "6.14.0", + "@sentry/minimal": "6.14.0", + "@sentry/types": "6.14.0", + "@sentry/utils": "6.14.0", "tslib": "^1.9.3" }, "dependencies": { @@ -35456,12 +35455,12 @@ } }, "@sentry/hub": { - "version": "6.13.3", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.13.3.tgz", - "integrity": "sha512-eYppBVqvhs5cvm33snW2sxfcw6G20/74RbBn+E4WDo15hozis89kU7ZCJDOPkXuag3v1h9igns/kM6PNBb41dw==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.14.0.tgz", + "integrity": "sha512-27ZN0YOxxy+2BV8VyelCejeeVJXy3Bs91bF6ICv3fekfL6cpyGswVMFltmSxraZOMxS4+Xz2HEgjlddgtd8yDQ==", "requires": { - "@sentry/types": "6.13.3", - "@sentry/utils": "6.13.3", + "@sentry/types": "6.14.0", + "@sentry/utils": "6.14.0", "tslib": "^1.9.3" }, "dependencies": { @@ -35473,12 +35472,12 @@ } }, "@sentry/minimal": { - "version": "6.13.3", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.13.3.tgz", - "integrity": "sha512-63MlYYRni3fs5Bh8XBAfVZ+ctDdWg0fapSTP1ydIC37fKvbE+5zhyUqwrEKBIiclEApg1VKX7bkKxVdu/vsFdw==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.14.0.tgz", + "integrity": "sha512-LLw2xwCxfnVToYZQQYqVb5ZGYW5nzZWXT/HlnHObwy1IJLTuGsHzFNxwfrTDVe9bsmAFGTo+2yHF+1bdYIfiCQ==", "requires": { - "@sentry/hub": "6.13.3", - "@sentry/types": "6.13.3", + "@sentry/hub": "6.14.0", + "@sentry/types": "6.14.0", "tslib": "^1.9.3" }, "dependencies": { @@ -35490,16 +35489,16 @@ } }, "@sentry/types": { - "version": "6.13.3", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.13.3.tgz", - "integrity": "sha512-Vrz5CdhaTRSvCQjSyIFIaV9PodjAVFkzJkTRxyY7P77RcegMsRSsG1yzlvCtA99zG9+e6MfoJOgbOCwuZids5A==" + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.14.0.tgz", + "integrity": "sha512-7t1YyKO69lLru2WZVGWik6f59qf8J75wSg41Sk5SySvsd7hjcxbj1PWz61/5ndRStvbZmabiVcn76nI2JKyD5A==" }, "@sentry/utils": { - "version": "6.13.3", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.13.3.tgz", - "integrity": "sha512-zYFuFH3MaYtBZTeJ4Yajg7pDf0pM3MWs3+9k5my9Fd+eqNcl7dYQYJbT9gyC0HXK1QI4CAMNNlHNl4YXhF91ag==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.14.0.tgz", + "integrity": "sha512-uEpQ2sjvS2bSj/QNIRWbXFXgk2+rWmw+QXbvVCIiYB7LK7Y7kry6StTt42UumMHlVLFLgXVKlTa50XrIblr60g==", "requires": { - "@sentry/types": "6.13.3", + "@sentry/types": "6.14.0", "tslib": "^1.9.3" }, "dependencies": { @@ -43593,7 +43592,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "optional": true }, "function-bind": { diff --git a/package.json b/package.json index 9fffb999ca..ab6162dfde 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "@fortawesome/free-regular-svg-icons": "^5.15.2", "@fortawesome/free-solid-svg-icons": "^5.15.4", "@ngneat/until-destroy": "^8.1.4", - "@sentry/browser": "^6.13.3", + "@sentry/browser": "^6.14.0", "angulartics2": "^10.1.0", "crypto-js": "^4.1.1", "deep-object-diff": "^1.1.0", From 4b47ec869cf6807e956e42c7da94faf7eaa3323e Mon Sep 17 00:00:00 2001 From: Snyk bot Date: Mon, 6 Dec 2021 18:36:51 +0000 Subject: [PATCH 12/21] refactor: upgrade @sentry/browser from 6.14.0 to 6.14.3 (#1060) --- package-lock.json | 126 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/package-lock.json b/package-lock.json index 22ab4bd414..e0b86c1bf0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,7 @@ "@fortawesome/free-regular-svg-icons": "^5.15.2", "@fortawesome/free-solid-svg-icons": "^5.15.4", "@ngneat/until-destroy": "^8.1.4", - "@sentry/browser": "^6.14.0", + "@sentry/browser": "^6.14.3", "angulartics2": "^10.1.0", "crypto-js": "^4.1.1", "deep-object-diff": "^1.1.0", @@ -4913,13 +4913,13 @@ "dev": true }, "node_modules/@sentry/browser": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.14.0.tgz", - "integrity": "sha512-tdLTvgBwBuHhGG2iABdoRf5pUbS99xVapkHXKp9977slMGnUznMUrLUAVenitPx9fGoyYDZc8ukMfabAblfDyA==", + "version": "6.14.3", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.14.3.tgz", + "integrity": "sha512-qp4K+XNYNWQxO1U6gvf6VgOMmI0JKCsvx1pKu7X4ZK7sGHmMgfwj7lukpxsqXZvDop8RxUI8/1KJ0azUsHlpAQ==", "dependencies": { - "@sentry/core": "6.14.0", - "@sentry/types": "6.14.0", - "@sentry/utils": "6.14.0", + "@sentry/core": "6.14.3", + "@sentry/types": "6.14.3", + "@sentry/utils": "6.14.3", "tslib": "^1.9.3" }, "engines": { @@ -4932,14 +4932,14 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/core": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.14.0.tgz", - "integrity": "sha512-GKs1A3yjcVB5ST4Mx9Eq4Z1yQaeq+AN1eJO1pnJhkOUnBXbmLGXvEp039W3Qn9iq9QuQmVRQz2C0+9GbrWmx9A==", - "dependencies": { - "@sentry/hub": "6.14.0", - "@sentry/minimal": "6.14.0", - "@sentry/types": "6.14.0", - "@sentry/utils": "6.14.0", + "version": "6.14.3", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.14.3.tgz", + "integrity": "sha512-3yHmYZzkXlOqPi/CGlNhb2RzXFvYAryBhrMJV26KJ9ULJF8r4OJ7TcWlupDooGk6Knmq8GQML58OApUvYi8IKg==", + "dependencies": { + "@sentry/hub": "6.14.3", + "@sentry/minimal": "6.14.3", + "@sentry/types": "6.14.3", + "@sentry/utils": "6.14.3", "tslib": "^1.9.3" }, "engines": { @@ -4952,12 +4952,12 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/hub": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.14.0.tgz", - "integrity": "sha512-27ZN0YOxxy+2BV8VyelCejeeVJXy3Bs91bF6ICv3fekfL6cpyGswVMFltmSxraZOMxS4+Xz2HEgjlddgtd8yDQ==", + "version": "6.14.3", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.14.3.tgz", + "integrity": "sha512-ZRWLHcAcv4oZAbpSwvCkXlaa1rVFDxcb9lxo5/5v5n6qJq2IG5Z+bXuT2DZlIHQmuCuqRnFSwuBjmBXY7OTHaw==", "dependencies": { - "@sentry/types": "6.14.0", - "@sentry/utils": "6.14.0", + "@sentry/types": "6.14.3", + "@sentry/utils": "6.14.3", "tslib": "^1.9.3" }, "engines": { @@ -4970,12 +4970,12 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/minimal": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.14.0.tgz", - "integrity": "sha512-LLw2xwCxfnVToYZQQYqVb5ZGYW5nzZWXT/HlnHObwy1IJLTuGsHzFNxwfrTDVe9bsmAFGTo+2yHF+1bdYIfiCQ==", + "version": "6.14.3", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.14.3.tgz", + "integrity": "sha512-2KNOJuhBpMICoOgdxX56UcO9vGdxCw5mNGYdWvJdKrMwRQr7mC+Fc9lTuTbrYTj6zkfklj2lbdDc3j44Rg787A==", "dependencies": { - "@sentry/hub": "6.14.0", - "@sentry/types": "6.14.0", + "@sentry/hub": "6.14.3", + "@sentry/types": "6.14.3", "tslib": "^1.9.3" }, "engines": { @@ -4988,19 +4988,19 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/types": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.14.0.tgz", - "integrity": "sha512-7t1YyKO69lLru2WZVGWik6f59qf8J75wSg41Sk5SySvsd7hjcxbj1PWz61/5ndRStvbZmabiVcn76nI2JKyD5A==", + "version": "6.14.3", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.14.3.tgz", + "integrity": "sha512-GuyqvjQ/N0hIgAjGD1Rn0aQ8kpLBBsImk+Aoh7YFhnvXRhCNkp9N8BuXTfC/uMdMshcWa1OFik/udyjdQM3EJA==", "engines": { "node": ">=6" } }, "node_modules/@sentry/utils": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.14.0.tgz", - "integrity": "sha512-uEpQ2sjvS2bSj/QNIRWbXFXgk2+rWmw+QXbvVCIiYB7LK7Y7kry6StTt42UumMHlVLFLgXVKlTa50XrIblr60g==", + "version": "6.14.3", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.14.3.tgz", + "integrity": "sha512-jsCnclEsR2sV9aHMuaLA5gvxSa0xV4Sc6IJCJ81NTTdb/A5fFbteFBbhuISGF9YoFW1pwbpjuTA6+efXwvLwNQ==", "dependencies": { - "@sentry/types": "6.14.0", + "@sentry/types": "6.14.3", "tslib": "^1.9.3" }, "engines": { @@ -35418,13 +35418,13 @@ } }, "@sentry/browser": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.14.0.tgz", - "integrity": "sha512-tdLTvgBwBuHhGG2iABdoRf5pUbS99xVapkHXKp9977slMGnUznMUrLUAVenitPx9fGoyYDZc8ukMfabAblfDyA==", + "version": "6.14.3", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.14.3.tgz", + "integrity": "sha512-qp4K+XNYNWQxO1U6gvf6VgOMmI0JKCsvx1pKu7X4ZK7sGHmMgfwj7lukpxsqXZvDop8RxUI8/1KJ0azUsHlpAQ==", "requires": { - "@sentry/core": "6.14.0", - "@sentry/types": "6.14.0", - "@sentry/utils": "6.14.0", + "@sentry/core": "6.14.3", + "@sentry/types": "6.14.3", + "@sentry/utils": "6.14.3", "tslib": "^1.9.3" }, "dependencies": { @@ -35436,14 +35436,14 @@ } }, "@sentry/core": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.14.0.tgz", - "integrity": "sha512-GKs1A3yjcVB5ST4Mx9Eq4Z1yQaeq+AN1eJO1pnJhkOUnBXbmLGXvEp039W3Qn9iq9QuQmVRQz2C0+9GbrWmx9A==", - "requires": { - "@sentry/hub": "6.14.0", - "@sentry/minimal": "6.14.0", - "@sentry/types": "6.14.0", - "@sentry/utils": "6.14.0", + "version": "6.14.3", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.14.3.tgz", + "integrity": "sha512-3yHmYZzkXlOqPi/CGlNhb2RzXFvYAryBhrMJV26KJ9ULJF8r4OJ7TcWlupDooGk6Knmq8GQML58OApUvYi8IKg==", + "requires": { + "@sentry/hub": "6.14.3", + "@sentry/minimal": "6.14.3", + "@sentry/types": "6.14.3", + "@sentry/utils": "6.14.3", "tslib": "^1.9.3" }, "dependencies": { @@ -35455,12 +35455,12 @@ } }, "@sentry/hub": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.14.0.tgz", - "integrity": "sha512-27ZN0YOxxy+2BV8VyelCejeeVJXy3Bs91bF6ICv3fekfL6cpyGswVMFltmSxraZOMxS4+Xz2HEgjlddgtd8yDQ==", + "version": "6.14.3", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.14.3.tgz", + "integrity": "sha512-ZRWLHcAcv4oZAbpSwvCkXlaa1rVFDxcb9lxo5/5v5n6qJq2IG5Z+bXuT2DZlIHQmuCuqRnFSwuBjmBXY7OTHaw==", "requires": { - "@sentry/types": "6.14.0", - "@sentry/utils": "6.14.0", + "@sentry/types": "6.14.3", + "@sentry/utils": "6.14.3", "tslib": "^1.9.3" }, "dependencies": { @@ -35472,12 +35472,12 @@ } }, "@sentry/minimal": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.14.0.tgz", - "integrity": "sha512-LLw2xwCxfnVToYZQQYqVb5ZGYW5nzZWXT/HlnHObwy1IJLTuGsHzFNxwfrTDVe9bsmAFGTo+2yHF+1bdYIfiCQ==", + "version": "6.14.3", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.14.3.tgz", + "integrity": "sha512-2KNOJuhBpMICoOgdxX56UcO9vGdxCw5mNGYdWvJdKrMwRQr7mC+Fc9lTuTbrYTj6zkfklj2lbdDc3j44Rg787A==", "requires": { - "@sentry/hub": "6.14.0", - "@sentry/types": "6.14.0", + "@sentry/hub": "6.14.3", + "@sentry/types": "6.14.3", "tslib": "^1.9.3" }, "dependencies": { @@ -35489,16 +35489,16 @@ } }, "@sentry/types": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.14.0.tgz", - "integrity": "sha512-7t1YyKO69lLru2WZVGWik6f59qf8J75wSg41Sk5SySvsd7hjcxbj1PWz61/5ndRStvbZmabiVcn76nI2JKyD5A==" + "version": "6.14.3", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.14.3.tgz", + "integrity": "sha512-GuyqvjQ/N0hIgAjGD1Rn0aQ8kpLBBsImk+Aoh7YFhnvXRhCNkp9N8BuXTfC/uMdMshcWa1OFik/udyjdQM3EJA==" }, "@sentry/utils": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.14.0.tgz", - "integrity": "sha512-uEpQ2sjvS2bSj/QNIRWbXFXgk2+rWmw+QXbvVCIiYB7LK7Y7kry6StTt42UumMHlVLFLgXVKlTa50XrIblr60g==", + "version": "6.14.3", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.14.3.tgz", + "integrity": "sha512-jsCnclEsR2sV9aHMuaLA5gvxSa0xV4Sc6IJCJ81NTTdb/A5fFbteFBbhuISGF9YoFW1pwbpjuTA6+efXwvLwNQ==", "requires": { - "@sentry/types": "6.14.0", + "@sentry/types": "6.14.3", "tslib": "^1.9.3" }, "dependencies": { diff --git a/package.json b/package.json index ab6162dfde..f3e535abc3 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "@fortawesome/free-regular-svg-icons": "^5.15.2", "@fortawesome/free-solid-svg-icons": "^5.15.4", "@ngneat/until-destroy": "^8.1.4", - "@sentry/browser": "^6.14.0", + "@sentry/browser": "^6.14.3", "angulartics2": "^10.1.0", "crypto-js": "^4.1.1", "deep-object-diff": "^1.1.0", From c88eba11564e4f268815153b3cdbb576c03ddc9e Mon Sep 17 00:00:00 2001 From: ttoulouse2 <95472290+ttoulouse2@users.noreply.github.com> Date: Mon, 6 Dec 2021 21:02:32 +0100 Subject: [PATCH 13/21] feat: added french langauge --- angular.json | 6 +- build/default.conf | 5 + .../core/translation/translation.service.ts | 1 + src/assets/help/help.fr.md | 8 + src/locale/messages.de.xlf | 324 +- src/locale/messages.fr.xlf | 5181 +++++++++++++++++ src/locale/messages.xlf | 396 +- xliffmerge.json | 3 +- 8 files changed, 5569 insertions(+), 355 deletions(-) create mode 100644 src/assets/help/help.fr.md create mode 100644 src/locale/messages.fr.xlf diff --git a/angular.json b/angular.json index 1a0ab839e6..8bb51d2f6e 100644 --- a/angular.json +++ b/angular.json @@ -10,7 +10,8 @@ "i18n": { "sourceLocale": "en-US", "locales": { - "de": "src/locale/messages.de.xlf" + "de": "src/locale/messages.de.xlf", + "fr": "src/locale/messages.fr.xlf" } }, "architect": { @@ -65,7 +66,8 @@ "localized": { "localize": [ "de", - "en-US" + "en-US", + "fr" ] } } diff --git a/build/default.conf b/build/default.conf index d38723fd83..5309b33f0b 100644 --- a/build/default.conf +++ b/build/default.conf @@ -19,6 +19,11 @@ server { try_files $uri $uri/ /de/index.html; } + location /fr { + index index.html index.htm; + try_files $uri $uri/ /fr/index.html; + } + location /en { index index.html index.htm; try_files $uri $uri/ /en-US/index.html; diff --git a/src/app/core/translation/translation.service.ts b/src/app/core/translation/translation.service.ts index eab7decf84..12799625ef 100644 --- a/src/app/core/translation/translation.service.ts +++ b/src/app/core/translation/translation.service.ts @@ -21,6 +21,7 @@ export class TranslationService { this.availableLocales = [ { locale: "de", regionCode: "de" }, { locale: "en-US", regionCode: "us" }, + { locale: "fr", regionCode: "fr" }, ]; } diff --git a/src/assets/help/help.fr.md b/src/assets/help/help.fr.md new file mode 100644 index 0000000000..d58b14cf1f --- /dev/null +++ b/src/assets/help/help.fr.md @@ -0,0 +1,8 @@ +# Comment pouvons-nous vous aider? +Vous avez une question ou des problèmes techniques? Contactez-nous: + +- [support@aam-digital.com]() +- [WhatsApp](https://wa.me/491776181407) +- [Telegram](https://telegram.me/SebastianLeidig) + +_Nous sommes heureux d'entendre votre retour et de vous aider!_ diff --git a/src/locale/messages.de.xlf b/src/locale/messages.de.xlf index 7a0f3c2cab..58aa1a48b5 100644 --- a/src/locale/messages.de.xlf +++ b/src/locale/messages.de.xlf @@ -82,7 +82,7 @@ - Record Attendance: + Record Attendance: Anwesenheiten aufnehmen: src/app/child-dev-project/attendance/add-day-attendance/add-day-attendance.component.html @@ -287,7 +287,7 @@ Abort confirmation text - attended events + attended events haben an events teilgenommen src/app/child-dev-project/attendance/attendance-block/attendance-block.component.html @@ -298,7 +298,7 @@ Attended Tooltip - (excluding events excused or unknown) + (excluding events excused or unknown) (ausgenommene Events ; entschuldigt oder unbekannt) How many events were excluded Attended Tooltip @@ -319,7 +319,7 @@ - All excused (out of ) Alle entschuldigt (von ) @@ -343,7 +343,7 @@ - attended (of attended (of ) haben teilgenommen (von ) @@ -352,7 +352,7 @@ - without recorded status ohne aufgenommenen Status @@ -407,8 +407,7 @@ (focusedChild ? entity?.getAttendancePercentage(focusedChild) : entity?.getAttendancePercentageAverage() - ) | percent: "1.0-0" - }}"/> + ) | percent: "1.0-0""/> Anwesenheit: The material which has been borrowed src/app/child-dev-project/educational-material/model/educational-material.ts - 31 + 35 @@ -603,17 +602,17 @@ The amount of the material which has been borrowed src/app/child-dev-project/educational-material/model/educational-material.ts - 37 + 42 Description Beschreibung + An additional description for the borrowed material src/app/child-dev-project/educational-material/model/educational-material.ts - 41 + 47 - An additional description for the borrowed material pencil @@ -919,7 +918,7 @@ mat-cell *matCellDef="let childNoteInfo" class="dashboard-table-additional-info-cell" - >"/>> days + >"/>> days - Currently attending class at + Currently attending class at Besucht derzeit die Klasse der Schule src/app/child-dev-project/previous-schools/previous-schools.component.html @@ -1814,22 +1813,13 @@ 87,93 - - Import (.csv) - Importieren (.csv) - Import database button - - src/app/core/admin/admin/admin.component.html - 95 - - Application Configuration Programm-Konfiguration Application configuration header src/app/core/admin/admin/admin.component.html - 107 + 95 @@ -1838,7 +1828,7 @@ Download configuration button src/app/core/admin/admin/admin.component.html - 114 + 102 @@ -1847,7 +1837,7 @@ Upload configuration button src/app/core/admin/admin/admin.component.html - 122 + 110 @@ -1856,7 +1846,7 @@ App-Config header src/app/core/admin/admin/admin.component.html - 134 + 122 @@ -1865,7 +1855,7 @@ Debug PouchDB header src/app/core/admin/admin/admin.component.html - 139,142 + 127 @@ -1874,7 +1864,7 @@ Log button src/app/core/admin/admin/admin.component.html - 142 + 130 @@ -1883,7 +1873,7 @@ Empty database button src/app/core/admin/admin/admin.component.html - 151,159 + 139 @@ -1892,7 +1882,7 @@ Alert log header src/app/core/admin/admin/admin.component.html - 157 + 145 @@ -1900,7 +1890,7 @@ Komplette Datenbank überschreiben? src/app/core/admin/admin/admin.component.ts - 135 + 126 @@ -1910,7 +1900,7 @@ Sind Sie sicher, dass Sie dieses Backup übernehmen wollen? Dies wird existierende Einträge löschen und durch Einträge aus dem Backup ersetzen. src/app/core/admin/admin/admin.component.ts - 136 + 127 @@ -1918,39 +1908,49 @@ Backup wiederhergestellt src/app/core/admin/admin/admin.component.ts - 150 + 141 Import new data? Neue Daten importieren? - src/app/core/admin/admin/admin.component.ts - 175 + src/app/features/data-import/data-import.service.ts + 49 Are you sure you want to import this file? This will add or update records from the loaded file. Existing records with same "_id" in the database will be overwritten! Soll diese Datei wirklich importiert werden? Das wird alle Aufzeichnungen bla bla - src/app/core/admin/admin/admin.component.ts - 176 + src/app/features/data-import/data-import.service.ts + 50 Import completed? Import fertiggestellt? - src/app/core/admin/admin/admin.component.ts - 189 + src/app/features/data-import/data-import.service.ts + 63 + + + + Import (.csv) + + Importieren (.csv) + + src/app/features/data-import/data-import/data-import.component.html + 6,7 + Import database button Empty complete database? Komplette Datenbank löschen? src/app/core/admin/admin/admin.component.ts - 212 + 169 @@ -1958,7 +1958,7 @@ Soll wirklich die komplette Datenbank gelöscht werden? Dadurch werden alle Aufzeichnungen in der Datenbank gelöscht! src/app/core/admin/admin/admin.component.ts - 213 + 170 @@ -1966,7 +1966,7 @@ Import fertig src/app/core/admin/admin/admin.component.ts - 226 + 183 @@ -2074,7 +2074,7 @@ src/app/core/config/config-fix.ts - 653 + 654 @@ -2351,7 +2351,7 @@ src/app/core/config/config-fix.ts - 572 + 573 @@ -2496,7 +2496,7 @@ src/app/core/config/config-fix.ts - 581 + 582 @@ -2523,7 +2523,7 @@ Panel title src/app/core/config/config-fix.ts - 540 + 541 @@ -2532,7 +2532,7 @@ Title inside a panel src/app/core/config/config-fix.ts - 543 + 544 @@ -2541,7 +2541,7 @@ Title inside a panel src/app/core/config/config-fix.ts - 557 + 558 @@ -2550,7 +2550,7 @@ Panel title src/app/core/config/config-fix.ts - 563 + 564 @@ -2559,7 +2559,7 @@ Title inside a panel src/app/core/config/config-fix.ts - 594 + 595 @@ -2568,7 +2568,7 @@ Panel title src/app/core/config/config-fix.ts - 600 + 601 @@ -2577,7 +2577,7 @@ Panel title src/app/core/config/config-fix.ts - 609 + 610 @@ -2586,7 +2586,7 @@ Child status src/app/child-dev-project/children/demo-data-generators/demo-child-generator.service.ts - 58 + 63 src/app/child-dev-project/children/demo-data-generators/fixtures/dropout-types.ts @@ -2594,7 +2594,7 @@ src/app/core/config/config-fix.ts - 631 + 632 @@ -2603,7 +2603,7 @@ Panel title src/app/core/config/config-fix.ts - 672 + 673 @@ -2612,7 +2612,7 @@ Panel title src/app/core/config/config-fix.ts - 701 + 702 @@ -2621,7 +2621,7 @@ Name of a report src/app/core/config/config-fix.ts - 717 + 718 @@ -2630,7 +2630,7 @@ Label of report query src/app/core/config/config-fix.ts - 721 + 722 @@ -2639,7 +2639,7 @@ Label of report query src/app/core/config/config-fix.ts - 724 + 725 @@ -2648,7 +2648,7 @@ Label of report query src/app/core/config/config-fix.ts - 728 + 729 @@ -2657,7 +2657,7 @@ Label for report query src/app/core/config/config-fix.ts - 735 + 736 @@ -2666,7 +2666,7 @@ Label for report query src/app/core/config/config-fix.ts - 738 + 739 @@ -2675,7 +2675,7 @@ Label for report query src/app/core/config/config-fix.ts - 742 + 743 @@ -2684,7 +2684,7 @@ Label for report query src/app/core/config/config-fix.ts - 747 + 748 @@ -2693,7 +2693,7 @@ Label for report query src/app/core/config/config-fix.ts - 750 + 751 @@ -2702,7 +2702,7 @@ Label for report query src/app/core/config/config-fix.ts - 754 + 755 @@ -2711,7 +2711,7 @@ Label for report query src/app/core/config/config-fix.ts - 760 + 761 @@ -2720,7 +2720,7 @@ Label for report query src/app/core/config/config-fix.ts - 765 + 766 @@ -2729,7 +2729,7 @@ Label for report query src/app/core/config/config-fix.ts - 768 + 769 @@ -2738,7 +2738,7 @@ Label for report query src/app/core/config/config-fix.ts - 772 + 773 @@ -2747,7 +2747,7 @@ Name of a report src/app/core/config/config-fix.ts - 782 + 783 @@ -2756,7 +2756,7 @@ Name of a report src/app/core/config/config-fix.ts - 799 + 800 @@ -2765,7 +2765,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 834 + 835 @@ -2774,7 +2774,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 855 + 856 @@ -2783,16 +2783,20 @@ Label for the language of a school src/app/core/config/config-fix.ts - 882 + 883 Phone Number Telefonnummer - Label for the phone number of a school + Label for the phone number of a child + + src/app/child-dev-project/children/model/child.ts + 104 + src/app/core/config/config-fix.ts - 896 + 897 @@ -2801,7 +2805,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 922 + 923 @@ -2810,7 +2814,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 923 + 924 @@ -2819,7 +2823,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 931 + 932 @@ -2828,7 +2832,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 932 + 933 @@ -2837,7 +2841,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 940 + 941 @@ -2846,7 +2850,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 941 + 942 @@ -2855,7 +2859,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 949 + 950 @@ -2864,7 +2868,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 950 + 951 @@ -2873,7 +2877,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 958 + 959 @@ -2882,7 +2886,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 959 + 960 @@ -2891,7 +2895,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 967 + 968 @@ -2900,7 +2904,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 968 + 969 @@ -2909,7 +2913,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 976 + 977 @@ -2918,7 +2922,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 977 + 978 @@ -2927,7 +2931,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 985 + 986 @@ -2936,7 +2940,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 986 + 987 @@ -2945,7 +2949,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 994 + 995 @@ -2954,7 +2958,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 995 + 996 @@ -2963,7 +2967,7 @@ Label for a child attribute src/app/core/config/config-fix.ts - 1003 + 1004 @@ -2972,7 +2976,7 @@ Description for a child attribute src/app/core/config/config-fix.ts - 1004 + 1005 @@ -3021,11 +3025,11 @@ Label for date of the ASER results src/app/child-dev-project/aser/model/aser.ts - 46 + 53 src/app/child-dev-project/educational-material/model/educational-material.ts - 27 + 31 src/app/child-dev-project/health-checkup/model/health-check.ts @@ -3046,7 +3050,7 @@ Label of the Math ASER result src/app/child-dev-project/aser/model/aser.ts - 68 + 75 @@ -3055,7 +3059,7 @@ Label of the English ASER result src/app/child-dev-project/aser/model/aser.ts - 62 + 69 @@ -3064,7 +3068,7 @@ Label of the Hindi ASER result src/app/child-dev-project/aser/model/aser.ts - 50 + 57 @@ -3073,7 +3077,7 @@ Label of the Bengali ASER result src/app/child-dev-project/aser/model/aser.ts - 56 + 63 @@ -3094,7 +3098,7 @@ src/app/core/config/config-fix.ts - 868 + 869 @@ -3131,11 +3135,11 @@ src/app/core/entity-components/entity-list/filter-generator.service.ts - 138 + 139 src/app/core/entity-components/entity-list/filter-generator.service.ts - 170 + 168 src/app/core/filter/filter-selection/filter-selection.ts @@ -3148,97 +3152,97 @@ Label for the remarks of a ASER result src/app/child-dev-project/aser/model/aser.ts - 74 + 81 src/app/core/config/config-fix.ts - 910 + 911 Nothing Nichts + Label math level src/app/child-dev-project/aser/model/mathLevels.ts - 10 + 12 src/app/child-dev-project/aser/model/readingLevels.ts - 10 + 12 - Label math level Numbers 1-9 Zahlen 1-9 + Label math level src/app/child-dev-project/aser/model/mathLevels.ts - 14 + 16 - Label math level Numbers 10-99 Zahlen 10-99 + Label math level src/app/child-dev-project/aser/model/mathLevels.ts - 18 + 20 - Label math level Subtraction Subtraktion + Label math level src/app/child-dev-project/aser/model/mathLevels.ts - 22 + 24 - Label math level Division Division + Label math level src/app/child-dev-project/aser/model/mathLevels.ts - 26 + 28 - Label math level Read Letters Kann Buchstaben lsen + Label reading level src/app/child-dev-project/aser/model/readingLevels.ts - 14 + 16 - Label reading level Read Words Kann Wörter lesen + Label reading level src/app/child-dev-project/aser/model/readingLevels.ts - 18 + 20 - Label reading level Read Sentence Kann Sätze lesen + Label reading level src/app/child-dev-project/aser/model/readingLevels.ts - 22 + 24 - Label reading level Read Paragraph Kann Absätze lesen + Label reading level src/app/child-dev-project/aser/model/readingLevels.ts - 26 + 28 - Label reading level PN @@ -3273,7 +3277,7 @@ Label for the mother tongue of a child src/app/core/config/config-fix.ts - 848 + 849 @@ -3291,7 +3295,7 @@ Label for the religion of a child src/app/core/config/config-fix.ts - 841 + 842 @@ -3345,11 +3349,11 @@ Label for the address of a child src/app/core/config/config-fix.ts - 827 + 828 src/app/core/config/config-fix.ts - 889 + 890 @@ -3362,7 +3366,7 @@ src/app/core/config/config-fix.ts - 875 + 876 @@ -3371,7 +3375,7 @@ Label for the timing of a school src/app/core/config/config-fix.ts - 903 + 904 @@ -3540,7 +3544,7 @@ Label gender - Total: + Total: Insgesamt: @@ -3673,15 +3677,15 @@ src/app/core/config/config-fix.ts - 687 + 688 src/app/core/config/config-fix.ts - 792 + 793 src/app/core/config/config-fix.ts - 809 + 810 @@ -3703,14 +3707,14 @@ Label for the assigned user(s) of a recurring activity - class + class Klasse + e.g. 'class 8' + The class a child is attending src/app/child-dev-project/children/child-block/child-block.component.html - 39,41 + 36 - e.g. 'class 8' - The class a child is attending Students with unhealthy BMI @@ -3842,11 +3846,11 @@ src/app/core/config/config-fix.ts - 787 + 788 src/app/core/config/config-fix.ts - 804 + 805 @@ -4180,7 +4184,7 @@ Generic back button - Adding new + Adding new Neuer Eintrag src/app/core/entity-components/entity-details/entity-details.component.html @@ -4290,7 +4294,7 @@ - (Showing entries) + (Showing entries) ( Einträge vorhanden) src/app/core/entity-components/entity-list/entity-list.component.html @@ -4368,7 +4372,7 @@ Placeholder for input to add entities src/app/core/entity-components/entity-utils/dynamic-form-components/edit-entity-array/edit-entity-array.component.ts - 19 + 16 @@ -4388,6 +4392,10 @@ This field is required Dieses Feld ist erforderlich Error message for any input + + src/app/core/configurable-enum/edit-configurable-enum/edit-configurable-enum.component.html + 11 + src/app/core/entity-components/entity-utils/dynamic-form-components/edit-number/edit-number.component.html 13 @@ -4435,24 +4443,24 @@ Select auswählen + context Select User + Placeholder for input to set an entity src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.ts - 49 + 48 - context Select User - Placeholder for input to set an entity loading... lädt... + A placeholder for the input element when select options are not loaded yet src/app/core/entity-components/entity-utils/entity-select/entity-select.component.ts - 30 + 29 - A placeholder for the input element when select options are not loaded yet - in total + in total insgesamt @@ -4545,17 +4553,17 @@ Eine neuere Version der App ist verfügbar! src/app/core/latest-changes/update-manager.service.ts - 82,81 + 104 Update Update + Action that a user can update the app with src/app/core/latest-changes/update-manager.service.ts - 83,81 + 105 - Action that a user can update the app with Your account does not have the required permission for this action. @@ -4734,7 +4742,7 @@ Search label - Insert at least characters + Insert at least characters Mindestens Buchstaben eingeben src/app/core/ui/search/search.component.html @@ -4890,7 +4898,7 @@ - Failed to change password: Please try again. If the problem persists contact Aam Digital support. + Failed to change password: Please try again. If the problem persists contact Aam Digital support. Passwort konnte nicht geändert werden: Please try again. If the problem persists contact Aam Digital support. src/app/core/user/user-account/user-account.component.html diff --git a/src/locale/messages.fr.xlf b/src/locale/messages.fr.xlf new file mode 100644 index 0000000000..8c135d0b7a --- /dev/null +++ b/src/locale/messages.fr.xlf @@ -0,0 +1,5181 @@ + + + + + + Date + Date + + src/app/child-dev-project/aser/model/aser.ts + 53 + + + src/app/child-dev-project/educational-material/model/educational-material.ts + 31 + + + src/app/child-dev-project/health-checkup/model/health-check.ts + 30 + + + src/app/child-dev-project/notes/model/note.ts + 72 + + + src/app/features/historical-data/historical-entity-data.ts + 11 + + Label for date of the ASER results + + + Hindi + Hindi + + src/app/child-dev-project/aser/model/aser.ts + 57 + + Label of the Hindi ASER result + + + Bengali + Bengali + + src/app/child-dev-project/aser/model/aser.ts + 63 + + Label of the Bengali ASER result + + + English + Anglais + + src/app/child-dev-project/aser/model/aser.ts + 69 + + Label of the English ASER result + + + Math + Mathématiques + + src/app/child-dev-project/aser/model/aser.ts + 75 + + Label of the Math ASER result + + + Remarks + Observations + + src/app/child-dev-project/aser/model/aser.ts + 81 + + + src/app/core/config/config-fix.ts + 911 + + Label for the remarks of a ASER result + + + Nothing + Aucune compétence + + src/app/child-dev-project/aser/model/mathLevels.ts + 12 + + + src/app/child-dev-project/aser/model/readingLevels.ts + 12 + + Label math level + + + Numbers 1-9 + Chiffres de 1 à 9 + + src/app/child-dev-project/aser/model/mathLevels.ts + 16 + + Label math level + + + Numbers 10-99 + Chiffres de 10 à 99 + + src/app/child-dev-project/aser/model/mathLevels.ts + 20 + + Label math level + + + Subtraction + Soustraction + + src/app/child-dev-project/aser/model/mathLevels.ts + 24 + + Label math level + + + Division + Division + + src/app/child-dev-project/aser/model/mathLevels.ts + 28 + + Label math level + + + Read Letters + Lecture de lettres uniques + + src/app/child-dev-project/aser/model/readingLevels.ts + 16 + + Label reading level + + + Read Words + Lecture de mots + + src/app/child-dev-project/aser/model/readingLevels.ts + 20 + + Label reading level + + + Read Sentence + Lecture de phrases + + src/app/child-dev-project/aser/model/readingLevels.ts + 24 + + Label reading level + + + Read Paragraph + Lecture de paragraphes + + src/app/child-dev-project/aser/model/readingLevels.ts + 28 + + Label reading level + + + Activate to also show entries for the activity that do not have any events with actual participation of this person + Activer pour afficher également les données de l'activité qui n'ont pas d'événements comportant la participation effective de cette personne. + + src/app/child-dev-project/attendance/activity-attendance-section/activity-attendance-section.component.html + 27,37 + + Tooltip that will appear when hovered over the + show-unrelated button + Show unrelated tooltip + + + Also show unrelated + Afficher les éléments non liés + + src/app/child-dev-project/attendance/activity-attendance-section/activity-attendance-section.component.html + 29,34 + + show unrelated attendance-entries for an activity that are not + linked to the child of interest + slider + + + Load all records + Charger toutes les données + + src/app/child-dev-project/attendance/activity-attendance-section/activity-attendance-section.component.html + 39,42 + + load all records, not only the ones from the last 6 months + load-all button + + + Month + Mois + + src/app/child-dev-project/attendance/activity-attendance-section/activity-attendance-section.component.ts + 30,28 + + The month something took place + + + Present + Présents + + src/app/child-dev-project/attendance/activity-attendance-section/activity-attendance-section.component.ts + 36,34 + + + src/app/core/config/default-config/default-attendance-status-types.ts + 10 + + How many children are present at a meeting + + + Events + Evènements + + src/app/child-dev-project/attendance/activity-attendance-section/activity-attendance-section.component.ts + 45,43 + + + src/app/core/config/config-fix.ts + 788 + + + src/app/core/config/config-fix.ts + 805 + + Events of an attendance + + + Attended + Présents + + src/app/child-dev-project/attendance/activity-attendance-section/activity-attendance-section.component.ts + 51,49 + + + src/app/child-dev-project/attendance/attendance-details/attendance-details.component.ts + 29 + + Percentage of people that attended an event + + + one-time event + Evènement unique + + src/app/child-dev-project/attendance/activity-card/activity-card.component.html + 14 + + Informs the user that this is a one-time event + One-time event + + + recurring activity - record for one day + activité récurrente - enregistrer pour la journeé + + src/app/child-dev-project/attendance/activity-card/activity-card.component.html + 23 + + Informs the user that this is a recurring event + Recurring-event + + + {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 + 31 + + + + + + + src/app/child-dev-project/attendance/activity-card/activity-card.component.html + 31,32 + + Amount of participants of an event + Participants + + + Record Attendance: + Faire l'appel: + + src/app/child-dev-project/attendance/add-day-attendance/add-day-attendance.component.html + 8,11 + + Title when recording the attendance at a particular + stage (e.g. selecting the event, recording it) + Record Attendance + + + Select Event + Sélectionner l'évènement + + src/app/child-dev-project/attendance/add-day-attendance/add-day-attendance.component.ts + 19,18 + + One of the stages while recording child-attendances + + + Record Attendance + Faire l'appel + + src/app/child-dev-project/attendance/add-day-attendance/add-day-attendance.component.ts + 20,18 + + One of the stages while recording child-attendances + + + Record event for + Faire l'appel pour le... + + src/app/child-dev-project/attendance/add-day-attendance/roll-call-setup/roll-call-setup.component.html + 9,14 + + Record an event for a particular date that is to be + inputted + Event-Record label + + + Show more + Plus d'évènements + + src/app/child-dev-project/attendance/add-day-attendance/roll-call-setup/roll-call-setup.component.html + 65,70 + + Show more events to record the attendance + Show more-button + + + My event is not listed ... + Mon évènement n'apparaît pas ... + + src/app/child-dev-project/attendance/add-day-attendance/roll-call-setup/roll-call-setup.component.html + 75,80 + + Allows to create a new event + Not listed + + + Record Attendance + Faire l'appel + + src/app/child-dev-project/attendance/add-day-attendance/roll-call-setup/roll-call-setup.component.html + 93,98 + + Start recording the attendance of a child at + an event + Record Attendance button + + + Attendance completed. + Appel effectué. + + src/app/child-dev-project/attendance/add-day-attendance/roll-call/roll-call.component.html + 46,54 + + shows when the user has registered the attendance of + all children + Attendance completed + + + Save & Exit + Sauvegarder & quitter + + src/app/child-dev-project/attendance/add-day-attendance/roll-call/roll-call.component.html + 61,67 + + Button to finish roll call early + Save-Button + + + Back + Retour + + src/app/child-dev-project/attendance/add-day-attendance/roll-call/roll-call.component.html + 73,79 + + Button to go to the previous child + Back-button + + + Skip + Sauter + + src/app/child-dev-project/attendance/add-day-attendance/roll-call/roll-call.component.html + 85,90 + + Button to skip a step in the roll call + Skip-Button + + + Finish + Terminer + + src/app/child-dev-project/attendance/add-day-attendance/roll-call/roll-call.component.html + 94,97 + + Finish entering the attendance of a child + + + Abort + Abandonner + + src/app/child-dev-project/attendance/add-day-attendance/roll-call/roll-call.component.html + 97,101 + + Abort entering the attendance of a child + + + Save & Exit + Sauvegarder & quitter + + src/app/child-dev-project/attendance/add-day-attendance/roll-call/roll-call.component.ts + 130,129 + + Save & Next confirmation title + + + Are you sure you want to save, exit and skip the remaining participants? + Êtes-vous sûr de vouloir sauvegarder, quitter et sauter les participants restants? + + src/app/child-dev-project/attendance/add-day-attendance/roll-call/roll-call.component.ts + 131,129 + + Save & Exit confirmation text + + + Abort + Abandonner + + src/app/child-dev-project/attendance/add-day-attendance/roll-call/roll-call.component.ts + 147,146 + + Abort confirmation title + + + Are you sure you want to exit and discard all recordings? + Êtes-vous sûr de vouloir quitter et supprimer tous les enregistrements? + + src/app/child-dev-project/attendance/add-day-attendance/roll-call/roll-call.component.ts + 148,146 + + Abort confirmation text + + + attended events + présent à évènement(s) + + src/app/child-dev-project/attendance/attendance-block/attendance-block.component.html + 32,34 + + How many attendees were present / how many attendees + were absent + Attended Tooltip + + + (excluding events excused or unknown) + (à l'exception de évènement(s) excusé ou sans information) + + src/app/child-dev-project/attendance/attendance-block/attendance-block.component.html + 40,42 + + How many events were excluded + Attended Tooltip + + + Remarks + Observations + + src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html + 35,38 + + Placeholder if no remarks for the attendance of a child are + given + Remarks + + + All excused (out of ) + Excusé pour tous les évènements (out of ) + + src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html + 50,54 + + 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 + 52,55 + + + src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html + 58,62 + + + + attended (of ) + présents (sur ) + + src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html + 55,60 + + + + without recorded status + sans statut enregistré + + src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html + 65,69 + + 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,69 + + + + Details + Détails + + src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html + 79,86 + + Allows the user to see details of an event that took + place at a particular day + Show Details Button + + + no events on this date + Aucun évènement à la date sélectionnée + + src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html + 89,95 + + Informs the user that there are no events at a particular date + No Events + + + Add new event + Ajouter un évènement + + src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html + 100,104 + + Allows the user to create a new event for the + selected date + Add New Event Button + + + Attendance: + Taux de présence: + + src/app/child-dev-project/attendance/attendance-details/attendance-details.component.html + 32,40 + + Attendance of a child (in percent) or the average of the + event (in percent) + Attendance + + + days present + jours présent + + src/app/child-dev-project/attendance/attendance-details/attendance-details.component.html + 53 + + How many days a child or a class was present + days present + + + days absent + jours absent + + src/app/child-dev-project/attendance/attendance-details/attendance-details.component.html + 73 + + How many days a child or a class was absent + days absent + + + unknown status + statut inconnu + + src/app/child-dev-project/attendance/attendance-details/attendance-details.component.html + 94 + + How many days the presence or absence of a child is + unknown + days absent + + + Event + Evènement + + src/app/child-dev-project/attendance/attendance-details/attendance-details.component.ts + 26 + + + + Attendance Register + + Registre des présences + + + src/app/child-dev-project/attendance/attendance-manager/attendance-manager.component.html + 7,8 + + The heading for the view showing the + Attendance Register + Heading for Attendance Register + + + Attendance data can be seen and edited in an individual's details as well as here across groups. + + Les données relatives aux présences peuvent être consultées et modifiées dans les fichiers des individus, ainsi que dans les groupes. + + + src/app/child-dev-project/attendance/attendance-manager/attendance-manager.component.html + 14,16 + + A general description-header + General description + + + Record Attendance + Faire l'appel + + src/app/child-dev-project/attendance/attendance-manager/attendance-manager.component.html + 22,23 + + Record attendance title + + + add a day's attendance + enregistrer les présences pour une journée + + src/app/child-dev-project/attendance/attendance-manager/attendance-manager.component.html + 26,27 + + Add day attendance subtitle + + + Select a group of children and easily mark their attendance one by one. This works well on a smartphone to record attendance on site. + Sélectionnez un groupe d'enfants, et enregistrez facilement leur présence un par un. Particulièrement adapté pour enregistrer les présences sur place avec un smartphone. + + src/app/child-dev-project/attendance/attendance-manager/attendance-manager.component.html + 31,33 + + Record attendance content + + + Record an event's attendance + Faire l'appel pour un évènement précis + + src/app/child-dev-project/attendance/attendance-manager/attendance-manager.component.html + 41,42 + + Record attendance button + + + Enter Monthly Attendance + Enregistrer la somme des présences par mois + + src/app/child-dev-project/attendance/attendance-manager/attendance-manager.component.html + 49,50 + + Monthly attendance title + + + add a month's attendance + enregistrer les présences pour un mois + + src/app/child-dev-project/attendance/attendance-manager/attendance-manager.component.html + 52,53 + + Monthly attendance subtitle + + + Enter attendance numbers for a whole month in a table format for a group of children. This allows you to quickly record attendance that was collected on paper. However, as you only enter a monthly total for each child you cannot see attendance in the day-wise calender. + Saisissez le nombre de présences totales pour le mois entier sous forme de tableau pour un groupe d'enfants. Cela vous permet d'enregistrer rapidement les présences qui ont été recueillies sur papier. Cependant, comme vous ne saisissez qu'un total mensuel pour chaque enfant, vous ne pouvez pas voir les présences dans le calendrier journalier. + + src/app/child-dev-project/attendance/attendance-manager/attendance-manager.component.html + 56,60 + + Monthly attendance content + + + Enter Attendance + Saisir les présences + + src/app/child-dev-project/attendance/attendance-manager/attendance-manager.component.html + 68,69 + + Enter attendance button + + + Analyse Attendance + Analyser les présences + + src/app/child-dev-project/attendance/attendance-manager/attendance-manager.component.html + 76,77 + + + src/app/child-dev-project/attendance/attendance-manager/attendance-manager.component.html + 93,94 + + Analyse attendance title + + + calculate summaries and averages + Calculer un aperçu et des moyennes + + src/app/child-dev-project/attendance/attendance-manager/attendance-manager.component.html + 79,80 + + Analyze attendance subtitle + + + Analyse and compare attendance for all children. To see an individual's attendance history you can open the child's overall details page. + Analyser et comparer l'assiduité de tous les enfants. Pour voir l'historique des présences d'un individu, vous pouvez ouvrir le fichier général de l'enfant. + + src/app/child-dev-project/attendance/attendance-manager/attendance-manager.component.html + 83,85 + + Analyze attendance content + + + School + École + + src/app/child-dev-project/attendance/attendance-migration/attendance-migration.service.ts + 20,18 + + + src/app/child-dev-project/children/model/childSchoolRelation.ts + 22 + + + src/app/child-dev-project/schools/demo-school-generator.service.ts + 42 + + + src/app/core/config/config-fix.ts + 387 + + + src/app/core/config/config-fix.ts + 498 + + + + Coaching + Accompagnement + + src/app/child-dev-project/attendance/attendance-migration/attendance-migration.service.ts + 25,23 + + + + Students more than one day absent + Élèves absents plus d'un jour + + src/app/child-dev-project/attendance/dashboard-widgets/attendance-week-dashboard/attendance-week-dashboard.component.html + 8,10 + + Dashbord attendance component subtitle + + + sick + malade + + src/app/child-dev-project/attendance/demo-data/demo-activity-events-generator.service.ts + 41 + + Event demo attendance remarks + + + fever + fièvre + + src/app/child-dev-project/attendance/demo-data/demo-activity-events-generator.service.ts + 42 + + Event demo attendance remarks + + + no information + Aucune information + + src/app/child-dev-project/attendance/demo-data/demo-activity-events-generator.service.ts + 43 + + Event demo attendance remarks + + + Title + Intitulé + + src/app/child-dev-project/attendance/model/recurring-activity.ts + 48 + + Label for the title of a recurring activity + + + Type + Type + + src/app/child-dev-project/attendance/model/recurring-activity.ts + 59 + + Label for the interaction type of a recurring activity + + + Participants + Participants + + src/app/child-dev-project/attendance/model/recurring-activity.ts + 67 + + + src/app/core/config/config-fix.ts + 688 + + + src/app/core/config/config-fix.ts + 793 + + + src/app/core/config/config-fix.ts + 810 + + Label for the participants of a recurring activity + + + Groups + Groupes + + src/app/child-dev-project/attendance/model/recurring-activity.ts + 76 + + Label for the linked schools of a recurring activity + + + Assigned user(s) + Utilisateur(s) affecté(e)(s) + + src/app/child-dev-project/attendance/model/recurring-activity.ts + 85 + + Label for the assigned user(s) of a recurring activity + + + class + classe + + src/app/child-dev-project/children/child-block/child-block.component.html + 36,38 + + e.g. 'class 8' + The class a child is attending + + + Students with unhealthy BMI + Élèves avec un IMC problématique + + src/app/child-dev-project/children/children-bmi-dashboard/children-bmi-dashboard.component.html + 8,9 + + Subtitle of the child-bmi dashboard-component + + + Children + Enfants + + src/app/child-dev-project/children/children-count-dashboard/children-count-dashboard.component.html + 8,9 + + Total amount of children + + + All + Tous + + src/app/child-dev-project/children/children-list/children-list.component.ts + 91 + + + src/app/child-dev-project/notes/notes-manager/notes-manager.component.ts + 60 + + + src/app/child-dev-project/notes/notes-manager/notes-manager.component.ts + 74 + + + src/app/core/config/config-fix.ts + 314 + + + src/app/core/config/config-fix.ts + 489 + + + src/app/core/entity-components/entity-list/filter-generator.service.ts + 139,137 + + + src/app/core/entity-components/entity-list/filter-generator.service.ts + 168,166 + + + src/app/core/filter/filter-selection/filter-selection.ts + 47 + + + + Dropout + Fin de scolarité + + src/app/child-dev-project/children/demo-data-generators/demo-child-generator.service.ts + 63 + + + src/app/child-dev-project/children/demo-data-generators/fixtures/dropout-types.ts + 4 + + + src/app/core/config/config-fix.ts + 632 + + Child status + + + Alipore + Alipore + + src/app/child-dev-project/children/demo-data-generators/fixtures/centers.ts + 5 + + + src/app/child-dev-project/children/demo-data-generators/fixtures/centers.ts + 6 + + + src/app/core/config/config-fix.ts + 130 + + center + + + Tollygunge + Tollygunge + + src/app/child-dev-project/children/demo-data-generators/fixtures/centers.ts + 7 + + + src/app/core/config/config-fix.ts + 134 + + center + + + Barabazar + Barabazar + + src/app/child-dev-project/children/demo-data-generators/fixtures/centers.ts + 8 + + + src/app/core/config/config-fix.ts + 138 + + center + + + Finished School or Training + Scolarité ou formation terminée + + src/app/child-dev-project/children/demo-data-generators/fixtures/dropout-types.ts + 3 + + Dropout type + + + Continues Education without project + Poursuit son éducation hors du projet + + src/app/child-dev-project/children/demo-data-generators/fixtures/dropout-types.ts + 5 + + Dropout type + + + Moved away + Élève a déménagé + + src/app/child-dev-project/children/demo-data-generators/fixtures/dropout-types.ts + 6 + + Dropout type + + + Hindu + Hindou + + src/app/child-dev-project/children/demo-data-generators/fixtures/religions.ts + 3 + + + src/app/child-dev-project/children/demo-data-generators/fixtures/religions.ts + 4 + + + src/app/child-dev-project/children/demo-data-generators/fixtures/religions.ts + 5 + + religion + + + Muslim + Musulman + + src/app/child-dev-project/children/demo-data-generators/fixtures/religions.ts + 6 + + + src/app/child-dev-project/children/demo-data-generators/fixtures/religions.ts + 7 + + religion + + + Christian + Chrétien + + src/app/child-dev-project/children/demo-data-generators/fixtures/religions.ts + 8 + + religion + + + Sikh + Sikh + + src/app/child-dev-project/children/demo-data-generators/fixtures/religions.ts + 9 + + religion + + + Name + Nom + + src/app/child-dev-project/children/model/child.ts + 39 + + + src/app/child-dev-project/schools/model/school.ts + 18 + + + src/app/core/config/config-fix.ts + 372 + + + src/app/core/config/config-fix.ts + 869 + + Label for the name of a child + + + Project Number + Numéro de projet + + src/app/child-dev-project/children/model/child.ts + 44 + + Label for the project number of a child + + + PN + Projet # + + src/app/child-dev-project/children/model/child.ts + 45 + + Short label for the project number + + + Date of birth + Date de naissance + + src/app/child-dev-project/children/model/child.ts + 50 + + Label for the date of birth of a child + + + DoB + DDN + + src/app/child-dev-project/children/model/child.ts + 51 + + Short label for the date of birth + + + Gender + Genre + + src/app/child-dev-project/children/model/child.ts + 58 + + Label for the gender of a child + + + Center + Centre + + src/app/child-dev-project/children/model/child.ts + 66 + + Label for the center of a child + + + Admission + Admission + + src/app/child-dev-project/children/model/child.ts + 70 + + Label for the admission date of a child + + + Status + Statut + + src/app/child-dev-project/children/model/child.ts + 74 + + + src/app/core/config/config-fix.ts + 448 + + Label for the status of a child + + + Dropout Date + Date de fin de scolarité + + src/app/child-dev-project/children/model/child.ts + 79 + + Label for the dropout date of a child + + + Dropout Type + Type de fin de scolarité + + src/app/child-dev-project/children/model/child.ts + 83 + + Label for the type of dropout of a child + + + Dropout remarks + Commentaires sur la fin de scolarité + + src/app/child-dev-project/children/model/child.ts + 87 + + Label for the remarks about a dropout of a child + + + Photo Filename + Nom du fichier de la photo + + src/app/child-dev-project/children/model/child.ts + 99 + + Label for the filename of a photo of a child + + + Phone Number + Numéro de téléphone + + src/app/child-dev-project/children/model/child.ts + 104 + + + src/app/core/config/config-fix.ts + 897 + + Label for the phone number of a child + + + Child + Enfant + + src/app/child-dev-project/children/model/childSchoolRelation.ts + 14 + + Label for the child of a relation + + + Class + Classe + + src/app/child-dev-project/children/model/childSchoolRelation.ts + 29 + + + src/app/core/config/config-fix.ts + 382 + + Label for the class of a relation + + + From + Date de début + + src/app/child-dev-project/children/model/childSchoolRelation.ts + 33 + + Label for the start date of a relation + + + The date a child joins a school + Date où l'enfant rejoint une école + + src/app/child-dev-project/children/model/childSchoolRelation.ts + 34 + + Description of the start date of a relation + + + To + Date de fin + + src/app/child-dev-project/children/model/childSchoolRelation.ts + 39 + + Label for the end date of a relation + + + The date of a child leaving the school + Date de départ d'un enfant de l'école + + src/app/child-dev-project/children/model/childSchoolRelation.ts + 40 + + Description of the end date of a relation + + + Result + Résultat + + src/app/child-dev-project/children/model/childSchoolRelation.ts + 46 + + Label for the percentage result of a relation + + + No "" date is set + La "" n'est pas sélectionnée + + src/app/child-dev-project/children/model/childSchoolRelation.ts + 66 + + Error assertValid failed + + + The "" date is after the "" date + La "" est postérieure à la "" + + src/app/child-dev-project/children/model/childSchoolRelation.ts + 70 + + Error assertValid failed + + + male + Masculin + + src/app/child-dev-project/children/model/genders.ts + 10 + + Label gender + + + female + Féminin + + src/app/child-dev-project/children/model/genders.ts + 14 + + Label gender + + + Non-binary/third gender + Non-binaire/troisième genre + + src/app/child-dev-project/children/model/genders.ts + 18 + + Label gender + + + Total: + + Total: + + + src/app/child-dev-project/educational-material/educational-material-component/educational-material.component.html + 11,12 + + Total amount of education material including a summary + Total amount + + + Material + Materiél + + src/app/child-dev-project/educational-material/model/educational-material.ts + 35 + + The material which has been borrowed + + + Amount + Quantité + + src/app/child-dev-project/educational-material/model/educational-material.ts + 42 + + The amount of the material which has been borrowed + + + Description + Description + + src/app/child-dev-project/educational-material/model/educational-material.ts + 47 + + An additional description for the borrowed material + + + pencil + crayon + + src/app/child-dev-project/educational-material/model/materials.ts + 10 + + Label school material + + + eraser + gomme + + src/app/child-dev-project/educational-material/model/materials.ts + 14 + + Label school material + + + sharpener + taille-crayon + + src/app/child-dev-project/educational-material/model/materials.ts + 18 + + Label school material + + + pen (black) + stylo (noir) + + src/app/child-dev-project/educational-material/model/materials.ts + 22 + + Label school material + + + oil pastels + pastels à l'huile + + src/app/child-dev-project/educational-material/model/materials.ts + 26 + + Label school material + + + crayons + crayons de couleur + + src/app/child-dev-project/educational-material/model/materials.ts + 30 + + Label school material + + + sketch pens + stylos à dessin + + src/app/child-dev-project/educational-material/model/materials.ts + 34 + + Label school material + + + scale (big) + balance (grande) + + src/app/child-dev-project/educational-material/model/materials.ts + 38 + + Label school material + + + scale (small) + balance (petite) + + src/app/child-dev-project/educational-material/model/materials.ts + 42 + + Label school material + + + geometry box + boîte de géométrie + + src/app/child-dev-project/educational-material/model/materials.ts + 46 + + Label school material + + + copy (single line, small) + copie (single line, small) + + src/app/child-dev-project/educational-material/model/materials.ts + 50 + + Label school material + + + copy (single line, big) + copie (ligne unique, grande) + + src/app/child-dev-project/educational-material/model/materials.ts + 54 + + Label school material + + + copy (four line) + copie (quatre lignes) + + src/app/child-dev-project/educational-material/model/materials.ts + 58 + + Label school material + + + copy (squared) + copie (carrée) + + src/app/child-dev-project/educational-material/model/materials.ts + 62 + + Label school material + + + copy (plain) + copie (simple) + + src/app/child-dev-project/educational-material/model/materials.ts + 66 + + Label school material + + + copy (line-plain) + copie (ligne simple) + + src/app/child-dev-project/educational-material/model/materials.ts + 70 + + Label school material + + + copy (drawing) + copie (dessin) + + src/app/child-dev-project/educational-material/model/materials.ts + 74 + + Label school material + + + copy (practical) + copie (pratique) + + src/app/child-dev-project/educational-material/model/materials.ts + 78 + + Label school material + + + graph book + carnet de graphiques + + src/app/child-dev-project/educational-material/model/materials.ts + 82 + + Label school material + + + project papers + Copies de projet + + src/app/child-dev-project/educational-material/model/materials.ts + 86 + + Label school material + + + project file + dossier de projet + + src/app/child-dev-project/educational-material/model/materials.ts + 90 + + Label school material + + + scrap book + album + + src/app/child-dev-project/educational-material/model/materials.ts + 94 + + Label school material + + + exam board + plaque d'écriture + + src/app/child-dev-project/educational-material/model/materials.ts + 98 + + Label school material + + + Bag + Sac + + src/app/child-dev-project/educational-material/model/materials.ts + 102 + + Label school material + + + School Uniform + Uniforme scolaire + + src/app/child-dev-project/educational-material/model/materials.ts + 107 + + Label school material + + + School Shoes + Chaussures d'école + + src/app/child-dev-project/educational-material/model/materials.ts + 112 + + Label school material + + + Sports Dress + Robe de sport + + src/app/child-dev-project/educational-material/model/materials.ts + 117 + + Label school material + + + Sports Shoes + Chaussures de sport + + src/app/child-dev-project/educational-material/model/materials.ts + 122 + + Label school material + + + Raincoat + impérméable + + src/app/child-dev-project/educational-material/model/materials.ts + 127 + + Label school material + + + BMI + IMC + + src/app/child-dev-project/health-checkup/health-checkup-component/health-checkup.component.ts + 30 + + + src/app/core/config/config-fix.ts + 412 + + Table header, Short for Body Mass Index + + + Height [cm] + Taille [cm] + + src/app/child-dev-project/health-checkup/model/health-check.ts + 35 + + Label for height in cm of a health check + + + Weight [kg] + Poids [kg] + + src/app/child-dev-project/health-checkup/model/health-check.ts + 43 + + Label for weight in kg of a health check + + + Children without recent report + Enfants sans observation récente + + src/app/child-dev-project/notes/dashboard-widgets/no-recent-notes-dashboard/no-recent-notes-dashboard.component.html + 22,25 + + Subtitle informing the user that these are the children without + recent reports + Subtitle + + + Name + Nom + + src/app/child-dev-project/notes/dashboard-widgets/no-recent-notes-dashboard/no-recent-notes-dashboard.component.html + 43,46 + + Name of a child + + + Days passed > days + Jours écoulés > days + + src/app/child-dev-project/notes/dashboard-widgets/no-recent-notes-dashboard/no-recent-notes-dashboard.component.html + 55,66 + + Format like 'Days passed > 5 days' + Amount of days back + + + includes children without a note + inclut les enfants sans observations + + src/app/child-dev-project/notes/dashboard-widgets/no-recent-notes-dashboard/no-recent-notes-dashboard.component.ts + 90 + + + src/app/child-dev-project/notes/dashboard-widgets/recent-notes-dashboard/recent-notes-dashboard.component.ts + 63 + + Spaces in front of the variables are added automatically + Tooltip + + + since the beginning of the week + depuis le début de la semaine + + src/app/child-dev-project/notes/dashboard-widgets/no-recent-notes-dashboard/no-recent-notes-dashboard.component.ts + 97,95 + + + src/app/child-dev-project/notes/dashboard-widgets/recent-notes-dashboard/recent-notes-dashboard.component.ts + 70,68 + + 'includes children without a note since the beginning of the week' + Tooltip-part + + + without a note within the last days + sans observations au cours des derniers days + + src/app/child-dev-project/notes/dashboard-widgets/no-recent-notes-dashboard/no-recent-notes-dashboard.component.ts + 106,104 + + + src/app/child-dev-project/notes/dashboard-widgets/recent-notes-dashboard/recent-notes-dashboard.component.ts + 79,77 + + 'includes children without a note within the last x days' + Tooltip-part + + + Children with recent report + Enfants avec une observation récente + + src/app/child-dev-project/notes/dashboard-widgets/recent-notes-dashboard/recent-notes-dashboard.component.html + 22,25 + + Subtitle informing the user that these are the children with + recent reports + Subtitle + + + Go to Notes + Lien vers la section observations + + src/app/child-dev-project/notes/dashboard-widgets/recent-notes-dashboard/recent-notes-dashboard.component.html + 37,39 + + Link that will take the user to a list of notes + Go to Notes Link + + + Guardians Meeting + Réunion des tuteurs + + src/app/child-dev-project/notes/demo-data/notes_group-stories.ts + 7 + + + src/app/child-dev-project/notes/demo-data/notes_group-stories.ts + 15 + + Note demo subject + + + + Our regular monthly meeting. Find the agenda and minutes in our meeting folder. + + + Notre réunion mensuelle régulière. Ordre du jour et retranscription sont dans notre dossier de réunion. + + + src/app/child-dev-project/notes/demo-data/notes_group-stories.ts + 8,10 + + + src/app/child-dev-project/notes/demo-data/notes_group-stories.ts + 16,18 + + + src/app/child-dev-project/notes/demo-data/notes_group-stories.ts + 25,27 + + + src/app/child-dev-project/notes/demo-data/notes_group-stories.ts + 33,35 + + Note demo text + + + Children Meeting + Réunion des enfants + + src/app/child-dev-project/notes/demo-data/notes_group-stories.ts + 24 + + + src/app/child-dev-project/notes/demo-data/notes_group-stories.ts + 32 + + Note demo subject + + + Drug Prevention Workshop + Atelier prévention contre la drogue + + src/app/child-dev-project/notes/demo-data/notes_group-stories.ts + 40 + + Note demo subject + + + + Expert conducted a two day workshop on drug prevention. + + + L'expert a dirigé un atelier de deux jours sur la prévention de la toxicomanie. + + + src/app/child-dev-project/notes/demo-data/notes_group-stories.ts + 41,43 + + Note demo text + + + Mother sick + Mère malade + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 7 + + Note demo subject + + + + Visited family after we heard that mother is seriously ill. She cannot get up. + Children are taking care of housework. Told her to see doctor. We should follow up next week. + + + Visite de la famille après avoir appris que la mère est gravement malade. Elle ne peut pas se lever. + Les enfants s'occupent des tâches ménagères. Nous lui avons dit de voir un médecin. Nous devrions faire un suivi la semaine prochaine. + + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 8,11 + + Note demo text + + + Discussed school change + Discussion sur un transfert d'école + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 16 + + Note demo subject + + + + Discussed future of the child with the parents. They agree that changing school can be a good option. + Will discuss further together with the child. + + + Discussion sur l'avenir de l'enfant avec ses parents. Ils sont d'accord sur l'idée que changer d'école peut être une bonne option. + Continuerons d'en discuter avec l'enfant. + + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 17,20 + + Note demo text + + + Follow up for school absence + Suivi pour absence à l'école + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 26 + + Note demo subject + + + + Called to ask for reason about absence. Mother made excuses but promised to send the child tomorrow. + + + J'ai appelé pour demander la raison de l'absence. La mère s'est excusée mais a promis d'envoyer l'enfant demain. + + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 27,29 + + Note demo text + + + Absent because ill + Absent du fait de maladie + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 34 + + Note demo subject + + + + Mother has called in the morning. Child cannot come to class because of fever. + + + La mère a appelé dans la matinée. L'enfant ne peut pas venir à cause d'une fièvre. + + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 35,37 + + Note demo text + + + Absence without information + Absence sans raison donnée + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 42 + + Note demo subject + + + + Child was not in school whole last week again. When calling the mother she didn't know about it. + Need to follow up urgently to discuss with the child and the guardians. + + + L'enfant n'était à nouveau pas à l'école toute la semaine dernière. Lorsque nous avons appelé la mère, elle n'était pas au courant. Besoin d'un suivi urgent pour en discuter avec l'enfant et les tuteurs. + + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 43,46 + + Note demo text + + + School is happy about progress + L'école est satisfaite du progrès qui a été fait + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 51 + + Note demo subject + + + + Visited the school and talked to the class teacher and principal. They are happy about the progress + and behaviour. + + + J'ai visité l'école et j'ai parlé à l'enseignant et au directeur. Ils sont satisfaits des progrès et du comportement de l'enfant en ce moment. + + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 52,55 + + Note demo text + + + Needs to work more for school + Besoin de plus travailler + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 60 + + Note demo subject + + + + Discussed the child's progress with coaching teacher. He is still a weak student and needs more support. + We should consider arranging an extra class for him. Discuss next social worker meeting. + + + J'ai discuté des progrès de l'enfant avec le professeur d'encadrement. Il reste un élève relativement faible et a besoin de plus de soutien. Nous devrions envisager d'organiser une classe supplémentaire pour lui. Prochaine réunion avec les travailleurs sociaux pour en discuter. + + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 61,64 + + Note demo text + + + Fight at school + Bagarre à l'école + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 69 + + Note demo subject + + + + Principal called us today. Our student got into a fight and was suspended for a week. + Need to follow up with the child and discuss the matter. + + + Le principal nous a appelé aujourd'hui. Notre élève s'est battu et a été exclu pour une semaine. Il faut faire un suivi avec l'enfant et discuter de l'affaire. + + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 70,73 + + Note demo text + + + Special help for family + Aide spéciale pour la famille + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 78 + + Note demo subject + + + + Since the father has lost his job the family is struggling to survive. + After home visits and discussion in our team we decided to refer them to a special support programme. + + + Depuis que le père a perdu son emploi, la famille a du mal à survivre. Après des visites à domicile et des discussions au sein de notre équipe, nous avons décidé de les orienter vers un programme de soutien spécial. + + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 79,82 + + Note demo text + + + Chance to repeat class + Possibilité de redoubler + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 87 + + Note demo subject + + + + Child has failed this school year as she did not go to school regularly. + After a long discussion with the child and her parents we agreed to support her to repeat the class + and she promised to attend school regularly. + + + L'enfant a échoué cette année scolaire du fait d'absences répétées. Après une longue discussion avec l'enfant et ses parents, nous avons accepté de l'aider à redoubler et elle a promis d'aller régulièrement à l'école. + + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 88,92 + + Note demo text + + + Distracted in class + Distrait en classe + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 97 + + Note demo subject + + + + Teacher has let us know that he is very unfocused during class these days. + Discussed with him - there are a lot of problems in the family currently. + + + Le professeur nous a informé qu'il manque de concentration en classe ces temps-ci. + En avons discuté avec lui - la famille a beaucoup de problèmes en ce moment. + + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 98,101 + + Note demo text + + + Disturbing class + Dérange la classe + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 106 + + Note demo subject + + + + She refused to listen to the teacher was disturbing the class. + Did counselling session with her. + + + Elle refuse d'écouter le professeur et dérange la classe. + Avons fait une session de thérapie avec elle. + + + src/app/child-dev-project/notes/demo-data/notes_individual-stories.ts + 107,110 + + Note demo text + + + got excused by it's mother + Excusé par sa mère + + src/app/child-dev-project/notes/demo-data/remarks.ts + 2 + + Absence remark + + + absent without excuse + absent sans excuse + + src/app/child-dev-project/notes/demo-data/remarks.ts + 3 + + Absence remark + + + absent because ill + absent car malade + + src/app/child-dev-project/notes/demo-data/remarks.ts + 4 + + Absence remark + + + Children + Enfants + + src/app/child-dev-project/notes/model/note.ts + 57 + + + src/app/core/config/config-fix.ts + 32 + + Label for the children of a note + + + Subject + Sujet + + src/app/child-dev-project/notes/model/note.ts + 74 + + Label for the subject of a note + + + Notes + Observations + + src/app/child-dev-project/notes/model/note.ts + 77 + + + src/app/core/config/config-fix.ts + 57 + + Label for the actual notes of a note + + + SW + Tuteur + + src/app/child-dev-project/notes/model/note.ts + 83 + + Label for the social worker(s) who created the note + + + Category + Categorie + + src/app/child-dev-project/notes/model/note.ts + 91 + + Label for the category of a note + + + Remarks + Observations + + src/app/child-dev-project/notes/note-details/child-meeting-attendance/child-meeting-note-attendance.component.html + 22 + + + + Date + Date + + src/app/child-dev-project/notes/note-details/note-details.component.html + 34 + + Placeholder for a date-input + Date input + + + Status + Statut + + src/app/child-dev-project/notes/note-details/note-details.component.html + 49 + + Status of a note + + + Type of Interaction + Type d'interaction + + src/app/child-dev-project/notes/note-details/note-details.component.html + 66 + + Type of Interaction when adding event + + + Add Author... + Ajouter un auteur... + + src/app/child-dev-project/notes/note-details/note-details.component.html + 88 + + placeholder when adding multiple authors + + + Authors + Auteurs + + src/app/child-dev-project/notes/note-details/note-details.component.html + 90 + + Authors of a note + + + Topic / Summary + Sujet / Résumé + + src/app/child-dev-project/notes/note-details/note-details.component.html + 107 + + Placeholder informing that this is the Topic/Summary + of the note + Placeholder + + + Notes + Observations + + src/app/child-dev-project/notes/note-details/note-details.component.html + 124 + + Placeholder informing that this is textarea the actual + note can be entered into + Placeholder + + + Participants + Participants + + src/app/child-dev-project/notes/note-details/note-details.component.html + 141 + + Participants of a note + + + Add participant ... + Ajouter un participant ... + + src/app/child-dev-project/notes/note-details/note-details.component.html + 143 + + Add participants of a note + + + Groups + Groupes + + src/app/child-dev-project/notes/note-details/note-details.component.html + 175 + + Groups that belong to a note + + + Add group ... + Ajouter un groupe ... + + src/app/child-dev-project/notes/note-details/note-details.component.html + 177 + + Add a group to a note + + + Include events + + Inclut les évènements récurrents ou uniques + + + src/app/child-dev-project/notes/notes-manager/notes-manager.component.html + 16,17 + + events are related to a + child + Slider that allows a user to also include events + + + Urgent + Urgent + + src/app/child-dev-project/notes/notes-manager/notes-manager.component.ts + 50,48 + + Filter-option for notes + + + Needs Follow-Up + Besoin de suivi + + src/app/child-dev-project/notes/notes-manager/notes-manager.component.ts + 55,53 + + + src/app/child-dev-project/warning-levels.ts + 14 + + Filter-option for notes + + + This Week + Cette semaine + + src/app/child-dev-project/notes/notes-manager/notes-manager.component.ts + 66,64 + + Filter-option for notes + + + Since Last Week + Depuis la semaine dernière + + src/app/child-dev-project/notes/notes-manager/notes-manager.component.ts + 71,69 + + Filter-option for notes + + + To change this field, please add a new entry to the history below + Pour modifier ce champ, veuillez ajouter une nouvelle entrée à l'historique ci-dessous + + src/app/child-dev-project/previous-schools/previous-schools.component.html + 4,6 + + + + Currently attending class at + Actuellement en classe à l' + + src/app/child-dev-project/previous-schools/previous-schools.component.html + 9,16 + + Context 'currently + attending class at school' + The class and school a child is currently attending + + + Clubs visited + Clubs visités + + src/app/child-dev-project/progress-dashboard-widget/demo-progress-dashboard-widget-generator.service.ts + 22 + + Example for demo task in the progress widget + + + Schools checked + Écoles inspectées + + src/app/child-dev-project/progress-dashboard-widget/demo-progress-dashboard-widget-generator.service.ts + 23 + + Example for demo task in the progress widget + + + Government Officials met + Fonctionnaires et responsables rencontrés + + src/app/child-dev-project/progress-dashboard-widget/demo-progress-dashboard-widget-generator.service.ts + 24 + + Example for demo task in the progress widget + + + Annual Survey + Questionnaire annuel + + src/app/child-dev-project/progress-dashboard-widget/demo-progress-dashboard-widget-generator.service.ts + 42 + + + src/app/core/config/default-config/default-interaction-types.ts + 68 + + Widget title + + + Evaluation targets reached + Objectifs d'évaluation atteints + + src/app/child-dev-project/progress-dashboard-widget/demo-progress-dashboard-widget-generator.service.ts + 57 + + Dashboard widget demo tile + + + Students graduating + Élèves obtenant leur diplômes + + src/app/child-dev-project/progress-dashboard-widget/demo-progress-dashboard-widget-generator.service.ts + 59 + + Dashboard widget demo entry + + + Students enrolled in training + Élèves inscrits à la formation + + src/app/child-dev-project/progress-dashboard-widget/demo-progress-dashboard-widget-generator.service.ts + 60 + + Dashboard widget demo entry + + + Students found job + Élèves ayant trouvé un travail + + src/app/child-dev-project/progress-dashboard-widget/demo-progress-dashboard-widget-generator.service.ts + 61 + + Dashboard widget demo entry + + + Progress Widget + Progrès + + src/app/child-dev-project/progress-dashboard-widget/progress-dashboard/progress-dashboard-config.ts + 24 + + + + Title + Intitulé + + src/app/child-dev-project/progress-dashboard-widget/progress-dashboard/progress-dashboard.component.html + 51,55 + + Input placeholder + + + Label + Intitulé + + src/app/child-dev-project/progress-dashboard-widget/progress-dashboard/progress-dashboard.component.html + 71,75 + + The label of a process + Process Label + + + Current + En ce moment + + src/app/child-dev-project/progress-dashboard-widget/progress-dashboard/progress-dashboard.component.html + 91,96 + + The Current amount of a process + Current process + + + Target + Objectif + + src/app/child-dev-project/progress-dashboard-widget/progress-dashboard/progress-dashboard.component.html + 101,105 + + The target amount of a process + Target process + + + Progress of X + Progrès de X + + src/app/child-dev-project/progress-dashboard-widget/progress-dashboard/progress-dashboard.component.ts + 55 + + The progress, e.g. of a certain activity + + + Part + Partie + + src/app/child-dev-project/progress-dashboard-widget/progress-dashboard/progress-dashboard.component.ts + 63,62 + + Part of a whole + + + High School + Lycée + + src/app/child-dev-project/schools/demo-school-generator.service.ts + 43 + + School demo name that is prepended to a name + + + 6 a.m. - 11 a.m. + 6h - 11h + + src/app/child-dev-project/schools/demo-school-generator.service.ts + 50 + + School demo timing + + + 11 a.m. - 4 p.m. + 11h - 16h + + src/app/child-dev-project/schools/demo-school-generator.service.ts + 51 + + School demo timing + + + 6:30-11:00 and 11:30-16:00 + 6h30-11h, 11h30-16h + + src/app/child-dev-project/schools/demo-school-generator.service.ts + 52 + + School demo timing + + + Solved + Résolu + + src/app/child-dev-project/warning-levels.ts + 10 + + Label warning level + + + Urgent Follow-Up + Suivi urgent + + src/app/child-dev-project/warning-levels.ts + 18 + + Label warning level + + + Conflicting Entity: + Conflit d'éléments: + + src/app/conflict-resolution/compare-rev/compare-rev.component.html + 16,21 + + Signals that there are conflicting database-entities + + + Choose conflicting version + Choisissez l'une des versions en conflit + + src/app/conflict-resolution/compare-rev/compare-rev.component.html + 32,37 + + + + Save manually resolved record + Sauvegarder l'enregistrement résolu manuellement + + src/app/conflict-resolution/compare-rev/compare-rev.component.html + 51,56 + + + + Current Entity: + Version actuelle: + + src/app/conflict-resolution/compare-rev/compare-rev.component.html + 57,62 + + A currently selected entity + + + Choose current version + Choisissez la version actuelle + + src/app/conflict-resolution/compare-rev/compare-rev.component.html + 76,83 + + Choose a current version between several conflicting versions of + database entries + + + automatically deleted trivial conflict + suppression automatique d'un conflit trivial + + src/app/conflict-resolution/compare-rev/compare-rev.component.ts + 72 + + + + Delete Conflicting Version? + Supprimer la version en conflit? + + src/app/conflict-resolution/compare-rev/compare-rev.component.ts + 95,94 + + + + Are you sure you want to keep the current version and delete this conflicting version? + Êtes-vous sûr de vouloir garder la version actuelle et supprimer la version en conflit? + + src/app/conflict-resolution/compare-rev/compare-rev.component.ts + 96,94 + + + + deleted conflicting version + Version en conflit supprimée + + src/app/conflict-resolution/compare-rev/compare-rev.component.ts + 105 + + + + Error trying to delete conflicting version: + Erreur lors de la suppression de la version en conflit: + + src/app/conflict-resolution/compare-rev/compare-rev.component.ts + 118,117 + + + + Error trying to save version: + Erreur lors de la sauvegarde de la version: + + src/app/conflict-resolution/compare-rev/compare-rev.component.ts + 131,130 + + + + Save Changes for Conflict Resolution? + Sauvegarder les modifications pour la résolution des conflits? + + src/app/conflict-resolution/compare-rev/compare-rev.component.ts + 154,153 + + + + Are you sure you want to save the following changes and delete the conflicting version? + Êtes-vous sûr de vouloir sauvegarder les modifications suivantes et supprimer la version en conflit? + + src/app/conflict-resolution/compare-rev/compare-rev.component.ts + 155,153 + + + + selected conflicting version + Version en conflit sélectionnée + + src/app/conflict-resolution/compare-rev/compare-rev.component.ts + 165 + + + + resolved manually + Résolu manuellement + + src/app/conflict-resolution/compare-rev/compare-rev.component.ts + 167 + + + + conflicts to resolve: + + conflits à résoudre: + + + src/app/conflict-resolution/conflict-resolution-list/conflict-resolution-list.component.html + 7,8 + + Shows the database conflicts that need to be + resolved + Conflicts to be resolved + + + Data + Données + + src/app/conflict-resolution/conflict-resolution-list/conflict-resolution-list.component.html + 28,32 + + Raw data, e.g. from a database + + + Administration & Configuration + Administration & Configuration + + src/app/core/admin/admin/admin.component.html + 1,5 + + Admin Header + + + Warning: This section is intended for system administrators only. Make sure you know what you are doing. + + Attention: cette section est destinée aux administrateurs systèmes uniquement. Assurez-vous de savoir ce que vous faites. + + + src/app/core/admin/admin/admin.component.html + 7,9 + + Admin security paragraph + + + Utility Functions + Fonctions utilitaires + + src/app/core/admin/admin/admin.component.html + 13,18 + + Utility Functions header + + + Auto-Update children's photo filenames + Mise à jour automatique du nom de fichier de l'image des enfants + + src/app/core/admin/admin/admin.component.html + 20,23 + + Auto-Update button + + + Migration + Migration + + src/app/core/admin/admin/admin.component.html + 27,31 + + Data migration + + + Migrate Notes to new author users + Migrer les observations vers les nouveaux utilisateurs auteurs + + src/app/core/admin/admin/admin.component.html + 34,38 + + Data migration for notes + + + Migrate Children to correct photo format + Migrer les enfants vers le bon format photo + + src/app/core/admin/admin/admin.component.html + 41,44 + + Data migration for photos + + + Backup + Backup + + src/app/core/admin/admin/admin.component.html + 53,58 + + Backup header + + + Download Backup (.json) + Télécharger le backup (.json) + + src/app/core/admin/admin/admin.component.html + 60,65 + + Download-Update button + + + Restore Backup (.json) + Restauration du backup (.json) + + src/app/core/admin/admin/admin.component.html + 68,74 + + Restore-Update button + + + Export + Exporter + + src/app/core/admin/admin/admin.component.html + 80,85 + + Export header + + + Download whole database (.csv) + Télécharger la base de données entière (.csv) + + src/app/core/admin/admin/admin.component.html + 87,95 + + Download database button + + + Application Configuration + Configuration de l'application + + src/app/core/admin/admin/admin.component.html + 95,100 + + Application configuration header + + + Download configuration + Télécharger la configuration + + src/app/core/admin/admin/admin.component.html + 102,108 + + Download configuration button + + + Upload new configuration + Téléverser la nouvelle configuration + + src/app/core/admin/admin/admin.component.html + 110,116 + + Upload configuration button + + + AppConfig + AppConfig + + src/app/core/admin/admin/admin.component.html + 122,127 + + App-Config header + + + Debug the PouchDB + Débeug du PouchDB + + src/app/core/admin/admin/admin.component.html + 127,129 + + Debug PouchDB header + + + Send to console.log() + Envoyer à console.log() + + src/app/core/admin/admin/admin.component.html + 130,136 + + Log button + + + Empty Database + Effacer la base de données + + src/app/core/admin/admin/admin.component.html + 139,146 + + Empty database button + + + Alert Log + Alert Log + + src/app/core/admin/admin/admin.component.html + 145,148 + + Alert log header + + + Overwrite complete database? + Écraser la base de donnée entière? + + src/app/core/admin/admin/admin.component.ts + 126,125 + + + + Are you sure you want to restore this backup? This will + delete all existing records, + restoring records from the loaded file. + Êtes-vous sûr de vouloir restaurer ce backup? Ceci va + supprimer l'entièreté des enregistrements existants, + restaurant enregistrements du fichier téléchargé. + + src/app/core/admin/admin/admin.component.ts + 127,125 + + + + Backup restored + Backup restauré + + src/app/core/admin/admin/admin.component.ts + 141,140 + + + + Empty complete database? + Vider l'entièreté de la base de donnée? + + src/app/core/admin/admin/admin.component.ts + 169,168 + + + + Are you sure you want to clear the database? This will delete all existing records in the database! + Êtes-vous sûr de vouloir effacer la base de données? Ceci va supprimer les enregistrements existants dans la base de données! + + src/app/core/admin/admin/admin.component.ts + 170,168 + + + + Import completed + Importation terminée + + src/app/core/admin/admin/admin.component.ts + 183,182 + + + + ID + Identifiant + + src/app/core/admin/user-list/user-list.component.html + 3,5 + + User-ID + + + Username + Nom d'utilisateur + + src/app/core/admin/user-list/user-list.component.html + 7,8 + + + src/app/core/session/login/login.component.html + 32 + + + src/app/core/user/user-account/user-account.component.html + 26 + + + + Details + Détails + + src/app/core/admin/user-list/user-list.component.html + 12,16 + + Details of a certain User + + + Could not load file '': + Échec lors du chargement du fichier '': + + src/app/core/app-config/app-config.ts + 82,84 + + + + Coming Soon + Bientôt disponible + + src/app/core/coming-soon/coming-soon/coming-soon.component.html + 2 + + Coming Soon header + + + Sorry, this feature isn't quite ready yet. We are working hard to make this available for you. Let us know below if you need this functionality. + Désolé, cette fonctionnalité n'est pas encore tout à fait prête. Nous travaillons à la rendre disponible pour vous. Faites-nous savoir ci-dessous si vous en avez besoin. + + src/app/core/coming-soon/coming-soon/coming-soon.component.html + 4,6 + + Coming Soon description + + + I need this feature + J'ai besoin de cette fonctionnalité + + src/app/core/coming-soon/coming-soon/coming-soon.component.html + 27,34 + + Indicates that the user needs this feature and can send + a feature-request + Feature Button + + + I can tell you about my use case + Je peux vous en dire plus sur ma situation + + src/app/core/coming-soon/coming-soon/coming-soon.component.html + 48,49 + + + + Thank you for letting us know. + Merci de nous en avoir informé. + + src/app/core/coming-soon/coming-soon/coming-soon.component.ts + 78 + + Sent after the user has sent a feature-request + + + Dashboard + Tableau de bord + + src/app/core/config/config-fix.ts + 27 + + Menu item + + + Schools + Écoles + + src/app/core/config/config-fix.ts + 37 + + Menu item + + + Recurring Activities + Activités récurrentes + + src/app/core/config/config-fix.ts + 42 + + + src/app/core/config/config-fix.ts + 654 + + Menu item + + + Record Attendance + Faire l'appel + + src/app/core/config/config-fix.ts + 47 + + Record attendance menu item + Menu item + + + Manage Attendance + Gérer les présences + + src/app/core/config/config-fix.ts + 52 + + Menu item + + + Admin + Administrateur + + src/app/core/config/config-fix.ts + 62 + + Menu item + + + Users + Utilisateurs + + src/app/core/config/config-fix.ts + 67 + + Menu item + + + Reports + Rapports + + src/app/core/config/config-fix.ts + 72 + + Menu item + + + Database Conflicts + Conflits dans la base de donnée + + src/app/core/config/config-fix.ts + 77 + + Menu item + + + Help + Aide + + src/app/core/config/config-fix.ts + 82 + + Menu item + + + OK (copy with us) + OK (copie avec nous) + + src/app/core/config/config-fix.ts + 104 + + Document status + + + OK (copy needed for us) + OK (nous avons besoin de la copie) + + src/app/core/config/config-fix.ts + 108 + + Document status + + + needs correction + besoin de correction + + src/app/core/config/config-fix.ts + 112 + + Document status + + + applied + Remis + + src/app/core/config/config-fix.ts + 116 + + Document status + + + doesn't have + n'a pas + + src/app/core/config/config-fix.ts + 120 + + Document status + + + not eligible + non éligible + + src/app/core/config/config-fix.ts + 124 + + Document status + + + Record Attendance + Faire l'appel + + src/app/core/config/config-fix.ts + 152 + + record attendance shortcut + Dashboard shortcut widget + + + last week + la semaine dernière + + src/app/core/config/config-fix.ts + 176 + + Attendance week dashboard widget label + + + this week + cette semaine + + src/app/core/config/config-fix.ts + 183 + + Attendance week dashboard widget label + + + Notes & Reports + Observations & Rapports + + src/app/core/config/config-fix.ts + 201 + + + src/app/core/config/config-fix.ts + 573 + + Title for notes overview + + + Standard + Standard + + src/app/core/config/config-fix.ts + 211 + + + src/app/core/config/config-fix.ts + 215 + + Translated name of default column group + + + Mobile + Mobile + + src/app/core/config/config-fix.ts + 212 + + + src/app/core/config/config-fix.ts + 225 + + + src/app/core/config/config-fix.ts + 419 + + + src/app/core/config/config-fix.ts + 472 + + Translated name of mobile column group + + + assets/help/help.en.md + assets/help/help.fr.md + + src/app/core/config/config-fix.ts + 291 + + Filename of markdown help page (make sure the filename you enter as a translation actually exists on the server!) + + + Schools List + Liste des écoles + + src/app/core/config/config-fix.ts + 303 + + Title of schools overview + + + Private School + École privée + + src/app/core/config/config-fix.ts + 312 + + + src/app/core/config/config-fix.ts + 876 + + Label for private schools filter - true case + + + Government School + École publique + + src/app/core/config/config-fix.ts + 313 + + Label for private schools filter - false case + + + Basic Information + Informations de base + + src/app/core/config/config-fix.ts + 325 + + + src/app/core/config/config-fix.ts + 511 + + Panel title + + + Students + Élèves + + src/app/core/config/config-fix.ts + 353 + + Panel title + + + Children List + Liste des enfants + + src/app/core/config/config-fix.ts + 368 + + Title children overview + + + Age + Âge + + src/app/core/config/config-fix.ts + 377 + + Column label for age of child + + + Attendance (School) + Présence (école) + + src/app/core/config/config-fix.ts + 394 + + Column label for school attendance of child + + + Attendance (Coaching) + Présence (formation) + + src/app/core/config/config-fix.ts + 403 + + Column label for coaching attendance of child + + + School Info + Informations scolaires + + src/app/core/config/config-fix.ts + 418 + + + src/app/core/config/config-fix.ts + 435 + + Translated name of default column group + + + Basic Info + Informations de base + + src/app/core/config/config-fix.ts + 422 + + Column group name + + + Health + Santé + + src/app/core/config/config-fix.ts + 458 + + + src/app/core/config/config-fix.ts + 582 + + Column group name + + + Active Children + Enfants actifs + + src/app/core/config/config-fix.ts + 487 + + Active children filter label - true case + + + Inactive + Inactifs + + src/app/core/config/config-fix.ts + 488 + + Active children filter label - false case + + + Education + Éducation + + src/app/core/config/config-fix.ts + 541 + + Panel title + + + School History + Parcours scolaire + + src/app/core/config/config-fix.ts + 544 + + Title inside a panel + + + ASER Results + Résultats ASER + + src/app/core/config/config-fix.ts + 558 + + Title inside a panel + + + Attendance + Présence + + src/app/core/config/config-fix.ts + 564 + + Panel title + + + Height & Weight Tracking + Suivi de la taille & du poids + + src/app/core/config/config-fix.ts + 595 + + Title inside a panel + + + Educational Materials + Matériels scolaires + + src/app/core/config/config-fix.ts + 601 + + Panel title + + + Observations + Observations + + src/app/core/config/config-fix.ts + 610 + + Panel title + + + Activity + Activité + + src/app/core/config/config-fix.ts + 673 + + Panel title + + + Events & Attendance + Évènements & présence + + src/app/core/config/config-fix.ts + 702 + + Panel title + + + Basic Report + Rapport de base + + src/app/core/config/config-fix.ts + 718 + + Name of a report + + + All children + Tous les enfants + + src/app/core/config/config-fix.ts + 722 + + Label of report query + + + Male children + Garçons + + src/app/core/config/config-fix.ts + 725 + + Label of report query + + + Female children + Filles + + src/app/core/config/config-fix.ts + 729 + + Label of report query + + + All schools + Toutes les écoles + + src/app/core/config/config-fix.ts + 736 + + Label for report query + + + Children attending a school + Enfants fréquentant une école + + src/app/core/config/config-fix.ts + 739 + + Label for report query + + + Governmental schools + Écoles publiques + + src/app/core/config/config-fix.ts + 743 + + Label for report query + + + Children attending a governmental school + Enfants fréquentant une école publique + + src/app/core/config/config-fix.ts + 748 + + Label for report query + + + Male children attending a governmental school + Garçons fréquentant une école publique + + src/app/core/config/config-fix.ts + 751 + + Label for report query + + + Female children attending a governmental school + Filles fréquentant une école publique + + src/app/core/config/config-fix.ts + 755 + + Label for report query + + + Private schools + Écoles privées + + src/app/core/config/config-fix.ts + 761 + + Label for report query + + + Children attending a private school + Enfants fréquentant une école privée + + src/app/core/config/config-fix.ts + 766 + + Label for report query + + + Male children attending a private school + Garçons fréquentant une école privée + + src/app/core/config/config-fix.ts + 769 + + Label for report query + + + Female children attending a private school + Filles fréquentant une école privée + + src/app/core/config/config-fix.ts + 773 + + Label for report query + + + Event Report + Rapport d'évènement + + src/app/core/config/config-fix.ts + 783 + + Name of a report + + + Overall Activity Report + Rapport d'activité globale + + src/app/core/config/config-fix.ts + 800 + + Name of a report + + + Address + Adresse + + src/app/core/config/config-fix.ts + 828 + + + src/app/core/config/config-fix.ts + 890 + + Label for the address of a child + + + Blood Group + Groupe sanguin + + src/app/core/config/config-fix.ts + 835 + + Label for a child attribute + + + Religion + Religion + + src/app/core/config/config-fix.ts + 842 + + Label for the religion of a child + + + Mother Tongue + Langue maternelle + + src/app/core/config/config-fix.ts + 849 + + Label for the mother tongue of a child + + + Last Dental Check-Up + Dernier examen dentaire + + src/app/core/config/config-fix.ts + 856 + + Label for a child attribute + + + Language + Langue + + src/app/core/config/config-fix.ts + 883 + + Label for the language of a school + + + School Timing + Horaires scolaires + + src/app/core/config/config-fix.ts + 904 + + Label for the timing of a school + + + Motivated + Motivé + + src/app/core/config/config-fix.ts + 923 + + Label for a child attribute + + + The child is motivated during the class. + L'enfant est motivé en classe. + + src/app/core/config/config-fix.ts + 924 + + Description for a child attribute + + + Participates + Participe + + src/app/core/config/config-fix.ts + 932 + + Label for a child attribute + + + The child is actively participating in the class. + L'enfant participe activement en classe. + + src/app/core/config/config-fix.ts + 933 + + Description for a child attribute + + + Interacts + Interagi + + src/app/core/config/config-fix.ts + 941 + + Label for a child attribute + + + The child interacts with other students during the class. + L'enfant interagi avec les autres enfants pendant la classe. + + src/app/core/config/config-fix.ts + 942 + + Description for a child attribute + + + Homework + Devoirs + + src/app/core/config/config-fix.ts + 950 + + Label for a child attribute + + + The child does its homework. + L'enfant fait ses devoirs. + + src/app/core/config/config-fix.ts + 951 + + Description for a child attribute + + + On time + À l'heure + + src/app/core/config/config-fix.ts + 959 + + Label for a child attribute + + + The child is always on time for the class. + L'enfant est toujours à l'heure pour la classe. + + src/app/core/config/config-fix.ts + 960 + + Description for a child attribute + + + Asks + Pose des questions + + src/app/core/config/config-fix.ts + 968 + + Label for a child attribute + + + The child is asking questions during the class. + L'enfant pose des questions en classe. + + src/app/core/config/config-fix.ts + 969 + + Description for a child attribute + + + Listens + Écoute + + src/app/core/config/config-fix.ts + 977 + + Label for a child attribute + + + The child is listening during the class. + L'enfant écoute en classe. + + src/app/core/config/config-fix.ts + 978 + + Description for a child attribute + + + Solves on board + Résoud au tableau + + src/app/core/config/config-fix.ts + 986 + + Label for a child attribute + + + The child can solve exercises on the board. + L'enfant peut résoudre des problèmes au tableau. + + src/app/core/config/config-fix.ts + 987 + + Description for a child attribute + + + Concentrated + Concentré + + src/app/core/config/config-fix.ts + 995 + + Label for a child attribute + + + The child is concentrated during the class. + L'enfant est concentré en classe. + + src/app/core/config/config-fix.ts + 996 + + Description for a child attribute + + + Not disturbing + Ne perturbe pas + + src/app/core/config/config-fix.ts + 1004 + + Label for a child attribute + + + The child does not disturb the class. + L'enfant ne perturbe pas la classe. + + src/app/core/config/config-fix.ts + 1005 + + Description for a child attribute + + + Absent + Absent + + src/app/core/config/default-config/default-attendance-status-types.ts + 17 + + Child was absent + + + Late + En retard + + src/app/core/config/default-config/default-attendance-status-types.ts + 24 + + Child was late + + + Holiday + En vacance + + src/app/core/config/default-config/default-attendance-status-types.ts + 31 + + Child was on holiday + + + Excused + Excusé + + src/app/core/config/default-config/default-attendance-status-types.ts + 38 + + Child was excused + + + Home Visit + Visite à domicile + + src/app/core/config/default-config/default-interaction-types.ts + 10 + + Interaction type/Category of a Note + + + Talk with Guardians + Entretien avec les tuteurs + + src/app/core/config/default-config/default-interaction-types.ts + 14 + + Interaction type/Category of a Note + + + Talk with Child + Entretien avec l'enfant + + src/app/core/config/default-config/default-interaction-types.ts + 18 + + Interaction type/Category of a Note + + + Incident + Incident + + src/app/core/config/default-config/default-interaction-types.ts + 22 + + Interaction type/Category of a Note + + + Discussion/Decision + Discussion/Décision + + src/app/core/config/default-config/default-interaction-types.ts + 26 + + Interaction type/Category of a Note + + + School/Hostel Visit + Visite à l'école/auberge + + src/app/core/config/default-config/default-interaction-types.ts + 31 + + Interaction type/Category of a Note + + + Phone Call + Appel au téléphone + + src/app/core/config/default-config/default-interaction-types.ts + 35 + + Interaction type/Category of a Note + + + Talk with Coaching Teacher + Entretien avec l'enseignant de formation + + src/app/core/config/default-config/default-interaction-types.ts + 39 + + Interaction type/Category of a Note + + + Talk with Peer + Entretien avec un camarade + + src/app/core/config/default-config/default-interaction-types.ts + 43 + + Interaction type/Category of a Note + + + Talk with Neighbours + Entretien avec les voisins + + src/app/core/config/default-config/default-interaction-types.ts + 47 + + Interaction type/Category of a Note + + + Guardians' Meeting + Réunion des tuteurs + + src/app/core/config/default-config/default-interaction-types.ts + 51 + + Interaction type/Category of a Note + + + Children's Meeting + Réunion des enfants + + src/app/core/config/default-config/default-interaction-types.ts + 57 + + Interaction type/Category of a Note + + + Daily Routine + Routine quotidienne + + src/app/core/config/default-config/default-interaction-types.ts + 63 + + Interaction type/Category of a Note + + + Excursion/Trip + Excursion/Voyage + + src/app/core/config/default-config/default-interaction-types.ts + 73 + + Interaction type/Category of a Note + + + Contact with other partners (club/NGO/...) + Contact avec d'autres parternaires (club/ONG/...) + + src/app/core/config/default-config/default-interaction-types.ts + 79 + + Interaction type/Category of a Note + + + Ration Distribution + Distribution de rations + + src/app/core/config/default-config/default-interaction-types.ts + 83 + + Interaction type/Category of a Note + + + Coaching Class + Session de formation + + src/app/core/config/default-config/default-interaction-types.ts + 89 + + Interaction type/Category of a Note + + + School Class + Classe + + src/app/core/config/default-config/default-interaction-types.ts + 95 + + Interaction type/Category of a Note + + + Life Skills Workshop + Atelier de préparation à la vie + + src/app/core/config/default-config/default-interaction-types.ts + 101 + + Interaction type/Category of a Note + + + This field is required + Ce champ doit être rempli + + src/app/core/configurable-enum/edit-configurable-enum/edit-configurable-enum.component.html + 11,12 + + + src/app/core/entity-components/entity-utils/dynamic-form-components/edit-number/edit-number.component.html + 13,14 + + + src/app/core/entity-components/entity-utils/dynamic-form-components/edit-percentage/edit-percentage.component.html + 21,22 + + + src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.html + 27,31 + + + src/app/core/entity-components/entity-utils/dynamic-form-components/edit-text/edit-text.component.html + 10,11 + + Error message for any input + + + Yes + Oui + + src/app/core/confirmation-dialog/confirmation-dialog/confirmation-dialog.component.html + 13,14 + + Confirmation dialog Yes + + + No + Non + + src/app/core/confirmation-dialog/confirmation-dialog/confirmation-dialog.component.html + 20,21 + + Confirmation dialog No + + + OK + OK + + src/app/core/confirmation-dialog/confirmation-dialog/confirmation-dialog.component.html + 30,31 + + Confirmation dialog OK + + + Quick actions + Actions rapides + + src/app/core/dashboard-shortcut-widget/dashboard-shortcut-widget/dashboard-shortcut-widget.component.html + 10,11 + + Shows a list of certain actions that a user can click on + + + Generating sample data for this demo ... + Génération de l'échantillon de données pour cette démonstration ... + + src/app/core/demo-data/demo-data-generating-progress-dialog.component.ts + 1 + + + + Back + Retour + + src/app/core/entity-components/entity-details/entity-details.component.html + 25,28 + + Generic back button + + + Adding new + Ajout d'un(e) + + src/app/core/entity-components/entity-details/entity-details.component.html + 39,42 + + An entity is a child, note, school, + e.t.c + Title when adding a new entity + + + Please save before entering further data + Veuillez sauvegarder avant d'ajouter de nouvelles données + + src/app/core/entity-components/entity-details/entity-details.component.html + 59,62 + + + + Delete + + Supprimer + + + src/app/core/entity-components/entity-details/entity-details.component.html + 86,87 + + Generic delete button + + + Save + Sauvegarder + + src/app/core/entity-components/entity-form/entity-form/entity-form.component.html + 44,50 + + + src/app/core/form-dialog/form-dialog-wrapper/form-dialog-wrapper.component.html + 19,24 + + Save button for forms + + + Cancel + Annuler + + src/app/core/entity-components/entity-form/entity-form/entity-form.component.html + 54,59 + + + src/app/core/form-dialog/form-dialog-wrapper/form-dialog-wrapper.component.html + 29,34 + + Cancel button for forms + + + Edit + Modifier + + src/app/core/entity-components/entity-form/entity-form/entity-form.component.html + 68,72 + + Edit button for forms + + + Filter + Filtrer + + src/app/core/entity-components/entity-list/entity-list.component.html + 13,18 + + Allows the user to filter through entities + Filter placeholder + + + (Showing entries) + ( éléments affichés) + + src/app/core/entity-components/entity-list/entity-list.component.html + 34,37 + + The amount of entities that can be seen in a list + + + Add New + Ajouter + + src/app/core/entity-components/entity-list/entity-list.component.html + 56,60 + + Add New Button + + + Download CSV + Télécharger au format CSV + + src/app/core/entity-components/entity-list/entity-list.component.html + 76,83 + + Download list contents as CSV + + + Record deleted + Élément supprimé + + src/app/core/entity-components/entity-subrecord/entity-subrecord/entity-subrecord.component.ts + 241,240 + + Record deleted info + + + Are you sure you want to delete this record? + Êtes-vous sûr de vouloir supprimer cet élément ? + + src/app/core/entity-components/entity-subrecord/entity-subrecord/entity-subrecord.component.ts + 242 + + Delete confirmation message + + + Show All + Tout afficher + + src/app/core/entity-components/entity-subrecord/list-paginator/list-paginator.component.html + 7,11 + + All toggle for paginator + + + This field is read-only. Edit Date of Birth to change age. Select Jan 1st if you only know the year of birth. + Ce champ est en lecture seule. Modifiez la date de naissance pour modifier l'âge. Sélectionnez 1er janvier si vous ne connaissez que l'année de naissance. + + src/app/core/entity-components/entity-utils/dynamic-form-components/edit-age/edit-age.component.html + 21 + + Tooltip for the disabled age field + + + Age + Âge + + src/app/core/entity-components/entity-utils/dynamic-form-components/edit-age/edit-age.component.html + 26 + + Placeholder for the input that displays the age + + + Add + Ajouter + + src/app/core/entity-components/entity-utils/dynamic-form-components/edit-entity-array/edit-entity-array.component.ts + 16 + + context Add User(s) + Placeholder for input to add entities + + + Only numbers are allowed + Seuls les chiffres sont autorisés + + src/app/core/entity-components/entity-utils/dynamic-form-components/edit-number/edit-number.component.html + 10,11 + + + src/app/core/entity-components/entity-utils/dynamic-form-components/edit-percentage/edit-percentage.component.html + 12,13 + + Error message for number input + + + Must be equal or less than 100% + Doit être égal ou inférieur à 100%. + + src/app/core/entity-components/entity-utils/dynamic-form-components/edit-percentage/edit-percentage.component.html + 15,16 + + Error message for percentage input + + + Must be equal or more than 0% + Doit être égal ou supérieur à 0%. + + src/app/core/entity-components/entity-utils/dynamic-form-components/edit-percentage/edit-percentage.component.html + 18,19 + + Error message for percentage input + + + filename for child photo uploaded by server administrator + nom de fichier pour la photo de l'enfant téléchargé par l'administrateur du serveur + + src/app/core/entity-components/entity-utils/dynamic-form-components/edit-photo/edit-photo.component.html + 15 + + Tooltip for edit photo component + + + Select + Sélectionner + + src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.ts + 48 + + context Select User + Placeholder for input to set an entity + + + loading... + chargement... + + src/app/core/entity-components/entity-utils/entity-select/entity-select.component.ts + 29 + + A placeholder for the input element when select options are not loaded yet + + + in total + + au total + + + src/app/core/entity-components/entity-utils/view-components/display-entity-array/display-entity-array.component.html + 7,8 + + context 10 in total + Displaying the amount of involved entities + + + Preparing data (Indexing) + Préparation des données (Indexation) + + src/app/core/entity/database-indexing/database-indexing.service.ts + 57,56 + + + + Delete? + Supprimer? + + src/app/core/entity/entity-remove.service.ts + 89,88 + + Delete confirmation title + + + Are you sure you want to delete this ? + Êtes-vous sûr de vouloir supprimer cet(te) ? + + src/app/core/entity/entity-remove.service.ts + 92,90 + + Delete confirmation text + + + Deleted Entity + Élément supprimé + + src/app/core/entity/entity-remove.service.ts + 102,100 + + Deleted Entity information + + + Undo + Annuler l'action + + src/app/core/entity/entity-remove.service.ts + 129,127 + + Undo deleting an entity + + + Delete + Supprimer + + src/app/core/form-dialog/form-dialog-wrapper/form-dialog-wrapper.component.html + 45,48 + + Generic delete button + + + Save Changes? + Sauvegarder les modifications? + + src/app/core/form-dialog/form-dialog.service.ts + 59 + + Save changes header + + + Do you want to save the changes you made to the record? + Voulez-vous sauvegarder les modifications apportées à cet élément? + + src/app/core/form-dialog/form-dialog.service.ts + 60 + + Save changes message + + + More Information + Plus d'informations + + src/app/core/latest-changes/changelog/changelog.component.html + 49,50 + + Show more information about a change that was made to the app + + + Show previous changes + Afficher les modifications précédentes + + src/app/core/latest-changes/changelog/changelog.component.html + 58,59 + + + + Close + Fermer + + src/app/core/latest-changes/changelog/changelog.component.html + 66,67 + + Generic close button + + + No Changelog Available + Aucun historique des modifications disponible + + src/app/core/latest-changes/changelog/changelog.component.ts + 75 + + + + Could not load latest changes: + Les dernières modifications n'ont pas pu être chargées: + + src/app/core/latest-changes/latest-changes.service.ts + 129 + + + + A new version of the app is available! + Une nouvelle version de l'application est disponible! + + src/app/core/latest-changes/update-manager.service.ts + 104,103 + + + + Update + Mettre à jour + + src/app/core/latest-changes/update-manager.service.ts + 105,103 + + Action that a user can update the app with + + + Your account does not have the required permission for this action. + Votre compte ne dispose pas des permissions requises pour cette action. + + src/app/core/permissions/disable-entity-operation.directive.ts + 36 + + Missing permission + + + Please Sign In + Veuillez vous identifier + + src/app/core/session/login/login.component.html + 19 + + Sign in title + + + Password + Mot de passe + + src/app/core/session/login/login.component.html + 49 + + + src/app/core/webdav/cloud-file-service-user-settings/cloud-file-service-user-settings.component.html + 52,55 + + password placeholder + + + Login + S'identifier + + src/app/core/session/login/login.component.html + 68,69 + + Login button + + + Please connect to the internet and try again + Veuillez vous connecter à internet et réessayer + + src/app/core/session/login/login.component.ts + 68 + + LoginError + + + Username and/or password incorrect + Nom d'utilisateur et/ou mot de passe incorrect + + src/app/core/session/login/login.component.ts + 73 + + LoginError + + + An unexpected error occurred. + Please reload the the page and try again. + If you keep seeing this error message, please contact your system administrator. + + Une erreur inattendue s'est produite. + Veuillez recharger la page et réessayer. + Si vous continuez à voir ce message d'erreur, veuillez contacter votre administrateur système. + + + src/app/core/session/login/login.component.ts + 82,85 + + LoginError + + + Your password was changed recently. Please retry with your new password! + Votre mot de passe a été modifié récemment. Veuillez réessayer avec votre nouveau mot de passe ! + + src/app/core/session/session-service/synced-session.service.ts + 133,132 + + + + The following processes are still running in the background. Until these are finished some pages may be slow or incomplete. + Les processus suivants sont toujours en cours d'exécution en arrière-plan. Jusqu'à ce qu'ils soient terminés, certaines pages peuvent être lentes ou incomplètes. + + src/app/core/sync-status/background-processing-indicator/background-processing-indicator.component.html + 19,24 + + + + Close + Fermer + + src/app/core/sync-status/background-processing-indicator/background-processing-indicator.component.html + 53,57 + + Generic close button + + + Downloading Initial Database ... + + Téléchargement de la base de données initiale ... + + + src/app/core/sync-status/sync-status/initial-sync-dialog.component.html + 2,3 + + Download header + + + Synchronizing with remote database. + Synchronisation avec la base de données distante. + + src/app/core/sync-status/sync-status/initial-sync-dialog.component.html + 5 + + Sync notification line 1 + + + Login may not be possible until this is completed. + La connexion peut ne pas être possible tant que cette opération n'est pas terminée. + + src/app/core/sync-status/sync-status/initial-sync-dialog.component.html + 7,8 + + Sync notification line 2 + + + Synchronizing database + Synchronisation de la base de données + + src/app/core/sync-status/sync-status/sync-status.component.ts + 112 + + + + Database up-to-date + Base de données à jour + + src/app/core/sync-status/sync-status/sync-status.component.ts + 117 + + + + 0 in + 0 sur + + src/app/core/translation/TranslatableMatPaginator.ts + 8 + + + + - of + - sur + + src/app/core/translation/TranslatableMatPaginator.ts + 18,20 + + + + Items per page + Éléments par page + + src/app/core/translation/TranslatableMatPaginator.ts + 26 + + + + Next page + Page suivante + + src/app/core/translation/TranslatableMatPaginator.ts + 27 + + + + Prev page + Page précédente + + src/app/core/translation/TranslatableMatPaginator.ts + 28 + + + + First page + Première page + + src/app/core/translation/TranslatableMatPaginator.ts + 29 + + + + Last page + Dernière page + + src/app/core/translation/TranslatableMatPaginator.ts + 30 + + + + Search + Rechercher + + src/app/core/ui/search/search.component.html + 6,10 + + Search label + + + Insert at least characters + Insérer au moins caractères + + src/app/core/ui/search/search.component.html + 25,28 + + The user has inserted too few characters to start a search + + + Search in progress... + Recherche en cours... + + src/app/core/ui/search/search.component.html + 35,40 + + A search is in progress + + + There were no results + Aucun résultat + + src/app/core/ui/search/search.component.html + 43,48 + + No search results are available + + + Please only enter numbers or letters + Veuillez saisir uniquement des lettres ou des chiffres + + src/app/core/ui/search/search.component.html + 52,57 + + Invalid characters were entered into the search field + + + User Account + Compte d'utilisateur + + src/app/core/user/user-account/user-account.component.html + 19 + + User-Account label + + + Password change is not allowed in demo mode. + Le changement de mot de passe n'est pas autorisé en mode démonstration. + + src/app/core/user/user-account/user-account.component.html + 40,41 + + + + Password change is not possible while being offline. + Le changement de mot de passe n'est pas possible hors connexion. + + src/app/core/user/user-account/user-account.component.html + 46,47 + + + + retry + Essayez à nouveau + + src/app/core/user/user-account/user-account.component.html + 53,54 + + retry switching from offline to online + + + Current Password + Mot de passe actuel + + src/app/core/user/user-account/user-account.component.html + 59,64 + + + + Please provide your correct current password for confirmation. + Veuillez fournir votre mot de passe actuel correct pour confirmer. + + src/app/core/user/user-account/user-account.component.html + 73,74 + + An incorrect password was entered trying + to change the password + Password Confirmation + + + New password + Nouveau mot de passe + + src/app/core/user/user-account/user-account.component.html + 80,81 + + + + Must be at least 8 characters long. + Le mot de passe doit comporter au moins 8 caractères. + + src/app/core/user/user-account/user-account.component.html + 88,89 + + Password validation + + + Must contain lower case letters, upper case letters, symbols and numbers to be secure. + Le mot de passe doit contenir des lettres minuscules, majuscules, et des chiffres pour être sécurisé. + + src/app/core/user/user-account/user-account.component.html + 94,96 + + Illegal password pattern + + + Confirm new password + Confirmez votre nouveau mot de passe + + src/app/core/user/user-account/user-account.component.html + 103,108 + + + + Confirmation does not match your new password. + La confirmation ne correspond pas à votre nouveau mot de passe. + + src/app/core/user/user-account/user-account.component.html + 117,118 + + Illegal new password + + + Password changed successfully. + Mot de passe modifié avec succès. + + src/app/core/user/user-account/user-account.component.html + 124,125 + + + + Failed to change password: Please try again. If the problem persists contact Aam Digital support. + Échec lors de la modification du mot de passe: Please try again. If the problem persists contact Aam Digital support. + + src/app/core/user/user-account/user-account.component.html + 126,130 + + + + Change Password + Modifier le mot de passe + + src/app/core/user/user-account/user-account.component.html + 141,142 + + Change password button + + + Please enter your username and password for your Nextcloud account. This will be used for photo uploads. + Veuillez saisir votre nom d'utilisateur et votre mot de passe pour votre compte Nextcloud. Ils seront utilisés pour le téléchargement des photos. + + src/app/core/webdav/cloud-file-service-user-settings/cloud-file-service-user-settings.component.html + 4,10 + + + + Cloud Image Service User + Utilisateur du service d'image sur Cloud + + src/app/core/webdav/cloud-file-service-user-settings/cloud-file-service-user-settings.component.html + 15,21 + + Cloud username placeholder + + + Cloud Image Service Password + Mot de passe du service d'image sur Cloud + + src/app/core/webdav/cloud-file-service-user-settings/cloud-file-service-user-settings.component.html + 26,29 + + Cloud password placeholder + + + Couldn't connect to the cloud service. Please check your username and password or try again later. + Impossible de se connecter au service de cloud. Veuillez vérifier votre nom d'utilisateur et votre mot de passe ou réessayer plus tard. + + src/app/core/webdav/cloud-file-service-user-settings/cloud-file-service-user-settings.component.html + 32,37 + + + + Please enter your password for this app, so your cloud service password above will then be encrypted and stored for future uses. + Veuillez saisir votre mot de passe pour cette application. Le mot de passe de votre service cloud ci-dessus sera alors crypté et stocké pour des utilisations futures. + + src/app/core/webdav/cloud-file-service-user-settings/cloud-file-service-user-settings.component.html + 40,46 + + + + The password you entered is not correct. Please enter your user account password for this app here (not your password for the cloud service above). + Le mot de passe que vous avez saisi est incorrect. Veuillez saisir le mot de passe de votre compte utilisateur pour cette application (et non votre mot de passe pour le service cloud ci-dessus). + + src/app/core/webdav/cloud-file-service-user-settings/cloud-file-service-user-settings.component.html + 58,63 + + + + Save + Sauvegarder + + src/app/core/webdav/cloud-file-service-user-settings/cloud-file-service-user-settings.component.html + 71,73 + + Generic save button + + + Successfully saved cloud service credentials. + Les informations d'identification du service cloud ont été enregistrées avec succès. + + src/app/core/webdav/cloud-file-service-user-settings/cloud-file-service-user-settings.component.ts + 87,86 + + + + Import new data? + Importer de nouvelles données ? + + src/app/features/data-import/data-import.service.ts + 49,48 + + + + Are you sure you want to import this file? This will add or update records from the loaded file. Existing records with same "_id" in the database will be overwritten! + Êtes-vous sûr de vouloir importer ce fichier ? Cela ajoutera ou mettra à jour nouveaux éléments du fichier chargé. Les enregistrements existants avec le même "_id" dans la base de données seront écrasés ! + + src/app/features/data-import/data-import.service.ts + 50,48 + + + + Import completed? + Importation terminée? + + src/app/features/data-import/data-import.service.ts + 63,62 + + + + Import (.csv) + + Importer (.csv) + + + src/app/features/data-import/data-import/data-import.component.html + 6,7 + + Import database button + + + not true at all + complètement faux + + src/app/features/historical-data/rating-answers.ts + 4 + + Rating answer + + + rarely true + rarement vrai + + src/app/features/historical-data/rating-answers.ts + 8 + + Rating answer + + + usually true + habituellement vrai + + src/app/features/historical-data/rating-answers.ts + 12 + + Rating answer + + + absolutely True + tout à fait vrai + + src/app/features/historical-data/rating-answers.ts + 16 + + Rating answer + + + no answer possible + non applicable + + src/app/features/historical-data/rating-answers.ts + 20 + + Rating answer + + + not + pas + + src/app/features/reporting/report-row.ts + 31 + + e.g. 'not male' + Not a certain property + + + without + sans + + src/app/features/reporting/report-row.ts + 33 + + e.g. 'without religion' + Excluding a certain property + + + Reports have not been configured for you yet. + La fonctionalité "Rapports" n'a pas encore été configurée pour vous. + + src/app/features/reporting/reporting/reporting.component.html + 2,5 + + + + Ask for a setup call + demander un appel pour la mise en place + + src/app/features/reporting/reporting/reporting.component.html + 8,15 + + Button if no reports are configured yet + + + Select Report + Sélectionner un type de rapport + + src/app/features/reporting/reporting/reporting.component.html + 19,20 + + + + Enter a date range + Saisir une plage de dates + + src/app/features/reporting/reporting/reporting.component.html + 28,29 + + + + Start date + Date de début + + src/app/features/reporting/reporting/reporting.component.html + 34,39 + + Date selection for the reporting + + + End date + Date de fin + + src/app/features/reporting/reporting/reporting.component.html + 40,43 + + Date selection for the reporting + + + Calculate + Calculer + + src/app/features/reporting/reporting/reporting.component.html + 59,64 + + Calculate the results for a report + + + Download report + Télécharger le rapport + + src/app/features/reporting/reporting/reporting.component.html + 80,85 + + Button that allows to download a report + + + + diff --git a/src/locale/messages.xlf b/src/locale/messages.xlf index df22499ab8..2ab7aef770 100644 --- a/src/locale/messages.xlf +++ b/src/locale/messages.xlf @@ -6,11 +6,11 @@ Date src/app/child-dev-project/aser/model/aser.ts - 46 + 53 src/app/child-dev-project/educational-material/model/educational-material.ts - 27 + 31 src/app/child-dev-project/health-checkup/model/health-check.ts @@ -30,7 +30,7 @@ Hindi src/app/child-dev-project/aser/model/aser.ts - 50 + 57 Label of the Hindi ASER result @@ -38,7 +38,7 @@ Bengali src/app/child-dev-project/aser/model/aser.ts - 56 + 63 Label of the Bengali ASER result @@ -46,7 +46,7 @@ English src/app/child-dev-project/aser/model/aser.ts - 62 + 69 Label of the English ASER result @@ -54,7 +54,7 @@ Math src/app/child-dev-project/aser/model/aser.ts - 68 + 75 Label of the Math ASER result @@ -62,11 +62,11 @@ Remarks src/app/child-dev-project/aser/model/aser.ts - 74 + 81 src/app/core/config/config-fix.ts - 910 + 911 Label for the remarks of a ASER result @@ -74,11 +74,11 @@ Nothing src/app/child-dev-project/aser/model/mathLevels.ts - 10 + 12 src/app/child-dev-project/aser/model/readingLevels.ts - 10 + 12 Label math level @@ -86,7 +86,7 @@ Numbers 1-9 src/app/child-dev-project/aser/model/mathLevels.ts - 14 + 16 Label math level @@ -94,7 +94,7 @@ Numbers 10-99 src/app/child-dev-project/aser/model/mathLevels.ts - 18 + 20 Label math level @@ -102,7 +102,7 @@ Subtraction src/app/child-dev-project/aser/model/mathLevels.ts - 22 + 24 Label math level @@ -110,7 +110,7 @@ Division src/app/child-dev-project/aser/model/mathLevels.ts - 26 + 28 Label math level @@ -118,7 +118,7 @@ Read Letters src/app/child-dev-project/aser/model/readingLevels.ts - 14 + 16 Label reading level @@ -126,7 +126,7 @@ Read Words src/app/child-dev-project/aser/model/readingLevels.ts - 18 + 20 Label reading level @@ -134,7 +134,7 @@ Read Sentence src/app/child-dev-project/aser/model/readingLevels.ts - 22 + 24 Label reading level @@ -142,7 +142,7 @@ Read Paragraph src/app/child-dev-project/aser/model/readingLevels.ts - 26 + 28 Label reading level @@ -203,11 +203,11 @@ src/app/core/config/config-fix.ts - 787 + 788 src/app/core/config/config-fix.ts - 804 + 805 Events of an attendance @@ -258,7 +258,7 @@ Participants - Record Attendance: + Record Attendance: src/app/child-dev-project/attendance/add-day-attendance/add-day-attendance.component.html 8,11 @@ -287,7 +287,7 @@ Record event for src/app/child-dev-project/attendance/add-day-attendance/roll-call-setup/roll-call-setup.component.html - 9,15 + 9,14 Record an event for a particular date that is to be inputted @@ -306,7 +306,7 @@ My event is not listed ... src/app/child-dev-project/attendance/add-day-attendance/roll-call-setup/roll-call-setup.component.html - 75,81 + 75,80 Allows to create a new event Not listed @@ -315,7 +315,7 @@ Record Attendance src/app/child-dev-project/attendance/add-day-attendance/roll-call-setup/roll-call-setup.component.html - 93,99 + 93,98 Start recording the attendance of a child at an event @@ -362,7 +362,7 @@ Finish src/app/child-dev-project/attendance/add-day-attendance/roll-call/roll-call.component.html - 94,98 + 94,97 Finish entering the attendance of a child @@ -407,7 +407,7 @@ Abort confirmation text - attended events + attended events src/app/child-dev-project/attendance/attendance-block/attendance-block.component.html 32,34 @@ -417,7 +417,7 @@ Attended Tooltip - (excluding events excused or unknown) + (excluding events excused or unknown) src/app/child-dev-project/attendance/attendance-block/attendance-block.component.html 40,42 @@ -436,7 +436,7 @@ Remarks - All excused (out of ) src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html @@ -458,7 +458,7 @@ - attended (of attended (of ) src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html @@ -466,7 +466,7 @@ - without recorded status src/app/child-dev-project/attendance/attendance-calendar/attendance-calendar.component.html @@ -516,8 +516,7 @@ (focusedChild ? entity?.getAttendancePercentage(focusedChild) : entity?.getAttendancePercentageAverage() - ) | percent: "1.0-0" - }}"/> + ) | percent: "1.0-0""/> src/app/child-dev-project/attendance/attendance-details/attendance-details.component.html 32,40 @@ -708,7 +707,7 @@ Students more than one day absent src/app/child-dev-project/attendance/dashboard-widgets/attendance-week-dashboard/attendance-week-dashboard.component.html - 8,11 + 8,10 Dashbord attendance component subtitle @@ -760,15 +759,15 @@ src/app/core/config/config-fix.ts - 687 + 688 src/app/core/config/config-fix.ts - 792 + 793 src/app/core/config/config-fix.ts - 809 + 810 Label for the participants of a recurring activity @@ -789,10 +788,10 @@ Label for the assigned user(s) of a recurring activity - class + class src/app/child-dev-project/children/child-block/child-block.component.html - 39,41 + 36,38 e.g. 'class 8' The class a child is attending @@ -837,11 +836,11 @@ src/app/core/entity-components/entity-list/filter-generator.service.ts - 138,136 + 139,137 src/app/core/entity-components/entity-list/filter-generator.service.ts - 170,168 + 168,166 src/app/core/filter/filter-selection/filter-selection.ts @@ -852,7 +851,7 @@ Dropout src/app/child-dev-project/children/demo-data-generators/demo-child-generator.service.ts - 58 + 63 src/app/child-dev-project/children/demo-data-generators/fixtures/dropout-types.ts @@ -860,7 +859,7 @@ src/app/core/config/config-fix.ts - 631 + 632 Child status @@ -988,7 +987,7 @@ src/app/core/config/config-fix.ts - 868 + 869 Label for the name of a child @@ -1092,6 +1091,18 @@ Label for the filename of a photo of a child + + Phone Number + + src/app/child-dev-project/children/model/child.ts + 104 + + + src/app/core/config/config-fix.ts + 897 + + Label for the phone number of a child + Child @@ -1193,11 +1204,11 @@ Label gender - Total: + Total: src/app/child-dev-project/educational-material/educational-material-component/educational-material.component.html - 11,13 + 11,12 Total amount of education material including a summary Total amount @@ -1206,7 +1217,7 @@ Material src/app/child-dev-project/educational-material/model/educational-material.ts - 31 + 35 The material which has been borrowed @@ -1214,7 +1225,7 @@ Amount src/app/child-dev-project/educational-material/model/educational-material.ts - 37 + 42 The amount of the material which has been borrowed @@ -1222,7 +1233,7 @@ Description src/app/child-dev-project/educational-material/model/educational-material.ts - 41 + 47 An additional description for the borrowed material @@ -1509,7 +1520,7 @@ mat-cell *matCellDef="let childNoteInfo" class="dashboard-table-additional-info-cell" - >"/>> days + >"/>> days src/app/child-dev-project/notes/dashboard-widgets/no-recent-notes-dashboard/no-recent-notes-dashboard.component.html 55,66 @@ -2093,7 +2104,7 @@ - Currently attending class at + Currently attending class at src/app/child-dev-project/previous-schools/previous-schools.component.html 9,16 @@ -2501,23 +2512,15 @@ Download whole database (.csv) src/app/core/admin/admin/admin.component.html - 87,93 + 87,95 Download database button - - Import (.csv) - - src/app/core/admin/admin/admin.component.html - 95,101 - - Import database button - Application Configuration src/app/core/admin/admin/admin.component.html - 107,112 + 95,100 Application configuration header @@ -2525,7 +2528,7 @@ Download configuration src/app/core/admin/admin/admin.component.html - 114,120 + 102,108 Download configuration button @@ -2533,7 +2536,7 @@ Upload new configuration src/app/core/admin/admin/admin.component.html - 122,128 + 110,116 Upload configuration button @@ -2541,7 +2544,7 @@ AppConfig src/app/core/admin/admin/admin.component.html - 134,139 + 122,127 App-Config header @@ -2549,7 +2552,7 @@ Debug the PouchDB src/app/core/admin/admin/admin.component.html - 139,142 + 127,129 Debug PouchDB header @@ -2557,7 +2560,7 @@ Send to console.log() src/app/core/admin/admin/admin.component.html - 142,148 + 130,136 Log button @@ -2565,7 +2568,7 @@ Empty Database src/app/core/admin/admin/admin.component.html - 151,159 + 139,146 Empty database button @@ -2573,7 +2576,7 @@ Alert Log src/app/core/admin/admin/admin.component.html - 157,160 + 145,148 Alert log header @@ -2581,7 +2584,7 @@ Overwrite complete database? src/app/core/admin/admin/admin.component.ts - 135,134 + 126,125 @@ -2590,56 +2593,35 @@ restoring records from the loaded file. src/app/core/admin/admin/admin.component.ts - 136,134 + 127,125 Backup restored src/app/core/admin/admin/admin.component.ts - 150,149 - - - - Import new data? - - src/app/core/admin/admin/admin.component.ts - 175,174 - - - - Are you sure you want to import this file? This will add or update records from the loaded file. Existing records with same "_id" in the database will be overwritten! - - src/app/core/admin/admin/admin.component.ts - 176,174 - - - - Import completed? - - src/app/core/admin/admin/admin.component.ts - 189,188 + 141,140 Empty complete database? src/app/core/admin/admin/admin.component.ts - 212,211 + 169,168 Are you sure you want to clear the database? This will delete all existing records in the database! src/app/core/admin/admin/admin.component.ts - 213,211 + 170,168 Import completed src/app/core/admin/admin/admin.component.ts - 226,225 + 183,182 @@ -2752,7 +2734,7 @@ src/app/core/config/config-fix.ts - 653 + 654 Menu item @@ -2894,7 +2876,7 @@ src/app/core/config/config-fix.ts - 572 + 573 Title for notes overview @@ -2954,7 +2936,7 @@ src/app/core/config/config-fix.ts - 875 + 876 Label for private schools filter - true case @@ -3046,7 +3028,7 @@ src/app/core/config/config-fix.ts - 581 + 582 Column group name @@ -3070,7 +3052,7 @@ Education src/app/core/config/config-fix.ts - 540 + 541 Panel title @@ -3078,7 +3060,7 @@ School History src/app/core/config/config-fix.ts - 543 + 544 Title inside a panel @@ -3086,7 +3068,7 @@ ASER Results src/app/core/config/config-fix.ts - 557 + 558 Title inside a panel @@ -3094,7 +3076,7 @@ Attendance src/app/core/config/config-fix.ts - 563 + 564 Panel title @@ -3102,7 +3084,7 @@ Height & Weight Tracking src/app/core/config/config-fix.ts - 594 + 595 Title inside a panel @@ -3110,7 +3092,7 @@ Educational Materials src/app/core/config/config-fix.ts - 600 + 601 Panel title @@ -3118,7 +3100,7 @@ Observations src/app/core/config/config-fix.ts - 609 + 610 Panel title @@ -3126,7 +3108,7 @@ Activity src/app/core/config/config-fix.ts - 672 + 673 Panel title @@ -3134,7 +3116,7 @@ Events & Attendance src/app/core/config/config-fix.ts - 701 + 702 Panel title @@ -3142,7 +3124,7 @@ Basic Report src/app/core/config/config-fix.ts - 717 + 718 Name of a report @@ -3150,7 +3132,7 @@ All children src/app/core/config/config-fix.ts - 721 + 722 Label of report query @@ -3158,7 +3140,7 @@ Male children src/app/core/config/config-fix.ts - 724 + 725 Label of report query @@ -3166,7 +3148,7 @@ Female children src/app/core/config/config-fix.ts - 728 + 729 Label of report query @@ -3174,7 +3156,7 @@ All schools src/app/core/config/config-fix.ts - 735 + 736 Label for report query @@ -3182,7 +3164,7 @@ Children attending a school src/app/core/config/config-fix.ts - 738 + 739 Label for report query @@ -3190,7 +3172,7 @@ Governmental schools src/app/core/config/config-fix.ts - 742 + 743 Label for report query @@ -3198,7 +3180,7 @@ Children attending a governmental school src/app/core/config/config-fix.ts - 747 + 748 Label for report query @@ -3206,7 +3188,7 @@ Male children attending a governmental school src/app/core/config/config-fix.ts - 750 + 751 Label for report query @@ -3214,7 +3196,7 @@ Female children attending a governmental school src/app/core/config/config-fix.ts - 754 + 755 Label for report query @@ -3222,7 +3204,7 @@ Private schools src/app/core/config/config-fix.ts - 760 + 761 Label for report query @@ -3230,7 +3212,7 @@ Children attending a private school src/app/core/config/config-fix.ts - 765 + 766 Label for report query @@ -3238,7 +3220,7 @@ Male children attending a private school src/app/core/config/config-fix.ts - 768 + 769 Label for report query @@ -3246,7 +3228,7 @@ Female children attending a private school src/app/core/config/config-fix.ts - 772 + 773 Label for report query @@ -3254,7 +3236,7 @@ Event Report src/app/core/config/config-fix.ts - 782 + 783 Name of a report @@ -3262,7 +3244,7 @@ Overall Activity Report src/app/core/config/config-fix.ts - 799 + 800 Name of a report @@ -3270,11 +3252,11 @@ Address src/app/core/config/config-fix.ts - 827 + 828 src/app/core/config/config-fix.ts - 889 + 890 Label for the address of a child @@ -3282,7 +3264,7 @@ Blood Group src/app/core/config/config-fix.ts - 834 + 835 Label for a child attribute @@ -3290,7 +3272,7 @@ Religion src/app/core/config/config-fix.ts - 841 + 842 Label for the religion of a child @@ -3298,7 +3280,7 @@ Mother Tongue src/app/core/config/config-fix.ts - 848 + 849 Label for the mother tongue of a child @@ -3306,7 +3288,7 @@ Last Dental Check-Up src/app/core/config/config-fix.ts - 855 + 856 Label for a child attribute @@ -3314,23 +3296,15 @@ Language src/app/core/config/config-fix.ts - 882 + 883 Label for the language of a school - - Phone Number - - src/app/core/config/config-fix.ts - 896 - - Label for the phone number of a school - School Timing src/app/core/config/config-fix.ts - 903 + 904 Label for the timing of a school @@ -3338,7 +3312,7 @@ Motivated src/app/core/config/config-fix.ts - 922 + 923 Label for a child attribute @@ -3346,7 +3320,7 @@ The child is motivated during the class. src/app/core/config/config-fix.ts - 923 + 924 Description for a child attribute @@ -3354,7 +3328,7 @@ Participates src/app/core/config/config-fix.ts - 931 + 932 Label for a child attribute @@ -3362,7 +3336,7 @@ The child is actively participating in the class. src/app/core/config/config-fix.ts - 932 + 933 Description for a child attribute @@ -3370,7 +3344,7 @@ Interacts src/app/core/config/config-fix.ts - 940 + 941 Label for a child attribute @@ -3378,7 +3352,7 @@ The child interacts with other students during the class. src/app/core/config/config-fix.ts - 941 + 942 Description for a child attribute @@ -3386,7 +3360,7 @@ Homework src/app/core/config/config-fix.ts - 949 + 950 Label for a child attribute @@ -3394,7 +3368,7 @@ The child does its homework. src/app/core/config/config-fix.ts - 950 + 951 Description for a child attribute @@ -3402,7 +3376,7 @@ On time src/app/core/config/config-fix.ts - 958 + 959 Label for a child attribute @@ -3410,7 +3384,7 @@ The child is always on time for the class. src/app/core/config/config-fix.ts - 959 + 960 Description for a child attribute @@ -3418,7 +3392,7 @@ Asks src/app/core/config/config-fix.ts - 967 + 968 Label for a child attribute @@ -3426,7 +3400,7 @@ The child is asking questions during the class. src/app/core/config/config-fix.ts - 968 + 969 Description for a child attribute @@ -3434,7 +3408,7 @@ Listens src/app/core/config/config-fix.ts - 976 + 977 Label for a child attribute @@ -3442,7 +3416,7 @@ The child is listening during the class. src/app/core/config/config-fix.ts - 977 + 978 Description for a child attribute @@ -3450,7 +3424,7 @@ Solves on board src/app/core/config/config-fix.ts - 985 + 986 Label for a child attribute @@ -3458,7 +3432,7 @@ The child can solve exercises on the board. src/app/core/config/config-fix.ts - 986 + 987 Description for a child attribute @@ -3466,7 +3440,7 @@ Concentrated src/app/core/config/config-fix.ts - 994 + 995 Label for a child attribute @@ -3474,7 +3448,7 @@ The child is concentrated during the class. src/app/core/config/config-fix.ts - 995 + 996 Description for a child attribute @@ -3482,7 +3456,7 @@ Not disturbing src/app/core/config/config-fix.ts - 1003 + 1004 Label for a child attribute @@ -3490,7 +3464,7 @@ The child does not disturb the class. src/app/core/config/config-fix.ts - 1004 + 1005 Description for a child attribute @@ -3678,6 +3652,30 @@ Interaction type/Category of a Note + + This field is required + + src/app/core/configurable-enum/edit-configurable-enum/edit-configurable-enum.component.html + 11,12 + + + src/app/core/entity-components/entity-utils/dynamic-form-components/edit-number/edit-number.component.html + 13,14 + + + src/app/core/entity-components/entity-utils/dynamic-form-components/edit-percentage/edit-percentage.component.html + 21,22 + + + src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.html + 27,31 + + + src/app/core/entity-components/entity-utils/dynamic-form-components/edit-text/edit-text.component.html + 10,11 + + Error message for any input + Yes @@ -3726,7 +3724,7 @@ Generic back button - Adding new + Adding new src/app/core/entity-components/entity-details/entity-details.component.html 39,42 @@ -3793,7 +3791,7 @@ Filter placeholder - (Showing entries) + (Showing entries) src/app/core/entity-components/entity-list/entity-list.component.html 34,37 @@ -3860,7 +3858,7 @@ Add src/app/core/entity-components/entity-utils/dynamic-form-components/edit-entity-array/edit-entity-array.component.ts - 19 + 16 context Add User(s) Placeholder for input to add entities @@ -3877,26 +3875,6 @@ Error message for number input - - This field is required - - src/app/core/entity-components/entity-utils/dynamic-form-components/edit-number/edit-number.component.html - 13,14 - - - src/app/core/entity-components/entity-utils/dynamic-form-components/edit-percentage/edit-percentage.component.html - 21,22 - - - src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.html - 27,31 - - - src/app/core/entity-components/entity-utils/dynamic-form-components/edit-text/edit-text.component.html - 10,11 - - Error message for any input - Must be equal or less than 100% @@ -3925,7 +3903,7 @@ Select src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.ts - 49 + 48 context Select User Placeholder for input to set an entity @@ -3934,16 +3912,16 @@ loading... src/app/core/entity-components/entity-utils/entity-select/entity-select.component.ts - 30 + 29 A placeholder for the input element when select options are not loaded yet - in total + in total src/app/core/entity-components/entity-utils/view-components/display-entity-array/display-entity-array.component.html - 7,9 + 7,8 context 10 in total Displaying the amount of involved entities @@ -4052,14 +4030,14 @@ A new version of the app is available! src/app/core/latest-changes/update-manager.service.ts - 82,81 + 104,103 Update src/app/core/latest-changes/update-manager.service.ts - 83,81 + 105,103 Action that a user can update the app with @@ -4245,7 +4223,7 @@ Search label - Insert at least characters + Insert at least characters src/app/core/ui/search/search.component.html 25,28 @@ -4377,7 +4355,7 @@ - Failed to change password: Please try again. If the problem persists contact Aam Digital support. + Failed to change password: Please try again. If the problem persists contact Aam Digital support. src/app/core/user/user-account/user-account.component.html 126,130 @@ -4395,7 +4373,7 @@ Please enter your username and password for your Nextcloud account. This will be used for photo uploads. src/app/core/webdav/cloud-file-service-user-settings/cloud-file-service-user-settings.component.html - 4,11 + 4,10 @@ -4425,21 +4403,21 @@ Please enter your password for this app, so your cloud service password above will then be encrypted and stored for future uses. src/app/core/webdav/cloud-file-service-user-settings/cloud-file-service-user-settings.component.html - 40,47 + 40,46 The password you entered is not correct. Please enter your user account password for this app here (not your password for the cloud service above). src/app/core/webdav/cloud-file-service-user-settings/cloud-file-service-user-settings.component.html - 58,64 + 58,63 Save src/app/core/webdav/cloud-file-service-user-settings/cloud-file-service-user-settings.component.html - 71,74 + 71,73 Generic save button @@ -4450,6 +4428,36 @@ 87,86 + + Import new data? + + src/app/features/data-import/data-import.service.ts + 49,48 + + + + Are you sure you want to import this file? This will add or update records from the loaded file. Existing records with same "_id" in the database will be overwritten! + + src/app/features/data-import/data-import.service.ts + 50,48 + + + + Import completed? + + src/app/features/data-import/data-import.service.ts + 63,62 + + + + Import (.csv) + + + src/app/features/data-import/data-import/data-import.component.html + 6,7 + + Import database button + not true at all diff --git a/xliffmerge.json b/xliffmerge.json index 03398777dc..750fa5172e 100644 --- a/xliffmerge.json +++ b/xliffmerge.json @@ -8,7 +8,8 @@ "encoding": "UTF-8", "defaultLanguage": "en-US", "languages": [ - "de" + "de", + "fr" ], "removeUnusedIds": true, "supportNgxTranslate": false, From 0ad048841edbcc8d356252fc5fd9003cf2d62fc9 Mon Sep 17 00:00:00 2001 From: Schottkyc137 <45085299+Schottkyc137@users.noreply.github.com> Date: Wed, 8 Dec 2021 11:26:42 +0100 Subject: [PATCH 14/21] fix: report component throws error if no report is configured fixes: #984 --- src/app/features/reporting/reporting/reporting.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/features/reporting/reporting/reporting.component.ts b/src/app/features/reporting/reporting/reporting.component.ts index 6dd0780fb6..aa12c686ea 100644 --- a/src/app/features/reporting/reporting/reporting.component.ts +++ b/src/app/features/reporting/reporting/reporting.component.ts @@ -37,7 +37,7 @@ export class ReportingComponent implements OnInit { ngOnInit() { this.activatedRoute.data.subscribe( (data: RouteData) => { - this.availableReports = data.config.reports; + this.availableReports = data.config?.reports; if (this.availableReports?.length === 1) { this.selectedReport = this.availableReports[0]; } From b7d1470537f350c4136f434a342843041139bc04 Mon Sep 17 00:00:00 2001 From: Schottkyc137 <45085299+Schottkyc137@users.noreply.github.com> Date: Wed, 8 Dec 2021 14:04:01 +0100 Subject: [PATCH 15/21] fix(#1050): Topic is directly focused in note details fixes: #1050 --- .../notes/note-details/note-details.component.html | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/child-dev-project/notes/note-details/note-details.component.html b/src/app/child-dev-project/notes/note-details/note-details.component.html index 45c194d251..75c3edd48a 100644 --- a/src/app/child-dev-project/notes/note-details/note-details.component.html +++ b/src/app/child-dev-project/notes/note-details/note-details.component.html @@ -107,6 +107,7 @@

{{ entity.date?.toLocaleDateString() }}: {{ entity.subject }}

placeholder="Topic / Summary" name="subject" type="text" + cdkFocusInitial [(ngModel)]="entity.subject" /> From e1f94b6c3a54501df04d78289bcfb118ea37537b Mon Sep 17 00:00:00 2001 From: Snyk bot Date: Sat, 11 Dec 2021 10:27:58 +0000 Subject: [PATCH 16/21] refactor: upgrade @sentry/browser from 6.14.3 to 6.15.0 (#1066) --- package-lock.json | 126 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/package-lock.json b/package-lock.json index e0b86c1bf0..c10f1e0f0e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,7 @@ "@fortawesome/free-regular-svg-icons": "^5.15.2", "@fortawesome/free-solid-svg-icons": "^5.15.4", "@ngneat/until-destroy": "^8.1.4", - "@sentry/browser": "^6.14.3", + "@sentry/browser": "^6.15.0", "angulartics2": "^10.1.0", "crypto-js": "^4.1.1", "deep-object-diff": "^1.1.0", @@ -4913,13 +4913,13 @@ "dev": true }, "node_modules/@sentry/browser": { - "version": "6.14.3", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.14.3.tgz", - "integrity": "sha512-qp4K+XNYNWQxO1U6gvf6VgOMmI0JKCsvx1pKu7X4ZK7sGHmMgfwj7lukpxsqXZvDop8RxUI8/1KJ0azUsHlpAQ==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.15.0.tgz", + "integrity": "sha512-ZiqfHK5DMVgDsgMTuSwxilWIqEnZzy4yuJ9Sr6Iap1yZddPSiKHYjbBieSHn57UsWHViRB3ojbwu44LfvXKJdQ==", "dependencies": { - "@sentry/core": "6.14.3", - "@sentry/types": "6.14.3", - "@sentry/utils": "6.14.3", + "@sentry/core": "6.15.0", + "@sentry/types": "6.15.0", + "@sentry/utils": "6.15.0", "tslib": "^1.9.3" }, "engines": { @@ -4932,14 +4932,14 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/core": { - "version": "6.14.3", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.14.3.tgz", - "integrity": "sha512-3yHmYZzkXlOqPi/CGlNhb2RzXFvYAryBhrMJV26KJ9ULJF8r4OJ7TcWlupDooGk6Knmq8GQML58OApUvYi8IKg==", - "dependencies": { - "@sentry/hub": "6.14.3", - "@sentry/minimal": "6.14.3", - "@sentry/types": "6.14.3", - "@sentry/utils": "6.14.3", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.15.0.tgz", + "integrity": "sha512-mCbKyqvD1G3Re6gv6N8tRkBz84gvVWDfLtC6d1WBArIopzter6ktEbvq0cMT6EOvGI2OLXuJ6mtHA93/Q0gGpw==", + "dependencies": { + "@sentry/hub": "6.15.0", + "@sentry/minimal": "6.15.0", + "@sentry/types": "6.15.0", + "@sentry/utils": "6.15.0", "tslib": "^1.9.3" }, "engines": { @@ -4952,12 +4952,12 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/hub": { - "version": "6.14.3", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.14.3.tgz", - "integrity": "sha512-ZRWLHcAcv4oZAbpSwvCkXlaa1rVFDxcb9lxo5/5v5n6qJq2IG5Z+bXuT2DZlIHQmuCuqRnFSwuBjmBXY7OTHaw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.15.0.tgz", + "integrity": "sha512-cUbHPeG6kKpGBaEMgbTWeU03Y1Up5T3urGF+cgtrn80PmPYYSUPvVvWlZQWPb8CJZ1yQ0gySWo5RUTatBFrEHA==", "dependencies": { - "@sentry/types": "6.14.3", - "@sentry/utils": "6.14.3", + "@sentry/types": "6.15.0", + "@sentry/utils": "6.15.0", "tslib": "^1.9.3" }, "engines": { @@ -4970,12 +4970,12 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/minimal": { - "version": "6.14.3", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.14.3.tgz", - "integrity": "sha512-2KNOJuhBpMICoOgdxX56UcO9vGdxCw5mNGYdWvJdKrMwRQr7mC+Fc9lTuTbrYTj6zkfklj2lbdDc3j44Rg787A==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.15.0.tgz", + "integrity": "sha512-7RJIvZsjBa1qFUfMrAzQsWdfZT6Gm4t6ZTYfkpsXPBA35hkzglKbBrhhsUvkxGIhUGw/PiCUqxBUjcmzQP0vfg==", "dependencies": { - "@sentry/hub": "6.14.3", - "@sentry/types": "6.14.3", + "@sentry/hub": "6.15.0", + "@sentry/types": "6.15.0", "tslib": "^1.9.3" }, "engines": { @@ -4988,19 +4988,19 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/types": { - "version": "6.14.3", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.14.3.tgz", - "integrity": "sha512-GuyqvjQ/N0hIgAjGD1Rn0aQ8kpLBBsImk+Aoh7YFhnvXRhCNkp9N8BuXTfC/uMdMshcWa1OFik/udyjdQM3EJA==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.15.0.tgz", + "integrity": "sha512-zBw5gPUsofXUSpS3ZAXqRNedLRBvirl3sqkj2Lez7X2EkKRgn5D8m9fQIrig/X3TsKcXUpijDW5Buk5zeCVzJA==", "engines": { "node": ">=6" } }, "node_modules/@sentry/utils": { - "version": "6.14.3", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.14.3.tgz", - "integrity": "sha512-jsCnclEsR2sV9aHMuaLA5gvxSa0xV4Sc6IJCJ81NTTdb/A5fFbteFBbhuISGF9YoFW1pwbpjuTA6+efXwvLwNQ==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.15.0.tgz", + "integrity": "sha512-gnhKKyFtnNmKWjDizo7VKD0/Vx8cgW1lCusM6WI7jy2jlO3bQA0+Dzgmr4mIReZ74mq4VpOd2Vfrx7ZldW1DMw==", "dependencies": { - "@sentry/types": "6.14.3", + "@sentry/types": "6.15.0", "tslib": "^1.9.3" }, "engines": { @@ -35418,13 +35418,13 @@ } }, "@sentry/browser": { - "version": "6.14.3", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.14.3.tgz", - "integrity": "sha512-qp4K+XNYNWQxO1U6gvf6VgOMmI0JKCsvx1pKu7X4ZK7sGHmMgfwj7lukpxsqXZvDop8RxUI8/1KJ0azUsHlpAQ==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.15.0.tgz", + "integrity": "sha512-ZiqfHK5DMVgDsgMTuSwxilWIqEnZzy4yuJ9Sr6Iap1yZddPSiKHYjbBieSHn57UsWHViRB3ojbwu44LfvXKJdQ==", "requires": { - "@sentry/core": "6.14.3", - "@sentry/types": "6.14.3", - "@sentry/utils": "6.14.3", + "@sentry/core": "6.15.0", + "@sentry/types": "6.15.0", + "@sentry/utils": "6.15.0", "tslib": "^1.9.3" }, "dependencies": { @@ -35436,14 +35436,14 @@ } }, "@sentry/core": { - "version": "6.14.3", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.14.3.tgz", - "integrity": "sha512-3yHmYZzkXlOqPi/CGlNhb2RzXFvYAryBhrMJV26KJ9ULJF8r4OJ7TcWlupDooGk6Knmq8GQML58OApUvYi8IKg==", - "requires": { - "@sentry/hub": "6.14.3", - "@sentry/minimal": "6.14.3", - "@sentry/types": "6.14.3", - "@sentry/utils": "6.14.3", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.15.0.tgz", + "integrity": "sha512-mCbKyqvD1G3Re6gv6N8tRkBz84gvVWDfLtC6d1WBArIopzter6ktEbvq0cMT6EOvGI2OLXuJ6mtHA93/Q0gGpw==", + "requires": { + "@sentry/hub": "6.15.0", + "@sentry/minimal": "6.15.0", + "@sentry/types": "6.15.0", + "@sentry/utils": "6.15.0", "tslib": "^1.9.3" }, "dependencies": { @@ -35455,12 +35455,12 @@ } }, "@sentry/hub": { - "version": "6.14.3", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.14.3.tgz", - "integrity": "sha512-ZRWLHcAcv4oZAbpSwvCkXlaa1rVFDxcb9lxo5/5v5n6qJq2IG5Z+bXuT2DZlIHQmuCuqRnFSwuBjmBXY7OTHaw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.15.0.tgz", + "integrity": "sha512-cUbHPeG6kKpGBaEMgbTWeU03Y1Up5T3urGF+cgtrn80PmPYYSUPvVvWlZQWPb8CJZ1yQ0gySWo5RUTatBFrEHA==", "requires": { - "@sentry/types": "6.14.3", - "@sentry/utils": "6.14.3", + "@sentry/types": "6.15.0", + "@sentry/utils": "6.15.0", "tslib": "^1.9.3" }, "dependencies": { @@ -35472,12 +35472,12 @@ } }, "@sentry/minimal": { - "version": "6.14.3", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.14.3.tgz", - "integrity": "sha512-2KNOJuhBpMICoOgdxX56UcO9vGdxCw5mNGYdWvJdKrMwRQr7mC+Fc9lTuTbrYTj6zkfklj2lbdDc3j44Rg787A==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.15.0.tgz", + "integrity": "sha512-7RJIvZsjBa1qFUfMrAzQsWdfZT6Gm4t6ZTYfkpsXPBA35hkzglKbBrhhsUvkxGIhUGw/PiCUqxBUjcmzQP0vfg==", "requires": { - "@sentry/hub": "6.14.3", - "@sentry/types": "6.14.3", + "@sentry/hub": "6.15.0", + "@sentry/types": "6.15.0", "tslib": "^1.9.3" }, "dependencies": { @@ -35489,16 +35489,16 @@ } }, "@sentry/types": { - "version": "6.14.3", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.14.3.tgz", - "integrity": "sha512-GuyqvjQ/N0hIgAjGD1Rn0aQ8kpLBBsImk+Aoh7YFhnvXRhCNkp9N8BuXTfC/uMdMshcWa1OFik/udyjdQM3EJA==" + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.15.0.tgz", + "integrity": "sha512-zBw5gPUsofXUSpS3ZAXqRNedLRBvirl3sqkj2Lez7X2EkKRgn5D8m9fQIrig/X3TsKcXUpijDW5Buk5zeCVzJA==" }, "@sentry/utils": { - "version": "6.14.3", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.14.3.tgz", - "integrity": "sha512-jsCnclEsR2sV9aHMuaLA5gvxSa0xV4Sc6IJCJ81NTTdb/A5fFbteFBbhuISGF9YoFW1pwbpjuTA6+efXwvLwNQ==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.15.0.tgz", + "integrity": "sha512-gnhKKyFtnNmKWjDizo7VKD0/Vx8cgW1lCusM6WI7jy2jlO3bQA0+Dzgmr4mIReZ74mq4VpOd2Vfrx7ZldW1DMw==", "requires": { - "@sentry/types": "6.14.3", + "@sentry/types": "6.15.0", "tslib": "^1.9.3" }, "dependencies": { diff --git a/package.json b/package.json index f3e535abc3..771b07f482 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "@fortawesome/free-regular-svg-icons": "^5.15.2", "@fortawesome/free-solid-svg-icons": "^5.15.4", "@ngneat/until-destroy": "^8.1.4", - "@sentry/browser": "^6.14.3", + "@sentry/browser": "^6.15.0", "angulartics2": "^10.1.0", "crypto-js": "^4.1.1", "deep-object-diff": "^1.1.0", From 90d59760147e9cfb1c7fc6d5385e546030fb31e2 Mon Sep 17 00:00:00 2001 From: Simon <33730997+TheSlimvReal@users.noreply.github.com> Date: Fri, 17 Dec 2021 17:34:01 +0100 Subject: [PATCH 17/21] fix(*): username input is automatically focused on login screen (#1024) --- src/app/core/session/login/login.component.html | 2 +- src/app/core/session/login/login.component.spec.ts | 9 +++++++++ src/app/core/session/login/login.component.ts | 10 ++++++++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/app/core/session/login/login.component.html b/src/app/core/session/login/login.component.html index 23fd388477..8e507ed2c7 100644 --- a/src/app/core/session/login/login.component.html +++ b/src/app/core/session/login/login.component.html @@ -27,6 +27,7 @@