Skip to content

Commit

Permalink
Merge pull request #114 from AmpersandTarski/feat/forms-michiel-liwei
Browse files Browse the repository at this point in the history
Feat/forms michiel liwei
  • Loading branch information
LiWeiYeh committed Dec 22, 2022
2 parents fc4774a + cadc515 commit 9d59f77
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ <h5>{{ data.Name }}</h5>
<label class="box-form-label">Description</label>
<div class="box-form-value">
<app-atomic-bigalphanumeric
[resource]="this"
propertyName="Description"
[property]="data.Description"
isUni
isTot
Expand All @@ -32,6 +34,8 @@ <h5>{{ data.Name }}</h5>
<label class="box-form-label">(Planned) start date</label>
<div class="box-form-value">
<app-atomic-date
[resource]="this"
propertyName="Start_32_date"
[property]="data._40_Planned_41__32_start_32_date"
isUni
isTot
Expand All @@ -43,6 +47,8 @@ <h5>{{ data.Name }}</h5>
<label class="box-form-label">Status</label>
<div class="box-form-value">
<app-atomic-alphanumeric
[resource]="this"
propertyName="Status"
[property]="data.Status"
isUni
isTot
Expand All @@ -53,7 +59,14 @@ <h5>{{ data.Name }}</h5>
<div class="field col-12 box-form-field">
<label class="box-form-label">Active</label>
<div class="box-form-value">
<app-atomic-boolean [property]="data.Active" isUni isTot crud="CRUD"></app-atomic-boolean>
<app-atomic-boolean
[resource]="this"
propertyName="Active"
[property]="data.Active"
isUni
isTot
crud="CRUD"
></app-atomic-boolean>
</div>
</div>
<div class="field col-12 box-form-field">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { ProjectInterface } from '../project/project.interface';
export class ProjectEditComponent implements OnInit, Resource<ProjectInterface> {
public data$!: Observable<ProjectInterface>;
public projectId!: string;

constructor(private route: ActivatedRoute, private service: BackendService) {}

ngOnInit(): void {
Expand Down
10 changes: 10 additions & 0 deletions src/app/shared/atomic-components/BaseAtomicComponent.class.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { Resource } from '../interfacing/resource.interface';

@Component({
template: '',
Expand All @@ -8,6 +9,15 @@ export abstract class BaseAtomicComponent<T> implements OnInit, OnChanges {
// TODO Refactor to combination of parent-propertyName. We need a link to the parent anyway
property: T | Array<T> | null = null;

@Input()
// The type of the T for Resource<T> is not relevant nor to be determined here; therefore unknown
// We require a Resource, that implements the required methods (like patch)
// Most likely this is a top-level component for a specific application interface (e.g. ProjectComponent)
resource!: Resource<unknown>;

@Input()
propertyName!: string;

public data: Array<T> = [];

private _isUni: boolean = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,47 +1,31 @@
import { Component, Input, OnInit } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { BaseAtomicComponent } from '../BaseAtomicComponent.class';
import { FormControl } from '@angular/forms';
import { debounceTime, distinctUntilChanged, map, tap } from 'rxjs';
import { Resource } from '../../interfacing/resource.interface';

@Component({
selector: 'app-atomic-alphanumeric',
templateUrl: './atomic-alphanumeric.component.html',
styleUrls: ['./atomic-alphanumeric.component.css'],
})
export class AtomicAlphanumericComponent extends BaseAtomicComponent<string> implements OnInit {
// make generic and put in BaseAtomicComponent class
formControl!: FormControl<string | null>;
newItemControl: FormControl<string> = new FormControl<string>('', { nonNullable: true, updateOn: 'blur' });

@Input()
// The type of the T for Resource<T> is not relevant nor to determine here; therefore unknow
// We require a Resource, that implements the required methods (like patch)
// Most likely this is a top-level component for a specific application interface (e.g. ProjectComponent)
resource!: Resource<unknown>; // TODO move to the base class. It is needed for all atomic components

@Input()
propertyName!: string; // TODO move to the base class. It is needed for all atomic components

override ngOnInit(): void {
super.ngOnInit();
this.formControl = new FormControl(this.data[0], { nonNullable: false, updateOn: 'blur' });

this.formControl.valueChanges
.pipe(
debounceTime(300),
distinctUntilChanged(),
map((x) => (x === '' ? null : x)), // transform empty string to null value
)
.subscribe((x) =>
this.resource
.patch([
{
op: 'replace',
path: this.propertyName, // FIXME: this must be relative to path of this.resource
value: x,
},
])
.subscribe(),
);
this.formControl.valueChanges.subscribe((x) =>
this.resource
.patch([
{
op: 'replace',
path: this.propertyName, // FIXME: this must be relative to path of this.resource
value: x,
},
])
.subscribe(),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<div class="w-full" *ngIf="isUni; else isNotUni">
<textarea
pInputTextarea
[(ngModel)]="property"
[formControl]="formControl"
[required]="isTot"
maxlength="64000"
class="w-full min-w-10rem"
Expand All @@ -22,7 +22,7 @@
<div class="p-inputgroup">
<textarea
pInputTextarea
[(ngModel)]="newItem"
[formControl]="newItemControl"
[required]="isNewItemInputRequired()"
maxlength="64000"
placeholder="Add text"
Expand All @@ -35,12 +35,6 @@
</ng-template>

<ng-template #notUpdatable>
<div *ngIf="isUni; else isNotUniAndNotUpdatable">
<div class="wordwrap">{{ property }}</div>
</div>
</ng-template>

<ng-template #isNotUniAndNotUpdatable>
<div *ngFor="let row of data" class="wordwrap">{{ row }}</div>
</ng-template>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { BaseAtomicComponent } from '../BaseAtomicComponent.class';

@Component({
selector: 'app-atomic-bigalphanumeric',
templateUrl: './atomic-bigalphanumeric.component.html',
styleUrls: ['./atomic-bigalphanumeric.component.css'],
})
export class AtomicBigalphanumericComponent extends BaseAtomicComponent<string> {
newItem!: string;
export class AtomicBigalphanumericComponent extends BaseAtomicComponent<string> implements OnInit {
formControl!: FormControl<string | null>;
newItemControl: FormControl<string> = new FormControl<string>('', { nonNullable: true, updateOn: 'blur' });

// TODO: make FormGroup for when !isUni

override ngOnInit(): void {
super.ngOnInit();
this.formControl = new FormControl(this.data[0], { nonNullable: false, updateOn: 'blur' });

this.formControl.valueChanges.subscribe((x) =>
this.resource
.patch([
{
op: 'replace',
path: this.propertyName, // FIXME: this must be relative to path of this.resource
value: x,
},
])
.subscribe(),
);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
<div *ngIf="canRead(); else notReadable">
<div class="p-inputgroup" *ngIf="isUni; else isNotUni">
<div class="w-full">
<p-inputSwitch
*ngIf="isUni && canRead()"
[(ngModel)]="property"
[disabled]="!canUpdate()"
(click)="getState()"
></p-inputSwitch>
<p-inputSwitch *ngIf="isUni && canRead()" [formControl]="formControl" (click)="getState()"></p-inputSwitch>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,41 @@
import { Component, EventEmitter, Output } from '@angular/core';
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { FormControl } from '@angular/forms';
import { BaseAtomicComponent } from '../BaseAtomicComponent.class';

@Component({
selector: 'app-atomic-boolean',
templateUrl: './atomic-boolean.component.html',
styleUrls: ['./atomic-boolean.component.css'],
})
export class AtomicBooleanComponent extends BaseAtomicComponent<boolean> {
export class AtomicBooleanComponent extends BaseAtomicComponent<boolean> implements OnInit {
@Output() state = new EventEmitter();

getState() {
formControl!: FormControl<boolean | null>;
newItemControl: FormControl<boolean> = new FormControl<boolean>(false, {
nonNullable: true,
updateOn: 'change',
});

override ngOnInit(): void {
super.ngOnInit();
this.formControl = new FormControl(this.data[0], { nonNullable: false, updateOn: 'blur' });
if (!this.canUpdate()) {
this.formControl.disable();
}
this.formControl.valueChanges.subscribe((x) =>
this.resource
.patch([
{
op: 'replace',
path: this.propertyName, // FIXME: this must be relative to path of this.resource
value: x,
},
])
.subscribe(),
);
}

public getState() {
this.state.emit(this.property);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
[showClear]="true"
[readonlyInput]="true"
[dateFormat]="format"
[(ngModel)]="property"
(ngModelChange)="onDateChange($event)"
[formControl]="formControl"
></p-calendar>
</div>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,40 @@
import { DatePipe } from '@angular/common';
import { Component, Input } from '@angular/core';
import { Component, Input, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { BaseAtomicComponent } from '../BaseAtomicComponent.class';

@Component({
selector: 'app-atomic-date',
templateUrl: './atomic-date.component.html',
styleUrls: ['./atomic-date.component.css'],
})
export class AtomicDateComponent extends BaseAtomicComponent<string> {
export class AtomicDateComponent extends BaseAtomicComponent<string> implements OnInit {
// Possible formats can be found at https://www.primefaces.org/primeng/calendar.
// Scroll down to DateFormat for the documentation
@Input() format: string = 'yy-mm-dd';

public onDateChange(date: Date): void {
console.log(date);
formControl!: FormControl<string | null>;
newItemControl: FormControl<string> = new FormControl<string>('', { nonNullable: true, updateOn: 'change' });

override ngOnInit(): void {
super.ngOnInit();
this.formControl = new FormControl(this.data[0], { nonNullable: false, updateOn: 'change' });

this.formControl.valueChanges.subscribe((x) =>
this.resource
.patch([
{
op: 'replace',
path: this.propertyName, // FIXME: this must be relative to path of this.resource
value: this.formatDate(x!),
},
])
.subscribe(),
);
}

public formatDate(date: string): string {
let datePipe: DatePipe = new DatePipe('en-US');
this.property = datePipe.transform(date, 'yyyy-MM-dd');
return datePipe.transform(date, 'yyyy-MM-dd')!;
}
}
3 changes: 2 additions & 1 deletion src/app/shared/interfacing/patch-replace.interface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export interface PatchReplace {
op: 'replace';
path: string;
value: string | null;
// make generic
value: string | boolean | null;
}

0 comments on commit 9d59f77

Please sign in to comment.