Bump angular to v14

pull/10822/head
Oliver Günther 3 years ago
parent c2ec1a256c
commit facc347fc3
No known key found for this signature in database
GPG Key ID: A3A8BDAD7C0C552C
  1. 1
      frontend/.gitignore
  2. 2
      frontend/angular.json
  3. 59419
      frontend/package-lock.json
  4. 52
      frontend/package.json
  5. 4
      frontend/src/app/core/forms/forms.service.spec.ts
  6. 10
      frontend/src/app/core/forms/forms.service.ts
  7. 4
      frontend/src/app/features/enterprise/enterprise-modal/enterprise-trial-form/ee-trial-form.component.ts
  8. 14
      frontend/src/app/features/enterprise/enterprise-modal/enterprise-trial.modal.ts
  9. 4
      frontend/src/app/features/enterprise/enterprise-trial.service.ts
  10. 4
      frontend/src/app/features/invite-user-modal/principal/principal-search.component.ts
  11. 10
      frontend/src/app/features/invite-user-modal/principal/principal.component.ts
  12. 10
      frontend/src/app/features/invite-user-modal/project-selection/project-selection.component.ts
  13. 4
      frontend/src/app/features/invite-user-modal/role/role-search.component.ts
  14. 6
      frontend/src/app/features/projects/components/new-project/new-project.component.ts
  15. 4
      frontend/src/app/features/user-preferences/notifications-settings/inline-create/notification-setting-inline-create.component.ts
  16. 64
      frontend/src/app/features/user-preferences/notifications-settings/page/notifications-settings-page.component.ts
  17. 26
      frontend/src/app/features/user-preferences/notifications-settings/table/notification-settings-table.component.ts
  18. 6
      frontend/src/app/features/user-preferences/reminder-settings/email-alerts/email-alerts-settings.component.ts
  19. 6
      frontend/src/app/features/user-preferences/reminder-settings/immediate-reminders/immediate-reminder-settings.component.ts
  20. 10
      frontend/src/app/features/user-preferences/reminder-settings/page/reminder-settings-page.component.ts
  21. 6
      frontend/src/app/features/user-preferences/reminder-settings/pause-reminders/pause-reminders.component.ts
  22. 20
      frontend/src/app/features/user-preferences/reminder-settings/reminder-time/reminder-settings-daily-time.component.ts
  23. 12
      frontend/src/app/features/user-preferences/reminder-settings/workdays/workdays-settings.component.ts
  24. 1
      frontend/src/app/features/work-packages/components/wp-table/timeline/container/wp-timeline-container.directive.ts
  25. 1
      frontend/src/app/features/work-packages/routing/wp-view-base/view-services/wp-view-selection.service.ts
  26. 6
      frontend/src/app/shared/components/dynamic-forms/components/dynamic-form/dynamic-form.component.spec.ts
  27. 8
      frontend/src/app/shared/components/dynamic-forms/components/dynamic-form/dynamic-form.component.ts
  28. 4
      frontend/src/app/shared/components/dynamic-forms/services/dynamic-form/dynamic-form.service.spec.ts
  29. 8
      frontend/src/app/shared/components/dynamic-forms/services/dynamic-form/dynamic-form.service.ts
  30. 6
      frontend/src/app/shared/components/dynamic-forms/spec/helpers.ts
  31. 6
      frontend/src/app/shared/components/fields/changeset/resource-changeset.ts
  32. 1
      frontend/src/app/shared/components/op-context-menu/handlers/op-context-menu-trigger.directive.ts
  33. 13
      frontend/src/app/shared/components/op-context-menu/op-context-menu.service.ts
  34. 1
      frontend/src/app/shared/directives/a11y/keyboard-shortcut.service.ts
  35. 7
      frontend/src/app/shared/helpers/set-click-position/set-click-position.ts
  36. 6
      frontend/src/app/spot/components/form-field/form-binding.directive.ts
  37. 8
      frontend/src/app/spot/components/form-field/stories/FormFieldErrorSlot.example.ts
  38. 14
      frontend/src/polyfills.ts
  39. 6
      frontend/src/test.ts

@ -1,3 +1,4 @@
/.angular/cache
/.sass-cache /.sass-cache
/bower_components /bower_components
/coverage /coverage

@ -76,7 +76,6 @@
"optimization": true, "optimization": true,
"outputHashing": "all", "outputHashing": "all",
"sourceMap": false, "sourceMap": false,
"extractCss": true,
"namedChunks": false, "namedChunks": false,
"extractLicenses": true, "extractLicenses": true,
"fileReplacements": [ "fileReplacements": [
@ -136,7 +135,6 @@
} }
} }
}, },
"defaultProject": "OpenProject",
"schematics": { "schematics": {
"@schematics/angular:component": { "@schematics/angular:component": {
"prefix": "op", "prefix": "op",

File diff suppressed because it is too large Load Diff

@ -5,17 +5,17 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "~12.2.6", "@angular-devkit/build-angular": "^14.2.5",
"@angular-eslint/builder": "^12.0.0", "@angular-eslint/builder": "^13.2.1",
"@angular-eslint/eslint-plugin": "^12.0.0", "@angular-eslint/eslint-plugin": "^13.2.1",
"@angular-eslint/eslint-plugin-template": "^12.0.0", "@angular-eslint/eslint-plugin-template": "^13.2.1",
"@angular-eslint/schematics": "12.5.0", "@angular-eslint/schematics": "13.2.1",
"@angular-eslint/template-parser": "^12.0.0", "@angular-eslint/template-parser": "^13.2.1",
"@angular/language-service": "12.2.6", "@angular/language-service": "14.0.2",
"@babel/core": "^7.18.5", "@babel/core": "^7.18.5",
"@compodoc/compodoc": "^1.1.19", "@compodoc/compodoc": "^1.1.19",
"@html-eslint/eslint-plugin": "^0.11.0", "@html-eslint/eslint-plugin": "^0.13.1",
"@html-eslint/parser": "^0.11.0", "@html-eslint/parser": "^0.13.1",
"@jsdevtools/coverage-istanbul-loader": "3.0.5", "@jsdevtools/coverage-istanbul-loader": "3.0.5",
"@storybook/addon-actions": "^6.5.10", "@storybook/addon-actions": "^6.5.10",
"@storybook/addon-essentials": "^6.5.10", "@storybook/addon-essentials": "^6.5.10",
@ -29,7 +29,7 @@
"@storybook/preset-scss": "^1.0.3", "@storybook/preset-scss": "^1.0.3",
"@storybook/testing-library": "^0.0.13", "@storybook/testing-library": "^0.0.13",
"@types/chart.js": "^2.9.20", "@types/chart.js": "^2.9.20",
"@types/codemirror": "0.0.87", "@types/codemirror": "5.60.5",
"@types/dragula": "^3.7.0", "@types/dragula": "^3.7.0",
"@types/hammerjs": "^2.0.36", "@types/hammerjs": "^2.0.36",
"@types/jasmine": "~3.6.0", "@types/jasmine": "~3.6.0",
@ -79,21 +79,21 @@
"style-loader": "^3.3.1", "style-loader": "^3.3.1",
"theo": "^8.1.5", "theo": "^8.1.5",
"ts-node": "~8.3.0", "ts-node": "~8.3.0",
"typescript": "~4.2.4", "typescript": "~4.7.4",
"webpack-bundle-analyzer": "^4.4.2" "webpack-bundle-analyzer": "^4.4.2"
}, },
"dependencies": { "dependencies": {
"@angular/animations": "~12.2.6", "@angular/animations": "^14.2.5",
"@angular/cdk": "^12.2.6", "@angular/cdk": "^14.2.4",
"@angular/cli": "~12.2.6", "@angular/cli": "^14.2.5",
"@angular/common": "~12.2.6", "@angular/common": "^14.2.5",
"@angular/compiler": "~12.2.6", "@angular/compiler": "^14.2.5",
"@angular/compiler-cli": "~12.2.6", "@angular/compiler-cli": "^14.2.5",
"@angular/core": "~12.2.6", "@angular/core": "^14.2.5",
"@angular/forms": "~12.2.6", "@angular/forms": "^14.2.5",
"@angular/platform-browser": "~12.2.6", "@angular/platform-browser": "^14.2.5",
"@angular/platform-browser-dynamic": "~12.2.6", "@angular/platform-browser-dynamic": "^14.2.5",
"@angular/router": "~12.2.6", "@angular/router": "^14.2.5",
"@appsignal/javascript": "^1.3.23", "@appsignal/javascript": "^1.3.23",
"@appsignal/plugin-breadcrumbs-console": "^1.1.24", "@appsignal/plugin-breadcrumbs-console": "^1.1.24",
"@appsignal/plugin-breadcrumbs-network": "^1.1.21", "@appsignal/plugin-breadcrumbs-network": "^1.1.21",
@ -114,8 +114,8 @@
"@sentry/angular": "6.2.3", "@sentry/angular": "6.2.3",
"@sentry/tracing": "6.2.3", "@sentry/tracing": "6.2.3",
"@sentry/types": "^6.2.3", "@sentry/types": "^6.2.3",
"@uirouter/angular": "^8.0.1", "@uirouter/angular": "^9.1.0",
"@uirouter/core": "^6.0.7", "@uirouter/core": "^6.0.8",
"@uirouter/rx": "^0.6.5", "@uirouter/rx": "^0.6.5",
"@w11k/ngx-componentdestroyed": "^5.0.2", "@w11k/ngx-componentdestroyed": "^5.0.2",
"@xeokit/xeokit-bim-viewer": "2.3.10", "@xeokit/xeokit-bim-viewer": "2.3.10",
@ -171,8 +171,8 @@
}, },
"scripts": { "scripts": {
"analyze": "ng build --configuration production --stats-json && webpack-bundle-analyzer -h 0.0.0.0 -p 9999 ../public/assets/frontend/stats.json", "analyze": "ng build --configuration production --stats-json && webpack-bundle-analyzer -h 0.0.0.0 -p 9999 ../public/assets/frontend/stats.json",
"build": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --configuration production --named-chunks --extract-css --source-map", "build": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --configuration production --named-chunks --source-map",
"build:watch": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --watch --named-chunks --extract-css", "build:watch": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --watch --named-chunks",
"tokens:generate": "theo src/app/spot/styles/tokens/tokens.yml --transform web --format sass,json --dest src/app/spot/styles/tokens/dist", "tokens:generate": "theo src/app/spot/styles/tokens/tokens.yml --transform web --format sass,json --dest src/app/spot/styles/tokens/dist",
"icon-font:generate": "node ./src/app/spot/icon-font/generate.js ./src/app/spot/icon-font", "icon-font:generate": "node ./src/app/spot/icon-font/generate.js ./src/app/spot/icon-font",
"serve": "NG_PERSISTENT_BUILD_CACHE=1 node --max_old_space_size=8096 ./node_modules/@angular/cli/bin/ng serve --host 0.0.0.0 --public-host http://localhost:4200", "serve": "NG_PERSISTENT_BUILD_CACHE=1 node --max_old_space_size=8096 ./node_modules/@angular/cli/bin/ng serve --host 0.0.0.0 --public-host http://localhost:4200",

@ -1,7 +1,7 @@
import { TestBed } from '@angular/core/testing'; import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { FormBuilder } from '@angular/forms'; import { UntypedFormBuilder } from '@angular/forms';
import { FormsService } from './forms.service'; import { FormsService } from './forms.service';
describe('FormsService', () => { describe('FormsService', () => {
@ -26,7 +26,7 @@ describe('FormsService', () => {
], ],
}, },
}; };
const formBuilder = new FormBuilder(); const formBuilder = new UntypedFormBuilder();
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { catchError, map } from 'rxjs/operators'; import { catchError, map } from 'rxjs/operators';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
@ -12,7 +12,7 @@ export class FormsService {
private _httpClient:HttpClient, private _httpClient:HttpClient,
) { } ) { }
submit$(form:FormGroup, resourceEndpoint:string, resourceId?:string, formHttpMethod?:'post' | 'patch', formSchema?:IOPFormSchema):Observable<any> { submit$(form:UntypedFormGroup, resourceEndpoint:string, resourceId?:string, formHttpMethod?:'post' | 'patch', formSchema?:IOPFormSchema):Observable<any> {
const modelToSubmit = this.formatModelToSubmit(form.getRawValue(), formSchema); const modelToSubmit = this.formatModelToSubmit(form.getRawValue(), formSchema);
const httpMethod = resourceId ? 'patch' : (formHttpMethod || 'post'); const httpMethod = resourceId ? 'patch' : (formHttpMethod || 'post');
const url = resourceId ? `${resourceEndpoint}/${resourceId}` : resourceEndpoint; const url = resourceId ? `${resourceEndpoint}/${resourceId}` : resourceEndpoint;
@ -37,7 +37,7 @@ export class FormsService {
); );
} }
validateForm$(form:FormGroup, resourceEndpoint:string, formSchema?:IOPFormSchema):Observable<any> { validateForm$(form:UntypedFormGroup, resourceEndpoint:string, formSchema?:IOPFormSchema):Observable<any> {
const modelToSubmit = this.formatModelToSubmit(form.value, formSchema); const modelToSubmit = this.formatModelToSubmit(form.value, formSchema);
return this._httpClient return this._httpClient
@ -116,7 +116,7 @@ export class FormsService {
return model; return model;
} }
private handleBackendFormValidationErrors(error:HttpErrorResponse, form:FormGroup):void { private handleBackendFormValidationErrors(error:HttpErrorResponse, form:UntypedFormGroup):void {
const errors:IOPFormError[] = error?.error?._embedded?.errors const errors:IOPFormError[] = error?.error?._embedded?.errors
? error?.error?._embedded?.errors : [error.error]; ? error?.error?._embedded?.errors : [error.error];
const formErrors = this.getFormattedErrors(errors); const formErrors = this.getFormattedErrors(errors);
@ -124,7 +124,7 @@ export class FormsService {
this.setFormValidationErrors(formErrors, form); this.setFormValidationErrors(formErrors, form);
} }
private setFormValidationErrors(errors:IFormattedValidationError[], form:FormGroup) { private setFormValidationErrors(errors:IFormattedValidationError[], form:UntypedFormGroup) {
errors.forEach((err:any) => { errors.forEach((err:any) => {
const formControl = form.get(err.key) || form.get('_links')?.get(err.key); const formControl = form.get(err.key) || form.get('_links')?.get(err.key);

@ -32,7 +32,7 @@ import {
ElementRef, ElementRef,
} from '@angular/core'; } from '@angular/core';
import { import {
FormBuilder, UntypedFormBuilder,
Validators, Validators,
} from '@angular/forms'; } from '@angular/forms';
import { I18nService } from 'core-app/core/i18n/i18n.service'; import { I18nService } from 'core-app/core/i18n/i18n.service';
@ -97,7 +97,7 @@ export class EETrialFormComponent {
constructor( constructor(
readonly elementRef:ElementRef, readonly elementRef:ElementRef,
readonly I18n:I18nService, readonly I18n:I18nService,
readonly formBuilder:FormBuilder, readonly formBuilder:UntypedFormBuilder,
readonly currentUserService:CurrentUserService, readonly currentUserService:CurrentUserService,
readonly configurationService:ConfigurationService, readonly configurationService:ConfigurationService,
readonly eeTrialService:EnterpriseTrialService, readonly eeTrialService:EnterpriseTrialService,

@ -36,14 +36,8 @@ import {
Input, Input,
ViewChild, ViewChild,
} from '@angular/core'; } from '@angular/core';
import { import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
DomSanitizer, import { UntypedFormControl, UntypedFormGroup } from '@angular/forms';
SafeResourceUrl,
} from '@angular/platform-browser';
import {
FormControl,
FormGroup,
} from '@angular/forms';
import { OpModalComponent } from 'core-app/shared/components/modal/modal.component'; import { OpModalComponent } from 'core-app/shared/components/modal/modal.component';
import { OpModalLocalsToken } from 'core-app/shared/components/modal/modal.service'; import { OpModalLocalsToken } from 'core-app/shared/components/modal/modal.service';
import { OpModalLocalsMap } from 'core-app/shared/components/modal/modal.types'; import { OpModalLocalsMap } from 'core-app/shared/components/modal/modal.types';
@ -66,7 +60,7 @@ export class EnterpriseTrialModalComponent extends OpModalComponent implements A
@Input() public opReferrer:string; @Input() public opReferrer:string;
public trialForm:FormGroup; public trialForm:UntypedFormGroup;
public trustedEEVideoURL:SafeResourceUrl; public trustedEEVideoURL:SafeResourceUrl;
@ -131,7 +125,7 @@ export class EnterpriseTrialModalComponent extends OpModalComponent implements A
// checks if form is valid and submits it // checks if form is valid and submits it
public onSubmit():void { public onSubmit():void {
if (this.trialForm.valid) { if (this.trialForm.valid) {
this.trialForm.addControl('_type', new FormControl('enterprise-trial')); this.trialForm.addControl('_type', new UntypedFormControl('enterprise-trial'));
void this.eeTrialService.sendForm(this.trialForm); void this.eeTrialService.sendForm(this.trialForm);
} }
} }

@ -42,6 +42,8 @@ import {
import { I18nService } from 'core-app/core/i18n/i18n.service'; import { I18nService } from 'core-app/core/i18n/i18n.service';
import { PathHelperService } from 'core-app/core/path-helper/path-helper.service'; import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
import { ToastService } from 'core-app/shared/components/toaster/toast.service'; import { ToastService } from 'core-app/shared/components/toaster/toast.service';
import { UntypedFormGroup } from '@angular/forms';
import { input } from 'reactivestates';
import { EXTERNAL_REQUEST_HEADER } from 'core-app/features/hal/http/openproject-header-interceptor'; import { EXTERNAL_REQUEST_HEADER } from 'core-app/features/hal/http/openproject-header-interceptor';
import { EnterpriseTrialStore } from 'core-app/features/enterprise/enterprise-trial.store'; import { EnterpriseTrialStore } from 'core-app/features/enterprise/enterprise-trial.store';
import { GonType } from 'core-app/core/gon/gon.service'; import { GonType } from 'core-app/core/gon/gon.service';
@ -128,7 +130,7 @@ export class EnterpriseTrialService {
// send POST request with form object // send POST request with form object
// receive an enterprise trial link to access a token // receive an enterprise trial link to access a token
public sendForm(form:FormGroup):Promise<unknown> { public sendForm(form:UntypedFormGroup):Promise<unknown> {
const request:unknown = { ...form.value, token_version: this.tokenVersion }; const request:unknown = { ...form.value, token_version: this.tokenVersion };
return this.http return this.http
.post( .post(

@ -6,7 +6,7 @@ import {
Output, Output,
ElementRef, ElementRef,
} from '@angular/core'; } from '@angular/core';
import { FormControl } from '@angular/forms'; import { UntypedFormControl } from '@angular/forms';
import { import {
Observable, Observable,
BehaviorSubject, BehaviorSubject,
@ -42,7 +42,7 @@ interface NgSelectPrincipalOption {
templateUrl: './principal-search.component.html', templateUrl: './principal-search.component.html',
}) })
export class PrincipalSearchComponent extends UntilDestroyedMixin implements OnInit { export class PrincipalSearchComponent extends UntilDestroyedMixin implements OnInit {
@Input() spotFormBinding:FormControl; @Input() spotFormBinding:UntypedFormControl;
@Input() type:PrincipalType; @Input() type:PrincipalType;

@ -4,8 +4,8 @@ import {
} from '@angular/core'; } from '@angular/core';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { import {
FormGroup, UntypedFormGroup,
FormControl, UntypedFormControl,
Validators, Validators,
AbstractControl, AbstractControl,
} from '@angular/forms'; } from '@angular/forms';
@ -99,10 +99,10 @@ export class PrincipalComponent implements OnInit {
}, },
}; };
public principalForm = new FormGroup({ public principalForm = new UntypedFormGroup({
// eslint-disable-next-line @typescript-eslint/unbound-method // eslint-disable-next-line @typescript-eslint/unbound-method
principal: new FormControl(null, [Validators.required]), principal: new UntypedFormControl(null, [Validators.required]),
userDynamicFields: new FormGroup({}), userDynamicFields: new UntypedFormGroup({}),
// eslint-disable-next-line @typescript-eslint/unbound-method // eslint-disable-next-line @typescript-eslint/unbound-method
role: new FormControl(null, [Validators.required]), role: new FormControl(null, [Validators.required]),
message: new FormControl(''), message: new FormControl(''),

@ -10,8 +10,8 @@ import {
} from '@angular/core'; } from '@angular/core';
import { import {
AbstractControl, AbstractControl,
FormControl, UntypedFormControl,
FormGroup, UntypedFormGroup,
Validators, Validators,
} from '@angular/forms'; } from '@angular/forms';
import { I18nService } from 'core-app/core/i18n/i18n.service'; import { I18nService } from 'core-app/core/i18n/i18n.service';
@ -73,11 +73,11 @@ export class ProjectSelectionComponent implements OnInit {
}, },
]; ];
projectAndTypeForm = new FormGroup({ projectAndTypeForm = new UntypedFormGroup({
// eslint-disable-next-line @typescript-eslint/unbound-method // eslint-disable-next-line @typescript-eslint/unbound-method
type: new FormControl(PrincipalType.User, [Validators.required]), type: new UntypedFormControl(PrincipalType.User, [Validators.required]),
// eslint-disable-next-line @typescript-eslint/unbound-method // eslint-disable-next-line @typescript-eslint/unbound-method
project: new FormControl(null, [Validators.required], ProjectAllowedValidator(this.currentUserService)), project: new UntypedFormControl(null, [Validators.required], ProjectAllowedValidator(this.currentUserService)),
}); });
get typeControl():AbstractControl { get typeControl():AbstractControl {

@ -4,7 +4,7 @@ import {
Input, Input,
OnInit, OnInit,
} from '@angular/core'; } from '@angular/core';
import { FormControl } from '@angular/forms'; import { UntypedFormControl } from '@angular/forms';
import { import {
combineLatest, combineLatest,
Observable, Observable,
@ -27,7 +27,7 @@ import { ApiV3FilterBuilder } from 'core-app/shared/helpers/api-v3/api-v3-filter
templateUrl: './role-search.component.html', templateUrl: './role-search.component.html',
}) })
export class RoleSearchComponent extends UntilDestroyedMixin implements OnInit { export class RoleSearchComponent extends UntilDestroyedMixin implements OnInit {
@Input() spotFormBinding:FormControl; @Input() spotFormBinding:UntypedFormControl;
public input$ = new Subject<string|null>(); public input$ = new Subject<string|null>();

@ -3,7 +3,7 @@ import { StateService, UIRouterGlobals } from '@uirouter/core';
import { PathHelperService } from 'core-app/core/path-helper/path-helper.service'; import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
import { IDynamicFieldGroupConfig, IOPFormlyFieldSettings } from 'core-app/shared/components/dynamic-forms/typings'; import { IDynamicFieldGroupConfig, IOPFormlyFieldSettings } from 'core-app/shared/components/dynamic-forms/typings';
import { I18nService } from 'core-app/core/i18n/i18n.service'; import { I18nService } from 'core-app/core/i18n/i18n.service';
import { FormControl, FormGroup } from '@angular/forms'; import { UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service'; import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
@ -64,8 +64,8 @@ export class NewProjectComponent extends UntilDestroyedMixin implements OnInit {
map((response) => response.elements.map((el:HalResource) => ({ href: el.href, name: el.name }))), map((response) => response.elements.map((el:HalResource) => ({ href: el.href, name: el.name }))),
); );
templateForm = new FormGroup({ templateForm = new UntypedFormGroup({
template: new FormControl(), template: new UntypedFormControl(),
}); });
get templateControl() { get templateControl() {

@ -5,7 +5,7 @@ import {
Input, Input,
Output, Output,
} from '@angular/core'; } from '@angular/core';
import { FormArray } from '@angular/forms'; import { UntypedFormArray } from '@angular/forms';
import { ApiV3ListFilter } from 'core-app/core/apiv3/paths/apiv3-list-resource.interface'; import { ApiV3ListFilter } from 'core-app/core/apiv3/paths/apiv3-list-resource.interface';
import { I18nService } from 'core-app/core/i18n/i18n.service'; import { I18nService } from 'core-app/core/i18n/i18n.service';
import { HalSourceLink } from 'core-app/features/hal/resources/hal-resource'; import { HalSourceLink } from 'core-app/features/hal/resources/hal-resource';
@ -25,7 +25,7 @@ export interface NotificationSettingProjectOption {
export class NotificationSettingInlineCreateComponent { export class NotificationSettingInlineCreateComponent {
@Input() userId:string; @Input() userId:string;
@Input() settings:FormArray; @Input() settings:UntypedFormArray;
@Output() selected = new EventEmitter<HalSourceLink>(); @Output() selected = new EventEmitter<HalSourceLink>();

@ -6,9 +6,9 @@ import {
OnInit, OnInit,
} from '@angular/core'; } from '@angular/core';
import { import {
FormArray, UntypedFormGroup,
FormControl, UntypedFormArray,
FormGroup, UntypedFormControl,
} from '@angular/forms'; } from '@angular/forms';
import { take } from 'rxjs/internal/operators/take'; import { take } from 'rxjs/internal/operators/take';
import { UIRouterGlobals } from '@uirouter/core'; import { UIRouterGlobals } from '@uirouter/core';
@ -65,27 +65,27 @@ export class NotificationsSettingsPageComponent extends UntilDestroyedMixin impl
public eeShowBanners = false; public eeShowBanners = false;
public form = new FormGroup({ public form = new UntypedFormGroup({
assignee: new FormControl(false), assignee: new FormControl(false),
responsible: new FormControl(false), responsible: new UntypedFormControl(false),
workPackageCreated: new FormControl(false), workPackageCreated: new UntypedFormControl(false),
workPackageProcessed: new FormControl(false), workPackageProcessed: new UntypedFormControl(false),
workPackageScheduled: new FormControl(false), workPackageScheduled: new UntypedFormControl(false),
workPackagePrioritized: new FormControl(false), workPackagePrioritized: new UntypedFormControl(false),
workPackageCommented: new FormControl(false), workPackageCommented: new UntypedFormControl(false),
startDate: new FormGroup({ startDate: new UntypedFormGroup({
active: new FormControl(false), active: new UntypedFormControl(false),
time: new FormControl(this.availableTimes[1]), time: new UntypedFormControl(this.availableTimes[1]),
}), }),
dueDate: new FormGroup({ dueDate: new UntypedFormGroup({
active: new FormControl(false), active: new UntypedFormControl(false),
time: new FormControl(this.availableTimes[1]), time: new UntypedFormControl(this.availableTimes[1]),
}), }),
overdue: new FormGroup({ overdue: new UntypedFormGroup({
active: new FormControl(false), active: new UntypedFormControl(false),
time: new FormControl(this.availableTimesOverdue[0]), time: new UntypedFormControl(this.availableTimesOverdue[0]),
}), }),
projectSettings: new FormArray([]), projectSettings: new UntypedFormArray([]),
}); });
text = { text = {
@ -201,24 +201,24 @@ export class NotificationsSettingsPageComponent extends UntilDestroyedMixin impl
return; return;
} }
const projectSettings = new FormArray([]); const projectSettings = new UntypedFormArray([]);
projectSettings.clear(); projectSettings.clear();
settings settings
.sort( .sort(
(a, b):number => a._links.project.title!.localeCompare(b._links.project.title!), (a, b):number => a._links.project.title!.localeCompare(b._links.project.title!),
) )
.forEach((setting) => projectSettings.push(new FormGroup({ .forEach((setting) => projectSettings.push(new UntypedFormGroup({
project: new FormControl(setting._links.project), project: new UntypedFormControl(setting._links.project),
assignee: new FormControl(setting.assignee), assignee: new UntypedFormControl(setting.assignee),
responsible: new FormControl(setting.responsible), responsible: new FormControl(setting.responsible),
workPackageCreated: new FormControl(setting.workPackageCreated), workPackageCreated: new UntypedFormControl(setting.workPackageCreated),
workPackageProcessed: new FormControl(setting.workPackageProcessed), workPackageProcessed: new UntypedFormControl(setting.workPackageProcessed),
workPackageScheduled: new FormControl(setting.workPackageScheduled), workPackageScheduled: new UntypedFormControl(setting.workPackageScheduled),
workPackagePrioritized: new FormControl(setting.workPackagePrioritized), workPackagePrioritized: new UntypedFormControl(setting.workPackagePrioritized),
workPackageCommented: new FormControl(setting.workPackageCommented), workPackageCommented: new UntypedFormControl(setting.workPackageCommented),
startDate: new FormControl(setting.startDate), startDate: new UntypedFormControl(setting.startDate),
dueDate: new FormControl(setting.dueDate), dueDate: new UntypedFormControl(setting.dueDate),
overdue: new FormControl(setting.overdue), overdue: new UntypedFormControl(setting.overdue),
}))); })));
this.form.setControl('projectSettings', projectSettings); this.form.setControl('projectSettings', projectSettings);

@ -6,7 +6,7 @@ import {
Input, Input,
OnInit, OnInit,
} from '@angular/core'; } from '@angular/core';
import { FormArray, FormGroup, FormControl } from '@angular/forms'; import { UntypedFormArray, UntypedFormGroup, UntypedFormControl } from '@angular/forms';
import { PathHelperService } from 'core-app/core/path-helper/path-helper.service'; import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
import { I18nService } from 'core-app/core/i18n/i18n.service'; import { I18nService } from 'core-app/core/i18n/i18n.service';
import idFromLink from 'core-app/features/hal/helpers/id-from-link'; import idFromLink from 'core-app/features/hal/helpers/id-from-link';
@ -23,7 +23,7 @@ import { OVERDUE_REMINDER_AVAILABLE_TIMEFRAMES, REMINDER_AVAILABLE_TIMEFRAMES }
export class NotificationSettingsTableComponent implements OnInit { export class NotificationSettingsTableComponent implements OnInit {
@Input() userId:string; @Input() userId:string;
@Input() settings:FormArray; @Input() settings:UntypedFormArray;
public eeShowBanners = false; public eeShowBanners = false;
@ -91,18 +91,18 @@ export class NotificationSettingsTableComponent implements OnInit {
} }
addProjectSettings(project:HalSourceLink):void { addProjectSettings(project:HalSourceLink):void {
this.settings.push(new FormGroup({ this.settings.push(new UntypedFormGroup({
project: new FormControl(project), project: new UntypedFormControl(project),
assignee: new FormControl(false), assignee: new FormControl(false),
responsible: new FormControl(false), responsible: new UntypedFormControl(false),
workPackageCreated: new FormControl(false), workPackageCreated: new UntypedFormControl(false),
workPackageProcessed: new FormControl(false), workPackageProcessed: new UntypedFormControl(false),
workPackageScheduled: new FormControl(false), workPackageScheduled: new UntypedFormControl(false),
workPackagePrioritized: new FormControl(false), workPackagePrioritized: new UntypedFormControl(false),
workPackageCommented: new FormControl(false), workPackageCommented: new UntypedFormControl(false),
startDate: new FormControl(this.availableTimes[2].value), startDate: new UntypedFormControl(this.availableTimes[2].value),
dueDate: new FormControl(this.availableTimes[2].value), dueDate: new UntypedFormControl(this.availableTimes[2].value),
overdue: new FormControl(this.availableTimesOverdue[0].value), overdue: new UntypedFormControl(this.availableTimesOverdue[0].value),
})); }));
} }

@ -6,7 +6,7 @@ import {
import { I18nService } from 'core-app/core/i18n/i18n.service'; import { I18nService } from 'core-app/core/i18n/i18n.service';
import { UserPreferencesService } from 'core-app/features/user-preferences/state/user-preferences.service'; import { UserPreferencesService } from 'core-app/features/user-preferences/state/user-preferences.service';
import { import {
FormGroup, UntypedFormGroup,
FormGroupDirective, FormGroupDirective,
} from '@angular/forms'; } from '@angular/forms';
@ -31,7 +31,7 @@ export const emailAlerts:EmailAlertType[] = [
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class EmailAlertsSettingsComponent implements OnInit { export class EmailAlertsSettingsComponent implements OnInit {
form:FormGroup; form:UntypedFormGroup;
alerts:EmailAlertType[] = emailAlerts; alerts:EmailAlertType[] = emailAlerts;
@ -56,6 +56,6 @@ export class EmailAlertsSettingsComponent implements OnInit {
} }
ngOnInit():void { ngOnInit():void {
this.form = this.rootFormGroup.control.get('emailAlerts') as FormGroup; this.form = this.rootFormGroup.control.get('emailAlerts') as UntypedFormGroup;
} }
} }

@ -6,7 +6,7 @@ import {
import { I18nService } from 'core-app/core/i18n/i18n.service'; import { I18nService } from 'core-app/core/i18n/i18n.service';
import { UserPreferencesService } from 'core-app/features/user-preferences/state/user-preferences.service'; import { UserPreferencesService } from 'core-app/features/user-preferences/state/user-preferences.service';
import { import {
FormGroup, UntypedFormGroup,
FormGroupDirective, FormGroupDirective,
} from '@angular/forms'; } from '@angular/forms';
@ -16,7 +16,7 @@ import {
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class ImmediateReminderSettingsComponent implements OnInit { export class ImmediateReminderSettingsComponent implements OnInit {
form:FormGroup; form:UntypedFormGroup;
text = { text = {
title: this.I18n.t('js.reminders.settings.immediate.title'), title: this.I18n.t('js.reminders.settings.immediate.title'),
@ -32,6 +32,6 @@ export class ImmediateReminderSettingsComponent implements OnInit {
} }
ngOnInit():void { ngOnInit():void {
this.form = this.rootFormGroup.control.get('immediateReminders') as FormGroup; this.form = this.rootFormGroup.control.get('immediateReminders') as UntypedFormGroup;
} }
} }

@ -11,8 +11,8 @@ import { take } from 'rxjs/internal/operators/take';
import { UIRouterGlobals } from '@uirouter/core'; import { UIRouterGlobals } from '@uirouter/core';
import { UserPreferencesService } from 'core-app/features/user-preferences/state/user-preferences.service'; import { UserPreferencesService } from 'core-app/features/user-preferences/state/user-preferences.service';
import { import {
FormArray, UntypedFormArray,
FormBuilder, UntypedFormBuilder,
} from '@angular/forms'; } from '@angular/forms';
import { import {
DailyRemindersSettings, DailyRemindersSettings,
@ -97,7 +97,7 @@ export class ReminderSettingsPageComponent extends UntilDestroyedMixin implement
private storeService:UserPreferencesService, private storeService:UserPreferencesService,
private currentUserService:CurrentUserService, private currentUserService:CurrentUserService,
private uiRouterGlobals:UIRouterGlobals, private uiRouterGlobals:UIRouterGlobals,
private fb:FormBuilder, private fb:UntypedFormBuilder,
private cdRef:ChangeDetectorRef, private cdRef:ChangeDetectorRef,
) { ) {
super(); super();
@ -132,7 +132,7 @@ export class ReminderSettingsPageComponent extends UntilDestroyedMixin implement
this.form.get('pauseReminders')?.patchValue(settings.pauseReminders); this.form.get('pauseReminders')?.patchValue(settings.pauseReminders);
const dailyReminderTimes = this.form.get('dailyReminders.times') as FormArray; const dailyReminderTimes = this.form.get('dailyReminders.times') as UntypedFormArray;
dailyReminderTimes.clear({ emitEvent: false }); dailyReminderTimes.clear({ emitEvent: false });
[...settings.dailyReminders.times].sort().forEach((time) => { [...settings.dailyReminders.times].sort().forEach((time) => {
dailyReminderTimes.push(this.fb.control(time), { emitEvent: false }); dailyReminderTimes.push(this.fb.control(time), { emitEvent: false });
@ -140,7 +140,7 @@ export class ReminderSettingsPageComponent extends UntilDestroyedMixin implement
dailyReminderTimes.enable({ emitEvent: true }); dailyReminderTimes.enable({ emitEvent: true });
const workdays = this.form.get('workdays') as FormArray; const workdays = this.form.get('workdays') as UntypedFormArray;
for (let i = 0; i <= 6; i++) { for (let i = 0; i <= 6; i++) {
const control = workdays.at(i); const control = workdays.at(i);
control.setValue(settings.workdays.includes(i + 1)); control.setValue(settings.workdays.includes(i + 1));

@ -4,7 +4,7 @@ import {
OnInit, OnInit,
} from '@angular/core'; } from '@angular/core';
import { import {
FormGroup, UntypedFormGroup,
FormGroupDirective, FormGroupDirective,
} from '@angular/forms'; } from '@angular/forms';
import { I18nService } from 'core-app/core/i18n/i18n.service'; import { I18nService } from 'core-app/core/i18n/i18n.service';
@ -21,7 +21,7 @@ import { Observable } from 'rxjs';
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class PauseRemindersComponent implements OnInit { export class PauseRemindersComponent implements OnInit {
form:FormGroup; form:UntypedFormGroup;
selectedDates$:Observable<[string, string]>; selectedDates$:Observable<[string, string]>;
@ -41,7 +41,7 @@ export class PauseRemindersComponent implements OnInit {
} }
ngOnInit():void { ngOnInit():void {
this.form = this.rootFormGroup.control.get('pauseReminders') as FormGroup; this.form = this.rootFormGroup.control.get('pauseReminders') as UntypedFormGroup;
this.selectedDates$ = this this.selectedDates$ = this
.form .form
.valueChanges .valueChanges

@ -16,9 +16,9 @@ import {
} from 'rxjs'; } from 'rxjs';
import { UserPreferencesService } from 'core-app/features/user-preferences/state/user-preferences.service'; import { UserPreferencesService } from 'core-app/features/user-preferences/state/user-preferences.service';
import { import {
FormArray, UntypedFormArray,
FormControl, UntypedFormControl,
FormGroup, UntypedFormGroup,
FormGroupDirective, FormGroupDirective,
} from '@angular/forms'; } from '@angular/forms';
import { ConfigurationService } from 'core-app/core/config/configuration.service'; import { ConfigurationService } from 'core-app/core/config/configuration.service';
@ -42,7 +42,7 @@ export class ReminderSettingsDailyTimeComponent implements OnInit {
// Upon a reload of the page, it is accepted to loose this information. // Upon a reload of the page, it is accepted to loose this information.
public inactiveTimes:Array<{ position:number, time:string }> = []; public inactiveTimes:Array<{ position:number, time:string }> = [];
public form:FormGroup; public form:UntypedFormGroup;
// Hours suggested if a new time is added by a user. // Hours suggested if a new time is added by a user.
public suggestedTimes = ['08:00', '12:00', '15:00', '18:00']; public suggestedTimes = ['08:00', '12:00', '15:00', '18:00'];
@ -83,7 +83,7 @@ export class ReminderSettingsDailyTimeComponent implements OnInit {
} }
ngOnInit():void { ngOnInit():void {
this.form = this.rootFormGroup.control.get('dailyReminders') as FormGroup; this.form = this.rootFormGroup.control.get('dailyReminders') as UntypedFormGroup;
this.enabled$ = this this.enabled$ = this
.form .form
@ -96,12 +96,12 @@ export class ReminderSettingsDailyTimeComponent implements OnInit {
this.selectedTimes$ = (this this.selectedTimes$ = (this
.form .form
.get('times') as FormArray) .get('times') as UntypedFormArray)
.valueChanges .valueChanges
.pipe( .pipe(
startWith(() => this.form.get('times')?.value as FormArray), startWith(() => this.form.get('times')?.value as UntypedFormArray),
map(() => { map(() => {
const timesArray = this.form.get('times') as FormArray; const timesArray = this.form.get('times') as UntypedFormArray;
const activeTimes = timesArray.controls.map((c) => c.value as string); const activeTimes = timesArray.controls.map((c) => c.value as string);
this this
@ -211,10 +211,10 @@ export class ReminderSettingsDailyTimeComponent implements OnInit {
.includes(selected), .includes(selected),
); );
const timesForm = this.form.get('times') as FormArray; const timesForm = this.form.get('times') as UntypedFormArray;
timesForm.clear({ emitEvent: false }); timesForm.clear({ emitEvent: false });
times.forEach((time) => { times.forEach((time) => {
timesForm.push(new FormControl(time), { emitEvent: false }); timesForm.push(new UntypedFormControl(time), { emitEvent: false });
}); });
timesForm.enable({ emitEvent: true }); timesForm.enable({ emitEvent: true });

@ -4,8 +4,8 @@ import {
OnInit, OnInit,
} from '@angular/core'; } from '@angular/core';
import { import {
FormArray, UntypedFormArray,
FormControl, UntypedFormControl,
FormGroupDirective, FormGroupDirective,
} from '@angular/forms'; } from '@angular/forms';
import * as moment from 'moment'; import * as moment from 'moment';
@ -18,7 +18,7 @@ import { I18nService } from 'core-app/core/i18n/i18n.service';
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class WorkdaysSettingsComponent implements OnInit { export class WorkdaysSettingsComponent implements OnInit {
control:FormArray; control:UntypedFormArray;
/** /**
* The locale might render workdays in a different order, which is what moment return with localeSorted * The locale might render workdays in a different order, which is what moment return with localeSorted
@ -46,16 +46,16 @@ export class WorkdaysSettingsComponent implements OnInit {
} }
ngOnInit():void { ngOnInit():void {
this.control = this.formGroup.control.get('workdays') as FormArray; this.control = this.formGroup.control.get('workdays') as UntypedFormArray;
} }
indexOfLocalWorkday(day:string):number { indexOfLocalWorkday(day:string):number {
return this.isoWorkdays.indexOf(day); return this.isoWorkdays.indexOf(day);
} }
controlForLocalWorkday(day:string):FormControl { controlForLocalWorkday(day:string):UntypedFormControl {
const index = this.indexOfLocalWorkday(day); const index = this.indexOfLocalWorkday(day);
return this.control.at(index) as FormControl; return this.control.at(index) as UntypedFormControl;
} }
/** Workdays from moment.js are in non-ISO order, that means Sunday=0, Saturday=6 */ /** Workdays from moment.js are in non-ISO order, that means Sunday=0, Saturday=6 */

@ -67,6 +67,7 @@ import {
zoomLevelOrder, zoomLevelOrder,
} from '../wp-timeline'; } from '../wp-timeline';
import { WeekdayService } from 'core-app/core/days/weekday.service'; import { WeekdayService } from 'core-app/core/days/weekday.service';
import * as Mousetrap from 'mousetrap';
@Component({ @Component({
selector: 'wp-timeline-container', selector: 'wp-timeline-container',

@ -6,6 +6,7 @@ import { OPContextMenuService } from 'core-app/shared/components/op-context-menu
import { WorkPackageViewBaseService } from 'core-app/features/work-packages/routing/wp-view-base/view-services/wp-view-base.service'; import { WorkPackageViewBaseService } from 'core-app/features/work-packages/routing/wp-view-base/view-services/wp-view-base.service';
import { QueryResource } from 'core-app/features/hal/resources/query-resource'; import { QueryResource } from 'core-app/features/hal/resources/query-resource';
import { WorkPackageCollectionResource } from 'core-app/features/hal/resources/wp-collection-resource'; import { WorkPackageCollectionResource } from 'core-app/features/hal/resources/wp-collection-resource';
import * as Mousetrap from 'mousetrap';
export interface WorkPackageViewSelectionState { export interface WorkPackageViewSelectionState {
// Map of selected rows // Map of selected rows

@ -4,7 +4,7 @@ import { Component, forwardRef, ViewChild } from '@angular/core';
import { ComponentFixture, fakeAsync, flush, TestBed } from '@angular/core/testing'; import { ComponentFixture, fakeAsync, flush, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { defer, of } from 'rxjs'; import { defer, of } from 'rxjs';
import { FormControl, FormGroup, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; import { UntypedFormControl, UntypedFormGroup, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { FormlyModule } from '@ngx-formly/core'; import { FormlyModule } from '@ngx-formly/core';
@ -32,7 +32,7 @@ import { ConfirmDialogService } from "core-app/shared/components/modals/confirm-
providers: [], providers: [],
}) })
class DynamicFormsTestingComponent { class DynamicFormsTestingComponent {
control = new FormControl(''); control = new UntypedFormControl('');
@ViewChild(DynamicFormComponent) dynamicFormControl:DynamicFormComponent; @ViewChild(DynamicFormComponent) dynamicFormControl:DynamicFormComponent;
} }
@ -260,7 +260,7 @@ describe('DynamicFormComponent', () => {
}, },
}, },
}, },
form: new FormGroup({}), form: new UntypedFormGroup({}),
}; };
const I18nServiceStub = { const I18nServiceStub = {
t(key:string) { t(key:string) {

@ -15,7 +15,7 @@ import { catchError, finalize } from 'rxjs/operators';
import { HalSource } from 'core-app/features/hal/resources/hal-resource'; import { HalSource } from 'core-app/features/hal/resources/hal-resource';
import { ToastService } from 'core-app/shared/components/toaster/toast.service'; import { ToastService } from 'core-app/shared/components/toaster/toast.service';
import { DynamicFieldsService } from 'core-app/shared/components/dynamic-forms/services/dynamic-fields/dynamic-fields.service'; import { DynamicFieldsService } from 'core-app/shared/components/dynamic-forms/services/dynamic-fields/dynamic-fields.service';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { UntilDestroyedMixin } from 'core-app/shared/helpers/angular/until-destroyed.mixin'; import { UntilDestroyedMixin } from 'core-app/shared/helpers/angular/until-destroyed.mixin';
import { ConfirmDialogService } from 'core-app/shared/components/modals/confirm-dialog/confirm-dialog.service'; import { ConfirmDialogService } from 'core-app/shared/components/modals/confirm-dialog/confirm-dialog.service';
@ -143,7 +143,7 @@ export class DynamicFormComponent extends UntilDestroyedMixin implements OnChang
@Input() settings?:IOPFormSettings; @Input() settings?:IOPFormSettings;
@Input() dynamicFormGroup?:FormGroup; @Input() dynamicFormGroup?:UntypedFormGroup;
/** Initial payload to POST to the form */ /** Initial payload to POST to the form */
@Input() initialPayload:Object = {}; @Input() initialPayload:Object = {};
@ -178,7 +178,7 @@ export class DynamicFormComponent extends UntilDestroyedMixin implements OnChang
@Output() errored = new EventEmitter<IOPFormErrorResponse>(); @Output() errored = new EventEmitter<IOPFormErrorResponse>();
form:FormGroup; form:UntypedFormGroup;
fields:IOPFormlyFieldSettings[]; fields:IOPFormlyFieldSettings[];
@ -254,7 +254,7 @@ export class DynamicFormComponent extends UntilDestroyedMixin implements OnChang
this.modelChange.emit(changes); this.modelChange.emit(changes);
} }
submitForm(form:FormGroup) { submitForm(form:UntypedFormGroup) {
if (!this.handleSubmit) { if (!this.handleSubmit) {
return; return;
} }

@ -3,7 +3,7 @@ import { DynamicFormService } from 'core-app/shared/components/dynamic-forms/ser
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { DynamicFieldsService } from 'core-app/shared/components/dynamic-forms/services/dynamic-fields/dynamic-fields.service'; import { DynamicFieldsService } from 'core-app/shared/components/dynamic-forms/services/dynamic-fields/dynamic-fields.service';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { of } from 'rxjs'; import { of } from 'rxjs';
import { FormsService } from 'core-app/core/forms/forms.service'; import { FormsService } from 'core-app/core/forms/forms.service';
@ -112,7 +112,7 @@ describe('DynamicFormService', () => {
}, },
_meta: undefined, _meta: undefined,
}, },
form: new FormGroup({}), form: new UntypedFormGroup({}),
}; };
beforeEach(() => { beforeEach(() => {

@ -1,6 +1,6 @@
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { FormlyForm } from '@ngx-formly/core'; import { FormlyForm } from '@ngx-formly/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
@ -47,7 +47,7 @@ export class DynamicFormService {
this.formSchema = formConfig._embedded?.schema; this.formSchema = formConfig._embedded?.schema;
const formPayload = formConfig._embedded?.payload; const formPayload = formConfig._embedded?.payload;
const dynamicForm = { const dynamicForm = {
form: new FormGroup({}), form: new UntypedFormGroup({}),
fields: this._dynamicFieldsService.getConfig(this.formSchema, formPayload), fields: this._dynamicFieldsService.getConfig(this.formSchema, formPayload),
model: this._dynamicFieldsService.getModel(formPayload), model: this._dynamicFieldsService.getModel(formPayload),
}; };
@ -59,11 +59,11 @@ export class DynamicFormService {
return this._formsService.formatModelToEdit(formModel); return this._formsService.formatModelToEdit(formModel);
} }
validateForm$(form:FormGroup, resourceEndpoint:string) { validateForm$(form:UntypedFormGroup, resourceEndpoint:string) {
return this._formsService.validateForm$(form, resourceEndpoint, this.formSchema); return this._formsService.validateForm$(form, resourceEndpoint, this.formSchema);
} }
submit$(form:FormGroup, resourceEndpoint:string, resourceId?:string, formHttpMethod?:'post' | 'patch') { submit$(form:UntypedFormGroup, resourceEndpoint:string, resourceId?:string, formHttpMethod?:'post' | 'patch') {
return this._formsService.submit$(form, resourceEndpoint, resourceId, formHttpMethod, this.formSchema); return this._formsService.submit$(form, resourceEndpoint, resourceId, formHttpMethod, this.formSchema);
} }
} }

@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { Component, forwardRef, ViewChild } from '@angular/core'; import { Component, forwardRef, ViewChild } from '@angular/core';
import { FormGroup, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; import { UntypedFormGroup, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { TextInputComponent } from 'core-app/shared/components/dynamic-forms/components/dynamic-inputs/text-input/text-input.component'; import { TextInputComponent } from 'core-app/shared/components/dynamic-forms/components/dynamic-inputs/text-input/text-input.component';
import { IntegerInputComponent } from 'core-app/shared/components/dynamic-forms/components/dynamic-inputs/integer-input/integer-input.component'; import { IntegerInputComponent } from 'core-app/shared/components/dynamic-forms/components/dynamic-inputs/integer-input/integer-input.component';
@ -36,7 +36,7 @@ export function createDynamicInputFixture(fields:IOPFormlyFieldSettings[], model
providers, providers,
}) })
class DynamicInputsTestingComponent { class DynamicInputsTestingComponent {
form = new FormGroup({}); form = new UntypedFormGroup({});
model = model; model = model;
@ -117,7 +117,7 @@ export function createDynamicInputFixture(fields:IOPFormlyFieldSettings[], model
} }
export function testDynamicInputControValueAccessor(fixture:ComponentFixture<any>, model:any, selector:string) { export function testDynamicInputControValueAccessor(fixture:ComponentFixture<any>, model:any, selector:string) {
const dynamicForm:FormGroup = fixture.componentInstance.dynamicForm.form; const dynamicForm:UntypedFormGroup = fixture.componentInstance.dynamicForm.form;
const dynamicInput = fixture.debugElement.query(By.css(selector)).nativeElement; const dynamicInput = fixture.debugElement.query(By.css(selector)).nativeElement;
// Test ControlValueAccessor // Test ControlValueAccessor

@ -319,9 +319,9 @@ export class ResourceChangeset<T extends HalResource = HalResource> {
* Access some promised value * Access some promised value
* that should be cached for the lifetime duration of the form. * that should be cached for the lifetime duration of the form.
*/ */
public cacheValue<T>(key:string, request:() => Promise<T>):Promise<T> { public cacheValue<V>(key:string, request:() => Promise<V>):Promise<V> {
if (this.cache[key]) { if (this.cache[key] !== undefined) {
return this.cache[key] as Promise<T>; return this.cache[key] as Promise<V>;
} }
return this.cache[key] = request(); return this.cache[key] = request();

@ -2,6 +2,7 @@ import { AfterViewInit, Directive, ElementRef } from '@angular/core';
import { OPContextMenuService } from 'core-app/shared/components/op-context-menu/op-context-menu.service'; import { OPContextMenuService } from 'core-app/shared/components/op-context-menu/op-context-menu.service';
import { OpContextMenuHandler } from 'core-app/shared/components/op-context-menu/op-context-menu-handler'; import { OpContextMenuHandler } from 'core-app/shared/components/op-context-menu/op-context-menu-handler';
import { OpContextMenuItem } from 'core-app/shared/components/op-context-menu/op-context-menu.types'; import { OpContextMenuItem } from 'core-app/shared/components/op-context-menu/op-context-menu.types';
import * as Mousetrap from 'mousetrap';
@Directive({ @Directive({
selector: '[opContextMenuTrigger]', selector: '[opContextMenuTrigger]',

@ -1,7 +1,15 @@
import { import {
ApplicationRef, ComponentFactoryResolver, Injectable, Injector, ApplicationRef,
ComponentFactoryResolver,
Injectable,
Injector,
} from '@angular/core'; } from '@angular/core';
import { ComponentPortal, DomPortalOutlet, PortalInjector } from '@angular/cdk/portal'; import {
ComponentPortal,
ComponentType,
DomPortalOutlet,
PortalInjector,
} from '@angular/cdk/portal';
import { TransitionService } from '@uirouter/core'; import { TransitionService } from '@uirouter/core';
import { OpContextMenuHandler } from 'core-app/shared/components/op-context-menu/op-context-menu-handler'; import { OpContextMenuHandler } from 'core-app/shared/components/op-context-menu/op-context-menu-handler';
import { import {
@ -11,7 +19,6 @@ import {
import { OPContextMenuComponent } from 'core-app/shared/components/op-context-menu/op-context-menu.component'; import { OPContextMenuComponent } from 'core-app/shared/components/op-context-menu/op-context-menu.component';
import { KeyCodes } from 'core-app/shared/helpers/keyCodes.enum'; import { KeyCodes } from 'core-app/shared/helpers/keyCodes.enum';
import { FocusHelperService } from 'core-app/shared/directives/focus/focus-helper'; import { FocusHelperService } from 'core-app/shared/directives/focus/focus-helper';
import { ComponentType } from '@angular/cdk/portal/portal';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class OPContextMenuService { export class OPContextMenuService {

@ -30,6 +30,7 @@ import { Injectable } from '@angular/core';
import { FocusHelperService } from 'core-app/shared/directives/focus/focus-helper'; import { FocusHelperService } from 'core-app/shared/directives/focus/focus-helper';
import { PathHelperService } from 'core-app/core/path-helper/path-helper.service'; import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
import { CurrentProjectService } from 'core-app/core/current-project/current-project.service'; import { CurrentProjectService } from 'core-app/core/current-project/current-project.service';
import * as Mousetrap from 'mousetrap';
const accessKeys = { const accessKeys = {
preview: 1, preview: 1,

@ -30,9 +30,10 @@ export function getPosition(evt:any):number {
return range.startOffset; return range.startOffset;
} }
if (document.caretRangeFromPoint) { const legacyDocument = document as { caretRangeFromPoint?:(x:number, y:number) => { startOffset:number } };
return document if (legacyDocument.caretRangeFromPoint) {
.caretRangeFromPoint(evt.clientX!, evt.clientY!) return legacyDocument
.caretRangeFromPoint((evt as MouseEvent).clientX, (evt as MouseEvent).clientY)
.startOffset; .startOffset;
} }

@ -1,6 +1,6 @@
import { Directive, forwardRef, Input } from '@angular/core'; import { Directive, forwardRef, Input } from '@angular/core';
import { import {
FormArray, FormControl, FormGroup, NgControl, UntypedFormArray, UntypedFormControl, UntypedFormGroup, NgControl,
} from '@angular/forms'; } from '@angular/forms';
export const formControlBinding = { export const formControlBinding = {
@ -15,9 +15,9 @@ export const formControlBinding = {
exportAs: 'ngForm', exportAs: 'ngForm',
}) })
export class SpotFormBindingDirective extends NgControl { export class SpotFormBindingDirective extends NgControl {
@Input('spotFormBinding') form!:FormControl|FormGroup|FormArray; @Input('spotFormBinding') form!:UntypedFormControl|UntypedFormGroup|UntypedFormArray;
get control():FormControl|FormGroup|FormArray { get control():UntypedFormControl|UntypedFormGroup|UntypedFormArray {
return this.form; return this.form;
} }

@ -1,7 +1,7 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { import {
FormGroup, UntypedFormControl,
FormControl, UntypedFormGroup,
Validators, Validators,
} from '@angular/forms'; } from '@angular/forms';
@ -9,8 +9,8 @@ import {
templateUrl: './FormFieldErrorSlot.example.html', templateUrl: './FormFieldErrorSlot.example.html',
}) })
export class SbFormFieldErrorSlotExample { export class SbFormFieldErrorSlotExample {
public myForm = new FormGroup({ public myForm = new UntypedFormGroup({
myInput: new FormControl(null, [Validators.required, Validators.minLength(8)]), myInput: new UntypedFormControl(null, [Validators.required, Validators.minLength(8)]),
}); });
get myInputControl() { get myInputControl() {

@ -19,6 +19,9 @@
*/ */
// Ensure global is set for ng2-dragula and others // Ensure global is set for ng2-dragula and others
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access no-explicit-any
(window as any).global = window;
/* /*
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch for IE/Edge * with the following flag, it will bypass `zone.js` patch for IE/Edge
@ -30,11 +33,6 @@
*/ */
import 'zone.js'; import 'zone.js';
(window as any).global = window;
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
/** IE10 and IE11 requires the following for the Reflect API. */ /** IE10 and IE11 requires the following for the Reflect API. */
// import 'core-js/es6/reflect'; // import 'core-js/es6/reflect';
@ -42,12 +40,6 @@ import 'zone.js';
// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
// import 'core-js/es7/reflect'; // import 'core-js/es7/reflect';
/**
* Required to support Web Animations `@angular/platform-browser/animations`.
* Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
* */
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
/** /**
* By default, zone.js will patch all possible macroTask and DomEvents * By default, zone.js will patch all possible macroTask and DomEvents
* user can disable parts of macroTask/DomEvents patch by setting following flags * user can disable parts of macroTask/DomEvents patch by setting following flags

@ -13,6 +13,9 @@ import {
import { GlobalI18n } from 'core-app/core/i18n/i18n.service'; import { GlobalI18n } from 'core-app/core/i18n/i18n.service';
import { I18nShim } from './test/i18n-shim'; import { I18nShim } from './test/i18n-shim';
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access no-explicit-any
(window as any).global = window;
require('expose-loader?_!lodash'); require('expose-loader?_!lodash');
declare const require:any; declare const require:any;
@ -29,6 +32,9 @@ window.I18n = new I18nShim();
getTestBed().initTestEnvironment( getTestBed().initTestEnvironment(
BrowserDynamicTestingModule, BrowserDynamicTestingModule,
platformBrowserDynamicTesting(), platformBrowserDynamicTesting(),
{
teardown: { destroyAfterEach: false },
},
); );
// Then we find all the tests. // Then we find all the tests.

Loading…
Cancel
Save