#3376 Erscheinungstermin Filter Option Mit Input Box

This commit is contained in:
Lorenz Hilpert
2023-08-11 10:28:14 +02:00
parent 6ab1ea2e70
commit 8054c96315
8 changed files with 142 additions and 85 deletions

View File

@@ -266,6 +266,11 @@
"name": "text-decrease",
"data": "m40-200 220-560h80l220 560h-75l-57-150H172l-57 150H40Zm156-214h208L302-685h-4L196-414Zm414-36v-60h310v60H610Z",
"viewBox":"0 -960 960 960"
},
{
"name": "calendar-today",
"data": "M180-80q-24 0-42-18t-18-42v-620q0-24 18-42t42-18h65v-60h65v60h340v-60h65v60h65q24 0 42 18t18 42v620q0 24-18 42t-42 18H180Zm0-60h600v-430H180v430Zm0-490h600v-130H180v130Zm0 0v-130 130Z",
"viewBox": "0 -960 960 960"
}
],

View File

@@ -1,70 +1,64 @@
<div class="options-wrapper">
<div
*ngIf="uiStartOption"
class="option"
<div class="grid grid-flow-col items-center justify-start gap-4" [formGroup]="formGroup">
<shared-form-control
[attr.data-label]="uiStartOption?.label"
[attr.data-value]="uiStartOption?.value"
[attr.data-key]="uiStartOption?.key"
[attr.data-selected]="uiStartOption?.selected"
>
<div class="option-wrapper">
<span> {{ uiStartOption?.label }}: </span>
<button
class="cta-picker"
[class.open]="dpStartTrigger?.opened"
[uiOverlayTrigger]="dpStart"
#dpStartTrigger="uiOverlayTrigger"
type="button"
>
<span>
{{ uiStartOption?.value | date: 'dd.MM.yy' }}
</span>
<ui-icon icon="arrow_head" size="1em"></ui-icon>
</button>
</div>
<ui-datepicker
class="dp-left"
#dpStart
yPosition="below"
xPosition="after"
[ngModel]="uiStartOption?.value"
saveLabel="Übernehmen"
(save)="uiStartOption?.setValue($event)"
>
</ui-datepicker>
</div>
<div
*ngIf="uiStopOption"
class="option"
<shared-input-control>
<input placeholder="TT.MM.JJJJ" sharedInputControlInput uiDateInput type="text" formControlName="start" />
<shared-input-control-suffix>
<button
type="button"
class="grid items-center justify-center h-10 w-14 my-2 border-l solid border-[#AEB7C1] text-[#596470]"
[uiOverlayTrigger]="dpStart"
#dpStartTrigger="uiOverlayTrigger"
>
<shared-icon icon="calendar-today"></shared-icon>
</button>
</shared-input-control-suffix>
</shared-input-control>
</shared-form-control>
<div class="font-bold -mt-4">bis</div>
<shared-form-control
[attr.data-label]="uiStopOption?.label"
[attr.data-value]="uiStopOption?.value"
[attr.data-key]="uiStopOption?.key"
[attr.data-selected]="uiStopOption?.selected"
>
<div class="option-wrapper">
<span> {{ uiStopOption?.label }}: </span>
<button
class="cta-picker"
[class.open]="dpStopTrigger?.opened"
[uiOverlayTrigger]="dpStop"
#dpStopTrigger="uiOverlayTrigger"
type="button"
>
<span>
{{ uiStopOptionValue | date: 'dd.MM.yy' }}
</span>
<ui-icon icon="arrow_head" size="1em"></ui-icon>
</button>
</div>
<ui-datepicker
class="dp-right"
yPosition="below"
xPosition="after"
#dpStop
[ngModel]="uiStopOptionValue"
(save)="setStopValue($event)"
saveLabel="Übernehmen"
>
</ui-datepicker>
</div>
<shared-input-control>
<input placeholder="TT.MM.JJJJ" sharedInputControlInput uiDateInput type="text" formControlName="stop" />
<shared-input-control-suffix>
<button
type="button"
class="grid items-center justify-center h-10 w-14 my-2 border-l solid border-[#AEB7C1] text-[#596470]"
[uiOverlayTrigger]="dpStop"
#dpStartTrigger="uiOverlayTrigger"
>
<shared-icon icon="calendar-today"></shared-icon>
</button>
</shared-input-control-suffix>
</shared-input-control>
</shared-form-control>
</div>
<ui-datepicker
class="dp-left"
#dpStart
yPosition="below"
xPosition="after"
[ngModel]="uiStartOption?.value"
saveLabel="Übernehmen"
(save)="uiStartOption?.setValue($event)"
>
</ui-datepicker>
<ui-datepicker
class="dp-right"
yPosition="below"
xPosition="after"
#dpStop
[ngModel]="uiStopOption?.value"
(save)="setStopValue($event)"
saveLabel="Übernehmen"
>
</ui-datepicker>

View File

@@ -1,6 +1,8 @@
import { Component, ChangeDetectionStrategy, Input, ChangeDetectorRef } from '@angular/core';
import { Subscription } from 'rxjs';
import { IOption, Option } from '../../../tree';
import { FormControl, FormGroup } from '@angular/forms';
import { UiValidators } from '@ui/validators';
@Component({
selector: 'shared-input-option-date-range',
@@ -11,9 +13,23 @@ import { IOption, Option } from '../../../tree';
export class FilterInputOptionDateRangeComponent {
private _options: Option[];
formGroup = new FormGroup({
start: new FormControl<Date>(undefined, UiValidators.date),
stop: new FormControl<Date>(undefined, UiValidators.date),
});
get startControl(): FormControl<Date> {
return this.formGroup.get('start') as FormControl<Date>;
}
get stopControl(): FormControl<Date> {
return this.formGroup.get('stop') as FormControl<Date>;
}
@Input()
set options(value: IOption[]) {
this._options = value?.map((option) => (option instanceof Option ? option : Option.create(option)));
this.subscribeChanges();
}
@@ -29,12 +45,6 @@ export class FilterInputOptionDateRangeComponent {
return this.uiOptions?.find((o) => o.key === 'stop');
}
get uiStopOptionValue() {
const stopDate = new Date(this.uiStopOption?.value);
stopDate?.setDate(stopDate?.getDate() - 1); // to update the view correctly after setStopValue() gets called !
return stopDate?.toJSON();
}
optionChangeSubscription: Subscription;
constructor(private cdr: ChangeDetectorRef) {}
@@ -44,6 +54,18 @@ export class FilterInputOptionDateRangeComponent {
if (this.uiStartOption) {
this.optionChangeSubscription.add(
this.uiStartOption.changes.subscribe(() => {
if (new Date(this.uiStartOption.value) !== new Date(this.formGroup.get('start').value)) {
this.formGroup.patchValue({ start: (this.uiStartOption.value as any) as Date });
}
this.cdr.markForCheck();
})
);
this.optionChangeSubscription.add(
this.formGroup.get('start').valueChanges.subscribe((value) => {
if (new Date(this.uiStartOption.value) !== new Date(this.formGroup.get('start').value)) {
this.uiStartOption.setValue(value);
}
this.cdr.markForCheck();
})
);
@@ -51,6 +73,19 @@ export class FilterInputOptionDateRangeComponent {
if (this.uiStopOption) {
this.optionChangeSubscription.add(
this.uiStopOption.changes.subscribe(() => {
if (new Date(this.uiStopOption.value) !== new Date(this.formGroup.get('stop').value)) {
this.formGroup.patchValue({ stop: (this.uiStopOption.value as any) as Date });
}
this.cdr.markForCheck();
})
);
this.optionChangeSubscription.add(
this.formGroup.get('stop').valueChanges.subscribe((value) => {
if (new Date(this.uiStopOption.value) !== new Date(this.formGroup.get('stop').value)) {
this.uiStopOption.setValue(value);
}
this.cdr.markForCheck();
})
);
@@ -63,8 +98,8 @@ export class FilterInputOptionDateRangeComponent {
}
setStopValue(date: Date) {
const stopDate = date;
stopDate?.setDate(stopDate?.getDate() + 1); // to include the selected stop date !
const stopDate = new Date(date);
stopDate.setHours(23, 59, 59, 999);
this.uiStopOption?.setValue(stopDate);
}
}

View File

@@ -3,12 +3,26 @@ import { CommonModule } from '@angular/common';
import { FilterInputOptionDateRangeComponent } from './filter-input-option-date-range.component';
import { UiDatepickerModule } from '@ui/datepicker';
import { FormsModule } from '@angular/forms';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { UiIconModule } from '@ui/icon';
import { UiCommonModule } from '@ui/common';
import { FormControlComponent } from '@shared/components/form-control';
import { IconComponent } from '@shared/components/icon';
import { InputControlModule } from '@shared/components/input-control';
import { UiDateInputDirective } from '@ui/input';
@NgModule({
imports: [CommonModule, UiCommonModule, UiDatepickerModule, FormsModule, UiIconModule],
imports: [
CommonModule,
InputControlModule,
FormControlComponent,
UiCommonModule,
UiDatepickerModule,
ReactiveFormsModule,
FormsModule,
IconComponent,
UiDateInputDirective,
],
exports: [FilterInputOptionDateRangeComponent],
declarations: [FilterInputOptionDateRangeComponent],
})

View File

@@ -1,5 +1,5 @@
<label class="shared-fomr-control-label">{{ displayLabel }}</label>
<ng-content select="shared-select, input"></ng-content>
<ng-content select="shared-select, input, shared-input-control"></ng-content>
<div class="shared-fomr-control-error">
{{ control?.errors | firstError: label }}
</div>

View File

@@ -1,5 +1,5 @@
.shared-input-control {
@apply relative leading-[21px] text-p2 font-bold;
@apply relative leading-[1.3125rem] text-p2;
}
.shared-input-control:has(input.ng-invalid.ng-dirty) {
@@ -7,7 +7,11 @@
}
.shared-input-control-wrapper {
@apply flex flex-row items-center grow border border-solid border-[#AEB7C1] rounded-[5px] p-4;
@apply grid grid-flow-col items-stretch grow border border-solid border-[#AEB7C1] rounded h-14;
}
.shared-input-control-wrapper input {
@apply bg-transparent px-4;
}
.shared-input-control-wrapper:has(input.ng-invalid.ng-dirty) {
@@ -31,14 +35,6 @@
@apply inline-block grow-0;
}
.shared-input-control-prefix {
@apply -ml-2 mr-2;
}
.shared-input-control-suffix {
@apply -mr-2 ml-2;
}
.shared-input-control-error {
@apply text-left mt-[2px];
@apply text-left mt-[.125rem];
}

View File

@@ -1,4 +1,4 @@
import { OnDestroy, TemplateRef } from '@angular/core';
import { OnDestroy } from '@angular/core';
import { QueryList } from '@angular/core';
import { ContentChildren } from '@angular/core';
import { Component, ChangeDetectionStrategy, ViewEncapsulation, AfterContentInit, ContentChild, ViewChild } from '@angular/core';

View File

@@ -9,12 +9,14 @@ import {
ViewChild,
TemplateRef,
ContentChild,
ChangeDetectorRef,
} from '@angular/core';
import { Datepicker } from './datepicker';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Subscription } from 'rxjs';
import { DateAdapter, UiOverlayTrigger } from '@ui/common';
import { DatepickerPositionX, DatepickerPositionY } from './datepicker-positions';
import { isDate } from 'lodash';
@Component({
selector: 'ui-datepicker',
@@ -59,7 +61,7 @@ export class UiDatepickerComponent extends Datepicker implements UiOverlayTrigge
onTouched = () => {};
constructor(dateAdapter: DateAdapter) {
constructor(dateAdapter: DateAdapter, private _cdr: ChangeDetectorRef) {
super(dateAdapter);
const sub = this.selectedChange.subscribe((date) => {
this.onChange(date);
@@ -75,8 +77,19 @@ export class UiDatepickerComponent extends Datepicker implements UiOverlayTrigge
super.onDestroy();
}
writeValue(obj: Date): void {
this.setSelected(obj, { emit: false });
writeValue(obj: Date | string): void {
let date = undefined;
if (obj) {
date = new Date(obj);
}
this.setSelected(date, { emit: false });
if (isDate(date)) {
this.setDisplayed(date, { emit: false });
}
this._cdr.markForCheck();
}
registerOnChange(fn: any): void {