add component for a custom date picker that also knows relative date ranges like 'last month'
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
||||
<app-date-picker></app-date-picker>
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Component} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-date-picker-test',
|
||||
templateUrl: './date-picker-test.component.html'
|
||||
})
|
||||
export class DatePickerTestComponent {
|
||||
|
||||
constructor(){
|
||||
}
|
||||
|
||||
}
|
||||
207
pdb-js/src/app/components/datepicker/date-picker.component.html
Normal file
207
pdb-js/src/app/components/datepicker/date-picker.component.html
Normal file
@@ -0,0 +1,207 @@
|
||||
<style>
|
||||
#date-box {
|
||||
width: 23.5em;
|
||||
}
|
||||
|
||||
.header-box {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.date-picker-overlay {
|
||||
width: 500px;
|
||||
transition: box-shadow 200ms cubic-bezier(0, 0, 0.2, 1);
|
||||
box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2),
|
||||
0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.tab-quick {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 2em;
|
||||
}
|
||||
.tab-quick-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.date-picker-form-field {
|
||||
width: 23.5em;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="header-box">
|
||||
<button
|
||||
mat-button
|
||||
matTooltip="Date Picker"
|
||||
(click)="isOpen = !isOpen"
|
||||
cdkOverlayOrigin
|
||||
#trigger="cdkOverlayOrigin"
|
||||
>
|
||||
{{ dateValue.display }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ng-template
|
||||
cdkConnectedOverlay
|
||||
[cdkConnectedOverlayOrigin]="trigger"
|
||||
[cdkConnectedOverlayOpen]="isOpen"
|
||||
>
|
||||
<div class="date-picker-overlay">
|
||||
<mat-tab-group
|
||||
animationDuration="0ms"
|
||||
(selectedTabChange)="tabChange()"
|
||||
[(selectedIndex)]="selectedTabIndex"
|
||||
>
|
||||
<mat-tab label="Quick">
|
||||
<div class="tab-quick">
|
||||
<div class="tab-quick-column">
|
||||
<button mat-button (click)="applyQuick('BD/P1D', 'today')">
|
||||
Today
|
||||
</button>
|
||||
<button mat-button (click)="applyQuick('B-1D/P1D', 'yesterday')">
|
||||
Yesterday
|
||||
</button>
|
||||
<button mat-button (click)="applyQuick('BW/EW', 'this week')">
|
||||
This Week
|
||||
</button>
|
||||
<button mat-button (click)="applyQuick('BM/EM', 'this month')">
|
||||
This Month
|
||||
</button>
|
||||
<button mat-button (click)="applyQuick('BQ/EQ', 'this quarter')">
|
||||
This Quarter
|
||||
</button>
|
||||
<button mat-button (click)="applyQuick('BY/EY', 'this year')">
|
||||
This Year
|
||||
</button>
|
||||
</div>
|
||||
<div class="tab-quick-column">
|
||||
<button mat-button (click)="applyQuick('B-7D/ED', 'last 7 days')">
|
||||
Last 7 Days
|
||||
</button>
|
||||
<button mat-button (click)="applyQuick('B-1W/ED', 'last week')">
|
||||
Last Week
|
||||
</button>
|
||||
<button mat-button (click)="applyQuick('B-30D/ED', 'last 30 days')">
|
||||
Last 30 Days
|
||||
</button>
|
||||
<button mat-button (click)="applyQuick('B-1M/E-1M', 'last month')">
|
||||
Last Month
|
||||
</button>
|
||||
<button
|
||||
mat-button
|
||||
(click)="applyQuick('B-3M/E-1M', 'last 3 months')"
|
||||
>
|
||||
Last 3 Months
|
||||
</button>
|
||||
<button mat-button (click)="applyQuick('B-1Y/E-1Y', 'last year')">
|
||||
Last Year
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</mat-tab>
|
||||
|
||||
<mat-tab label="Relative">
|
||||
<mat-form-field
|
||||
class="pdb-form-number-small"
|
||||
(wheel)="scrollRelativeTimeRange($event, 'seconds', 59)"
|
||||
>
|
||||
<mat-label>Seconds:</mat-label>
|
||||
<input
|
||||
matInput
|
||||
name="relative-time-range-seconds"
|
||||
[(ngModel)]="relativeTimeRange.seconds"
|
||||
type="number"
|
||||
min="0"
|
||||
max="59"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field
|
||||
class="pdb-form-number-small"
|
||||
(wheel)="scrollRelativeTimeRange($event, 'minutes', 59)"
|
||||
>
|
||||
<mat-label>Minutes:</mat-label>
|
||||
<input
|
||||
matInput
|
||||
name="relative-time-range-minutes"
|
||||
[(ngModel)]="relativeTimeRange.minutes"
|
||||
type="number"
|
||||
min="0"
|
||||
max="59"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field
|
||||
class="pdb-form-number-small"
|
||||
(wheel)="scrollRelativeTimeRange($event, 'hours', 23)"
|
||||
>
|
||||
<mat-label>Hours:</mat-label>
|
||||
<input
|
||||
matInput
|
||||
name="relative-time-range-hours"
|
||||
[(ngModel)]="relativeTimeRange.hours"
|
||||
type="number"
|
||||
min="0"
|
||||
max="23"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field
|
||||
class="pdb-form-number-small"
|
||||
(wheel)="scrollRelativeTimeRange($event, 'days', 367)"
|
||||
>
|
||||
<mat-label>Days:</mat-label>
|
||||
<input
|
||||
matInput
|
||||
name="relative-time-range-days"
|
||||
[(ngModel)]="relativeTimeRange.days"
|
||||
type="number"
|
||||
min="0"
|
||||
max="367"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field
|
||||
class="pdb-form-number-small"
|
||||
(wheel)="scrollRelativeTimeRange($event, 'months', 11)"
|
||||
>
|
||||
<mat-label>Months:</mat-label>
|
||||
<input
|
||||
matInput
|
||||
name="relative-time-range-months"
|
||||
[(ngModel)]="relativeTimeRange.months"
|
||||
type="number"
|
||||
min="0"
|
||||
max="11"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field
|
||||
class="pdb-form-number-small"
|
||||
(wheel)="scrollRelativeTimeRange($event, 'years', 10)"
|
||||
>
|
||||
<mat-label>Years:</mat-label>
|
||||
<input
|
||||
matInput
|
||||
name="relative-time-range-years"
|
||||
[(ngModel)]="relativeTimeRange.years"
|
||||
type="number"
|
||||
min="0"
|
||||
max="10"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<button mat-button (click)="applyRelativeTimeRange()">Apply</button>
|
||||
</mat-tab>
|
||||
<mat-tab label="Absolute">
|
||||
<form [formGroup]="dateRangeFormGroup">
|
||||
<mat-form-field class="date-picker-form-field">
|
||||
<mat-label>Date Range:</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[formControl]="dateRangeFormGroup.controls.dateRange"
|
||||
name="dates"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<button mat-button (click)="applyAbsoluteTime()">Apply</button>
|
||||
</form>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
</div>
|
||||
</ng-template>
|
||||
107
pdb-js/src/app/components/datepicker/date-picker.component.ts
Normal file
107
pdb-js/src/app/components/datepicker/date-picker.component.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { FormControl, FormGroup, Validators } from "@angular/forms";
|
||||
|
||||
export type DateType = "quick" | "relative" | "absolute";
|
||||
|
||||
export type DateValue = { type: DateType; value: string; display: string };
|
||||
|
||||
@Component({
|
||||
selector: "app-date-picker",
|
||||
templateUrl: "./date-picker.component.html",
|
||||
})
|
||||
export class DatePickerComponent {
|
||||
isOpen = false;
|
||||
|
||||
relativeTimeRangeUnit = "relativeTimeRangeMinutes";
|
||||
|
||||
relativeTimeRangeAmount = 15;
|
||||
|
||||
relativeTimeRange = {
|
||||
seconds: 0,
|
||||
minutes: 15,
|
||||
hours: 0,
|
||||
days: 0,
|
||||
months: 0,
|
||||
years: 0,
|
||||
};
|
||||
|
||||
dateRangeFormGroup = new FormGroup({
|
||||
dateRange: new FormControl<string>(
|
||||
"2019-10-05 00:00:00 - 2019-10-11 23:59:59",
|
||||
[
|
||||
Validators.pattern(
|
||||
/^\d{4}-\d{2}-\d{2} ([01][0-9]|2[0-3]):\d{2}:\d{2} - \d{4}-\d{2}-\d{2} ([01][0-9]|2[0-3]):\d{2}:\d{2}$/,
|
||||
),
|
||||
],
|
||||
),
|
||||
});
|
||||
|
||||
dateValue: DateValue = {
|
||||
type: "quick",
|
||||
value: "BM/EM",
|
||||
display: "this month",
|
||||
};
|
||||
|
||||
selectedTabIndex = 0;
|
||||
|
||||
constructor() {}
|
||||
|
||||
dateDisplay(): string {
|
||||
return this.dateValue.value;
|
||||
}
|
||||
|
||||
tabChange() {
|
||||
//(<any> window).initSimpleDatePicker(); // breaks form control
|
||||
}
|
||||
|
||||
applyQuick(value: string, display: string) {
|
||||
this.dateValue.type = "quick";
|
||||
this.dateValue.value = value;
|
||||
this.dateValue.display = display;
|
||||
this.isOpen = false;
|
||||
}
|
||||
|
||||
private fixToRange(val: number, min: number, max: number) {
|
||||
return val < min ? min : (val > max ? max : val);
|
||||
}
|
||||
|
||||
applyRelativeTimeRange() {
|
||||
const x = this.relativeTimeRange;
|
||||
const years = x.years ? x.years + "Y" : "";
|
||||
const months = x.months ? x.months + "M" : "";
|
||||
const days = x.days ? x.days + "D" : "";
|
||||
const time = x.hours || x.minutes || x.seconds ? "T" : "";
|
||||
const hours = x.hours ? x.hours + "H" : "";
|
||||
const minutes = x.minutes ? x.minutes + "M" : "";
|
||||
const seconds = x.seconds ? x.seconds + "S" : "";
|
||||
const isoTimeRange =
|
||||
`P${years}${months}${days}${time}${hours}${minutes}${seconds}`;
|
||||
|
||||
this.dateValue.type = "relative";
|
||||
this.dateValue.value = isoTimeRange;
|
||||
this.dateValue.display = isoTimeRange;
|
||||
this.isOpen = false;
|
||||
}
|
||||
|
||||
applyAbsoluteTime() {
|
||||
this.dateValue.type = "absolute";
|
||||
this.dateValue.value = <string> this.dateRangeFormGroup.controls.dateRange
|
||||
.value;
|
||||
this.dateValue.display = <string> this.dateRangeFormGroup.controls.dateRange
|
||||
.value;
|
||||
this.isOpen = false;
|
||||
console.log(this.dateValue);
|
||||
}
|
||||
|
||||
scrollRelativeTimeRange(
|
||||
event: WheelEvent,
|
||||
unit: "seconds" | "minutes" | "hours" | "days" | "months" | "years",
|
||||
max: number,
|
||||
) {
|
||||
this.relativeTimeRange[unit] = this.fixToRange(
|
||||
this.relativeTimeRange[unit] + (event.deltaY > 0 ? -1 : 1),
|
||||
0,
|
||||
max,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user