New Angular based web version #1
@@ -0,0 +1,89 @@
|
|||||||
|
@if (!loaded) {
|
||||||
|
<p-skeleton height="4rem" styleClass="mb-2" />
|
||||||
|
} @else {
|
||||||
|
<form [formGroup]="formGroup" class="flex flex-col gap-4" (ngSubmit)="onSubmit()">
|
||||||
|
|
||||||
|
<div class="flex gap-2 w-full">
|
||||||
|
<div class="flex flex-col gap-2 w-full">
|
||||||
|
<label for="date"> Datum </label>
|
||||||
|
<p-datepicker [iconDisplay]="'input'"
|
||||||
|
[firstDayOfWeek]="1"
|
||||||
|
placeholder="Datum auswählen"
|
||||||
|
[showIcon]="true"
|
||||||
|
inputId="date"
|
||||||
|
formControlName="date"
|
||||||
|
styleClass="w-full"
|
||||||
|
dateFormat="dd.mm.yy" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-2 w-full">
|
||||||
|
<label for="time"> Uhrzeit </label>
|
||||||
|
<p-datepicker [iconDisplay]="'input'"
|
||||||
|
[showIcon]="true"
|
||||||
|
[timeOnly]="true"
|
||||||
|
placeholder="Uhrzeit auswählen"
|
||||||
|
inputId="time"
|
||||||
|
formControlName="time"
|
||||||
|
styleClass="w-full"
|
||||||
|
inputStyleClass="w-full" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<label for="rabbit"> Kaninchen </label>
|
||||||
|
@if (rabbits$ | async; as rabbits) {
|
||||||
|
<p-select
|
||||||
|
[options]="rabbits"
|
||||||
|
placeholder="Kaninchen auswählen"
|
||||||
|
formControlName="rabbit"
|
||||||
|
optionLabel="name"
|
||||||
|
inputId="rabbit"
|
||||||
|
styleClass="w-full" />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<label for="medicines"> Medizin </label>
|
||||||
|
@if (medicines$ | async; as medicines) {
|
||||||
|
<p-multiSelect
|
||||||
|
[options]="medicines"
|
||||||
|
[showToggleAll]="false"
|
||||||
|
[showHeader]="false"
|
||||||
|
[autoOptionFocus]="false"
|
||||||
|
[filter]="false"
|
||||||
|
[showClear]="true"
|
||||||
|
[maxSelectedLabels]="medicines.length"
|
||||||
|
optionLabel="abbreviation"
|
||||||
|
formControlName="medicines"
|
||||||
|
inputId="medicines"
|
||||||
|
placeholder="Medizin auswählen"
|
||||||
|
display="chip"
|
||||||
|
styleClass="w-full">
|
||||||
|
<ng-template let-medicine pTemplate="item">
|
||||||
|
{{ medicine.name }} ({{ medicine.abbreviation }})
|
||||||
|
</ng-template>
|
||||||
|
</p-multiSelect>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<label for="weight"> Gewicht </label>
|
||||||
|
<p-inputGroup>
|
||||||
|
<input id="weight" placeholder="Gewicht eingeben" type="number" min="1" pInputText formControlName="weight" />
|
||||||
|
<p-inputGroupAddon>g</p-inputGroupAddon>
|
||||||
|
</p-inputGroup>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<label for="comment"> Kommentar </label>
|
||||||
|
<input pInputText id="comment" placeholder="Kommentar eingeben" type="text" formControlName="comment"
|
||||||
|
class="w-full" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<p-button type="button" label="Abbrechen" (click)="navigateToOverviewPage()" severity="warn" />
|
||||||
|
<p-button type="submit" label="Abschicken" severity="success" [disabled]="formGroup.invalid" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import { AsyncPipe } from '@angular/common';
|
||||||
|
import { Component, inject } from '@angular/core';
|
||||||
|
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
|
import { ButtonModule } from 'primeng/button';
|
||||||
|
import { ChipModule } from 'primeng/chip';
|
||||||
|
import { DatePickerModule } from 'primeng/datepicker';
|
||||||
|
import { FloatLabelModule } from 'primeng/floatlabel';
|
||||||
|
import { InputGroupModule } from 'primeng/inputgroup';
|
||||||
|
import { InputGroupAddonModule } from 'primeng/inputgroupaddon';
|
||||||
|
import { InputNumberModule } from 'primeng/inputnumber';
|
||||||
|
import { InputTextModule } from 'primeng/inputtext';
|
||||||
|
import { MultiSelectModule } from 'primeng/multiselect';
|
||||||
|
import { SelectModule } from 'primeng/select';
|
||||||
|
import { SkeletonModule } from 'primeng/skeleton';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-edit-entry',
|
||||||
|
imports: [
|
||||||
|
AsyncPipe,
|
||||||
|
ButtonModule,
|
||||||
|
ChipModule,
|
||||||
|
DatePickerModule,
|
||||||
|
FloatLabelModule,
|
||||||
|
InputGroupAddonModule,
|
||||||
|
InputGroupModule,
|
||||||
|
InputNumberModule,
|
||||||
|
InputTextModule,
|
||||||
|
MultiSelectModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
SelectModule,
|
||||||
|
SkeletonModule,
|
||||||
|
],
|
||||||
|
templateUrl: './edit-entry.component.html',
|
||||||
|
styleUrl: './edit-entry.component.scss'
|
||||||
|
})
|
||||||
|
export class EditEntryComponent {
|
||||||
|
private readonly formBuilder = inject(FormBuilder);
|
||||||
|
|
||||||
|
protected readonly formGroup = this.formBuilder.group({
|
||||||
|
date: [<Date | null>null],
|
||||||
|
time: [<Date | null>null],
|
||||||
|
rabbit: [<Rabbit | null>null, Validators.required],
|
||||||
|
weight: [
|
||||||
|
<number | null>null,
|
||||||
|
Validators.min(1),
|
||||||
|
],
|
||||||
|
medicines: [<Medicine[]>[]],
|
||||||
|
comment: [<string | null>null],
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -2,34 +2,37 @@
|
|||||||
<p-scrollTop />
|
<p-scrollTop />
|
||||||
<div class="mb-4 flex gap-2 md:justify-between">
|
<div class="mb-4 flex gap-2 md:justify-between">
|
||||||
<div class="basis-full lg:basis-1/4 md:basis-1/2 p-0">
|
<div class="basis-full lg:basis-1/4 md:basis-1/2 p-0">
|
||||||
<p-select styleClass="w-full" [formControl]="selectedRabbit" placeholder="Kaninchen" [showClear]="true"
|
<!-- <p-select styleClass="w-full" [formControl]="selectedRabbit" placeholder="Kaninchen" [showClear]="true"
|
||||||
[options]="(rabbits$ | async)!" optionLabel="name" />
|
[options]="(rabbits$ | async)!" optionLabel="name" /> -->
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p-button label="Erstellen" routerLink="/weight-entries/create">
|
<p-button label="Erstellen" routerLink="/weight-entries/create">
|
||||||
<ng-icon name="matAddSharp"></ng-icon>
|
<!-- <ng-icon name="matAddSharp"></ng-icon> -->
|
||||||
</p-button>
|
</p-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@if (filteredWeightEntries$ | async; as weightEntries) {
|
@if (consumptionEntries$ | async; as entries) {
|
||||||
<p-dataView [value]="weightEntries"
|
<p-dataView
|
||||||
[paginator]="true"
|
[value]="entries"
|
||||||
[rows]="rowsPerPageDefaultOption"
|
[paginator]="true"
|
||||||
[rowsPerPageOptions]="rowsPerPageOptions"
|
[rows]="rowsPerPageDefaultOption"
|
||||||
[pageLinks]="0"
|
[rowsPerPageOptions]="rowsPerPageOptions"
|
||||||
[showCurrentPageReport]="true"
|
[pageLinks]="0"
|
||||||
[currentPageReportTemplate]="currentPageReportTemplate"
|
[showCurrentPageReport]="true"
|
||||||
layout="list">
|
[currentPageReportTemplate]="currentPageReportTemplate"
|
||||||
<ng-template #list let-entries>
|
layout="list"
|
||||||
<div class="flex flex-col gap-2">
|
>
|
||||||
@for (weightEntry of entries; track weightEntry.id) {
|
<ng-template #list let-entries>
|
||||||
<app-weight-entry-card [weightEntry]="weightEntry"
|
<div class="flex flex-col gap-2">
|
||||||
(entryDeleted)="onEntryDeleted($event)"></app-weight-entry-card>
|
@for (entry of entries; track entry.id) {
|
||||||
}
|
{{ entry | json }}
|
||||||
</div>
|
<!-- <app-weight-entry-card [weightEntry]="weightEntry"
|
||||||
</ng-template>
|
(entryDeleted)="onEntryDeleted($event)"></app-weight-entry-card> -->
|
||||||
</p-dataView>
|
}
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</p-dataView>
|
||||||
} @else {
|
} @else {
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
@for (_ of skeletonsIterationSource; track $index) {
|
@for (_ of skeletonsIterationSource; track $index) {
|
||||||
|
|||||||
@@ -1,24 +1,19 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { Component, inject } from '@angular/core';
|
import { Component, inject } from '@angular/core';
|
||||||
import { FormControl, ReactiveFormsModule } from '@angular/forms';
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||||
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
import { RouterLink } from '@angular/router';
|
import { RouterLink } from '@angular/router';
|
||||||
import { MessageService } from 'primeng/api';
|
|
||||||
import { ButtonModule } from 'primeng/button';
|
import { ButtonModule } from 'primeng/button';
|
||||||
import { DataViewModule } from 'primeng/dataview';
|
import { DataViewModule } from 'primeng/dataview';
|
||||||
import { SelectModule } from 'primeng/select';
|
|
||||||
import { ScrollTopModule } from 'primeng/scrolltop';
|
import { ScrollTopModule } from 'primeng/scrolltop';
|
||||||
|
import { SelectModule } from 'primeng/select';
|
||||||
import { SkeletonModule } from 'primeng/skeleton';
|
import { SkeletonModule } from 'primeng/skeleton';
|
||||||
import {
|
import {
|
||||||
BehaviorSubject,
|
|
||||||
combineLatest,
|
|
||||||
map,
|
map,
|
||||||
Observable,
|
Observable,
|
||||||
of,
|
tap
|
||||||
startWith,
|
|
||||||
tap,
|
|
||||||
} from 'rxjs';
|
} from 'rxjs';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { Client, GetConsumptions_ResponseDto } from '../../../shared/api/swagger.generated';
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-entries',
|
selector: 'app-entries',
|
||||||
@@ -36,18 +31,24 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|||||||
styleUrl: './entries.component.scss'
|
styleUrl: './entries.component.scss'
|
||||||
})
|
})
|
||||||
export class EntriesComponent {
|
export class EntriesComponent {
|
||||||
private readonly http = inject(HttpClient);
|
private readonly client = inject(Client);
|
||||||
|
|
||||||
protected readonly consumptionEntries$: Observable<ConsumptionEntry[]>;
|
protected readonly consumptionEntries$: Observable<GetConsumptions_ResponseDto[] | undefined>;
|
||||||
|
|
||||||
|
protected readonly rowsPerPageDefaultOption = 25;
|
||||||
|
protected readonly rowsPerPageOptions = [10, 25, 50, 100];
|
||||||
|
protected readonly currentPageReportTemplate = '{currentPage} / {totalPages}';
|
||||||
|
|
||||||
|
protected readonly skeletonsIterationSource = Array(10).fill(0);
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.consumptionEntries$ = this.http.get<GetConsumptionEntriesResponse>('/api/v1/consumptions')
|
this.consumptionEntries$ = this.client.consumptionsGET()
|
||||||
.pipe(
|
.pipe(
|
||||||
takeUntilDestroyed(),
|
takeUntilDestroyed(),
|
||||||
tap((response) => {
|
tap((response) => {
|
||||||
console.log('Entries response:', response);
|
console.log('Entries response:', response);
|
||||||
}),
|
}),
|
||||||
map(response => response.consumptions)
|
map((response) => response.consumptions)
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user