Browse Source

Upgrade of angular. (#928)

* Upgrade of angular.

* Fix build

* Update build.
pull/932/head
Sebastian Stehle 4 years ago
committed by GitHub
parent
commit
60069c8e27
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .github/workflows/release.yml
  2. 12
      frontend/angular.json
  3. 38943
      frontend/package-lock.json
  4. 167
      frontend/package.json
  5. 1
      frontend/src/app/app.module.ts
  6. 2
      frontend/src/app/features/administration/pages/event-consumers/event-consumer.component.html
  7. 4
      frontend/src/app/features/administration/pages/users/users-page.component.ts
  8. 12
      frontend/src/app/features/administration/state/users.forms.ts
  9. 3
      frontend/src/app/features/api/module.ts
  10. 48
      frontend/src/app/features/api/pages/graphql/graphql-page.component.scss
  11. 2
      frontend/src/app/features/content/pages/content/content-page.component.html
  12. 4
      frontend/src/app/features/content/pages/schemas/schemas-page.component.ts
  13. 6
      frontend/src/app/features/content/shared/forms/stock-photo-editor.component.ts
  14. 2
      frontend/src/app/features/content/shared/references/content-creator.component.html
  15. 4
      frontend/src/app/features/content/shared/references/reference-dropdown.component.ts
  16. 4
      frontend/src/app/features/content/shared/references/references-checkboxes.component.ts
  17. 4
      frontend/src/app/features/content/shared/references/references-tags.component.ts
  18. 4
      frontend/src/app/features/schemas/pages/schema/fields/forms/field-form-common.component.ts
  19. 4
      frontend/src/app/features/schemas/pages/schema/fields/forms/field-form-ui.component.ts
  20. 4
      frontend/src/app/features/schemas/pages/schema/fields/forms/field-form-validation.component.ts
  21. 4
      frontend/src/app/features/schemas/pages/schema/fields/forms/field-form.component.ts
  22. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/array-validation.component.ts
  23. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/assets-ui.component.ts
  24. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/assets-validation.component.ts
  25. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/boolean-ui.component.ts
  26. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/boolean-validation.component.ts
  27. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/component-ui.component.ts
  28. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/component-validation.component.ts
  29. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/components-ui.component.ts
  30. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/components-validation.component.ts
  31. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/date-time-ui.component.ts
  32. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/date-time-validation.component.ts
  33. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/geolocation-ui.component.ts
  34. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/geolocation-validation.component.ts
  35. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/json-more.component.ts
  36. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/json-ui.component.ts
  37. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/json-validation.component.ts
  38. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/number-ui.component.ts
  39. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/number-validation.component.ts
  40. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/references-ui.component.ts
  41. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/references-validation.component.ts
  42. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/string-ui.component.ts
  43. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/string-validation.component.ts
  44. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/tags-ui.component.ts
  45. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/tags-validation.component.ts
  46. 4
      frontend/src/app/features/schemas/pages/schemas/schemas-page.component.ts
  47. 4
      frontend/src/app/features/settings/pages/more/more-page.component.html
  48. 6
      frontend/src/app/features/teams/state/team-contributors.forms.ts
  49. 4
      frontend/src/app/framework/angular/forms/control-errors.component.ts
  50. 4
      frontend/src/app/framework/angular/forms/editable-title.component.ts
  51. 4
      frontend/src/app/framework/angular/forms/editors/autocomplete.component.ts
  52. 6
      frontend/src/app/framework/angular/forms/editors/date-time-editor.component.ts
  53. 4
      frontend/src/app/framework/angular/forms/editors/dropdown.component.ts
  54. 4
      frontend/src/app/framework/angular/forms/editors/tag-editor.component.ts
  55. 10
      frontend/src/app/framework/angular/forms/error-formatting.spec.ts
  56. 10
      frontend/src/app/framework/angular/forms/error-validator.spec.ts
  57. 20
      frontend/src/app/framework/angular/forms/extended-form-array.spec.ts
  58. 4
      frontend/src/app/framework/angular/forms/extended-form-array.ts
  59. 16
      frontend/src/app/framework/angular/forms/extended-form-group.spec.ts
  60. 4
      frontend/src/app/framework/angular/forms/extended-form-group.ts
  61. 40
      frontend/src/app/framework/angular/forms/forms-helper.spec.ts
  62. 12
      frontend/src/app/framework/angular/forms/forms-helper.ts
  63. 6
      frontend/src/app/framework/angular/forms/templated-form-array.spec.ts
  64. 6
      frontend/src/app/framework/angular/forms/templated-form-group.spec.ts
  65. 4
      frontend/src/app/framework/angular/forms/templated-form-group.ts
  66. 108
      frontend/src/app/framework/angular/forms/validators.spec.ts
  67. 2
      frontend/src/app/framework/angular/stateful.component.ts
  68. 13
      frontend/src/app/framework/utils/modal-view.ts
  69. 2
      frontend/src/app/shared/components/assets/image-cropper.component.scss
  70. 2
      frontend/src/app/shared/components/contents/content-list-field.component.html
  71. 4
      frontend/src/app/shared/components/contents/content-list-field.component.ts
  72. 8
      frontend/src/app/shared/components/contents/content-status.component.html
  73. 4
      frontend/src/app/shared/components/contents/content-value-editor.component.ts
  74. 6
      frontend/src/app/shared/components/forms/geolocation-editor.component.ts
  75. 24
      frontend/src/app/shared/state/apps.forms.ts
  76. 28
      frontend/src/app/shared/state/assets.forms.ts
  77. 6
      frontend/src/app/shared/state/backups.forms.ts
  78. 6
      frontend/src/app/shared/state/clients.forms.ts
  79. 4
      frontend/src/app/shared/state/comments.form.ts
  80. 4
      frontend/src/app/shared/state/contents.forms.spec.ts
  81. 22
      frontend/src/app/shared/state/contents.forms.ts
  82. 8
      frontend/src/app/shared/state/contributors.forms.ts
  83. 8
      frontend/src/app/shared/state/languages.forms.ts
  84. 10
      frontend/src/app/shared/state/roles.forms.ts
  85. 18
      frontend/src/app/shared/state/rules.forms.ts
  86. 230
      frontend/src/app/shared/state/schemas.forms.ts
  87. 6
      frontend/src/app/shared/state/teams.forms.ts
  88. 4
      frontend/src/app/shared/state/workflows.forms.ts
  89. 1
      frontend/src/app/theme/_bootstrap-vars.scss
  90. 9
      frontend/src/app/theme/theme.scss
  91. 3
      frontend/tsconfig.json

2
.github/workflows/release.yml

@ -31,7 +31,7 @@ jobs:
${{ runner.os }}-buildx- ${{ runner.os }}-buildx-
- name: BUILD - name: BUILD
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
push: false push: false
load: true load: true

12
frontend/angular.json

@ -27,9 +27,15 @@
"tsConfig": "tsconfig.app.json", "tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss", "inlineStyleLanguage": "scss",
"allowedCommonJsDependencies": [ "allowedCommonJsDependencies": [
"@tweenjs/tween.js",
"angular2-chartjs", "angular2-chartjs",
"cropperjs",
"mousetrap",
"mersenne-twister",
"oidc-client",
"pikaday/pikaday", "pikaday/pikaday",
"progressbar.js" "progressbar.js",
"slugify"
], ],
"assets": [ "assets": [
"src/app/assets" "src/app/assets"
@ -119,5 +125,7 @@
} }
} }
}, },
"defaultProject": "squidex" "cli": {
"analytics": "a157454d-c7c0-4947-986a-982746edc974"
}
} }

38943
frontend/package-lock.json

File diff suppressed because it is too large

167
frontend/package.json

@ -16,116 +16,115 @@
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/animations": "13.1.1", "@angular/animations": "14.2.6",
"@angular/cdk": "13.1.1", "@angular/cdk": "14.2.5",
"@angular/cdk-experimental": "13.1.1", "@angular/cdk-experimental": "14.2.5",
"@angular/common": "13.1.1", "@angular/common": "14.2.6",
"@angular/core": "13.1.1", "@angular/core": "14.2.6",
"@angular/forms": "13.1.1", "@angular/forms": "14.2.6",
"@angular/localize": "13.1.1", "@angular/localize": "14.2.6",
"@angular/platform-browser": "13.1.1", "@angular/platform-browser": "14.2.6",
"@angular/platform-browser-dynamic": "13.1.1", "@angular/platform-browser-dynamic": "14.2.6",
"@angular/platform-server": "13.1.1", "@angular/platform-server": "14.2.6",
"@angular/router": "13.1.1", "@angular/router": "14.2.6",
"@babel/runtime": "^7.16.7", "@babel/runtime": "^7.19.4",
"@egjs/hammerjs": "2.0.17", "@egjs/hammerjs": "2.0.17",
"@graphiql/toolkit": "^0.6.1", "@graphiql/toolkit": "^0.8.0",
"ace-builds": "1.4.13", "ace-builds": "1.12.0",
"angular-gridster2": "11.2.0", "angular-gridster2": "14.1.1",
"angular-mentions": "1.4.0", "angular-mentions": "1.5.0",
"angular2-chartjs": "0.5.1", "angular2-chartjs": "0.5.1",
"babel-polyfill": "6.26.0", "babel-polyfill": "6.26.0",
"bootstrap": "5.1.3", "bootstrap": "5.2.2",
"codemirror-graphql": "1.2.11", "core-js": "3.25.5",
"core-js": "3.20.1",
"cropperjs": "2.0.0-alpha.1", "cropperjs": "2.0.0-alpha.1",
"date-fns": "2.28.0", "date-fns": "2.29.3",
"font-awesome": "4.7.0", "font-awesome": "4.7.0",
"graphiql": "1.4.2", "graphiql": "2.0.9",
"graphql": "15.5.1", "graphql": "16.6.0",
"image-focus": "1.2.0", "graphql-ws": "^5.11.2",
"image-focus": "1.2.1",
"keycharm": "0.4.0", "keycharm": "0.4.0",
"leaflet": "1.7.1", "leaflet": "1.9.2",
"leaflet-control-geocoder": "2.3.0", "leaflet-control-geocoder": "2.4.0",
"marked": "4.0.8", "marked": "4.1.1",
"mersenne-twister": "1.1.0", "mersenne-twister": "1.1.0",
"mousetrap": "1.6.5", "mousetrap": "1.6.5",
"ngx-color-picker": "11.0.0", "ngx-color-picker": "13.0.0",
"ngx-doc-viewer": "2.0.5", "ngx-doc-viewer": "14.0.0",
"ngx-virtual-scroller": "^4.0.3", "ngx-virtual-scroller": "^4.0.3",
"oidc-client": "1.11.5", "oidc-client": "1.11.5",
"pikaday": "1.8.2", "pikaday": "1.8.2",
"progressbar.js": "1.1.0", "progressbar.js": "1.1.0",
"prop-types": "15.8.0", "react": "18.2.0",
"react": "17.0.2", "react-dom": "18.2.0",
"react-dom": "17.0.2",
"resize-observer-polyfill": "1.5.1", "resize-observer-polyfill": "1.5.1",
"rxjs": "7.5.1", "rxjs": "7.5.7",
"simplemde": "1.11.2", "simplemde": "1.11.2",
"slugify": "1.6.4", "slugify": "1.6.5",
"tinymce": "5.10.2", "tinymce": "5.10.2",
"tslib": "2.3.1", "tslib": "2.4.0",
"tui-calendar": "^1.15.1", "tui-calendar": "^1.15.3",
"typemoq": "^2.1.0", "typemoq": "^2.1.0",
"video.js": "7.17.0", "video.js": "7.20.3",
"vis-data": "7.1.2", "vis-data": "7.1.4",
"vis-network": "9.1.0", "vis-network": "9.1.2",
"vis-util": "5.0.2", "vis-util": "5.0.3",
"zone.js": "0.11.4" "zone.js": "0.11.8"
}, },
"devDependencies": { "devDependencies": {
"@angular-builders/custom-webpack": "^13.0.0", "@angular-builders/custom-webpack": "^14.0.1",
"@angular-devkit/build-angular": "~13.1.2", "@angular-devkit/build-angular": "^14.2.6",
"@angular/cli": "~13.1.2", "@angular/cli": "^14.2.6",
"@angular/compiler": "^13.1.1", "@angular/compiler": "^14.2.6",
"@angular/compiler-cli": "~13.1.0", "@angular/compiler-cli": "^14.2.6",
"@angular/elements": "^13.1.1", "@angular/elements": "^14.2.6",
"@babel/core": "^7.16.7", "@babel/core": "^7.19.3",
"@compodoc/compodoc": "^1.1.19", "@compodoc/compodoc": "^1.1.19",
"@storybook/addon-actions": "^6.4.20", "@storybook/addon-actions": "^6.5.12",
"@storybook/addon-essentials": "^6.4.20", "@storybook/addon-essentials": "^6.5.12",
"@storybook/addon-interactions": "^6.4.20", "@storybook/addon-interactions": "^6.5.12",
"@storybook/addon-links": "^6.4.20", "@storybook/addon-links": "^6.5.12",
"@storybook/angular": "^6.4.20", "@storybook/angular": "^6.5.12",
"@storybook/builder-webpack5": "^6.4.20", "@storybook/builder-webpack5": "^6.5.12",
"@storybook/manager-webpack5": "^6.4.20", "@storybook/manager-webpack5": "^6.5.12",
"@storybook/testing-library": "^0.0.9", "@storybook/testing-library": "^0.0.13",
"@types/codemirror": "0.0.108", "@types/codemirror": "5.60.5",
"@types/core-js": "2.5.5", "@types/core-js": "2.5.5",
"@types/jasmine": "3.10.2", "@types/jasmine": "4.3.0",
"@types/marked": "4.0.1", "@types/marked": "4.0.7",
"@types/mersenne-twister": "1.1.2", "@types/mersenne-twister": "1.1.2",
"@types/mousetrap": "1.6.9", "@types/mousetrap": "1.6.9",
"@types/node": "17.0.6", "@types/node": "18.11.0",
"@types/react": "17.0.38", "@types/react": "18.0.21",
"@types/react-dom": "17.0.11", "@types/react-dom": "18.0.6",
"@types/simplemde": "1.11.8", "@types/simplemde": "1.11.8",
"@types/tapable": "2.2.2", "@types/tapable": "2.2.2",
"@types/tinymce": "4.6.4", "@types/tinymce": "4.6.5",
"@types/ws": "8.2.2", "@types/ws": "8.5.3",
"@typescript-eslint/eslint-plugin": "5.8.1", "@typescript-eslint/eslint-plugin": "5.40.0",
"@typescript-eslint/parser": "5.8.1", "@typescript-eslint/parser": "5.40.0",
"@webcomponents/custom-elements": "^1.5.0", "@webcomponents/custom-elements": "^1.5.0",
"babel-loader": "^8.2.3", "babel-loader": "^8.2.5",
"copy-webpack-plugin": "10.2.0", "copy-webpack-plugin": "11.0.0",
"eslint": "8.6.0", "eslint": "8.25.0",
"eslint-config-airbnb-typescript": "16.1.0", "eslint-config-airbnb-typescript": "17.0.0",
"eslint-plugin-deprecation": "^1.3.2", "eslint-plugin-deprecation": "^1.3.2",
"eslint-plugin-import": "2.25.3", "eslint-plugin-import": "2.26.0",
"eslint-plugin-jsx-a11y": "6.5.1", "eslint-plugin-jsx-a11y": "6.6.1",
"eslint-webpack-plugin": "3.1.1", "eslint-webpack-plugin": "3.2.0",
"jasmine-core": "~3.10.0", "jasmine-core": "~4.4.0",
"karma": "~6.3.0", "karma": "~6.4.1",
"karma-chrome-launcher": "~3.1.0", "karma-chrome-launcher": "~3.1.1",
"karma-coverage": "~2.1.0", "karma-coverage": "~2.2.0",
"karma-jasmine": "~4.0.0", "karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~1.7.0", "karma-jasmine-html-reporter": "~2.0.0",
"raw-loader": "^4.0.2", "raw-loader": "^4.0.2",
"stylelint": "14.2.0", "stylelint": "14.14.0",
"stylelint-config-standard": "24.0.0", "stylelint-config-standard": "29.0.0",
"stylelint-config-standard-scss": "^3.0.0", "stylelint-config-standard-scss": "^5.0.0",
"stylelint-scss": "4.1.0", "stylelint-scss": "4.3.0",
"stylelint-webpack-plugin": "3.1.0", "stylelint-webpack-plugin": "3.3.0",
"typescript": "~4.5.2" "typescript": "4.7.2"
} }
} }

1
frontend/src/app/app.module.ts

@ -114,7 +114,6 @@ export class AppRouteReuseStrategy extends BaseRouteReuseStrategy {
{ provide: UIOptions, useFactory: configUIOptions }, { provide: UIOptions, useFactory: configUIOptions },
{ provide: APP_BASE_HREF, useValue: basePath() }, { provide: APP_BASE_HREF, useValue: basePath() },
], ],
entryComponents: [AppComponent],
}) })
export class AppModule { export class AppModule {
public ngDoBootstrap(appRef: ApplicationRef) { public ngDoBootstrap(appRef: ApplicationRef) {

2
frontend/src/app/features/administration/pages/event-consumers/event-consumer.component.html

@ -1,7 +1,7 @@
<tr [class.faulted]="eventConsumer.error && eventConsumer.error && eventConsumer.error.length > 0"> <tr [class.faulted]="eventConsumer.error && eventConsumer.error && eventConsumer.error.length > 0">
<td class="cell-auto"> <td class="cell-auto">
<span class="truncate"> <span class="truncate">
<i class="faulted-icon icon icon-bug" (click)="error.emit()" [class.hidden]="!eventConsumer.error || eventConsumer.error?.length === 0"></i> <i class="faulted-icon icon icon-bug" (click)="error.emit()" [class.hidden]="!eventConsumer.error || eventConsumer.error.length === 0"></i>
{{eventConsumer.name}} {{eventConsumer.name}}
</span> </span>

4
frontend/src/app/features/administration/pages/users/users-page.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms'; import { UntypedFormControl } from '@angular/forms';
import { UserDto, UsersState } from '@app/features/administration/internal'; import { UserDto, UsersState } from '@app/features/administration/internal';
import { ResourceOwner, Router2State } from '@app/framework'; import { ResourceOwner, Router2State } from '@app/framework';
@ -19,7 +19,7 @@ import { ResourceOwner, Router2State } from '@app/framework';
], ],
}) })
export class UsersPageComponent extends ResourceOwner implements OnInit { export class UsersPageComponent extends ResourceOwner implements OnInit {
public usersFilter = new FormControl(); public usersFilter = new UntypedFormControl();
constructor( constructor(
public readonly usersRoute: Router2State, public readonly usersRoute: Router2State,

12
frontend/src/app/features/administration/state/users.forms.ts

@ -5,29 +5,29 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { FormControl, Validators } from '@angular/forms'; import { UntypedFormControl, Validators } from '@angular/forms';
import { ExtendedFormGroup, Form, ValidatorsEx } from '@app/shared'; import { ExtendedFormGroup, Form, ValidatorsEx } from '@app/shared';
import { UpsertUserDto, UserDto } from './../services/users.service'; import { UpsertUserDto, UserDto } from './../services/users.service';
export class UserForm extends Form<ExtendedFormGroup, UpsertUserDto, UserDto> { export class UserForm extends Form<ExtendedFormGroup, UpsertUserDto, UserDto> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
email: new FormControl('', [ email: new UntypedFormControl('', [
Validators.email, Validators.email,
Validators.required, Validators.required,
Validators.maxLength(100), Validators.maxLength(100),
]), ]),
displayName: new FormControl('', [ displayName: new UntypedFormControl('', [
Validators.required, Validators.required,
Validators.maxLength(100), Validators.maxLength(100),
]), ]),
password: new FormControl('', password: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
passwordConfirm: new FormControl('', passwordConfirm: new UntypedFormControl('',
ValidatorsEx.match('password', 'i18n:users.passwordConfirmValidationMessage'), ValidatorsEx.match('password', 'i18n:users.passwordConfirmValidationMessage'),
), ),
permissions: new FormControl('', permissions: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
})); }));

3
frontend/src/app/features/api/module.ts

@ -15,9 +15,6 @@ const routes: Routes = [
path: '', path: '',
component: ApiAreaComponent, component: ApiAreaComponent,
children: [ children: [
{
path: '',
},
{ {
path: 'graphql', path: 'graphql',
component: GraphQLPageComponent, component: GraphQLPageComponent,

48
frontend/src/app/features/api/pages/graphql/graphql-page.component.scss

@ -1,47 +1,27 @@
@import 'mixins'; @import 'mixins';
@import 'vars'; @import 'vars';
:host ::ng-deep { @function hsl-str($color) {
@import '~graphiql/graphiql'; @return unquote('#{hue($color)}, #{saturation($color)}, #{lightness($color)}');
}
:host ::ng-deep {
.graphiql-container { .graphiql-container {
@include absolute(0, 0, 0, 0); @include absolute(0, 0, 0, 0);
& * { --color-primary: #{hsl-str($color-theme-brand)};
box-sizing: content-box; --color-success: #{hsl-str($color-theme-success)};
} --color-error: #{hsl-str($color-theme-error)};
--border-radius-4: #{$border-radius};
/* stylelint-disable-next-line selector-class-pattern */ --border-radius-8: #{$border-radius};
& .editorWrap { --border-radius-12: #{$border-radius};
overflow: hidden;
}
svg { .graphiql-sessions {
fill: $color-black; border-radius: $border-radius;
} }
/* stylelint-disable-next-line selector-class-pattern */
.historyPaneWrap {
border-radius: 0;
border-left: 1px solid $color-border;
box-shadow: none !important;
}
/* stylelint-disable-next-line selector-class-pattern */
.docExplorerWrap {
border-radius: 0;
border-left: 1px solid $color-border;
box-shadow: none !important;
}
}
/* stylelint-disable-next-line selector-class-pattern */
.CodeMirror {
padding: 0;
} }
/* stylelint-disable-next-line selector-class-pattern */ .graphiql-logo {
.CodeMirror-linenumbers { display: none;
min-width: 29px;
} }
} }

2
frontend/src/app/features/content/pages/content/content-page.component.html

@ -53,7 +53,7 @@
<ng-container *ngIf="content; else noContentMenu"> <ng-container *ngIf="content; else noContentMenu">
<sqx-watching-users resource="{{schema.id}}/{{content.id}}"></sqx-watching-users> <sqx-watching-users resource="{{schema.id}}/{{content.id}}"></sqx-watching-users>
<sqx-notifo topic="apps/{{contentsState.appId}}/schemas/{{schema?.name}}/contents/{{content.id}}"></sqx-notifo> <sqx-notifo topic="apps/{{contentsState.appId}}/schemas/{{schema.name}}/contents/{{content.id}}"></sqx-notifo>
<sqx-language-selector class="languages-buttons" <sqx-language-selector class="languages-buttons"
(languageChange)="changeLanguage($event)" (languageChange)="changeLanguage($event)"

4
frontend/src/app/features/content/pages/schemas/schemas-page.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { FormControl } from '@angular/forms'; import { UntypedFormControl } from '@angular/forms';
import { combineLatest } from 'rxjs'; import { combineLatest } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { AppsState, getCategoryTree, SchemaCategory, SchemasState, Settings, UIOptions, value$ } from '@app/shared'; import { AppsState, getCategoryTree, SchemaCategory, SchemasState, Settings, UIOptions, value$ } from '@app/shared';
@ -17,7 +17,7 @@ import { AppsState, getCategoryTree, SchemaCategory, SchemasState, Settings, UIO
templateUrl: './schemas-page.component.html', templateUrl: './schemas-page.component.html',
}) })
export class SchemasPageComponent { export class SchemasPageComponent {
public schemasFilter = new FormControl(); public schemasFilter = new UntypedFormControl();
public isEmbedded = false; public isEmbedded = false;

6
frontend/src/app/features/content/shared/forms/stock-photo-editor.component.ts

@ -6,7 +6,7 @@
*/ */
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, Input, OnInit } from '@angular/core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, Input, OnInit } from '@angular/core';
import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms'; import { NG_VALUE_ACCESSOR, UntypedFormControl } from '@angular/forms';
import { BehaviorSubject, of } from 'rxjs'; import { BehaviorSubject, of } from 'rxjs';
import { debounceTime, map, switchMap, tap } from 'rxjs/operators'; import { debounceTime, map, switchMap, tap } from 'rxjs/operators';
import { DialogModel, StatefulControlComponent, StockPhotoDto, StockPhotoService, thumbnail, Types, value$, valueProjection$ } from '@app/shared'; import { DialogModel, StatefulControlComponent, StockPhotoDto, StockPhotoService, thumbnail, Types, value$, valueProjection$ } from '@app/shared';
@ -46,11 +46,11 @@ export class StockPhotoEditorComponent extends StatefulControlComponent<State, s
this.setDisabledState(value === true); this.setDisabledState(value === true);
} }
public valueControl = new FormControl(''); public valueControl = new UntypedFormControl('');
public stockPhotoRequests = new BehaviorSubject<Request>({ page: 1 }); public stockPhotoRequests = new BehaviorSubject<Request>({ page: 1 });
public stockPhotoThumbnail = valueProjection$(this.valueControl, x => thumbnail(x, undefined, 300) || x); public stockPhotoThumbnail = valueProjection$(this.valueControl, x => thumbnail(x, undefined, 300) || x);
public stockPhotoSearch = new FormControl(''); public stockPhotoSearch = new UntypedFormControl('');
public searchDialog = new DialogModel(); public searchDialog = new DialogModel();

2
frontend/src/app/features/content/shared/references/content-creator.component.html

@ -30,7 +30,7 @@
{{ 'contents.referencesCreatePublish' | sqxTranslate }} {{ 'contents.referencesCreatePublish' | sqxTranslate }}
</button> </button>
<sqx-form-error [bubble]="true" [closeable]="true" [error]="contentForm?.error | async"></sqx-form-error> <sqx-form-error [bubble]="true" [closeable]="true" [error]="contentForm.error | async"></sqx-form-error>
</div> </div>
</div> </div>
</ng-container> </ng-container>

4
frontend/src/app/features/content/shared/references/reference-dropdown.component.ts

@ -6,7 +6,7 @@
*/ */
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, Input, OnChanges, SimpleChanges } from '@angular/core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, Input, OnChanges, SimpleChanges } from '@angular/core';
import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms'; import { NG_VALUE_ACCESSOR, UntypedFormControl } from '@angular/forms';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { ContentsDto } from '@app/shared'; import { ContentsDto } from '@app/shared';
import { ContentDto, getContentValue, LanguageDto, LocalizerService, ResolveContents, StatefulControlComponent, Types, value$ } from '@app/shared/internal'; import { ContentDto, getContentValue, LanguageDto, LocalizerService, ResolveContents, StatefulControlComponent, Types, value$ } from '@app/shared/internal';
@ -61,7 +61,7 @@ export class ReferenceDropdownComponent extends StatefulControlComponent<State,
this.setDisabledState(value === true); this.setDisabledState(value === true);
} }
public control = new FormControl(''); public control = new UntypedFormControl('');
public get isValid() { public get isValid() {
return !!this.schemaId && !!this.language; return !!this.schemaId && !!this.language;

4
frontend/src/app/features/content/shared/references/references-checkboxes.component.ts

@ -6,7 +6,7 @@
*/ */
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, Input, OnChanges, SimpleChanges } from '@angular/core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, Input, OnChanges, SimpleChanges } from '@angular/core';
import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms'; import { NG_VALUE_ACCESSOR, UntypedFormControl } from '@angular/forms';
import { AppsState, ContentDto, ContentsService, LanguageDto, LocalizerService, StatefulControlComponent, UIOptions } from '@app/shared/internal'; import { AppsState, ContentDto, ContentsService, LanguageDto, LocalizerService, StatefulControlComponent, UIOptions } from '@app/shared/internal';
import { ReferencesTagsConverter } from './references-tag-converter'; import { ReferencesTagsConverter } from './references-tag-converter';
@ -45,7 +45,7 @@ export class ReferencesCheckboxesComponent extends StatefulControlComponent<Stat
this.setDisabledState(value === true); this.setDisabledState(value === true);
} }
public control = new FormControl([]); public control = new UntypedFormControl([]);
public get isValid() { public get isValid() {
return !!this.schemaId && !!this.language; return !!this.schemaId && !!this.language;

4
frontend/src/app/features/content/shared/references/references-tags.component.ts

@ -6,7 +6,7 @@
*/ */
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, Input, OnChanges, SimpleChanges } from '@angular/core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, Input, OnChanges, SimpleChanges } from '@angular/core';
import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms'; import { NG_VALUE_ACCESSOR, UntypedFormControl } from '@angular/forms';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { Types } from '@app/framework'; import { Types } from '@app/framework';
import { ContentDto, ContentsDto, LanguageDto, LocalizerService, ResolveContents, StatefulControlComponent } from '@app/shared/internal'; import { ContentDto, ContentsDto, LanguageDto, LocalizerService, ResolveContents, StatefulControlComponent } from '@app/shared/internal';
@ -54,7 +54,7 @@ export class ReferencesTagsComponent extends StatefulControlComponent<State, Rea
this.setDisabledState(value === true); this.setDisabledState(value === true);
} }
public control = new FormControl([]); public control = new UntypedFormControl([]);
public get isValid() { public get isValid() {
return !!this.schemaId && !!this.language; return !!this.schemaId && !!this.language;

4
frontend/src/app/features/schemas/pages/schema/fields/forms/field-form-common.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { FieldDto, SchemaDto } from '@app/shared'; import { FieldDto, SchemaDto } from '@app/shared';
@Component({ @Component({
@ -16,7 +16,7 @@ import { FieldDto, SchemaDto } from '@app/shared';
}) })
export class FieldFormCommonComponent { export class FieldFormCommonComponent {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/forms/field-form-ui.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { FieldDto, SchemaDto } from '@app/shared'; import { FieldDto, SchemaDto } from '@app/shared';
@Component({ @Component({
@ -16,7 +16,7 @@ import { FieldDto, SchemaDto } from '@app/shared';
}) })
export class FieldFormUIComponent { export class FieldFormUIComponent {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/forms/field-form-validation.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { AppSettingsDto, FieldDto, LanguageDto, SchemaDto } from '@app/shared'; import { AppSettingsDto, FieldDto, LanguageDto, SchemaDto } from '@app/shared';
@Component({ @Component({
@ -16,7 +16,7 @@ import { AppSettingsDto, FieldDto, LanguageDto, SchemaDto } from '@app/shared';
}) })
export class FieldFormValidationComponent { export class FieldFormValidationComponent {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/forms/field-form.component.ts

@ -6,7 +6,7 @@
*/ */
import { AfterViewInit, Component, EventEmitter, Input, Output } from '@angular/core'; import { AfterViewInit, Component, EventEmitter, Input, Output } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { AppSettingsDto, FieldDto, LanguageDto, SchemaDto } from '@app/shared'; import { AppSettingsDto, FieldDto, LanguageDto, SchemaDto } from '@app/shared';
@Component({ @Component({
@ -22,7 +22,7 @@ export class FieldFormComponent implements AfterViewInit {
public isEditable?: boolean | null; public isEditable?: boolean | null;
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/array-validation.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { ArrayFieldPropertiesDto, FieldDto } from '@app/shared'; import { ArrayFieldPropertiesDto, FieldDto } from '@app/shared';
@Component({ @Component({
@ -16,7 +16,7 @@ import { ArrayFieldPropertiesDto, FieldDto } from '@app/shared';
}) })
export class ArrayValidationComponent { export class ArrayValidationComponent {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/assets-ui.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { AssetsFieldPropertiesDto, FieldDto } from '@app/shared'; import { AssetsFieldPropertiesDto, FieldDto } from '@app/shared';
@Component({ @Component({
@ -16,7 +16,7 @@ import { AssetsFieldPropertiesDto, FieldDto } from '@app/shared';
}) })
export class AssetsUIComponent { export class AssetsUIComponent {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/assets-validation.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { AssetsFieldPropertiesDto, FieldDto, LanguageDto } from '@app/shared'; import { AssetsFieldPropertiesDto, FieldDto, LanguageDto } from '@app/shared';
@Component({ @Component({
@ -16,7 +16,7 @@ import { AssetsFieldPropertiesDto, FieldDto, LanguageDto } from '@app/shared';
}) })
export class AssetsValidationComponent { export class AssetsValidationComponent {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/boolean-ui.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { BOOLEAN_FIELD_EDITORS, BooleanFieldPropertiesDto, FieldDto } from '@app/shared'; import { BOOLEAN_FIELD_EDITORS, BooleanFieldPropertiesDto, FieldDto } from '@app/shared';
@Component({ @Component({
@ -18,7 +18,7 @@ export class BooleanUIComponent {
public readonly editors = BOOLEAN_FIELD_EDITORS; public readonly editors = BOOLEAN_FIELD_EDITORS;
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/boolean-validation.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { BooleanFieldPropertiesDto, FieldDto, hasNoValue$, LanguageDto } from '@app/shared'; import { BooleanFieldPropertiesDto, FieldDto, hasNoValue$, LanguageDto } from '@app/shared';
@ -17,7 +17,7 @@ import { BooleanFieldPropertiesDto, FieldDto, hasNoValue$, LanguageDto } from '@
}) })
export class BooleanValidationComponent implements OnChanges { export class BooleanValidationComponent implements OnChanges {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/component-ui.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { FieldDto, ReferencesFieldPropertiesDto } from '@app/shared'; import { FieldDto, ReferencesFieldPropertiesDto } from '@app/shared';
@Component({ @Component({
@ -16,7 +16,7 @@ import { FieldDto, ReferencesFieldPropertiesDto } from '@app/shared';
}) })
export class ComponentUIComponent { export class ComponentUIComponent {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/component-validation.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { FieldDto, ReferencesFieldPropertiesDto, SchemaTagSource } from '@app/shared'; import { FieldDto, ReferencesFieldPropertiesDto, SchemaTagSource } from '@app/shared';
@Component({ @Component({
@ -16,7 +16,7 @@ import { FieldDto, ReferencesFieldPropertiesDto, SchemaTagSource } from '@app/sh
}) })
export class ComponentValidationComponent { export class ComponentValidationComponent {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/components-ui.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { FieldDto, ReferencesFieldPropertiesDto } from '@app/shared'; import { FieldDto, ReferencesFieldPropertiesDto } from '@app/shared';
@Component({ @Component({
@ -16,7 +16,7 @@ import { FieldDto, ReferencesFieldPropertiesDto } from '@app/shared';
}) })
export class ComponentsUIComponent { export class ComponentsUIComponent {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/components-validation.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { FieldDto, ReferencesFieldPropertiesDto, SchemaTagSource } from '@app/shared'; import { FieldDto, ReferencesFieldPropertiesDto, SchemaTagSource } from '@app/shared';
@Component({ @Component({
@ -16,7 +16,7 @@ import { FieldDto, ReferencesFieldPropertiesDto, SchemaTagSource } from '@app/sh
}) })
export class ComponentsValidationComponent { export class ComponentsValidationComponent {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/date-time-ui.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { DATETIME_FIELD_EDITORS, DateTimeFieldPropertiesDto, FieldDto, FloatConverter } from '@app/shared'; import { DATETIME_FIELD_EDITORS, DateTimeFieldPropertiesDto, FieldDto, FloatConverter } from '@app/shared';
@Component({ @Component({
@ -19,7 +19,7 @@ export class DateTimeUIComponent {
public readonly editors = DATETIME_FIELD_EDITORS; public readonly editors = DATETIME_FIELD_EDITORS;
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/date-time-validation.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { DateTimeFieldPropertiesDto, FieldDto, hasNoValue$, LanguageDto } from '@app/shared'; import { DateTimeFieldPropertiesDto, FieldDto, hasNoValue$, LanguageDto } from '@app/shared';
@ -19,7 +19,7 @@ const CALCULATED_DEFAULT_VALUES: ReadonlyArray<string> = ['Now', 'Today'];
}) })
export class DateTimeValidationComponent implements OnChanges { export class DateTimeValidationComponent implements OnChanges {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/geolocation-ui.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { FieldDto, GeolocationFieldPropertiesDto } from '@app/shared'; import { FieldDto, GeolocationFieldPropertiesDto } from '@app/shared';
@Component({ @Component({
@ -16,7 +16,7 @@ import { FieldDto, GeolocationFieldPropertiesDto } from '@app/shared';
}) })
export class GeolocationUIComponent { export class GeolocationUIComponent {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/geolocation-validation.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { FieldDto, GeolocationFieldPropertiesDto } from '@app/shared'; import { FieldDto, GeolocationFieldPropertiesDto } from '@app/shared';
@Component({ @Component({
@ -16,7 +16,7 @@ import { FieldDto, GeolocationFieldPropertiesDto } from '@app/shared';
}) })
export class GeolocationValidationComponent { export class GeolocationValidationComponent {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/json-more.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { FieldDto, JsonFieldPropertiesDto } from '@app/shared'; import { FieldDto, JsonFieldPropertiesDto } from '@app/shared';
@Component({ @Component({
@ -16,7 +16,7 @@ import { FieldDto, JsonFieldPropertiesDto } from '@app/shared';
}) })
export class JsonMoreComponent { export class JsonMoreComponent {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/json-ui.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { FieldDto, JsonFieldPropertiesDto } from '@app/shared'; import { FieldDto, JsonFieldPropertiesDto } from '@app/shared';
@Component({ @Component({
@ -16,7 +16,7 @@ import { FieldDto, JsonFieldPropertiesDto } from '@app/shared';
}) })
export class JsonUIComponent { export class JsonUIComponent {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/json-validation.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { FieldDto, JsonFieldPropertiesDto } from '@app/shared'; import { FieldDto, JsonFieldPropertiesDto } from '@app/shared';
@Component({ @Component({
@ -16,7 +16,7 @@ import { FieldDto, JsonFieldPropertiesDto } from '@app/shared';
}) })
export class JsonValidationComponent { export class JsonValidationComponent {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/number-ui.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { FieldDto, FloatConverter, NUMBER_FIELD_EDITORS, NumberFieldPropertiesDto, ResourceOwner, valueProjection$ } from '@app/shared'; import { FieldDto, FloatConverter, NUMBER_FIELD_EDITORS, NumberFieldPropertiesDto, ResourceOwner, valueProjection$ } from '@app/shared';
@ -20,7 +20,7 @@ export class NumberUIComponent extends ResourceOwner implements OnChanges {
public readonly editors = NUMBER_FIELD_EDITORS; public readonly editors = NUMBER_FIELD_EDITORS;
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/number-validation.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { FieldDto, LanguageDto, NumberFieldPropertiesDto, RootFieldDto, SchemaDto, Types } from '@app/shared'; import { FieldDto, LanguageDto, NumberFieldPropertiesDto, RootFieldDto, SchemaDto, Types } from '@app/shared';
@Component({ @Component({
@ -16,7 +16,7 @@ import { FieldDto, LanguageDto, NumberFieldPropertiesDto, RootFieldDto, SchemaDt
}) })
export class NumberValidationComponent { export class NumberValidationComponent {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/references-ui.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { FieldDto, REFERENCES_FIELD_EDITORS, ReferencesFieldPropertiesDto } from '@app/shared'; import { FieldDto, REFERENCES_FIELD_EDITORS, ReferencesFieldPropertiesDto } from '@app/shared';
@Component({ @Component({
@ -18,7 +18,7 @@ export class ReferencesUIComponent {
public readonly editors = REFERENCES_FIELD_EDITORS; public readonly editors = REFERENCES_FIELD_EDITORS;
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/references-validation.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { FieldDto, LanguageDto, ReferencesFieldPropertiesDto, SchemaTagSource } from '@app/shared'; import { FieldDto, LanguageDto, ReferencesFieldPropertiesDto, SchemaTagSource } from '@app/shared';
@Component({ @Component({
@ -16,7 +16,7 @@ import { FieldDto, LanguageDto, ReferencesFieldPropertiesDto, SchemaTagSource }
}) })
export class ReferencesValidationComponent { export class ReferencesValidationComponent {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/string-ui.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { FieldDto, ResourceOwner, SchemaTagSource, STRING_FIELD_EDITORS, StringFieldPropertiesDto, valueProjection$ } from '@app/shared'; import { FieldDto, ResourceOwner, SchemaTagSource, STRING_FIELD_EDITORS, StringFieldPropertiesDto, valueProjection$ } from '@app/shared';
@ -19,7 +19,7 @@ export class StringUIComponent extends ResourceOwner implements OnChanges {
public readonly editors = STRING_FIELD_EDITORS; public readonly editors = STRING_FIELD_EDITORS;
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/string-validation.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { AppSettingsDto, FieldDto, hasNoValue$, hasValue$, LanguageDto, ModalModel, PatternDto, ResourceOwner, RootFieldDto, SchemaDto, STRING_CONTENT_TYPES, StringFieldPropertiesDto, Types, value$ } from '@app/shared'; import { AppSettingsDto, FieldDto, hasNoValue$, hasValue$, LanguageDto, ModalModel, PatternDto, ResourceOwner, RootFieldDto, SchemaDto, STRING_CONTENT_TYPES, StringFieldPropertiesDto, Types, value$ } from '@app/shared';
@ -19,7 +19,7 @@ export class StringValidationComponent extends ResourceOwner implements OnChange
public readonly contentTypes = STRING_CONTENT_TYPES; public readonly contentTypes = STRING_CONTENT_TYPES;
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/tags-ui.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { FieldDto, TAGS_FIELD_EDITORS, TagsFieldPropertiesDto } from '@app/shared'; import { FieldDto, TAGS_FIELD_EDITORS, TagsFieldPropertiesDto } from '@app/shared';
@Component({ @Component({
@ -18,7 +18,7 @@ export class TagsUIComponent {
public readonly editors = TAGS_FIELD_EDITORS; public readonly editors = TAGS_FIELD_EDITORS;
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schema/fields/types/tags-validation.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { FieldDto, LanguageDto, TagsFieldPropertiesDto } from '@app/shared'; import { FieldDto, LanguageDto, TagsFieldPropertiesDto } from '@app/shared';
@Component({ @Component({
@ -16,7 +16,7 @@ import { FieldDto, LanguageDto, TagsFieldPropertiesDto } from '@app/shared';
}) })
export class TagsValidationComponent { export class TagsValidationComponent {
@Input() @Input()
public fieldForm!: FormGroup; public fieldForm!: UntypedFormGroup;
@Input() @Input()
public field!: FieldDto; public field!: FieldDto;

4
frontend/src/app/features/schemas/pages/schemas/schemas-page.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms'; import { UntypedFormControl } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { combineLatest } from 'rxjs'; import { combineLatest } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
@ -22,7 +22,7 @@ export class SchemasPageComponent extends ResourceOwner implements OnInit {
public addSchemaDialog = new DialogModel(); public addSchemaDialog = new DialogModel();
public addCategoryForm = new CreateCategoryForm(); public addCategoryForm = new CreateCategoryForm();
public schemasFilter = new FormControl(); public schemasFilter = new UntypedFormControl();
public categories = public categories =
combineLatest([ combineLatest([

4
frontend/src/app/features/settings/pages/more/more-page.component.html

@ -12,7 +12,7 @@
<div class="form-group"> <div class="form-group">
<label for="email">{{ 'common.name' | sqxTranslate }}</label> <label for="email">{{ 'common.name' | sqxTranslate }}</label>
<input type="text" class="form-control" readonly [value]="app?.name"> <input type="text" class="form-control" readonly [value]="app.name">
</div> </div>
<div class="form-group"> <div class="form-group">
@ -53,7 +53,7 @@
<ng-template #notUploading> <ng-template #notUploading>
<div> <div>
<sqx-avatar [image]="app?.image" [identifier]="app?.name" [size]="150"></sqx-avatar> <sqx-avatar [image]="app.image" [identifier]="app.name" [size]="150"></sqx-avatar>
<ng-container *ngIf="isEditableImage && app?.image"> <ng-container *ngIf="isEditableImage && app?.image">
<button class="btn btn-danger btn-sm app-image-remove" title="i18n:apps.removeImage" (click)="removeImage()"> <button class="btn btn-danger btn-sm app-image-remove" title="i18n:apps.removeImage" (click)="removeImage()">

6
frontend/src/app/features/teams/state/team-contributors.forms.ts

@ -5,7 +5,7 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { FormControl, Validators } from '@angular/forms'; import { UntypedFormControl, Validators } from '@angular/forms';
import { debounceTime, map, shareReplay } from 'rxjs/operators'; import { debounceTime, map, shareReplay } from 'rxjs/operators';
import { AssignContributorDto, ExtendedFormGroup, Form, hasNoValue$, Types, UserDto, value$ } from '@app/shared'; import { AssignContributorDto, ExtendedFormGroup, Form, hasNoValue$, Types, UserDto, value$ } from '@app/shared';
@ -18,7 +18,7 @@ export class AssignTeamContributorForm extends Form<ExtendedFormGroup, AssignCon
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
user: new FormControl('', user: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
})); }));
@ -48,7 +48,7 @@ export class ImportContributorsForm extends Form<ExtendedFormGroup, ImportContri
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
import: new FormControl('', import: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
})); }));

4
frontend/src/app/framework/angular/forms/control-errors.component.ts

@ -6,7 +6,7 @@
*/ */
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Host, Input, OnChanges, OnDestroy, Optional } from '@angular/core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Host, Input, OnChanges, OnDestroy, Optional } from '@angular/core';
import { AbstractControl, FormArray, FormGroupDirective } from '@angular/forms'; import { AbstractControl, FormGroupDirective, UntypedFormArray } from '@angular/forms';
import { merge } from 'rxjs'; import { merge } from 'rxjs';
import { LocalizerService, StatefulComponent, Types } from '@app/framework/internal'; import { LocalizerService, StatefulComponent, Types } from '@app/framework/internal';
import { formatError } from './error-formatting'; import { formatError } from './error-formatting';
@ -34,7 +34,7 @@ export class ControlErrorsComponent extends StatefulComponent<State> implements
public fieldName: string | null | undefined; public fieldName: string | null | undefined;
public get isTouched() { public get isTouched() {
return this.control?.touched || Types.is(this.control, FormArray); return this.control?.touched || Types.is(this.control, UntypedFormArray);
} }
constructor(changeDetector: ChangeDetectorRef, constructor(changeDetector: ChangeDetectorRef,

4
frontend/src/app/framework/angular/forms/editable-title.component.ts

@ -6,7 +6,7 @@
*/ */
import { Component, EventEmitter, Input, Output } from '@angular/core'; import { Component, EventEmitter, Input, Output } from '@angular/core';
import { FormControl, Validators } from '@angular/forms'; import { UntypedFormControl, Validators } from '@angular/forms';
import { Keys } from '@app/framework/internal'; import { Keys } from '@app/framework/internal';
@Component({ @Component({
@ -41,7 +41,7 @@ export class EditableTitleComponent {
} }
public renaming = false; public renaming = false;
public renameForm = new FormControl(); public renameForm = new UntypedFormControl();
public onKeyDown(event: KeyboardEvent) { public onKeyDown(event: KeyboardEvent) {
if (Keys.isEscape(event)) { if (Keys.isEscape(event)) {

4
frontend/src/app/framework/angular/forms/editors/autocomplete.component.ts

@ -6,7 +6,7 @@
*/ */
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ElementRef, forwardRef, Input, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ElementRef, forwardRef, Input, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms'; import { NG_VALUE_ACCESSOR, UntypedFormControl } from '@angular/forms';
import { merge, Observable, of, Subject } from 'rxjs'; import { merge, Observable, of, Subject } from 'rxjs';
import { catchError, debounceTime, finalize, map, switchMap, tap } from 'rxjs/operators'; import { catchError, debounceTime, finalize, map, switchMap, tap } from 'rxjs/operators';
import { Keys, ModalModel, RelativePosition, StatefulControlComponent, Types } from '@app/framework/internal'; import { Keys, ModalModel, RelativePosition, StatefulControlComponent, Types } from '@app/framework/internal';
@ -100,7 +100,7 @@ export class AutocompleteComponent extends StatefulControlComponent<State, Reado
public suggestionsModal = new ModalModel(); public suggestionsModal = new ModalModel();
public queryInput = new FormControl(); public queryInput = new UntypedFormControl();
constructor(changeDetector: ChangeDetectorRef) { constructor(changeDetector: ChangeDetectorRef) {
super(changeDetector, { super(changeDetector, {

6
frontend/src/app/framework/angular/forms/editors/date-time-editor.component.ts

@ -6,7 +6,7 @@
*/ */
import { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Input, OnInit, Output, ViewChild } from '@angular/core'; import { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Input, OnInit, Output, ViewChild } from '@angular/core';
import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms'; import { NG_VALUE_ACCESSOR, UntypedFormControl } from '@angular/forms';
import * as Pikaday from 'pikaday/pikaday'; import * as Pikaday from 'pikaday/pikaday';
import { DateHelper, DateTime, StatefulControlComponent, UIOptions } from '@app/framework/internal'; import { DateHelper, DateTime, StatefulControlComponent, UIOptions } from '@app/framework/internal';
import { FocusComponent } from './../forms-helper'; import { FocusComponent } from './../forms-helper';
@ -69,8 +69,8 @@ export class DateTimeEditorComponent extends StatefulControlComponent<State, str
@ViewChild('dateInput', { static: false }) @ViewChild('dateInput', { static: false })
public dateInput!: ElementRef<HTMLInputElement>; public dateInput!: ElementRef<HTMLInputElement>;
public readonly timeControl = new FormControl(); public readonly timeControl = new UntypedFormControl();
public readonly dateControl = new FormControl(); public readonly dateControl = new UntypedFormControl();
public get shouldShowDateButtons() { public get shouldShowDateButtons() {
return !this.hideDateButtonsSettings && !this.hideDateButtons; return !this.hideDateButtonsSettings && !this.hideDateButtons;

4
frontend/src/app/framework/angular/forms/editors/dropdown.component.ts

@ -6,7 +6,7 @@
*/ */
import { AfterContentInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, EventEmitter, forwardRef, Input, OnChanges, OnInit, Output, QueryList, SimpleChanges, TemplateRef } from '@angular/core'; import { AfterContentInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, EventEmitter, forwardRef, Input, OnChanges, OnInit, Output, QueryList, SimpleChanges, TemplateRef } from '@angular/core';
import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms'; import { NG_VALUE_ACCESSOR, UntypedFormControl } from '@angular/forms';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { Keys, ModalModel, RelativePosition, StatefulControlComponent, Types } from '@app/framework/internal'; import { Keys, ModalModel, RelativePosition, StatefulControlComponent, Types } from '@app/framework/internal';
@ -89,7 +89,7 @@ export class DropdownComponent extends StatefulControlComponent<State, ReadonlyA
public templateSelection!: TemplateRef<any>; public templateSelection!: TemplateRef<any>;
public templateItem!: TemplateRef<any>; public templateItem!: TemplateRef<any>;
public queryInput = new FormControl(); public queryInput = new UntypedFormControl();
constructor(changeDetector: ChangeDetectorRef) { constructor(changeDetector: ChangeDetectorRef) {
super(changeDetector, { super(changeDetector, {

4
frontend/src/app/framework/angular/forms/editors/tag-editor.component.ts

@ -6,7 +6,7 @@
*/ */
import { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core'; import { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core';
import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms'; import { NG_VALUE_ACCESSOR, UntypedFormControl } from '@angular/forms';
import { distinctUntilChanged, map, tap } from 'rxjs/operators'; import { distinctUntilChanged, map, tap } from 'rxjs/operators';
import { getTagValues, Keys, ModalModel, StatefulControlComponent, StringConverter, TagValue, TextMeasurer, Types } from '@app/framework/internal'; import { getTagValues, Keys, ModalModel, StatefulControlComponent, StringConverter, TagValue, TextMeasurer, Types } from '@app/framework/internal';
@ -126,7 +126,7 @@ export class TagEditorComponent extends StatefulControlComponent<State, Readonly
public suggestionsSorted: ReadonlyArray<TagValue> = []; public suggestionsSorted: ReadonlyArray<TagValue> = [];
public suggestionsModal = new ModalModel(); public suggestionsModal = new ModalModel();
public addInput = new FormControl(); public addInput = new UntypedFormControl();
constructor(changeDetector: ChangeDetectorRef) { constructor(changeDetector: ChangeDetectorRef) {
super(changeDetector, { super(changeDetector, {

10
frontend/src/app/framework/angular/forms/error-formatting.spec.ts

@ -5,7 +5,7 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; import { UntypedFormControl, UntypedFormGroup, ValidatorFn, Validators } from '@angular/forms';
import { LocalizerService } from './../../services/localizer.service'; import { LocalizerService } from './../../services/localizer.service';
import { formatError } from './error-formatting'; import { formatError } from './error-formatting';
import { ValidatorsEx } from './validators'; import { ValidatorsEx } from './validators';
@ -197,10 +197,10 @@ describe('formatErrors', () => {
}); });
it('should format match', () => { it('should format match', () => {
const formControl1 = new FormControl(1); const formControl1 = new UntypedFormControl(1);
const formControl2 = new FormControl(2); const formControl2 = new UntypedFormControl(2);
const formGroup = new FormGroup({ const formGroup = new UntypedFormGroup({
field1: formControl1, field1: formControl1,
field2: formControl2, field2: formControl2,
}); });
@ -214,7 +214,7 @@ describe('formatErrors', () => {
}); });
function validate(value: any, validator: ValidatorFn) { function validate(value: any, validator: ValidatorFn) {
const formControl = new FormControl(value); const formControl = new UntypedFormControl(value);
const formError = validator(formControl)!; const formError = validator(formControl)!;
const formMessage = formatError(localizer, 'MY_FIELD', Object.keys(formError)[0], Object.values(formError)[0], value); const formMessage = formatError(localizer, 'MY_FIELD', Object.keys(formError)[0], Object.values(formError)[0], value);

10
frontend/src/app/framework/angular/forms/error-validator.spec.ts

@ -5,17 +5,17 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { FormArray, FormControl, FormGroup } from '@angular/forms'; import { UntypedFormArray, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { ErrorDto } from '@app/framework/internal'; import { ErrorDto } from '@app/framework/internal';
import { ErrorValidator } from './error-validator'; import { ErrorValidator } from './error-validator';
describe('ErrorValidator', () => { describe('ErrorValidator', () => {
const validator = new ErrorValidator(); const validator = new ErrorValidator();
const control = new FormGroup({ const control = new UntypedFormGroup({
nested1: new FormArray([ nested1: new UntypedFormArray([
new FormGroup({ new UntypedFormGroup({
nested2: new FormControl(), nested2: new UntypedFormControl(),
}), }),
]), ]),
}); });

20
frontend/src/app/framework/angular/forms/extended-form-array.spec.ts

@ -5,14 +5,14 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { FormArray, FormControl } from '@angular/forms'; import { UntypedFormArray, UntypedFormControl } from '@angular/forms';
import { ExtendedFormArray, UndefinableFormArray } from './extended-form-array'; import { ExtendedFormArray, UndefinableFormArray } from './extended-form-array';
describe('ExtendedFormArray', () => { describe('ExtendedFormArray', () => {
it('should provide value even if controls are disabled', () => { it('should provide value even if controls are disabled', () => {
const control = new ExtendedFormArray([ const control = new ExtendedFormArray([
new FormControl('1'), new UntypedFormControl('1'),
new FormControl('2'), new UntypedFormControl('2'),
]); ]);
expect(control.value).toEqual(['1', '2']); expect(control.value).toEqual(['1', '2']);
@ -43,8 +43,8 @@ describe('UndefinableFormArray', () => {
it('should provide value even if controls are disabled', () => { it('should provide value even if controls are disabled', () => {
const control = new UndefinableFormArray([ const control = new UndefinableFormArray([
new FormControl('1'), new UntypedFormControl('1'),
new FormControl('2'), new UntypedFormControl('2'),
]); ]);
expect(control.value).toEqual(['1', '2']); expect(control.value).toEqual(['1', '2']);
@ -89,7 +89,7 @@ describe('UndefinableFormArray', () => {
assertValue(control, ['1'], () => { assertValue(control, ['1'], () => {
control.setValue(undefined); control.setValue(undefined);
control.push(new FormControl('1')); control.push(new UntypedFormControl('1'));
}); });
}); });
@ -98,22 +98,22 @@ describe('UndefinableFormArray', () => {
assertValue(control, ['1'], () => { assertValue(control, ['1'], () => {
control.setValue(undefined); control.setValue(undefined);
control.insert(0, new FormControl('1')); control.insert(0, new UntypedFormControl('1'));
}); });
}); });
function buildControl(undefinable: boolean) { function buildControl(undefinable: boolean) {
return undefinable ? return undefinable ?
new UndefinableFormArray([ new UndefinableFormArray([
new FormControl(''), new UntypedFormControl(''),
]) : ]) :
new ExtendedFormArray([ new ExtendedFormArray([
new FormControl(''), new UntypedFormControl(''),
]); ]);
} }
}); });
function assertValue(control: FormArray, expected: any, action: () => void) { function assertValue(control: UntypedFormArray, expected: any, action: () => void) {
let currentValue: any; let currentValue: any;
control.valueChanges.subscribe(value => { control.valueChanges.subscribe(value => {

4
frontend/src/app/framework/angular/forms/extended-form-array.ts

@ -5,10 +5,10 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { AbstractControl, AbstractControlOptions, AsyncValidatorFn, FormArray, ValidatorFn } from '@angular/forms'; import { AbstractControl, AbstractControlOptions, AsyncValidatorFn, UntypedFormArray, ValidatorFn } from '@angular/forms';
import { Types } from '@app/framework/internal'; import { Types } from '@app/framework/internal';
export class ExtendedFormArray extends FormArray { export class ExtendedFormArray extends UntypedFormArray {
constructor(controls: AbstractControl[], validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null) { constructor(controls: AbstractControl[], validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null) {
super(controls, validatorOrOpts, asyncValidator); super(controls, validatorOrOpts, asyncValidator);

16
frontend/src/app/framework/angular/forms/extended-form-group.spec.ts

@ -5,14 +5,14 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { FormControl, FormGroup } from '@angular/forms'; import { UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { ExtendedFormGroup, UndefinableFormGroup } from './extended-form-group'; import { ExtendedFormGroup, UndefinableFormGroup } from './extended-form-group';
describe('UndefinableFormGroup', () => { describe('UndefinableFormGroup', () => {
it('should provide value even if controls are disabled', () => { it('should provide value even if controls are disabled', () => {
const control = new ExtendedFormGroup({ const control = new ExtendedFormGroup({
test1: new FormControl('1'), test1: new UntypedFormControl('1'),
test2: new FormControl('2'), test2: new UntypedFormControl('2'),
}); });
expect(control.value).toEqual({ test1: '1', test2: '2' }); expect(control.value).toEqual({ test1: '1', test2: '2' });
@ -43,8 +43,8 @@ describe('ExtendedFormGroup', () => {
it('should provide value even if controls are disabled', () => { it('should provide value even if controls are disabled', () => {
const control = new ExtendedFormGroup({ const control = new ExtendedFormGroup({
test1: new FormControl('1'), test1: new UntypedFormControl('1'),
test2: new FormControl('2'), test2: new UntypedFormControl('2'),
}); });
expect(control.value).toEqual({ test1: '1', test2: '2' }); expect(control.value).toEqual({ test1: '1', test2: '2' });
@ -87,15 +87,15 @@ describe('ExtendedFormGroup', () => {
function buildControl(undefinable: boolean) { function buildControl(undefinable: boolean) {
return undefinable ? return undefinable ?
new UndefinableFormGroup({ new UndefinableFormGroup({
field: new FormControl(), field: new UntypedFormControl(),
}) : }) :
new ExtendedFormGroup({ new ExtendedFormGroup({
field: new FormControl(), field: new UntypedFormControl(),
}); });
} }
}); });
function assertValue(control: FormGroup, expected: any, action: () => void) { function assertValue(control: UntypedFormGroup, expected: any, action: () => void) {
let currentValue: any; let currentValue: any;
control.valueChanges.subscribe(value => { control.valueChanges.subscribe(value => {

4
frontend/src/app/framework/angular/forms/extended-form-group.ts

@ -5,10 +5,10 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { AbstractControl, AbstractControlOptions, AsyncValidatorFn, FormGroup, ValidatorFn } from '@angular/forms'; import { AbstractControl, AbstractControlOptions, AsyncValidatorFn, UntypedFormGroup, ValidatorFn } from '@angular/forms';
import { Types } from '@app/framework/internal'; import { Types } from '@app/framework/internal';
export class ExtendedFormGroup extends FormGroup { export class ExtendedFormGroup extends UntypedFormGroup {
constructor(controls: { [key: string]: AbstractControl }, validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null) { constructor(controls: { [key: string]: AbstractControl }, validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null) {
super(controls, validatorOrOpts, asyncValidator); super(controls, validatorOrOpts, asyncValidator);

40
frontend/src/app/framework/angular/forms/forms-helper.spec.ts

@ -5,13 +5,13 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { FormArray, FormControl, FormGroup, Validators } from '@angular/forms'; import { UntypedFormArray, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { getControlPath, hasNoValue$, hasValue$, touchedChange$, value$ } from './forms-helper'; import { getControlPath, hasNoValue$, hasValue$, touchedChange$, value$ } from './forms-helper';
describe('FormHelpers', () => { describe('FormHelpers', () => {
describe('value$', () => { describe('value$', () => {
it('should provide change values', () => { it('should provide change values', () => {
const form = new FormControl('1', Validators.required); const form = new UntypedFormControl('1', Validators.required);
const values: any[] = []; const values: any[] = [];
@ -26,7 +26,7 @@ describe('FormHelpers', () => {
}); });
it('should also trigger on disable', () => { it('should also trigger on disable', () => {
const form = new FormControl('1', Validators.required); const form = new UntypedFormControl('1', Validators.required);
const values: any[] = []; const values: any[] = [];
@ -45,7 +45,7 @@ describe('FormHelpers', () => {
}); });
it('should provide touched changes', () => { it('should provide touched changes', () => {
const form = new FormControl('1', Validators.required); const form = new UntypedFormControl('1', Validators.required);
const values: any[] = []; const values: any[] = [];
@ -61,7 +61,7 @@ describe('FormHelpers', () => {
}); });
it('should provide value when defined', () => { it('should provide value when defined', () => {
const form = new FormControl('1', Validators.required); const form = new UntypedFormControl('1', Validators.required);
const values: any[] = []; const values: any[] = [];
@ -77,7 +77,7 @@ describe('FormHelpers', () => {
}); });
it('should provide value when defined', () => { it('should provide value when defined', () => {
const form = new FormControl('1', Validators.required); const form = new UntypedFormControl('1', Validators.required);
const values: any[] = []; const values: any[] = [];
@ -94,7 +94,7 @@ describe('FormHelpers', () => {
describe('getControlPath', () => { describe('getControlPath', () => {
it('should calculate path for standalone control', () => { it('should calculate path for standalone control', () => {
const control = new FormControl(); const control = new UntypedFormControl();
const path = getControlPath(control); const path = getControlPath(control);
@ -102,8 +102,8 @@ describe('FormHelpers', () => {
}); });
it('should calculate path for nested control', () => { it('should calculate path for nested control', () => {
const control = new FormGroup({ const control = new UntypedFormGroup({
nested: new FormControl(), nested: new UntypedFormControl(),
}); });
const path = getControlPath(control.get('nested')); const path = getControlPath(control.get('nested'));
@ -112,9 +112,9 @@ describe('FormHelpers', () => {
}); });
it('should calculate path for deeply nested control', () => { it('should calculate path for deeply nested control', () => {
const control = new FormGroup({ const control = new UntypedFormGroup({
nested1: new FormGroup({ nested1: new UntypedFormGroup({
nested2: new FormControl(), nested2: new UntypedFormControl(),
}), }),
}); });
@ -124,10 +124,10 @@ describe('FormHelpers', () => {
}); });
it('should calculate path for deeply nested array control', () => { it('should calculate path for deeply nested array control', () => {
const control = new FormGroup({ const control = new UntypedFormGroup({
nested1: new FormArray([ nested1: new UntypedFormArray([
new FormGroup({ new UntypedFormGroup({
nested2: new FormControl(), nested2: new UntypedFormControl(),
}), }),
]), ]),
}); });
@ -138,10 +138,10 @@ describe('FormHelpers', () => {
}); });
it('should calculate api compatible path for deeply nested array control', () => { it('should calculate api compatible path for deeply nested array control', () => {
const control = new FormGroup({ const control = new UntypedFormGroup({
nested1: new FormArray([ nested1: new UntypedFormArray([
new FormGroup({ new UntypedFormGroup({
nested2: new FormControl(), nested2: new UntypedFormControl(),
}), }),
]), ]),
}); });

12
frontend/src/app/framework/angular/forms/forms-helper.ts

@ -5,7 +5,7 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { AbstractControl, FormArray, FormGroup, ValidatorFn } from '@angular/forms'; import { AbstractControl, UntypedFormArray, UntypedFormGroup, ValidatorFn } from '@angular/forms';
import { combineLatest, Observable } from 'rxjs'; import { combineLatest, Observable } from 'rxjs';
import { distinctUntilChanged, map, startWith } from 'rxjs/operators'; import { distinctUntilChanged, map, startWith } from 'rxjs/operators';
import { Types } from './../../utils/types'; import { Types } from './../../utils/types';
@ -15,9 +15,9 @@ export interface FocusComponent {
} }
export function formControls(form: AbstractControl): ReadonlyArray<AbstractControl> { export function formControls(form: AbstractControl): ReadonlyArray<AbstractControl> {
if (Types.is(form, FormGroup)) { if (Types.is(form, UntypedFormGroup)) {
return Object.values(form.controls); return Object.values(form.controls);
} else if (Types.is(form, FormArray)) { } else if (Types.is(form, UntypedFormArray)) {
return form.controls; return form.controls;
} else { } else {
return []; return [];
@ -51,7 +51,7 @@ export function getControlPath(control: AbstractControl | undefined | null, apiC
let name = ''; let name = '';
if (control.parent instanceof FormGroup) { if (control.parent instanceof UntypedFormGroup) {
for (const key in control.parent.controls) { for (const key in control.parent.controls) {
if (control.parent.controls[key] === control) { if (control.parent.controls[key] === control) {
name = key; name = key;
@ -168,13 +168,13 @@ export function hasNonCustomError(form: AbstractControl) {
} }
} }
if (Types.is(form, FormGroup)) { if (Types.is(form, UntypedFormGroup)) {
for (const key in form.controls) { for (const key in form.controls) {
if (hasNonCustomError(form.controls[key])) { if (hasNonCustomError(form.controls[key])) {
return true; return true;
} }
} }
} else if (Types.is(form, FormArray)) { } else if (Types.is(form, UntypedFormArray)) {
for (const control of form.controls) { for (const control of form.controls) {
if (hasNonCustomError(control)) { if (hasNonCustomError(control)) {
return true; return true;

6
frontend/src/app/framework/angular/forms/templated-form-array.spec.ts

@ -5,7 +5,7 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { FormControl, FormGroup } from '@angular/forms'; import { UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { FormArrayTemplate, TemplatedFormArray } from './templated-form-array'; import { FormArrayTemplate, TemplatedFormArray } from './templated-form-array';
describe('TemplatedFormArray', () => { describe('TemplatedFormArray', () => {
@ -14,8 +14,8 @@ describe('TemplatedFormArray', () => {
public removeCalled: number[] = []; public removeCalled: number[] = [];
public createControl() { public createControl() {
return new FormGroup({ return new UntypedFormGroup({
value: new FormControl(), value: new UntypedFormControl(),
}); });
} }

6
frontend/src/app/framework/angular/forms/templated-form-group.spec.ts

@ -5,7 +5,7 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { FormControl, FormGroup } from '@angular/forms'; import { UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { FormGroupTemplate, TemplatedFormGroup } from './templated-form-group'; import { FormGroupTemplate, TemplatedFormGroup } from './templated-form-group';
describe('TemplatedFormGroup', () => { describe('TemplatedFormGroup', () => {
@ -13,8 +13,8 @@ describe('TemplatedFormGroup', () => {
public clearCalled = 0; public clearCalled = 0;
public removeCalled: number[] = []; public removeCalled: number[] = [];
public setControls(form: FormGroup) { public setControls(form: UntypedFormGroup) {
form.setControl('value', new FormControl()); form.setControl('value', new UntypedFormControl());
} }
public clearControls() { public clearControls() {

4
frontend/src/app/framework/angular/forms/templated-form-group.ts

@ -5,12 +5,12 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { AbstractControlOptions, AsyncValidatorFn, FormGroup, ValidatorFn } from '@angular/forms'; import { AbstractControlOptions, AsyncValidatorFn, UntypedFormGroup, ValidatorFn } from '@angular/forms';
import { Types } from '@app/framework/internal'; import { Types } from '@app/framework/internal';
import { UndefinableFormGroup } from './extended-form-group'; import { UndefinableFormGroup } from './extended-form-group';
export interface FormGroupTemplate { export interface FormGroupTemplate {
setControls(form: FormGroup, value: any): void; setControls(form: UntypedFormGroup, value: any): void;
clearControls?(): void; clearControls?(): void;
} }

108
frontend/src/app/framework/angular/forms/validators.spec.ts

@ -5,7 +5,7 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { FormControl, FormGroup, Validators } from '@angular/forms'; import { UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { DateTime } from '@app/framework/internal'; import { DateTime } from '@app/framework/internal';
import { ValidatorsEx } from './validators'; import { ValidatorsEx } from './validators';
@ -18,7 +18,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if value is equal to min and max', () => { it('should return null if value is equal to min and max', () => {
const input = new FormControl(3); const input = new UntypedFormControl(3);
const error = <any>ValidatorsEx.between(3, 3)(input); const error = <any>ValidatorsEx.between(3, 3)(input);
@ -26,7 +26,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if value is valid', () => { it('should return null if value is valid', () => {
const input = new FormControl(4); const input = new UntypedFormControl(4);
const error = <any>ValidatorsEx.between(1, 5)(input); const error = <any>ValidatorsEx.between(1, 5)(input);
@ -34,7 +34,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if value is null', () => { it('should return null if value is null', () => {
const input = new FormControl(null); const input = new UntypedFormControl(null);
const error = <any>ValidatorsEx.between(1, 5)(input); const error = <any>ValidatorsEx.between(1, 5)(input);
@ -42,7 +42,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if value is undefined', () => { it('should return null if value is undefined', () => {
const input = new FormControl(undefined); const input = new UntypedFormControl(undefined);
const error = <any>ValidatorsEx.between(1, 5)(input); const error = <any>ValidatorsEx.between(1, 5)(input);
@ -50,7 +50,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return error if less than min', () => { it('should return error if less than min', () => {
const input = new FormControl(0); const input = new UntypedFormControl(0);
const error = <any>ValidatorsEx.between(1, undefined)(input); const error = <any>ValidatorsEx.between(1, undefined)(input);
@ -58,7 +58,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return error if greater than max', () => { it('should return error if greater than max', () => {
const input = new FormControl(6); const input = new UntypedFormControl(6);
const error = <any>ValidatorsEx.between(undefined, 5)(input); const error = <any>ValidatorsEx.between(undefined, 5)(input);
@ -66,7 +66,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return error if not in range', () => { it('should return error if not in range', () => {
const input = new FormControl(1); const input = new UntypedFormControl(1);
const error = <any>ValidatorsEx.between(2, 4)(input); const error = <any>ValidatorsEx.between(2, 4)(input);
@ -74,7 +74,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return error if not equal to min and max', () => { it('should return error if not equal to min and max', () => {
const input = new FormControl(2); const input = new UntypedFormControl(2);
const error = <any>ValidatorsEx.between(3, 3)(input); const error = <any>ValidatorsEx.between(3, 3)(input);
@ -90,7 +90,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if value is equal to min and max', () => { it('should return null if value is equal to min and max', () => {
const input = new FormControl('xxx'); const input = new UntypedFormControl('xxx');
const error = <any>ValidatorsEx.betweenLength(3, 3)(input); const error = <any>ValidatorsEx.betweenLength(3, 3)(input);
@ -98,7 +98,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if value is valid', () => { it('should return null if value is valid', () => {
const input = new FormControl('xxxx'); const input = new UntypedFormControl('xxxx');
const error = <any>ValidatorsEx.betweenLength(1, 5)(input); const error = <any>ValidatorsEx.betweenLength(1, 5)(input);
@ -106,7 +106,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if value is null', () => { it('should return null if value is null', () => {
const input = new FormControl(null); const input = new UntypedFormControl(null);
const error = <any>ValidatorsEx.betweenLength(1, 5)(input); const error = <any>ValidatorsEx.betweenLength(1, 5)(input);
@ -114,7 +114,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if value is undefined', () => { it('should return null if value is undefined', () => {
const input = new FormControl(undefined); const input = new UntypedFormControl(undefined);
const error = <any>ValidatorsEx.betweenLength(1, 5)(input); const error = <any>ValidatorsEx.betweenLength(1, 5)(input);
@ -122,7 +122,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return error if less than min', () => { it('should return error if less than min', () => {
const input = new FormControl('x'); const input = new UntypedFormControl('x');
const error = <any>ValidatorsEx.betweenLength(2, undefined)(input); const error = <any>ValidatorsEx.betweenLength(2, undefined)(input);
@ -130,7 +130,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return error if greater than max', () => { it('should return error if greater than max', () => {
const input = new FormControl('xxxxxx'); const input = new UntypedFormControl('xxxxxx');
const error = <any>ValidatorsEx.betweenLength(undefined, 5)(input); const error = <any>ValidatorsEx.betweenLength(undefined, 5)(input);
@ -138,7 +138,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return error if not in range', () => { it('should return error if not in range', () => {
const input = new FormControl('x'); const input = new UntypedFormControl('x');
const error = <any>ValidatorsEx.betweenLength(2, 4)(input); const error = <any>ValidatorsEx.betweenLength(2, 4)(input);
@ -146,7 +146,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return error if not equal to min and max', () => { it('should return error if not equal to min and max', () => {
const input = new FormControl('xx'); const input = new UntypedFormControl('xx');
const error = <any>ValidatorsEx.betweenLength(3, 3)(input); const error = <any>ValidatorsEx.betweenLength(3, 3)(input);
@ -156,7 +156,7 @@ describe('ValidatorsEx', () => {
describe('validDateTime', () => { describe('validDateTime', () => {
it('should return null validator if valid is not defined', () => { it('should return null validator if valid is not defined', () => {
const input = new FormControl(null); const input = new UntypedFormControl(null);
const error = <any>ValidatorsEx.validDateTime()(input); const error = <any>ValidatorsEx.validDateTime()(input);
@ -164,7 +164,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if date time is valid', () => { it('should return null if date time is valid', () => {
const input = new FormControl(DateTime.now().toISOString()); const input = new UntypedFormControl(DateTime.now().toISOString());
const error = ValidatorsEx.validDateTime()(input); const error = ValidatorsEx.validDateTime()(input);
@ -172,7 +172,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return error if value is invalid date', () => { it('should return error if value is invalid date', () => {
const input = new FormControl('invalid'); const input = new UntypedFormControl('invalid');
const error = <any>ValidatorsEx.validDateTime()(input); const error = <any>ValidatorsEx.validDateTime()(input);
@ -188,7 +188,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if value is in allowed values', () => { it('should return null if value is in allowed values', () => {
const input = new FormControl(10); const input = new UntypedFormControl(10);
const error = ValidatorsEx.validValues([10, 20, 30])(input); const error = ValidatorsEx.validValues([10, 20, 30])(input);
@ -196,7 +196,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return error if value is not in allowed values', () => { it('should return error if value is not in allowed values', () => {
const input = new FormControl(50); const input = new UntypedFormControl(50);
const error = <any>ValidatorsEx.validValues([10, 20, 30])(input); const error = <any>ValidatorsEx.validValues([10, 20, 30])(input);
@ -212,7 +212,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if value is in allowed values', () => { it('should return null if value is in allowed values', () => {
const input = new FormControl([10, 20]); const input = new UntypedFormControl([10, 20]);
const error = ValidatorsEx.validArrayValues([10, 20, 30])(input); const error = ValidatorsEx.validArrayValues([10, 20, 30])(input);
@ -220,7 +220,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return error if value is not in allowed values', () => { it('should return error if value is not in allowed values', () => {
const input = new FormControl([50]); const input = new UntypedFormControl([50]);
const error = <any>ValidatorsEx.validArrayValues([10, 20, 30])(input); const error = <any>ValidatorsEx.validArrayValues([10, 20, 30])(input);
@ -232,9 +232,9 @@ describe('ValidatorsEx', () => {
it('should revalidate if other control changes', () => { it('should revalidate if other control changes', () => {
const validator = ValidatorsEx.match('password', 'Passwords are not the same.'); const validator = ValidatorsEx.match('password', 'Passwords are not the same.');
const form = new FormGroup({ const form = new UntypedFormGroup({
password: new FormControl('1'), password: new UntypedFormControl('1'),
passwordConfirm: new FormControl('2', validator), passwordConfirm: new UntypedFormControl('2', validator),
}); });
form.controls['passwordConfirm'].setValue('1'); form.controls['passwordConfirm'].setValue('1');
@ -250,9 +250,9 @@ describe('ValidatorsEx', () => {
it('should return error if not the same value', () => { it('should return error if not the same value', () => {
const validator = ValidatorsEx.match('password', 'Passwords are not the same.'); const validator = ValidatorsEx.match('password', 'Passwords are not the same.');
const form = new FormGroup({ const form = new UntypedFormGroup({
password: new FormControl('1'), password: new UntypedFormControl('1'),
passwordConfirm: new FormControl('2', validator), passwordConfirm: new UntypedFormControl('2', validator),
}); });
expect(validator(form.controls['passwordConfirm'])).toEqual({ match: { message: 'Passwords are not the same.' } }); expect(validator(form.controls['passwordConfirm'])).toEqual({ match: { message: 'Passwords are not the same.' } });
@ -261,9 +261,9 @@ describe('ValidatorsEx', () => {
it('should return empty object if values are the same', () => { it('should return empty object if values are the same', () => {
const validator = ValidatorsEx.match('password', 'Passwords are not the same.'); const validator = ValidatorsEx.match('password', 'Passwords are not the same.');
const form = new FormGroup({ const form = new UntypedFormGroup({
password: new FormControl('1'), password: new UntypedFormControl('1'),
passwordConfirm: new FormControl('1', validator), passwordConfirm: new UntypedFormControl('1', validator),
}); });
expect(validator(form.controls['passwordConfirm'])).toBeNull(); expect(validator(form.controls['passwordConfirm'])).toBeNull();
@ -272,8 +272,8 @@ describe('ValidatorsEx', () => {
it('should throw error if other object is not found', () => { it('should throw error if other object is not found', () => {
const validator = ValidatorsEx.match('password', 'Passwords are not the same.'); const validator = ValidatorsEx.match('password', 'Passwords are not the same.');
const form = new FormGroup({ const form = new UntypedFormGroup({
passwordConfirm: new FormControl('2', validator), passwordConfirm: new UntypedFormControl('2', validator),
}); });
expect(() => validator(form.controls['passwordConfirm'])).toThrow(); expect(() => validator(form.controls['passwordConfirm'])).toThrow();
@ -282,7 +282,7 @@ describe('ValidatorsEx', () => {
it('should return empty object if control has no parent', () => { it('should return empty object if control has no parent', () => {
const validator = ValidatorsEx.match('password', 'Passwords are not the same.'); const validator = ValidatorsEx.match('password', 'Passwords are not the same.');
const control = new FormControl('2', validator); const control = new UntypedFormControl('2', validator);
expect(validator(control)).toBeNull(); expect(validator(control)).toBeNull();
}); });
@ -296,7 +296,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if value is valid pattern', () => { it('should return null if value is valid pattern', () => {
const input = new FormControl('1234'); const input = new UntypedFormControl('1234');
const error = ValidatorsEx.pattern(/^[0-9]{1,4}$/)(input); const error = ValidatorsEx.pattern(/^[0-9]{1,4}$/)(input);
@ -304,7 +304,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if value is null string', () => { it('should return null if value is null string', () => {
const input = new FormControl(null); const input = new UntypedFormControl(null);
const error = ValidatorsEx.pattern(/^[0-9]{1,4}$/)(input); const error = ValidatorsEx.pattern(/^[0-9]{1,4}$/)(input);
@ -312,7 +312,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if value is empty string', () => { it('should return null if value is empty string', () => {
const input = new FormControl(''); const input = new UntypedFormControl('');
const error = ValidatorsEx.pattern(/^[0-9]{1,4}$/)(input); const error = ValidatorsEx.pattern(/^[0-9]{1,4}$/)(input);
@ -320,7 +320,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return error with message if value does not match pattern string', () => { it('should return error with message if value does not match pattern string', () => {
const input = new FormControl('abc'); const input = new UntypedFormControl('abc');
const error = <any>ValidatorsEx.pattern('[0-9]{1,4}', 'My-Message')(input); const error = <any>ValidatorsEx.pattern('[0-9]{1,4}', 'My-Message')(input);
const expected: any = { const expected: any = {
@ -333,7 +333,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return error with message if value does not match pattern', () => { it('should return error with message if value does not match pattern', () => {
const input = new FormControl('abc'); const input = new UntypedFormControl('abc');
const error = <any>ValidatorsEx.pattern(/^[0-9]{1,4}$/, 'My-Message')(input); const error = <any>ValidatorsEx.pattern(/^[0-9]{1,4}$/, 'My-Message')(input);
const expected: any = { const expected: any = {
@ -346,7 +346,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return error without message if value does not match pattern string', () => { it('should return error without message if value does not match pattern string', () => {
const input = new FormControl('abc'); const input = new UntypedFormControl('abc');
const error = <any>ValidatorsEx.pattern('[0-9]{1,4}')(input); const error = <any>ValidatorsEx.pattern('[0-9]{1,4}')(input);
const expected: any = { const expected: any = {
@ -359,7 +359,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return error without message if value does not match pattern', () => { it('should return error without message if value does not match pattern', () => {
const input = new FormControl('abc'); const input = new UntypedFormControl('abc');
const error = <any>ValidatorsEx.pattern(/^[0-9]{1,4}$/)(input); const error = <any>ValidatorsEx.pattern(/^[0-9]{1,4}$/)(input);
const expected: any = { const expected: any = {
@ -374,7 +374,7 @@ describe('ValidatorsEx', () => {
describe('uniqueStrings', () => { describe('uniqueStrings', () => {
it('should return null if value is null', () => { it('should return null if value is null', () => {
const input = new FormControl(null); const input = new UntypedFormControl(null);
const error = ValidatorsEx.uniqueStrings()(input); const error = ValidatorsEx.uniqueStrings()(input);
@ -382,7 +382,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if value is not a string array', () => { it('should return null if value is not a string array', () => {
const input = new FormControl([1, 2, 3]); const input = new UntypedFormControl([1, 2, 3]);
const error = ValidatorsEx.uniqueStrings()(input); const error = ValidatorsEx.uniqueStrings()(input);
@ -390,7 +390,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if values are unique', () => { it('should return null if values are unique', () => {
const input = new FormControl(['1', '2', '3']); const input = new UntypedFormControl(['1', '2', '3']);
const error = ValidatorsEx.uniqueStrings()(input); const error = ValidatorsEx.uniqueStrings()(input);
@ -398,7 +398,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return error if values are not unique', () => { it('should return error if values are not unique', () => {
const input = new FormControl(['1', '2', '2', '3']); const input = new UntypedFormControl(['1', '2', '2', '3']);
const error = ValidatorsEx.uniqueStrings()(input); const error = ValidatorsEx.uniqueStrings()(input);
@ -408,7 +408,7 @@ describe('ValidatorsEx', () => {
describe('uniqueObjectValues', () => { describe('uniqueObjectValues', () => {
it('should return null if value is null', () => { it('should return null if value is null', () => {
const input = new FormControl(null); const input = new UntypedFormControl(null);
const error = ValidatorsEx.uniqueObjectValues(['myString'])(input); const error = ValidatorsEx.uniqueObjectValues(['myString'])(input);
@ -416,7 +416,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if value is not an object array', () => { it('should return null if value is not an object array', () => {
const input = new FormControl([1, 2, 3]); const input = new UntypedFormControl([1, 2, 3]);
const error = ValidatorsEx.uniqueObjectValues(['myString'])(input); const error = ValidatorsEx.uniqueObjectValues(['myString'])(input);
@ -424,7 +424,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if values array has one item', () => { it('should return null if values array has one item', () => {
const input = new FormControl([{}]); const input = new UntypedFormControl([{}]);
const error = ValidatorsEx.uniqueObjectValues(['myString'])(input); const error = ValidatorsEx.uniqueObjectValues(['myString'])(input);
@ -432,7 +432,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if values array has no duplicate', () => { it('should return null if values array has no duplicate', () => {
const input = new FormControl([{ myString: '1' }, { myString: '2' }]); const input = new UntypedFormControl([{ myString: '1' }, { myString: '2' }]);
const error = ValidatorsEx.uniqueObjectValues(['myString'])(input); const error = ValidatorsEx.uniqueObjectValues(['myString'])(input);
@ -440,7 +440,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return null if values array has unchecked duplicate', () => { it('should return null if values array has unchecked duplicate', () => {
const input = new FormControl([{ other: '1' }, { other: '1' }]); const input = new UntypedFormControl([{ other: '1' }, { other: '1' }]);
const error = ValidatorsEx.uniqueObjectValues(['myString'])(input); const error = ValidatorsEx.uniqueObjectValues(['myString'])(input);
@ -448,7 +448,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return error if values array has duplicate', () => { it('should return error if values array has duplicate', () => {
const input = new FormControl([{ myString: '1' }, { myString: '1' }]); const input = new UntypedFormControl([{ myString: '1' }, { myString: '1' }]);
const error = ValidatorsEx.uniqueObjectValues(['myString'])(input); const error = ValidatorsEx.uniqueObjectValues(['myString'])(input);
@ -456,7 +456,7 @@ describe('ValidatorsEx', () => {
}); });
it('should return error if values array has multiple duplicates', () => { it('should return error if values array has multiple duplicates', () => {
const input = new FormControl([{ myString: '1', myNumber: 2 }, { myString: '1', myNumber: 2 }]); const input = new UntypedFormControl([{ myString: '1', myNumber: 2 }, { myString: '1', myNumber: 2 }]);
const error = ValidatorsEx.uniqueObjectValues(['myString', 'myNumber'])(input); const error = ValidatorsEx.uniqueObjectValues(['myString', 'myNumber'])(input);

2
frontend/src/app/framework/angular/stateful.component.ts

@ -49,7 +49,7 @@ export class ResourceOwner implements OnDestroy {
} }
@Directive() @Directive()
export abstract class StatefulComponent<T = any> extends State<T> implements OnDestroy { export abstract class StatefulComponent<T extends {} = object> extends State<T> implements OnDestroy {
private readonly subscriptions = new ResourceOwner(); private readonly subscriptions = new ResourceOwner();
private readonly subscription: Subscription; private readonly subscription: Subscription;

13
frontend/src/app/framework/utils/modal-view.ts

@ -48,6 +48,7 @@ export class DialogModel implements Openable {
} }
export class ModalModel implements Openable { export class ModalModel implements Openable {
private static openModal?: ModalModel | null = null;
private readonly isOpen$: BehaviorSubject<boolean>; private readonly isOpen$: BehaviorSubject<boolean>;
public get isOpenChanges(): Observable<boolean> { public get isOpenChanges(): Observable<boolean> {
@ -64,11 +65,11 @@ export class ModalModel implements Openable {
public show(): ModalModel { public show(): ModalModel {
if (!this.isOpen$.value) { if (!this.isOpen$.value) {
if (openModal && openModal !== this) { if (ModalModel.openModal && ModalModel.openModal !== this) {
openModal.hide(); ModalModel.openModal.hide();
} }
openModal = this; ModalModel.openModal = this;
this.isOpen$.next(true); this.isOpen$.next(true);
} }
@ -78,8 +79,8 @@ export class ModalModel implements Openable {
public hide(): ModalModel { public hide(): ModalModel {
if (this.isOpen$.value) { if (this.isOpen$.value) {
if (openModal === this) { if (ModalModel.openModal === this) {
openModal = null; ModalModel.openModal = null;
} }
this.isOpen$.next(false); this.isOpen$.next(false);
@ -98,5 +99,3 @@ export class ModalModel implements Openable {
return this; return this;
} }
} }
let openModal: ModalModel | null = null;

2
frontend/src/app/shared/components/assets/image-cropper.component.scss

@ -12,7 +12,7 @@
} }
:host ::ng-deep { :host ::ng-deep {
@import '~cropperjs/dist/cropper'; @import 'cropperjs/dist/cropper';
img { img {
background-image: $asset-background; background-image: $asset-background;

2
frontend/src/app/shared/components/contents/content-list-field.component.html

@ -77,7 +77,7 @@
[statusColor]="content.scheduleJob.color"> [statusColor]="content.scheduleJob.color">
</sqx-content-status> </sqx-content-status>
{{ 'contents.scheduledAt' | sqxTranslate }}&nbsp;{{content.scheduleJob?.dueTime | sqxShortDate}} {{ 'contents.scheduledAt' | sqxTranslate }}&nbsp;{{content.scheduleJob.dueTime | sqxShortDate}}
</span> </span>
</ng-container> </ng-container>
<ng-container *ngSwitchCase="metaFields.statusColor"> <ng-container *ngSwitchCase="metaFields.statusColor">

4
frontend/src/app/shared/components/contents/content-list-field.component.ts

@ -6,7 +6,7 @@
*/ */
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges } from '@angular/core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { ContentDto, FieldValue, getContentValue, LanguageDto, META_FIELDS, SchemaDto, StatefulComponent, TableField, TableSettings } from '@app/shared/internal'; import { ContentDto, FieldValue, getContentValue, LanguageDto, META_FIELDS, SchemaDto, StatefulComponent, TableField, TableSettings } from '@app/shared/internal';
interface State { interface State {
@ -36,7 +36,7 @@ export class ContentListFieldComponent extends StatefulComponent<State> implemen
public patchAllowed?: boolean | null; public patchAllowed?: boolean | null;
@Input() @Input()
public patchForm?: FormGroup | null; public patchForm?: UntypedFormGroup | null;
@Input() @Input()
public schema?: SchemaDto; public schema?: SchemaDto;

8
frontend/src/app/shared/components/contents/content-status.component.html

@ -11,17 +11,17 @@
<div> <div>
<span class="label">{{ 'contents.scheduledTo' | sqxTranslate }}&nbsp;</span> <span class="label">{{ 'contents.scheduledTo' | sqxTranslate }}&nbsp;</span>
<span class="content-status default me-1" [style.color]="scheduled?.color" title="{{tooltipText}}"> <span class="content-status default me-1" [style.color]="scheduled.color" title="{{tooltipText}}">
<i class="icon-circle icon-sm"></i> <i class="icon-circle icon-sm"></i>
</span> </span>
<span>{{scheduled?.status}}</span> <span>{{scheduled.status}}</span>
</div> </div>
<div class="truncate"> <div class="truncate">
<span class="label">{{ 'contents.scheduledAt' | sqxTranslate }}&nbsp;</span> <span class="label">{{ 'contents.scheduledAt' | sqxTranslate }}&nbsp;</span>
<span>{{scheduled?.dueTime | sqxFullDateTime}}</span> <span>{{scheduled.dueTime | sqxFullDateTime}}</span>
</div> </div>
</div> </div>
</ng-container> </ng-container>
@ -29,7 +29,7 @@
<ng-template #simple> <ng-template #simple>
<span [class.truncate]="truncate"> <span [class.truncate]="truncate">
<ng-container *ngIf="scheduled; else noSchedule"> <ng-container *ngIf="scheduled; else noSchedule">
<span class="content-status pending" [style.color]="scheduled?.color" title="{{tooltipText}}"> <span class="content-status pending" [style.color]="scheduled.color" title="{{tooltipText}}">
<i class="icon-clock" [class.icon-sm]="small"></i> <i class="icon-clock" [class.icon-sm]="small"></i>
</span> </span>
</ng-container> </ng-container>

4
frontend/src/app/shared/components/contents/content-value-editor.component.ts

@ -6,7 +6,7 @@
*/ */
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { FieldDto, MathHelper } from '@app/shared/internal'; import { FieldDto, MathHelper } from '@app/shared/internal';
@Component({ @Component({
@ -20,7 +20,7 @@ export class ContentValueEditorComponent {
public field!: FieldDto; public field!: FieldDto;
@Input() @Input()
public form!: FormGroup; public form!: UntypedFormGroup;
public readonly uniqueId = MathHelper.guid(); public readonly uniqueId = MathHelper.guid();
} }

6
frontend/src/app/shared/components/forms/geolocation-editor.component.ts

@ -6,7 +6,7 @@
*/ */
import { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, forwardRef, Input, ViewChild } from '@angular/core'; import { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, forwardRef, Input, ViewChild } from '@angular/core';
import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms'; import { NG_VALUE_ACCESSOR, UntypedFormControl } from '@angular/forms';
import { distinctUntilChanged, map } from 'rxjs/operators'; import { distinctUntilChanged, map } from 'rxjs/operators';
import { ExtendedFormGroup, LocalStoreService, ResourceLoaderService, Settings, StatefulControlComponent, Types, UIOptions, ValidatorsEx } from '@app/shared/internal'; import { ExtendedFormGroup, LocalStoreService, ResourceLoaderService, Settings, StatefulControlComponent, Types, UIOptions, ValidatorsEx } from '@app/shared/internal';
@ -56,10 +56,10 @@ export class GeolocationEditorComponent extends StatefulControlComponent<State,
public geolocationForm = public geolocationForm =
new ExtendedFormGroup({ new ExtendedFormGroup({
latitude: new FormControl('', latitude: new UntypedFormControl('',
ValidatorsEx.between(-90, 90), ValidatorsEx.between(-90, 90),
), ),
longitude: new FormControl('', longitude: new UntypedFormControl('',
ValidatorsEx.between(-180, 180), ValidatorsEx.between(-180, 180),
), ),
}); });

24
frontend/src/app/shared/state/apps.forms.ts

@ -7,14 +7,14 @@
/* eslint-disable no-useless-escape */ /* eslint-disable no-useless-escape */
import { FormControl, Validators } from '@angular/forms'; import { UntypedFormControl, Validators } from '@angular/forms';
import { ExtendedFormGroup, Form, TemplatedFormArray, ValidatorsEx } from '@app/framework'; import { ExtendedFormGroup, Form, TemplatedFormArray, ValidatorsEx } from '@app/framework';
import { AppDto, AppSettingsDto, CreateAppDto, TransferToTeamDto, UpdateAppDto, UpdateAppSettingsDto } from './../services/apps.service'; import { AppDto, AppSettingsDto, CreateAppDto, TransferToTeamDto, UpdateAppDto, UpdateAppSettingsDto } from './../services/apps.service';
export class CreateAppForm extends Form<ExtendedFormGroup, CreateAppDto> { export class CreateAppForm extends Form<ExtendedFormGroup, CreateAppDto> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
name: new FormControl('', [ name: new UntypedFormControl('', [
Validators.required, Validators.required,
Validators.maxLength(40), Validators.maxLength(40),
ValidatorsEx.pattern('[a-z0-9]+(\-[a-z0-9]+)*', 'i18n:apps.appNameValidationMessage'), ValidatorsEx.pattern('[a-z0-9]+(\-[a-z0-9]+)*', 'i18n:apps.appNameValidationMessage'),
@ -26,7 +26,7 @@ export class CreateAppForm extends Form<ExtendedFormGroup, CreateAppDto> {
export class TransferAppForm extends Form<ExtendedFormGroup, TransferToTeamDto, AppDto> { export class TransferAppForm extends Form<ExtendedFormGroup, TransferToTeamDto, AppDto> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
teamId: new FormControl('', teamId: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
})); }));
@ -36,10 +36,10 @@ export class TransferAppForm extends Form<ExtendedFormGroup, TransferToTeamDto,
export class UpdateAppForm extends Form<ExtendedFormGroup, UpdateAppDto, AppDto> { export class UpdateAppForm extends Form<ExtendedFormGroup, UpdateAppDto, AppDto> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
label: new FormControl('', label: new UntypedFormControl('',
Validators.maxLength(40), Validators.maxLength(40),
), ),
description: new FormControl('', description: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
})); }));
@ -68,10 +68,10 @@ export class EditAppSettingsForm extends Form<ExtendedFormGroup, UpdateAppSettin
patterns: new TemplatedFormArray( patterns: new TemplatedFormArray(
PatternTemplate.INSTANCE, PatternTemplate.INSTANCE,
), ),
hideScheduler: new FormControl(false, hideScheduler: new UntypedFormControl(false,
Validators.nullValidator, Validators.nullValidator,
), ),
hideDateTimeButtons: new FormControl(false, hideDateTimeButtons: new UntypedFormControl(false,
Validators.nullValidator, Validators.nullValidator,
), ),
editors: new TemplatedFormArray( editors: new TemplatedFormArray(
@ -86,13 +86,13 @@ class PatternTemplate {
public createControl() { public createControl() {
return new ExtendedFormGroup({ return new ExtendedFormGroup({
name: new FormControl('', name: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
regex: new FormControl('', regex: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
message: new FormControl('', message: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
}); });
@ -104,10 +104,10 @@ class EditorTemplate {
public createControl() { public createControl() {
return new ExtendedFormGroup({ return new ExtendedFormGroup({
name: new FormControl('', name: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
url: new FormControl('', url: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
}); });

28
frontend/src/app/shared/state/assets.forms.ts

@ -5,7 +5,7 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { FormControl, Validators } from '@angular/forms'; import { UntypedFormControl, Validators } from '@angular/forms';
import slugify from 'slugify'; import slugify from 'slugify';
import { ExtendedFormGroup, Form, Mutable, TemplatedFormArray, Types } from '@app/framework'; import { ExtendedFormGroup, Form, Mutable, TemplatedFormArray, Types } from '@app/framework';
import { AnnotateAssetDto, AssetDto, AssetFolderDto, RenameAssetFolderDto, RenameAssetTagDto } from './../services/assets.service'; import { AnnotateAssetDto, AssetDto, AssetFolderDto, RenameAssetFolderDto, RenameAssetTagDto } from './../services/assets.service';
@ -21,16 +21,16 @@ export class AnnotateAssetForm extends Form<ExtendedFormGroup, AnnotateAssetDto,
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
isProtected: new FormControl(false, isProtected: new UntypedFormControl(false,
Validators.nullValidator, Validators.nullValidator,
), ),
fileName: new FormControl('', fileName: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
slug: new FormControl('', slug: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
tags: new FormControl([], tags: new UntypedFormControl([],
Validators.nullValidator, Validators.nullValidator,
), ),
metadata: new TemplatedFormArray( metadata: new TemplatedFormArray(
@ -162,10 +162,10 @@ class MetadataTemplate {
public createControl() { public createControl() {
return new ExtendedFormGroup({ return new ExtendedFormGroup({
name: new FormControl('', name: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
value: new FormControl('', value: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
}); });
@ -175,19 +175,19 @@ class MetadataTemplate {
export class EditAssetScriptsForm extends Form<ExtendedFormGroup, {}, object> { export class EditAssetScriptsForm extends Form<ExtendedFormGroup, {}, object> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
annotate: new FormControl('', annotate: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
create: new FormControl('', create: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
delete: new FormControl('', delete: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
move: new FormControl('', move: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
update: new FormControl('', update: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
})); }));
@ -197,7 +197,7 @@ export class EditAssetScriptsForm extends Form<ExtendedFormGroup, {}, object> {
export class RenameAssetFolderForm extends Form<ExtendedFormGroup, RenameAssetFolderDto, AssetFolderDto> { export class RenameAssetFolderForm extends Form<ExtendedFormGroup, RenameAssetFolderDto, AssetFolderDto> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
folderName: new FormControl('', folderName: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
})); }));
@ -207,7 +207,7 @@ export class RenameAssetFolderForm extends Form<ExtendedFormGroup, RenameAssetFo
export class RenameAssetTagForm extends Form<ExtendedFormGroup, RenameAssetTagDto, RenameAssetTagDto> { export class RenameAssetTagForm extends Form<ExtendedFormGroup, RenameAssetTagDto, RenameAssetTagDto> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
tagName: new FormControl('', tagName: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
})); }));

6
frontend/src/app/shared/state/backups.forms.ts

@ -7,7 +7,7 @@
/* eslint-disable no-useless-escape */ /* eslint-disable no-useless-escape */
import { FormControl, Validators } from '@angular/forms'; import { UntypedFormControl, Validators } from '@angular/forms';
import { ExtendedFormGroup, Form, hasNoValue$, ValidatorsEx } from '@app/framework'; import { ExtendedFormGroup, Form, hasNoValue$, ValidatorsEx } from '@app/framework';
import { StartRestoreDto } from './../services/backups.service'; import { StartRestoreDto } from './../services/backups.service';
@ -21,11 +21,11 @@ export class RestoreForm extends Form<ExtendedFormGroup, StartRestoreDto> {
constructor() { constructor() {
super( super(
new ExtendedFormGroup({ new ExtendedFormGroup({
name: new FormControl('', [ name: new UntypedFormControl('', [
Validators.maxLength(40), Validators.maxLength(40),
ValidatorsEx.pattern('[a-z0-9]+(\-[a-z0-9]+)*', 'i18n:apps.appNameValidationMessage'), ValidatorsEx.pattern('[a-z0-9]+(\-[a-z0-9]+)*', 'i18n:apps.appNameValidationMessage'),
]), ]),
url: new FormControl('', url: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
}), }),

6
frontend/src/app/shared/state/clients.forms.ts

@ -7,14 +7,14 @@
/* eslint-disable no-useless-escape */ /* eslint-disable no-useless-escape */
import { FormControl, Validators } from '@angular/forms'; import { UntypedFormControl, Validators } from '@angular/forms';
import { ExtendedFormGroup, Form, hasNoValue$, ValidatorsEx } from '@app/framework'; import { ExtendedFormGroup, Form, hasNoValue$, ValidatorsEx } from '@app/framework';
import { ClientDto, CreateClientDto, UpdateClientDto } from './../services/clients.service'; import { ClientDto, CreateClientDto, UpdateClientDto } from './../services/clients.service';
export class RenameClientForm extends Form<ExtendedFormGroup, UpdateClientDto, ClientDto> { export class RenameClientForm extends Form<ExtendedFormGroup, UpdateClientDto, ClientDto> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
name: new FormControl('', name: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
})); }));
@ -30,7 +30,7 @@ export class AddClientForm extends Form<ExtendedFormGroup, CreateClientDto> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
id: new FormControl('', [ id: new UntypedFormControl('', [
Validators.maxLength(40), Validators.maxLength(40),
ValidatorsEx.pattern('[a-z0-9]+(\-[a-z0-9]+)*', 'i18n:clients.clientIdValidationMessage'), ValidatorsEx.pattern('[a-z0-9]+(\-[a-z0-9]+)*', 'i18n:clients.clientIdValidationMessage'),
]), ]),

4
frontend/src/app/shared/state/comments.form.ts

@ -5,14 +5,14 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { FormControl, Validators } from '@angular/forms'; import { UntypedFormControl, Validators } from '@angular/forms';
import { ExtendedFormGroup, Form } from '@app/framework'; import { ExtendedFormGroup, Form } from '@app/framework';
import { UpsertCommentDto } from './../services/comments.service'; import { UpsertCommentDto } from './../services/comments.service';
export class UpsertCommentForm extends Form<ExtendedFormGroup, UpsertCommentDto> { export class UpsertCommentForm extends Form<ExtendedFormGroup, UpsertCommentDto> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
text: new FormControl('', text: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
})); }));

4
frontend/src/app/shared/state/contents.forms.spec.ts

@ -7,7 +7,7 @@
/* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable @typescript-eslint/naming-convention */
import { AbstractControl, FormArray } from '@angular/forms'; import { AbstractControl, UntypedFormArray } from '@angular/forms';
import { MathHelper } from '@app/framework'; import { MathHelper } from '@app/framework';
import { AppLanguageDto, createProperties, EditContentForm, getContentValue, HtmlValue, LanguageDto, RootFieldDto } from '@app/shared/internal'; import { AppLanguageDto, createProperties, EditContentForm, getContentValue, HtmlValue, LanguageDto, RootFieldDto } from '@app/shared/internal';
import { FieldRule, SchemaDto } from './../services/schemas.service'; import { FieldRule, SchemaDto } from './../services/schemas.service';
@ -959,7 +959,7 @@ describe('ContentForm', () => {
createField({ id: 4, properties: createProperties('Array'), partitioning: 'invariant' }), createField({ id: 4, properties: createProperties('Array'), partitioning: 'invariant' }),
]); ]);
const nestedForm = contentForm.form.get('field4.iv') as FormArray; const nestedForm = contentForm.form.get('field4.iv') as UntypedFormArray;
expect(nestedForm.controls.length).toBe(0); expect(nestedForm.controls.length).toBe(0);
}); });

22
frontend/src/app/shared/state/contents.forms.ts

@ -5,7 +5,7 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { FormControl, FormGroup, Validators } from '@angular/forms'; import { UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { BehaviorSubject, Observable } from 'rxjs'; import { BehaviorSubject, Observable } from 'rxjs';
import { distinctUntilChanged, map } from 'rxjs/operators'; import { distinctUntilChanged, map } from 'rxjs/operators';
import { debounceTimeSafe, ExtendedFormGroup, Form, FormArrayTemplate, TemplatedFormArray, Types, value$ } from '@app/framework'; import { debounceTimeSafe, ExtendedFormGroup, Form, FormArrayTemplate, TemplatedFormArray, Types, value$ } from '@app/framework';
@ -23,10 +23,10 @@ type SaveQueryFormType = { name: string; user: boolean };
export class SaveQueryForm extends Form<ExtendedFormGroup, SaveQueryFormType> { export class SaveQueryForm extends Form<ExtendedFormGroup, SaveQueryFormType> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
name: new FormControl('', name: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
user: new FormControl(false, user: new UntypedFormControl(false,
Validators.nullValidator, Validators.nullValidator,
), ),
})); }));
@ -47,7 +47,7 @@ export class PatchContentForm extends Form<ExtendedFormGroup, any> {
for (const field of this.editableFields) { for (const field of this.editableFields) {
const validators = FieldsValidators.create(field, this.language.isOptional); const validators = FieldsValidators.create(field, this.language.isOptional);
this.form.setControl(field.name, new FormControl(undefined, { validators })); this.form.setControl(field.name, new UntypedFormControl(undefined, { validators }));
} }
} }
@ -202,7 +202,7 @@ export class EditContentForm extends Form<ExtendedFormGroup, any> {
} }
} }
export class FieldForm extends AbstractContentForm<RootFieldDto, FormGroup> { export class FieldForm extends AbstractContentForm<RootFieldDto, UntypedFormGroup> {
private readonly partitions: { [partition: string]: FieldItemForm } = {}; private readonly partitions: { [partition: string]: FieldItemForm } = {};
private isRequired: boolean; private isRequired: boolean;
@ -279,7 +279,7 @@ export class FieldForm extends AbstractContentForm<RootFieldDto, FormGroup> {
} }
} }
export class FieldValueForm extends AbstractContentForm<FieldDto, FormControl> { export class FieldValueForm extends AbstractContentForm<FieldDto, UntypedFormControl> {
private isRequired = false; private isRequired = false;
constructor(globals: FormGlobals, field: FieldDto, fieldPath: string, isOptional: boolean, rules: RulesProvider, partition: string) { constructor(globals: FormGlobals, field: FieldDto, fieldPath: string, isOptional: boolean, rules: RulesProvider, partition: string) {
@ -318,7 +318,7 @@ export class FieldValueForm extends AbstractContentForm<FieldDto, FormControl> {
validators.push(globals.remoteValidator); validators.push(globals.remoteValidator);
} }
return new FormControl(value, { validators }); return new UntypedFormControl(value, { validators });
} }
} }
@ -514,7 +514,7 @@ abstract class ObjectTemplate<T extends ObjectFormBase = ObjectFormBase> impleme
protected abstract getSchema(value: any, model: T): ReadonlyArray<FieldDto> | undefined; protected abstract getSchema(value: any, model: T): ReadonlyArray<FieldDto> | undefined;
public setControls(form: FormGroup, value: any) { public setControls(form: UntypedFormGroup, value: any) {
const schema = this.getSchema(value, this.model); const schema = this.getSchema(value, this.model);
if (this.currentSchema !== schema) { if (this.currentSchema !== schema) {
@ -536,7 +536,7 @@ abstract class ObjectTemplate<T extends ObjectFormBase = ObjectFormBase> impleme
} }
} }
protected setControlsCore(schema: ReadonlyArray<FieldDto>, _: any, model: T, form: FormGroup) { protected setControlsCore(schema: ReadonlyArray<FieldDto>, _: any, model: T, form: UntypedFormGroup) {
const fieldByName: FieldMap = {}; const fieldByName: FieldMap = {};
const fieldSections: FieldSection<FieldDto, FieldItemForm>[] = []; const fieldSections: FieldSection<FieldDto, FieldItemForm>[] = [];
@ -629,8 +629,8 @@ class ComponentTemplate extends ObjectTemplate<ComponentForm> {
return model.globals.schemas[value?.schemaId]?.fields; return model.globals.schemas[value?.schemaId]?.fields;
} }
protected setControlsCore(schema: ReadonlyArray<FieldDto>, value: any, model: ComponentForm, form: FormGroup) { protected setControlsCore(schema: ReadonlyArray<FieldDto>, value: any, model: ComponentForm, form: UntypedFormGroup) {
form.setControl('schemaId', new FormControl()); form.setControl('schemaId', new UntypedFormControl());
this.model.internalSchema = model.globals.schemas[value?.schemaId]; this.model.internalSchema = model.globals.schemas[value?.schemaId];

8
frontend/src/app/shared/state/contributors.forms.ts

@ -5,7 +5,7 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { FormControl, Validators } from '@angular/forms'; import { UntypedFormControl, Validators } from '@angular/forms';
import { debounceTime, map, shareReplay } from 'rxjs/operators'; import { debounceTime, map, shareReplay } from 'rxjs/operators';
import { ExtendedFormGroup, Form, hasNoValue$, Types, value$ } from '@app/framework'; import { ExtendedFormGroup, Form, hasNoValue$, Types, value$ } from '@app/framework';
import { AssignContributorDto } from './../services/contributors.service'; import { AssignContributorDto } from './../services/contributors.service';
@ -20,10 +20,10 @@ export class AssignContributorForm extends Form<ExtendedFormGroup, AssignContrib
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
user: new FormControl('', user: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
role: new FormControl('', role: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
})); }));
@ -53,7 +53,7 @@ export class ImportContributorsForm extends Form<ExtendedFormGroup, ImportContri
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
import: new FormControl('', import: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
})); }));

8
frontend/src/app/shared/state/languages.forms.ts

@ -5,7 +5,7 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { FormControl, Validators } from '@angular/forms'; import { UntypedFormControl, Validators } from '@angular/forms';
import { ExtendedFormGroup, Form, value$ } from '@app/framework'; import { ExtendedFormGroup, Form, value$ } from '@app/framework';
import { AppLanguageDto, UpdateAppLanguageDto } from './../services/app-languages.service'; import { AppLanguageDto, UpdateAppLanguageDto } from './../services/app-languages.service';
@ -20,10 +20,10 @@ export class EditLanguageForm extends Form<ExtendedFormGroup, UpdateAppLanguageD
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
isMaster: new FormControl(false, isMaster: new UntypedFormControl(false,
Validators.nullValidator, Validators.nullValidator,
), ),
isOptional: new FormControl(false, isOptional: new UntypedFormControl(false,
Validators.nullValidator, Validators.nullValidator,
), ),
})); }));
@ -49,7 +49,7 @@ type AddLanguageFormType = { language: string };
export class AddLanguageForm extends Form<ExtendedFormGroup, AddLanguageFormType> { export class AddLanguageForm extends Form<ExtendedFormGroup, AddLanguageFormType> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
language: new FormControl(null, language: new UntypedFormControl(null,
Validators.required, Validators.required,
), ),
})); }));

10
frontend/src/app/shared/state/roles.forms.ts

@ -5,13 +5,13 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { FormControl, Validators } from '@angular/forms'; import { UntypedFormControl, Validators } from '@angular/forms';
import { ExtendedFormGroup, Form, hasNoValue$, hasValue$, TemplatedFormArray } from '@app/framework'; import { ExtendedFormGroup, Form, hasNoValue$, hasValue$, TemplatedFormArray } from '@app/framework';
import { CreateRoleDto, RoleDto, UpdateRoleDto } from './../services/roles.service'; import { CreateRoleDto, RoleDto, UpdateRoleDto } from './../services/roles.service';
export class EditRoleForm extends Form<TemplatedFormArray, UpdateRoleDto, RoleDto> { export class EditRoleForm extends Form<TemplatedFormArray, UpdateRoleDto, RoleDto> {
public get controls() { public get controls() {
return this.form.controls as FormControl[]; return this.form.controls as UntypedFormControl[];
} }
constructor() { constructor() {
@ -31,7 +31,7 @@ class PermissionTemplate {
public static readonly INSTANCE = new PermissionTemplate(); public static readonly INSTANCE = new PermissionTemplate();
public createControl(_: any, initialValue: string) { public createControl(_: any, initialValue: string) {
return new FormControl(initialValue, Validators.required); return new UntypedFormControl(initialValue, Validators.required);
} }
} }
@ -46,7 +46,7 @@ export class AddPermissionForm extends Form<ExtendedFormGroup, AddPermissionForm
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
permission: new FormControl('', permission: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
})); }));
@ -62,7 +62,7 @@ export class AddRoleForm extends Form<ExtendedFormGroup, CreateRoleDto> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
name: new FormControl('', name: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
})); }));

18
frontend/src/app/shared/state/rules.forms.ts

@ -5,11 +5,11 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { AbstractControl, FormControl, FormGroup, Validators } from '@angular/forms'; import { AbstractControl, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { ExtendedFormGroup, Form, ValidatorsEx } from '@app/framework'; import { ExtendedFormGroup, Form, ValidatorsEx } from '@app/framework';
import { RuleElementDto } from '../services/rules.service'; import { RuleElementDto } from '../services/rules.service';
export class ActionForm extends Form<any, FormGroup> { export class ActionForm extends Form<any, UntypedFormGroup> {
constructor(public readonly definition: RuleElementDto, constructor(public readonly definition: RuleElementDto,
public readonly actionType: string, public readonly actionType: string,
) { ) {
@ -31,7 +31,7 @@ export class ActionForm extends Form<any, FormGroup> {
defaultValue = property.options[0]; defaultValue = property.options[0];
} }
controls[property.name] = new FormControl(defaultValue, validator); controls[property.name] = new UntypedFormControl(defaultValue, validator);
} }
return new ExtendedFormGroup(controls); return new ExtendedFormGroup(controls);
@ -44,7 +44,7 @@ export class ActionForm extends Form<any, FormGroup> {
} }
} }
export class TriggerForm extends Form<any, FormGroup> { export class TriggerForm extends Form<any, UntypedFormGroup> {
constructor( constructor(
public readonly triggerType: string, public readonly triggerType: string,
) { ) {
@ -55,27 +55,27 @@ export class TriggerForm extends Form<any, FormGroup> {
switch (triggerType) { switch (triggerType) {
case 'ContentChanged': { case 'ContentChanged': {
return new ExtendedFormGroup({ return new ExtendedFormGroup({
handleAll: new FormControl(false, handleAll: new UntypedFormControl(false,
Validators.nullValidator, Validators.nullValidator,
), ),
schemas: new FormControl(undefined, schemas: new UntypedFormControl(undefined,
Validators.nullValidator, Validators.nullValidator,
), ),
}); });
} }
case 'Usage': { case 'Usage': {
return new ExtendedFormGroup({ return new ExtendedFormGroup({
limit: new FormControl(20000, limit: new UntypedFormControl(20000,
Validators.required, Validators.required,
), ),
numDays: new FormControl(3, numDays: new UntypedFormControl(3,
ValidatorsEx.between(1, 30), ValidatorsEx.between(1, 30),
), ),
}); });
} }
default: { default: {
return new ExtendedFormGroup({ return new ExtendedFormGroup({
condition: new FormControl('', condition: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
}); });

230
frontend/src/app/shared/state/schemas.forms.ts

@ -7,7 +7,7 @@
/* eslint-disable no-useless-escape */ /* eslint-disable no-useless-escape */
import { AbstractControl, FormControl, Validators } from '@angular/forms'; import { AbstractControl, UntypedFormControl, Validators } from '@angular/forms';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { ExtendedFormGroup, Form, TemplatedFormArray, ValidatorsEx, value$ } from '@app/framework'; import { ExtendedFormGroup, Form, TemplatedFormArray, ValidatorsEx, value$ } from '@app/framework';
import { AddFieldDto, CreateSchemaDto, FieldRule, SchemaDto, SchemaPropertiesDto, SynchronizeSchemaDto, UpdateSchemaDto } from './../services/schemas.service'; import { AddFieldDto, CreateSchemaDto, FieldRule, SchemaDto, SchemaPropertiesDto, SynchronizeSchemaDto, UpdateSchemaDto } from './../services/schemas.service';
@ -18,7 +18,7 @@ type CreateCategoryFormType = { name: string };
export class CreateCategoryForm extends Form<ExtendedFormGroup, CreateCategoryFormType> { export class CreateCategoryForm extends Form<ExtendedFormGroup, CreateCategoryFormType> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
name: new FormControl('', name: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
})); }));
@ -28,18 +28,18 @@ export class CreateCategoryForm extends Form<ExtendedFormGroup, CreateCategoryFo
export class CreateSchemaForm extends Form<ExtendedFormGroup, CreateSchemaDto> { export class CreateSchemaForm extends Form<ExtendedFormGroup, CreateSchemaDto> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
name: new FormControl('', [ name: new UntypedFormControl('', [
Validators.required, Validators.required,
Validators.maxLength(40), Validators.maxLength(40),
ValidatorsEx.pattern('[a-z0-9]+(\-[a-z0-9]+)*', 'i18n:schemas.schemaNameValidationMessage'), ValidatorsEx.pattern('[a-z0-9]+(\-[a-z0-9]+)*', 'i18n:schemas.schemaNameValidationMessage'),
]), ]),
type: new FormControl('Default', type: new UntypedFormControl('Default',
Validators.required, Validators.required,
), ),
initialCategory: new FormControl(undefined, initialCategory: new UntypedFormControl(undefined,
Validators.nullValidator, Validators.nullValidator,
), ),
importing: new FormControl({}, importing: new UntypedFormControl({},
Validators.nullValidator, Validators.nullValidator,
), ),
})); }));
@ -61,13 +61,13 @@ export class CreateSchemaForm extends Form<ExtendedFormGroup, CreateSchemaDto> {
export class SynchronizeSchemaForm extends Form<ExtendedFormGroup, SynchronizeSchemaDto> { export class SynchronizeSchemaForm extends Form<ExtendedFormGroup, SynchronizeSchemaDto> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
json: new FormControl({}, json: new UntypedFormControl({},
Validators.nullValidator, Validators.nullValidator,
), ),
fieldsDelete: new FormControl(false, fieldsDelete: new UntypedFormControl(false,
Validators.nullValidator, Validators.nullValidator,
), ),
fieldsRecreate: new FormControl(false, fieldsRecreate: new UntypedFormControl(false,
Validators.nullValidator, Validators.nullValidator,
), ),
})); }));
@ -113,13 +113,13 @@ class FieldRuleTemplate {
public createControl(_: any, fieldNames?: ReadonlyArray<string>) { public createControl(_: any, fieldNames?: ReadonlyArray<string>) {
return new ExtendedFormGroup({ return new ExtendedFormGroup({
action: new FormControl('Disable', action: new UntypedFormControl('Disable',
Validators.required, Validators.required,
), ),
field: new FormControl(fieldNames?.[0], field: new UntypedFormControl(fieldNames?.[0],
Validators.required, Validators.required,
), ),
condition: new FormControl('', condition: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
}); });
@ -165,10 +165,10 @@ class PreviewUrlTemplate {
public createControl() { public createControl() {
return new ExtendedFormGroup({ return new ExtendedFormGroup({
name: new FormControl('', name: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
url: new FormControl('', url: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
}); });
@ -178,22 +178,22 @@ class PreviewUrlTemplate {
export class EditSchemaScriptsForm extends Form<ExtendedFormGroup, {}, object> { export class EditSchemaScriptsForm extends Form<ExtendedFormGroup, {}, object> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
query: new FormControl('', query: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
queryPre: new FormControl('', queryPre: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
create: new FormControl('', create: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
change: new FormControl('', change: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
delete: new FormControl('', delete: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
update: new FormControl('', update: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
})); }));
@ -207,31 +207,31 @@ export class EditFieldForm extends Form<ExtendedFormGroup, {}, FieldPropertiesDt
private static buildForm(properties: FieldPropertiesDto) { private static buildForm(properties: FieldPropertiesDto) {
const config = { const config = {
label: new FormControl('', label: new UntypedFormControl('',
Validators.maxLength(100), Validators.maxLength(100),
), ),
hints: new FormControl('', hints: new UntypedFormControl('',
Validators.maxLength(1000), Validators.maxLength(1000),
), ),
placeholder: new FormControl('', placeholder: new UntypedFormControl('',
Validators.maxLength(1000), Validators.maxLength(1000),
), ),
editor: new FormControl(undefined, editor: new UntypedFormControl(undefined,
Validators.nullValidator, Validators.nullValidator,
), ),
editorUrl: new FormControl(undefined, editorUrl: new UntypedFormControl(undefined,
Validators.nullValidator, Validators.nullValidator,
), ),
isRequired: new FormControl(false, isRequired: new UntypedFormControl(false,
Validators.nullValidator, Validators.nullValidator,
), ),
isRequiredOnPublish: new FormControl(false, isRequiredOnPublish: new UntypedFormControl(false,
Validators.nullValidator, Validators.nullValidator,
), ),
isHalfWidth: new FormControl(false, isHalfWidth: new UntypedFormControl(false,
Validators.nullValidator, Validators.nullValidator,
), ),
tags: new FormControl([], tags: new UntypedFormControl([],
Validators.nullValidator, Validators.nullValidator,
), ),
}; };
@ -249,112 +249,112 @@ export class EditFieldFormVisitor implements FieldPropertiesVisitor<any> {
} }
public visitArray() { public visitArray() {
this.config['maxItems'] = new FormControl(undefined); this.config['maxItems'] = new UntypedFormControl(undefined);
this.config['minItems'] = new FormControl(undefined); this.config['minItems'] = new UntypedFormControl(undefined);
this.config['uniqueFields'] = new FormControl(undefined); this.config['uniqueFields'] = new UntypedFormControl(undefined);
} }
public visitAssets() { public visitAssets() {
this.config['allowDuplicates'] = new FormControl(undefined); this.config['allowDuplicates'] = new UntypedFormControl(undefined);
this.config['allowedExtensions'] = new FormControl(undefined); this.config['allowedExtensions'] = new UntypedFormControl(undefined);
this.config['aspectHeight'] = new FormControl(undefined); this.config['aspectHeight'] = new UntypedFormControl(undefined);
this.config['aspectHeight'] = new FormControl(undefined); this.config['aspectHeight'] = new UntypedFormControl(undefined);
this.config['aspectWidth'] = new FormControl(undefined); this.config['aspectWidth'] = new UntypedFormControl(undefined);
this.config['defaultValue'] = new FormControl(undefined); this.config['defaultValue'] = new UntypedFormControl(undefined);
this.config['defaultValues'] = new FormControl(undefined); this.config['defaultValues'] = new UntypedFormControl(undefined);
this.config['expectedType'] = new FormControl(undefined); this.config['expectedType'] = new UntypedFormControl(undefined);
this.config['folderId'] = new FormControl(undefined); this.config['folderId'] = new UntypedFormControl(undefined);
this.config['maxHeight'] = new FormControl(undefined); this.config['maxHeight'] = new UntypedFormControl(undefined);
this.config['maxItems'] = new FormControl(undefined); this.config['maxItems'] = new UntypedFormControl(undefined);
this.config['maxSize'] = new FormControl(undefined); this.config['maxSize'] = new UntypedFormControl(undefined);
this.config['maxWidth'] = new FormControl(undefined); this.config['maxWidth'] = new UntypedFormControl(undefined);
this.config['minHeight'] = new FormControl(undefined); this.config['minHeight'] = new UntypedFormControl(undefined);
this.config['minItems'] = new FormControl(undefined); this.config['minItems'] = new UntypedFormControl(undefined);
this.config['minSize'] = new FormControl(undefined); this.config['minSize'] = new UntypedFormControl(undefined);
this.config['minWidth'] = new FormControl(undefined); this.config['minWidth'] = new UntypedFormControl(undefined);
this.config['previewMode'] = new FormControl(undefined); this.config['previewMode'] = new UntypedFormControl(undefined);
this.config['resolveFirst'] = new FormControl(undefined); this.config['resolveFirst'] = new UntypedFormControl(undefined);
} }
public visitBoolean() { public visitBoolean() {
this.config['inlineEditable'] = new FormControl(undefined); this.config['inlineEditable'] = new UntypedFormControl(undefined);
this.config['defaultValues'] = new FormControl(undefined); this.config['defaultValues'] = new UntypedFormControl(undefined);
this.config['defaultValue'] = new FormControl(undefined); this.config['defaultValue'] = new UntypedFormControl(undefined);
} }
public visitComponent() { public visitComponent() {
this.config['schemaIds'] = new FormControl(undefined); this.config['schemaIds'] = new UntypedFormControl(undefined);
} }
public visitComponents() { public visitComponents() {
this.config['schemaIds'] = new FormControl(undefined); this.config['schemaIds'] = new UntypedFormControl(undefined);
this.config['maxItems'] = new FormControl(undefined); this.config['maxItems'] = new UntypedFormControl(undefined);
this.config['minItems'] = new FormControl(undefined); this.config['minItems'] = new UntypedFormControl(undefined);
this.config['uniqueFields'] = new FormControl(undefined); this.config['uniqueFields'] = new UntypedFormControl(undefined);
} }
public visitDateTime() { public visitDateTime() {
this.config['calculatedDefaultValue'] = new FormControl(undefined); this.config['calculatedDefaultValue'] = new UntypedFormControl(undefined);
this.config['defaultValue'] = new FormControl(undefined); this.config['defaultValue'] = new UntypedFormControl(undefined);
this.config['defaultValues'] = new FormControl(undefined); this.config['defaultValues'] = new UntypedFormControl(undefined);
this.config['format'] = new FormControl(undefined); this.config['format'] = new UntypedFormControl(undefined);
this.config['maxValue'] = new FormControl(undefined, ValidatorsEx.validDateTime()); this.config['maxValue'] = new UntypedFormControl(undefined, ValidatorsEx.validDateTime());
this.config['minValue'] = new FormControl(undefined, ValidatorsEx.validDateTime()); this.config['minValue'] = new UntypedFormControl(undefined, ValidatorsEx.validDateTime());
} }
public visitJson() { public visitJson() {
this.config['graphQLSchema'] = new FormControl(undefined); this.config['graphQLSchema'] = new UntypedFormControl(undefined);
} }
public visitNumber() { public visitNumber() {
this.config['allowedValues'] = new FormControl(undefined); this.config['allowedValues'] = new UntypedFormControl(undefined);
this.config['defaultValue'] = new FormControl(undefined); this.config['defaultValue'] = new UntypedFormControl(undefined);
this.config['defaultValues'] = new FormControl(undefined); this.config['defaultValues'] = new UntypedFormControl(undefined);
this.config['inlineEditable'] = new FormControl(undefined); this.config['inlineEditable'] = new UntypedFormControl(undefined);
this.config['isUnique'] = new FormControl(undefined); this.config['isUnique'] = new UntypedFormControl(undefined);
this.config['maxValue'] = new FormControl(undefined); this.config['maxValue'] = new UntypedFormControl(undefined);
this.config['minValue'] = new FormControl(undefined); this.config['minValue'] = new UntypedFormControl(undefined);
} }
public visitReferences() { public visitReferences() {
this.config['allowDuplicates'] = new FormControl(undefined); this.config['allowDuplicates'] = new UntypedFormControl(undefined);
this.config['defaultValue'] = new FormControl(undefined); this.config['defaultValue'] = new UntypedFormControl(undefined);
this.config['defaultValues'] = new FormControl(undefined); this.config['defaultValues'] = new UntypedFormControl(undefined);
this.config['maxItems'] = new FormControl(undefined); this.config['maxItems'] = new UntypedFormControl(undefined);
this.config['minItems'] = new FormControl(undefined); this.config['minItems'] = new UntypedFormControl(undefined);
this.config['mustBePublished'] = new FormControl(false); this.config['mustBePublished'] = new UntypedFormControl(false);
this.config['resolveReference'] = new FormControl(false); this.config['resolveReference'] = new UntypedFormControl(false);
this.config['schemaIds'] = new FormControl(undefined); this.config['schemaIds'] = new UntypedFormControl(undefined);
} }
public visitString() { public visitString() {
this.config['allowedValues'] = new FormControl(undefined); this.config['allowedValues'] = new UntypedFormControl(undefined);
this.config['contentType'] = new FormControl(undefined); this.config['contentType'] = new UntypedFormControl(undefined);
this.config['createEnum'] = new FormControl(undefined); this.config['createEnum'] = new UntypedFormControl(undefined);
this.config['defaultValue'] = new FormControl(undefined); this.config['defaultValue'] = new UntypedFormControl(undefined);
this.config['defaultValues'] = new FormControl(undefined); this.config['defaultValues'] = new UntypedFormControl(undefined);
this.config['folderId'] = new FormControl(undefined); this.config['folderId'] = new UntypedFormControl(undefined);
this.config['inlineEditable'] = new FormControl(undefined); this.config['inlineEditable'] = new UntypedFormControl(undefined);
this.config['isEmbeddable'] = new FormControl(undefined); this.config['isEmbeddable'] = new UntypedFormControl(undefined);
this.config['isUnique'] = new FormControl(undefined); this.config['isUnique'] = new UntypedFormControl(undefined);
this.config['maxCharacters'] = new FormControl(undefined); this.config['maxCharacters'] = new UntypedFormControl(undefined);
this.config['maxLength'] = new FormControl(undefined); this.config['maxLength'] = new UntypedFormControl(undefined);
this.config['maxWords'] = new FormControl(undefined); this.config['maxWords'] = new UntypedFormControl(undefined);
this.config['minCharacters'] = new FormControl(undefined); this.config['minCharacters'] = new UntypedFormControl(undefined);
this.config['minLength'] = new FormControl(undefined); this.config['minLength'] = new UntypedFormControl(undefined);
this.config['minWords'] = new FormControl(undefined); this.config['minWords'] = new UntypedFormControl(undefined);
this.config['pattern'] = new FormControl(undefined); this.config['pattern'] = new UntypedFormControl(undefined);
this.config['patternMessage'] = new FormControl(undefined); this.config['patternMessage'] = new UntypedFormControl(undefined);
this.config['schemaIds'] = new FormControl(undefined); this.config['schemaIds'] = new UntypedFormControl(undefined);
} }
public visitTags() { public visitTags() {
this.config['allowedValues'] = new FormControl(undefined); this.config['allowedValues'] = new UntypedFormControl(undefined);
this.config['createEnum'] = new FormControl(undefined); this.config['createEnum'] = new UntypedFormControl(undefined);
this.config['defaultValue'] = new FormControl(undefined); this.config['defaultValue'] = new UntypedFormControl(undefined);
this.config['defaultValues'] = new FormControl(undefined); this.config['defaultValues'] = new UntypedFormControl(undefined);
this.config['maxItems'] = new FormControl(undefined); this.config['maxItems'] = new UntypedFormControl(undefined);
this.config['minItems'] = new FormControl(undefined); this.config['minItems'] = new UntypedFormControl(undefined);
} }
public visitGeolocation() { public visitGeolocation() {
@ -369,25 +369,25 @@ export class EditFieldFormVisitor implements FieldPropertiesVisitor<any> {
export class EditSchemaForm extends Form<ExtendedFormGroup, UpdateSchemaDto, SchemaPropertiesDto> { export class EditSchemaForm extends Form<ExtendedFormGroup, UpdateSchemaDto, SchemaPropertiesDto> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
label: new FormControl('', label: new UntypedFormControl('',
Validators.maxLength(100), Validators.maxLength(100),
), ),
hints: new FormControl('', hints: new UntypedFormControl('',
Validators.maxLength(1000), Validators.maxLength(1000),
), ),
contentsSidebarUrl: new FormControl('', contentsSidebarUrl: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
contentSidebarUrl: new FormControl('', contentSidebarUrl: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
contentEditorUrl: new FormControl('', contentEditorUrl: new UntypedFormControl('',
Validators.nullValidator, Validators.nullValidator,
), ),
validateOnPublish: new FormControl(false, validateOnPublish: new UntypedFormControl(false,
Validators.nullValidator, Validators.nullValidator,
), ),
tags: new FormControl([], tags: new UntypedFormControl([],
Validators.nullValidator, Validators.nullValidator,
), ),
})); }));
@ -399,15 +399,15 @@ export class AddFieldForm extends Form<ExtendedFormGroup, AddFieldDto> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
type: new FormControl('String', type: new UntypedFormControl('String',
Validators.required, Validators.required,
), ),
name: new FormControl('', [ name: new UntypedFormControl('', [
Validators.required, Validators.required,
Validators.maxLength(40), Validators.maxLength(40),
ValidatorsEx.pattern('[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*', 'i18n:schemas.field.nameValidationMessage'), ValidatorsEx.pattern('[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*', 'i18n:schemas.field.nameValidationMessage'),
]), ]),
isLocalizable: new FormControl(false, isLocalizable: new UntypedFormControl(false,
Validators.nullValidator, Validators.nullValidator,
), ),
})); }));

6
frontend/src/app/shared/state/teams.forms.ts

@ -7,14 +7,14 @@
/* eslint-disable no-useless-escape */ /* eslint-disable no-useless-escape */
import { FormControl, Validators } from '@angular/forms'; import { UntypedFormControl, Validators } from '@angular/forms';
import { ExtendedFormGroup, Form } from '@app/framework'; import { ExtendedFormGroup, Form } from '@app/framework';
import { CreateTeamDto, TeamDto, UpdateTeamDto } from './../services/teams.service'; import { CreateTeamDto, TeamDto, UpdateTeamDto } from './../services/teams.service';
export class CreateTeamForm extends Form<ExtendedFormGroup, CreateTeamDto> { export class CreateTeamForm extends Form<ExtendedFormGroup, CreateTeamDto> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
name: new FormControl('', [ name: new UntypedFormControl('', [
Validators.required, Validators.required,
Validators.maxLength(40), Validators.maxLength(40),
]), ]),
@ -25,7 +25,7 @@ export class CreateTeamForm extends Form<ExtendedFormGroup, CreateTeamDto> {
export class UpdateTeamForm extends Form<ExtendedFormGroup, UpdateTeamDto, TeamDto> { export class UpdateTeamForm extends Form<ExtendedFormGroup, UpdateTeamDto, TeamDto> {
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
name: new FormControl('', [ name: new UntypedFormControl('', [
Validators.required, Validators.required,
Validators.maxLength(40), Validators.maxLength(40),
]), ]),

4
frontend/src/app/shared/state/workflows.forms.ts

@ -5,7 +5,7 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { FormControl, Validators } from '@angular/forms'; import { UntypedFormControl, Validators } from '@angular/forms';
import { ExtendedFormGroup, Form, hasNoValue$ } from '@app/framework'; import { ExtendedFormGroup, Form, hasNoValue$ } from '@app/framework';
import { CreateWorkflowDto } from './../services/workflows.service'; import { CreateWorkflowDto } from './../services/workflows.service';
@ -18,7 +18,7 @@ export class AddWorkflowForm extends Form<ExtendedFormGroup, CreateWorkflowDto>
constructor() { constructor() {
super(new ExtendedFormGroup({ super(new ExtendedFormGroup({
name: new FormControl('', name: new UntypedFormControl('',
Validators.required, Validators.required,
), ),
})); }));

1
frontend/src/app/theme/_bootstrap-vars.scss

@ -106,6 +106,7 @@ $navbar-padding-y: .375rem;
// Close button // Close button
$btn-close-width: .5rem; $btn-close-width: .5rem;
$btn-box-shadow: none;
// Blockquote // Blockquote
$blockquote-margin-y: 0; $blockquote-margin-y: 0;

9
frontend/src/app/theme/theme.scss

@ -1,17 +1,20 @@
@import 'bootstrap-vars'; @import 'bootstrap-vars';
// Bootstrap // Bootstrap
@import '~bootstrap/scss/bootstrap'; @import 'bootstrap/scss/bootstrap';
// Pikaday // Pikaday
@import '~pikaday/css/pikaday.css'; @import 'pikaday/css/pikaday.css';
// Bootstrap Overrides // Bootstrap Overrides
@import 'bootstrap'; @import 'bootstrap';
// icomoon // Icomoon
@import 'icomoon/style'; @import 'icomoon/style';
// GraphiQL
@import 'graphiql/graphiql';
// Custom files // Custom files
@import 'common'; @import 'common';
@import 'panels2'; @import 'panels2';

3
frontend/tsconfig.json

@ -18,10 +18,11 @@
"noUnusedParameters": false, "noUnusedParameters": false,
"outDir": "./build", "outDir": "./build",
"sourceMap": true, "sourceMap": true,
"skipLibCheck": true,
"strict": true, "strict": true,
"strictNullChecks": true, "strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true, "suppressImplicitAnyIndexErrors": true,
"target": "es2017", "target": "es2020",
"lib": [ "lib": [
"es2020", "es2020",
"dom" "dom"

Loading…
Cancel
Save