Skip to content

Commit

Permalink
refactor: forms using multi language inputs should be typed (#1494)
Browse files Browse the repository at this point in the history
  • Loading branch information
derschnee68 committed Mar 1, 2024
1 parent 4558e34 commit 17333d0
Show file tree
Hide file tree
Showing 22 changed files with 218 additions and 299 deletions.
@@ -1,13 +1,13 @@
import { Location } from '@angular/common';
import { Component } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { Router } from '@angular/router';
import { ProjectApiService } from '@dasch-swiss/vre/shared/app-api';
import { RouteConstants } from '@dasch-swiss/vre/shared/app-config';
import { ProjectService } from '@dasch-swiss/vre/shared/app-helper-services';
import { LoadProjectsAction } from '@dasch-swiss/vre/shared/app-state';
import { Store } from '@ngxs/store';
import { finalize } from 'rxjs/operators';
import { ProjectForm } from '../reusable-project-form/project-form.type';

@Component({
selector: 'app-create-project-form-page',
Expand All @@ -21,7 +21,7 @@ import { finalize } from 'rxjs/operators';
description: [],
keywords: []
}"
(formValueChange)="form = $event"></app-reusable-project-form>
(afterFormInit)="form = $event"></app-reusable-project-form>
<div style="display: flex; justify-content: space-between">
<button color="primary" mat-button type="reset" (click)="goBack()">
Expand All @@ -44,7 +44,7 @@ import { finalize } from 'rxjs/operators';
`,
})
export class CreateProjectFormPageComponent {
form: FormGroup;
form: ProjectForm;
loading = false;

constructor(
Expand All @@ -58,11 +58,11 @@ export class CreateProjectFormPageComponent {
this.loading = true;
this._projectApiService
.create({
shortcode: this.form.get('shortcode').value,
shortname: this.form.get('shortname').value,
longname: this.form.get('longname').value,
description: this.form.get('description').value,
keywords: this.form.get('keywords').value,
shortcode: this.form.getRawValue().shortcode,
shortname: this.form.getRawValue().shortname,
longname: this.form.getRawValue().longname,
description: this.form.getRawValue().description,
keywords: this.form.getRawValue().keywords,
selfjoin: true,
status: true,
})
Expand Down
@@ -1,28 +1,23 @@
import { Component } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { UpdateProjectRequest } from '@dasch-swiss/dsp-js';
import { ProjectApiService } from '@dasch-swiss/vre/shared/app-api';
import { RouteConstants } from '@dasch-swiss/vre/shared/app-config';
import { ProjectService } from '@dasch-swiss/vre/shared/app-helper-services';
import { NotificationService } from '@dasch-swiss/vre/shared/app-notification';
import { LoadProjectsAction, UpdateProjectAction } from '@dasch-swiss/vre/shared/app-state';
import { Actions, Store, ofActionSuccessful } from '@ngxs/store';
import { MultiLanguages } from '@dasch-swiss/vre/shared/app-string-literal';
import { Actions, ofActionSuccessful, Store } from '@ngxs/store';
import { map, switchMap, take } from 'rxjs/operators';
import { ProjectForm } from '../reusable-project-form/project-form.type';

@Component({
selector: 'app-edit-project-form-page',
template: ` <dasch-swiss-centered-layout>
<app-reusable-project-form
*ngIf="project$ | async as project"
[formData]="{
shortcode: project.shortcode,
shortname: project.shortname,
longname: project.longname,
description: project.description,
keywords: project.keywords
}"
(formValueChange)="form = $event"></app-reusable-project-form>
*ngIf="formData$ | async as formData"
[formData]="formData"
(afterFormInit)="form = $event"></app-reusable-project-form>
<div style="display: flex; justify-content: space-between">
<button
Expand All @@ -40,13 +35,22 @@ import { map, switchMap, take } from 'rxjs/operators';
</dasch-swiss-centered-layout>`,
})
export class EditProjectFormPageComponent {
form: FormGroup;
form: ProjectForm;
loading = false;
project$ = this.route.parent.parent.paramMap.pipe(
formData$ = this.route.parent.parent.paramMap.pipe(
map(params => params.get(RouteConstants.uuidParameter)),
map(uuid => this._projectService.uuidToIri(uuid)),
switchMap(iri => this._projectApiService.get(iri)),
map(project => project.project)
map(project => project.project),
map(project => {
return {
shortcode: project.shortcode,
shortname: project.shortname,
longname: project.longname,
description: project.description as MultiLanguages,
keywords: project.keywords,
};
})
);

constructor(
Expand All @@ -64,7 +68,7 @@ export class EditProjectFormPageComponent {

const projectData: UpdateProjectRequest = {
longname: this.form.value.longname,
description: this.form.value.description,
description: this.form.getRawValue().description,
keywords: this.form.value.keywords,
};

Expand Down
@@ -1,7 +1,6 @@
import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { ListNode } from '@dasch-swiss/dsp-js';
import { MultiLanguageFormArray } from '@dasch-swiss/vre/shared/app-string-literal';
import { DEFAULT_MULTILANGUAGE_FORM, MultiLanguageFormArray } from '@dasch-swiss/vre/shared/app-string-literal';
import { ListItemService } from '../list-item/list-item.service';

@Component({
Expand All @@ -17,7 +16,7 @@ import { ListItemService } from '../list-item/list-item.service';
<dasch-swiss-multi-language-input
[placeholder]="node.labels | appStringifyStringLiteral: 'all' | appTruncate: 128"
[editable]="false"
[formArray]="labelsControl"
[formArray]="readOnlyFormArray"
[validators]="[]">
</dasch-swiss-multi-language-input>
Expand Down Expand Up @@ -51,17 +50,9 @@ export class ListItemElementComponent implements OnInit, OnChanges {
showChildren = false;
showActionBubble = false;

readOnlyForm: FormGroup;
readOnlyFormArray: MultiLanguageFormArray;

// TODO remove with typed forms
get labelsControl() {
return this.readOnlyForm.get('labels') as MultiLanguageFormArray;
}

constructor(
private _fb: FormBuilder,
public listItemService: ListItemService
) {}
constructor(public listItemService: ListItemService) {}

ngOnInit() {
this.buildForm();
Expand All @@ -72,16 +63,7 @@ export class ListItemElementComponent implements OnInit, OnChanges {
}

private buildForm() {
this.readOnlyForm = this._fb.group({
labels: this._fb.array(
this.node.labels.map(({ language, value }) =>
this._fb.group({
language,
value,
})
)
),
});
this.readOnlyFormArray = DEFAULT_MULTILANGUAGE_FORM(this.node.labels);
}

mouseEnter() {
Expand Down
@@ -1,16 +1,18 @@
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { StringLiteral } from '@dasch-swiss/dsp-js';
import { ListApiService } from '@dasch-swiss/vre/shared/app-api';
import { ProjectService } from '@dasch-swiss/vre/shared/app-helper-services';
import { MultiLanguages } from '@dasch-swiss/vre/shared/app-string-literal';
import { ListItemForm } from '../list-item-form.type';

export interface CreateListItemDialogProps {
nodeIri: string;
parentIri: string;
projectIri: string;
position: number;
}

@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'app-create-list-item-dialog',
Expand All @@ -20,7 +22,7 @@ export interface CreateListItemDialogProps {
<div mat-dialog-content>
<app-reusable-list-item-form
[formData]="initialFormValue"
(formValueChange)="form = $event"></app-reusable-list-item-form>
(afterFormInit)="form = $event"></app-reusable-list-item-form>
</div>
<div mat-dialog-actions align="end">
Expand All @@ -39,7 +41,7 @@ export interface CreateListItemDialogProps {
`,
})
export class CreateListItemDialogComponent {
form: FormGroup;
form: ListItemForm;
loading = false;
initialFormValue = { labels: [] as MultiLanguages, comments: [] as MultiLanguages };

Expand All @@ -56,8 +58,8 @@ export class CreateListItemDialogComponent {
const payload = {
parentNodeIri: this.data.parentIri,
projectIri: this.data.projectIri,
labels: this.form.value.labels,
comments: this.form.value.descriptions,
labels: this.form.value.labels as StringLiteral[],
comments: this.form.value.comments as StringLiteral[],
position: this.data.position,
name: `${ProjectService.IriToUuid(this.data.projectIri)}-${Math.random().toString(36).substring(2)}${Math.random()
.toString(36)
Expand Down
@@ -1,10 +1,11 @@
import { Component, Inject } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { StringLiteral } from '@dasch-swiss/dsp-js';
import { ListApiService } from '@dasch-swiss/vre/shared/app-api';
import { MultiLanguages } from '@dasch-swiss/vre/shared/app-string-literal';
import { of } from 'rxjs';
import { finalize, switchMap } from 'rxjs/operators';
import { ListItemForm } from '../list-item-form.type';

export interface EditListItemDialogProps {
nodeIri: string;
Expand All @@ -20,7 +21,7 @@ export interface EditListItemDialogProps {
<div mat-dialog-content>
<app-reusable-list-item-form
[formData]="data.formData"
(formValueChange)="form = $event"></app-reusable-list-item-form>
(afterFormInit)="form = $event"></app-reusable-list-item-form>
</div>
<div mat-dialog-actions align="end">
Expand All @@ -39,7 +40,7 @@ export interface EditListItemDialogProps {
`,
})
export class EditListItemDialogComponent {
form: FormGroup;
form: ListItemForm;
loading = false;

constructor(
Expand All @@ -52,20 +53,20 @@ export class EditListItemDialogComponent {
updateChildNode() {
this.loading = true;

const data = {
const payload = {
projectIri: this.data.projectIri,
listIri: this.data.nodeIri,
labels: this.form.value.labels,
comments: this.form.value.comments.length > 0 ? this.form.value.comments : null, // TODO: improve form to avoir this ?
labels: this.form.getRawValue().labels as StringLiteral[],
comments: this.form.getRawValue().comments.length > 0 ? (this.form.value.comments as StringLiteral[]) : null, // TODO: improve form to avoir this ?
};

this._listApiService
.updateChildNode(data.listIri, data)
.updateChildNode(payload.listIri, payload)
.pipe(
switchMap(() => {
// if initial comments Length is not equal to 0 and the comment is now empty, send request to delete comment
if (this.data.formData.comments.length > 0 && this.form.value.comments.length === 0) {
return this._listApiService.deleteChildComments(data.listIri);
return this._listApiService.deleteChildComments(payload.listIri);
}
return of(true);
}),
Expand Down
@@ -1,25 +1,20 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ListInfoResponse, ListNode, ListNodeInfoResponse } from '@dasch-swiss/dsp-js';
import { FormBuilder, Validators } from '@angular/forms';
import { ListInfoResponse, ListNodeInfoResponse } from '@dasch-swiss/dsp-js';
import { ListApiService } from '@dasch-swiss/vre/shared/app-api';
import { ProjectService } from '@dasch-swiss/vre/shared/app-helper-services';
import { MultiLanguageFormArray } from '@dasch-swiss/vre/shared/app-string-literal';
import { DEFAULT_MULTILANGUAGE_FORM } from '@dasch-swiss/vre/shared/app-string-literal';
import { atLeastOneStringRequired } from '../../../main/form-validators/at-least-one-string-required.validator';
import { ListItemService } from '../list-item/list-item.service';

export class ListNodeOperation {
operation: 'create' | 'insert' | 'update' | 'delete' | 'reposition';
listNode: ListNode;
}

@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'app-list-item-form',
template: `
<form [formGroup]="form" (ngSubmit)="createChildNode()" style="display: flex">
<form [formGroup]="form" style="display: flex" (ngSubmit)="createChildNode()">
<dasch-swiss-multi-language-input
style="flex: 1"
[formArray]="labelsControl"
[formArray]="form.controls.labels"
[placeholder]="placeholder"
[validators]="labelsValidators">
</dasch-swiss-multi-language-input>
Expand All @@ -39,25 +34,18 @@ export class ListNodeOperation {
export class ListItemFormComponent implements OnInit {
loading = false;
placeholder: string;
form: FormGroup;

// TODO remove with typed forms
get labelsControl() {
return this.form.get('labels') as MultiLanguageFormArray;
}
form = this._fb.group({ labels: DEFAULT_MULTILANGUAGE_FORM([], [], [atLeastOneStringRequired('value')]) });

readonly labelsValidators = [Validators.maxLength(2000)];

constructor(
private _listApiService: ListApiService,
private _fb: FormBuilder,
private _cd: ChangeDetectorRef,
private _listItemService: ListItemService
private _listItemService: ListItemService,
private _fb: FormBuilder
) {}

ngOnInit() {
this._buildForm();

this._listApiService.getNodeInfo(this._listItemService.projectInfos.rootNodeIri).subscribe(response => {
if (response['listinfo']) {
// root node
Expand All @@ -77,26 +65,16 @@ export class ListItemFormComponent implements OnInit {
const data = {
parentNodeIri: this._listItemService.projectInfos.rootNodeIri,
projectIri: this._listItemService.projectInfos.projectIri,
labels: this.form.value.labels,
labels: this.form.controls.labels.getRawValue(),
name: `${ProjectService.IriToUuid(this._listItemService.projectInfos.projectIri)}-${Math.random()
.toString(36)
.substring(2)}${Math.random().toString(36).substring(2)}`,
};

this._listApiService.createChildNode(data.parentNodeIri, data).subscribe(() => {
this.loading = false;
this._resetForm();
this.form.controls.labels.clear();
this._listItemService.onUpdate$.next();
});
}

private _buildForm() {
this.form = this._fb.group({
labels: this._fb.array([], atLeastOneStringRequired('value')),
});
}

private _resetForm() {
(this.form.get('labels') as FormArray).clear();
}
}
@@ -0,0 +1,7 @@
import { FormGroup } from '@angular/forms';
import { MultiLanguageFormArray } from '@dasch-swiss/vre/shared/app-string-literal';

export type ListItemForm = FormGroup<{
labels: MultiLanguageFormArray;
comments: MultiLanguageFormArray;
}>;

0 comments on commit 17333d0

Please sign in to comment.