Compare commits

...

5 Commits

Author SHA1 Message Date
Developer 02
e5e12bfb61 feat: Löschen-Schaltfläche zur ReceiverInputComponent hinzufügen und Verwaltung der Empfängerdaten aktualisieren
- Löschen-Schaltfläche zur `ReceiverInputComponent` hinzugefügt, um den Texteingang zu leeren
- Logik in `receiver_filter` implementiert, um eine leere Zeile hinzuzufügen, wenn ein neuer Empfänger hinzugefügt wird, und Zeilen zu entfernen, wenn Eingaben gelöscht werden
- Verwaltung der `receiverData` aktualisiert, um dynamische Hinzufügung und Entfernung von Zeilen basierend auf Eingaben zu berücksichtigen
2024-08-22 20:15:03 +02:00
Developer 02
6a8baf08ed feat: ReceiverInputComponent zu ReceiverTableComponent hinzufügen
- `ReceiverInputComponent` für E-Mail-Eingabe mit Autocomplete erstellt
- `ReceiverInputComponent` in `ReceiverTableComponent` integriert
- `ReceiverInputComponent` mit Eingabeoptionen für E-Mail-Adressen konfiguriert
2024-08-22 18:24:09 +02:00
Developer 02
10ac34a9f7 refactor: ReceiverInputComponent in ReceiverTableComponent umbenennen und in das Verzeichnis components verschieben 2024-08-22 17:40:14 +02:00
Developer 02
72af1cc2a2 refactor: nicht verwendete Filtermethode aus der Receiver-Input-Komponente entfernen 2024-08-22 17:18:17 +02:00
Developer 02
cd32ae2a35 feat: neuen Receiver-Input-Komponente mit Autocomplete und Tabellenanzeige hinzufügen
- Implementierung der `ReceiverInputComponent` mit Angular Material Autocomplete und Tabelle
- Abruf und Filterung von E-Mail-Adressen aus `ReceiverService`
- Anzeige des E-Mail-Inputs mit Autocomplete-Optionen und einer Datentabelle
- Integration der `ReceiverInputComponent` in den `envelope-creation` Formularschritt
2024-08-22 17:04:46 +02:00
10 changed files with 238 additions and 13 deletions

View File

@@ -0,0 +1,16 @@
<form class="example-form">
<mat-form-field class="example-full-width">
<mat-label>Email</mat-label>
<input type="text" aria-label="Email" matInput [formControl]="control" [matAutocomplete]="auto">
@if (text) {
<button matSuffix mat-icon-button aria-label="Clear" (click)="text=''">
<mat-icon>close</mat-icon>
</button>
}
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
@for (option of filteredOptions | async; track option) {
<mat-option [value]="option">{{option}}</mat-option>
}
</mat-autocomplete>
</mat-form-field>
</form>

View File

@@ -0,0 +1,7 @@
.mat-stepper-vertical {
margin-top: 8px;
}
.mat-mdc-form-field {
margin-top: 16px;
}

View File

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ReceiverInputComponent } from './receiver-input.component';
describe('ReceiverInputComponent', () => {
let component: ReceiverInputComponent;
let fixture: ComponentFixture<ReceiverInputComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ReceiverInputComponent]
})
.compileComponents();
fixture = TestBed.createComponent(ReceiverInputComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,66 @@
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { ReactiveFormsModule, FormControl } from '@angular/forms';
import { MatInputModule } from '@angular/material/input';
import { Observable, map, startWith } from 'rxjs';
import { AsyncPipe } from '@angular/common';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { FormsModule } from '@angular/forms';
import { MatFormFieldModule } from '@angular/material/form-field';
@Component({
selector: 'receiver-input',
standalone: true,
imports: [
MatInputModule,
MatAutocompleteModule,
ReactiveFormsModule,
AsyncPipe,
MatFormFieldModule, MatInputModule, FormsModule, MatButtonModule, MatIconModule
],
templateUrl: './receiver-input.component.html',
styleUrl: './receiver-input.component.scss'
})
export class ReceiverInputComponent implements OnInit, OnChanges {
ngOnInit(): void {
this.setupFiltering();
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['options']) {
this.setupFiltering();
}
}
private setupFiltering(): void {
this.filteredOptions = this.control.valueChanges.pipe(
startWith(''),
map(value => this.filter(value || '', this.options)),
);
}
control = new FormControl('');
filteredOptions!: Observable<string[]>;
@Input() options: string[] = [];
@Input() filter: (value: string, options: string[]) => string[] = value => {
const filterValue = value.toLowerCase();
return this.options.filter(option => option.toLowerCase().includes(filterValue));
}
public get text(): string {
return this.control.value || '';
}
public set text(value: string) {
this.control.setValue(value)
}
public get lenght(): number {
return this.text.length;
}
}

View File

@@ -0,0 +1,21 @@
<table mat-table [dataSource]="receiverData" class="mat-elevation-z8">
<ng-container matColumnDef="email">
<th mat-header-cell *matHeaderCellDef> Email </th>
<td mat-cell *matCellDef="let element">
<receiver-input [options]="receiver_mails" [filter]="receiver_filter"></receiver-input>
</td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> Anrede Email </th>
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
</ng-container>
<ng-container matColumnDef="accessCode">
<th mat-header-cell *matHeaderCellDef> Zugriffscode </th>
<td mat-cell *matCellDef="let element"> {{element.accessCode}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

View File

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ReceiverTableComponent } from './receiver-table.component';
describe('ReceiverTableComponent', () => {
let component: ReceiverTableComponent;
let fixture: ComponentFixture<ReceiverTableComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ReceiverTableComponent]
})
.compileComponents();
fixture = TestBed.createComponent(ReceiverTableComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,73 @@
import { Component, OnInit, QueryList, ViewChild, ViewChildren } from '@angular/core';
import { FormsModule, ReactiveFormsModule, FormControl } from '@angular/forms';
import { MatInputModule } from '@angular/material/input';
import { MatTableModule } from '@angular/material/table';
import { Observable } from 'rxjs';
import { startWith, map } from 'rxjs/operators';
import { AsyncPipe } from '@angular/common';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatFormFieldModule } from '@angular/material/form-field';
import { ReceiverService } from '../../services/receiver.service'
import { ReceiverInputComponent } from '../receiver-input/receiver-input.component';
@Component({
selector: 'receiver-table',
standalone: true,
imports: [
MatTableModule,
FormsModule,
MatFormFieldModule,
MatInputModule,
MatAutocompleteModule,
ReactiveFormsModule,
AsyncPipe,
ReceiverInputComponent
],
templateUrl: './receiver-table.component.html',
styleUrl: './receiver-table.component.scss'
})
export class ReceiverTableComponent implements OnInit {
constructor(private receiverService: ReceiverService) { }
async ngOnInit() {
this.receiver_mails = await this.receiverService.getReceiverAsync().then((receivers: any[]) => receivers.map(r => r.emailAddress));
}
receiver_filter: (value: string, options: string[]) => string[] = (value, options) => {
const filterValue = value.toLowerCase();
// if added into last row
if (value.length > 0 && (this.receiverInputs.at(-1)?.lenght ?? 0) > 0) {
this.receiverData.push({ email: "", name: "", accessCode: "" });
this.update();
}
else if (value.length == 0) {
for (var i = 0; i < this.receiverInputs.length - 1; i++) {
if (this.receiverInputs[i].lenght === 0) {
this.receiverData.splice(i, 1);
this.update();
}
}
}
return options.filter(option => option.toLowerCase().includes(filterValue));
}
receiver_mails: string[] = [];
@ViewChildren(ReceiverInputComponent) receiverInputsQueryList!: QueryList<ReceiverInputComponent>;
get receiverInputs(): ReceiverInputComponent[] {
return this.receiverInputsQueryList?.toArray() ?? [];
}
receiverData: { email: string; name: string; accessCode: string }[] = [
{ email: "", name: "", accessCode: "" }
];
displayedColumns: string[] = ['email', 'name', 'accessCode'];
public update() {
this.receiverData = [...this.receiverData];
}
}

View File

@@ -2,6 +2,7 @@
<mat-step [stepControl]="firstFormGroup">
<form [formGroup]="firstFormGroup">
<ng-template matStepLabel>Titel & Vertragstyp</ng-template>
<receiver-table></receiver-table>
<mat-form-field>
<mat-label>Titel</mat-label>
<input matInput placeholder="Arbeitsvertrag" formControlName="firstCtrl" required>
@@ -21,11 +22,8 @@
</mat-step>
<mat-step [stepControl]="secondFormGroup">
<form [formGroup]="secondFormGroup">
<ng-template matStepLabel>Fill out your address</ng-template>
<mat-form-field>
<mat-label>Address</mat-label>
<input matInput formControlName="secondCtrl" placeholder="Ex. 1 Main St, New York, NY" required>
</mat-form-field>
<ng-template matStepLabel>Empfänger</ng-template>
<receiver-table></receiver-table>
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button matStepperNext>Next</button>

View File

@@ -5,7 +5,7 @@ import { MatFormFieldModule } from '@angular/material/form-field';
import { MatStepperModule } from '@angular/material/stepper';
import { MatButtonModule } from '@angular/material/button';
import { MatSelectModule } from '@angular/material/select';
import { ReceiverService } from '../../services/receiver.service';
import { ReceiverTableComponent } from "../../components/receiver-table/receiver-table.component";
@Component({
selector: 'app-envelope-creation',
@@ -17,16 +17,14 @@ import { ReceiverService } from '../../services/receiver.service';
ReactiveFormsModule,
MatFormFieldModule,
MatInputModule,
MatSelectModule
],
MatSelectModule,
ReceiverTableComponent
],
templateUrl: './envelope-creation.component.html',
styleUrl: './envelope-creation.component.scss'
})
export class EnvelopeCreationComponent {
constructor(private receiverService: ReceiverService) {
}
ngOnInit() {
this.selectedType = this.types[0].value;
}
@@ -43,8 +41,8 @@ export class EnvelopeCreationComponent {
selectedType: string = "Mietvertrag"
types: any[] = [
{ value: 0, viewValue: 'Mietvertrag' },
{ value: 1, viewValue: 'Kaufvertrag' }
{value: 0, viewValue: 'Mietvertrag'},
{value: 1, viewValue: 'Kaufvertrag'}
];
typeControl = new FormControl('Mietvertrag', [Validators.required]);
}