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
/bower_components
/coverage

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

File diff suppressed because it is too large Load Diff

@ -5,17 +5,17 @@
"version": "0.1.0",
"private": true,
"devDependencies": {
"@angular-devkit/build-angular": "~12.2.6",
"@angular-eslint/builder": "^12.0.0",
"@angular-eslint/eslint-plugin": "^12.0.0",
"@angular-eslint/eslint-plugin-template": "^12.0.0",
"@angular-eslint/schematics": "12.5.0",
"@angular-eslint/template-parser": "^12.0.0",
"@angular/language-service": "12.2.6",
"@angular-devkit/build-angular": "^14.2.5",
"@angular-eslint/builder": "^13.2.1",
"@angular-eslint/eslint-plugin": "^13.2.1",
"@angular-eslint/eslint-plugin-template": "^13.2.1",
"@angular-eslint/schematics": "13.2.1",
"@angular-eslint/template-parser": "^13.2.1",
"@angular/language-service": "14.0.2",
"@babel/core": "^7.18.5",
"@compodoc/compodoc": "^1.1.19",
"@html-eslint/eslint-plugin": "^0.11.0",
"@html-eslint/parser": "^0.11.0",
"@html-eslint/eslint-plugin": "^0.13.1",
"@html-eslint/parser": "^0.13.1",
"@jsdevtools/coverage-istanbul-loader": "3.0.5",
"@storybook/addon-actions": "^6.5.10",
"@storybook/addon-essentials": "^6.5.10",
@ -29,7 +29,7 @@
"@storybook/preset-scss": "^1.0.3",
"@storybook/testing-library": "^0.0.13",
"@types/chart.js": "^2.9.20",
"@types/codemirror": "0.0.87",
"@types/codemirror": "5.60.5",
"@types/dragula": "^3.7.0",
"@types/hammerjs": "^2.0.36",
"@types/jasmine": "~3.6.0",
@ -79,21 +79,21 @@
"style-loader": "^3.3.1",
"theo": "^8.1.5",
"ts-node": "~8.3.0",
"typescript": "~4.2.4",
"typescript": "~4.7.4",
"webpack-bundle-analyzer": "^4.4.2"
},
"dependencies": {
"@angular/animations": "~12.2.6",
"@angular/cdk": "^12.2.6",
"@angular/cli": "~12.2.6",
"@angular/common": "~12.2.6",
"@angular/compiler": "~12.2.6",
"@angular/compiler-cli": "~12.2.6",
"@angular/core": "~12.2.6",
"@angular/forms": "~12.2.6",
"@angular/platform-browser": "~12.2.6",
"@angular/platform-browser-dynamic": "~12.2.6",
"@angular/router": "~12.2.6",
"@angular/animations": "^14.2.5",
"@angular/cdk": "^14.2.4",
"@angular/cli": "^14.2.5",
"@angular/common": "^14.2.5",
"@angular/compiler": "^14.2.5",
"@angular/compiler-cli": "^14.2.5",
"@angular/core": "^14.2.5",
"@angular/forms": "^14.2.5",
"@angular/platform-browser": "^14.2.5",
"@angular/platform-browser-dynamic": "^14.2.5",
"@angular/router": "^14.2.5",
"@appsignal/javascript": "^1.3.23",
"@appsignal/plugin-breadcrumbs-console": "^1.1.24",
"@appsignal/plugin-breadcrumbs-network": "^1.1.21",
@ -114,8 +114,8 @@
"@sentry/angular": "6.2.3",
"@sentry/tracing": "6.2.3",
"@sentry/types": "^6.2.3",
"@uirouter/angular": "^8.0.1",
"@uirouter/core": "^6.0.7",
"@uirouter/angular": "^9.1.0",
"@uirouter/core": "^6.0.8",
"@uirouter/rx": "^0.6.5",
"@w11k/ngx-componentdestroyed": "^5.0.2",
"@xeokit/xeokit-bim-viewer": "2.3.10",
@ -171,8 +171,8 @@
},
"scripts": {
"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:watch": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --watch --named-chunks --extract-css",
"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",
"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",
"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 { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { HttpClient } from '@angular/common/http';
import { FormBuilder } from '@angular/forms';
import { UntypedFormBuilder } from '@angular/forms';
import { FormsService } from './forms.service';
describe('FormsService', () => {
@ -26,7 +26,7 @@ describe('FormsService', () => {
],
},
};
const formBuilder = new FormBuilder();
const formBuilder = new UntypedFormBuilder();
beforeEach(() => {
TestBed.configureTestingModule({

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

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

@ -36,14 +36,8 @@ import {
Input,
ViewChild,
} from '@angular/core';
import {
DomSanitizer,
SafeResourceUrl,
} from '@angular/platform-browser';
import {
FormControl,
FormGroup,
} from '@angular/forms';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
import { UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { OpModalComponent } from 'core-app/shared/components/modal/modal.component';
import { OpModalLocalsToken } from 'core-app/shared/components/modal/modal.service';
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;
public trialForm:FormGroup;
public trialForm:UntypedFormGroup;
public trustedEEVideoURL:SafeResourceUrl;
@ -131,7 +125,7 @@ export class EnterpriseTrialModalComponent extends OpModalComponent implements A
// checks if form is valid and submits it
public onSubmit():void {
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);
}
}

@ -42,6 +42,8 @@ import {
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { PathHelperService } from 'core-app/core/path-helper/path-helper.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 { EnterpriseTrialStore } from 'core-app/features/enterprise/enterprise-trial.store';
import { GonType } from 'core-app/core/gon/gon.service';
@ -128,7 +130,7 @@ export class EnterpriseTrialService {
// send POST request with form object
// 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 };
return this.http
.post(

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

@ -4,8 +4,8 @@ import {
} from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {
FormGroup,
FormControl,
UntypedFormGroup,
UntypedFormControl,
Validators,
AbstractControl,
} 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
principal: new FormControl(null, [Validators.required]),
userDynamicFields: new FormGroup({}),
principal: new UntypedFormControl(null, [Validators.required]),
userDynamicFields: new UntypedFormGroup({}),
// eslint-disable-next-line @typescript-eslint/unbound-method
role: new FormControl(null, [Validators.required]),
message: new FormControl(''),

@ -10,8 +10,8 @@ import {
} from '@angular/core';
import {
AbstractControl,
FormControl,
FormGroup,
UntypedFormControl,
UntypedFormGroup,
Validators,
} from '@angular/forms';
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
type: new FormControl(PrincipalType.User, [Validators.required]),
type: new UntypedFormControl(PrincipalType.User, [Validators.required]),
// 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 {

@ -4,7 +4,7 @@ import {
Input,
OnInit,
} from '@angular/core';
import { FormControl } from '@angular/forms';
import { UntypedFormControl } from '@angular/forms';
import {
combineLatest,
Observable,
@ -27,7 +27,7 @@ import { ApiV3FilterBuilder } from 'core-app/shared/helpers/api-v3/api-v3-filter
templateUrl: './role-search.component.html',
})
export class RoleSearchComponent extends UntilDestroyedMixin implements OnInit {
@Input() spotFormBinding:FormControl;
@Input() spotFormBinding:UntypedFormControl;
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 { IDynamicFieldGroupConfig, IOPFormlyFieldSettings } from 'core-app/shared/components/dynamic-forms/typings';
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 { map } from 'rxjs/operators';
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 }))),
);
templateForm = new FormGroup({
template: new FormControl(),
templateForm = new UntypedFormGroup({
template: new UntypedFormControl(),
});
get templateControl() {

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

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

@ -6,7 +6,7 @@ import {
Input,
OnInit,
} 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 { I18nService } from 'core-app/core/i18n/i18n.service';
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 {
@Input() userId:string;
@Input() settings:FormArray;
@Input() settings:UntypedFormArray;
public eeShowBanners = false;
@ -91,18 +91,18 @@ export class NotificationSettingsTableComponent implements OnInit {
}
addProjectSettings(project:HalSourceLink):void {
this.settings.push(new FormGroup({
project: new FormControl(project),
this.settings.push(new UntypedFormGroup({
project: new UntypedFormControl(project),
assignee: new FormControl(false),
responsible: new FormControl(false),
workPackageCreated: new FormControl(false),
workPackageProcessed: new FormControl(false),
workPackageScheduled: new FormControl(false),
workPackagePrioritized: new FormControl(false),
workPackageCommented: new FormControl(false),
startDate: new FormControl(this.availableTimes[2].value),
dueDate: new FormControl(this.availableTimes[2].value),
overdue: new FormControl(this.availableTimesOverdue[0].value),
responsible: new UntypedFormControl(false),
workPackageCreated: new UntypedFormControl(false),
workPackageProcessed: new UntypedFormControl(false),
workPackageScheduled: new UntypedFormControl(false),
workPackagePrioritized: new UntypedFormControl(false),
workPackageCommented: new UntypedFormControl(false),
startDate: new UntypedFormControl(this.availableTimes[2].value),
dueDate: new UntypedFormControl(this.availableTimes[2].value),
overdue: new UntypedFormControl(this.availableTimesOverdue[0].value),
}));
}

@ -6,7 +6,7 @@ import {
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { UserPreferencesService } from 'core-app/features/user-preferences/state/user-preferences.service';
import {
FormGroup,
UntypedFormGroup,
FormGroupDirective,
} from '@angular/forms';
@ -31,7 +31,7 @@ export const emailAlerts:EmailAlertType[] = [
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class EmailAlertsSettingsComponent implements OnInit {
form:FormGroup;
form:UntypedFormGroup;
alerts:EmailAlertType[] = emailAlerts;
@ -56,6 +56,6 @@ export class EmailAlertsSettingsComponent implements OnInit {
}
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 { UserPreferencesService } from 'core-app/features/user-preferences/state/user-preferences.service';
import {
FormGroup,
UntypedFormGroup,
FormGroupDirective,
} from '@angular/forms';
@ -16,7 +16,7 @@ import {
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ImmediateReminderSettingsComponent implements OnInit {
form:FormGroup;
form:UntypedFormGroup;
text = {
title: this.I18n.t('js.reminders.settings.immediate.title'),
@ -32,6 +32,6 @@ export class ImmediateReminderSettingsComponent implements OnInit {
}
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 { UserPreferencesService } from 'core-app/features/user-preferences/state/user-preferences.service';
import {
FormArray,
FormBuilder,
UntypedFormArray,
UntypedFormBuilder,
} from '@angular/forms';
import {
DailyRemindersSettings,
@ -97,7 +97,7 @@ export class ReminderSettingsPageComponent extends UntilDestroyedMixin implement
private storeService:UserPreferencesService,
private currentUserService:CurrentUserService,
private uiRouterGlobals:UIRouterGlobals,
private fb:FormBuilder,
private fb:UntypedFormBuilder,
private cdRef:ChangeDetectorRef,
) {
super();
@ -132,7 +132,7 @@ export class ReminderSettingsPageComponent extends UntilDestroyedMixin implement
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 });
[...settings.dailyReminders.times].sort().forEach((time) => {
dailyReminderTimes.push(this.fb.control(time), { emitEvent: false });
@ -140,7 +140,7 @@ export class ReminderSettingsPageComponent extends UntilDestroyedMixin implement
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++) {
const control = workdays.at(i);
control.setValue(settings.workdays.includes(i + 1));

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

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

@ -4,8 +4,8 @@ import {
OnInit,
} from '@angular/core';
import {
FormArray,
FormControl,
UntypedFormArray,
UntypedFormControl,
FormGroupDirective,
} from '@angular/forms';
import * as moment from 'moment';
@ -18,7 +18,7 @@ import { I18nService } from 'core-app/core/i18n/i18n.service';
changeDetection: ChangeDetectionStrategy.OnPush,
})
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
@ -46,16 +46,16 @@ export class WorkdaysSettingsComponent implements OnInit {
}
ngOnInit():void {
this.control = this.formGroup.control.get('workdays') as FormArray;
this.control = this.formGroup.control.get('workdays') as UntypedFormArray;
}
indexOfLocalWorkday(day:string):number {
return this.isoWorkdays.indexOf(day);
}
controlForLocalWorkday(day:string):FormControl {
controlForLocalWorkday(day:string):UntypedFormControl {
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 */

@ -67,6 +67,7 @@ import {
zoomLevelOrder,
} from '../wp-timeline';
import { WeekdayService } from 'core-app/core/days/weekday.service';
import * as Mousetrap from 'mousetrap';
@Component({
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 { QueryResource } from 'core-app/features/hal/resources/query-resource';
import { WorkPackageCollectionResource } from 'core-app/features/hal/resources/wp-collection-resource';
import * as Mousetrap from 'mousetrap';
export interface WorkPackageViewSelectionState {
// 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 { By } from '@angular/platform-browser';
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 { FormlyModule } from '@ngx-formly/core';
@ -32,7 +32,7 @@ import { ConfirmDialogService } from "core-app/shared/components/modals/confirm-
providers: [],
})
class DynamicFormsTestingComponent {
control = new FormControl('');
control = new UntypedFormControl('');
@ViewChild(DynamicFormComponent) dynamicFormControl:DynamicFormComponent;
}
@ -260,7 +260,7 @@ describe('DynamicFormComponent', () => {
},
},
},
form: new FormGroup({}),
form: new UntypedFormGroup({}),
};
const I18nServiceStub = {
t(key:string) {

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

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

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

@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
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 { 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';
@ -36,7 +36,7 @@ export function createDynamicInputFixture(fields:IOPFormlyFieldSettings[], model
providers,
})
class DynamicInputsTestingComponent {
form = new FormGroup({});
form = new UntypedFormGroup({});
model = model;
@ -117,7 +117,7 @@ export function createDynamicInputFixture(fields:IOPFormlyFieldSettings[], model
}
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;
// Test ControlValueAccessor

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

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

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

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

@ -1,6 +1,6 @@
import { Directive, forwardRef, Input } from '@angular/core';
import {
FormArray, FormControl, FormGroup, NgControl,
UntypedFormArray, UntypedFormControl, UntypedFormGroup, NgControl,
} from '@angular/forms';
export const formControlBinding = {
@ -15,9 +15,9 @@ export const formControlBinding = {
exportAs: 'ngForm',
})
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;
}

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

@ -19,6 +19,9 @@
*/
// 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
* with the following flag, it will bypass `zone.js` patch for IE/Edge
@ -30,11 +33,6 @@
*/
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. */
// 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.
// 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
* 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 { 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');
declare const require:any;
@ -29,6 +32,9 @@ window.I18n = new I18nShim();
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting(),
{
teardown: { destroyAfterEach: false },
},
);
// Then we find all the tests.

Loading…
Cancel
Save