#1881 Task Calendar Updating View Correctly and Fetching Weeks and Months

This commit is contained in:
Lorenz Hilpert
2021-06-16 15:32:04 +02:00
parent 407d2b0c1c
commit b34babc622
11 changed files with 122 additions and 50 deletions

View File

@@ -1,3 +1,5 @@
<button class="close" type="button"><ui-icon icon="close" size="16px" (click)="close()"></ui-icon></button>
<button class="close" type="button" (click)="close()"><ui-icon icon="close" size="16px"></ui-icon></button>
<h1>Digitale Titelvorschau</h1>
<iframe [src]="src"></iframe>
<div class="iframe-container">
<iframe class="iframe" [src]="src"></iframe>
</div>

View File

@@ -1,10 +1,16 @@
:host {
@apply flex flex-col relative;
@apply grid grid-flow-row relative;
max-width: calc(100vw - 2rem);
max-height: calc(100vw - 2rem);
}
iframe {
@apply w-full;
height: calc(100vh - 8rem);
.iframe-container {
width: 600px;
max-width: 100%;
}
.iframe {
@apply w-full h-full;
}
h1 {
@@ -12,7 +18,7 @@ h1 {
}
button.close {
@apply absolute top-0 right-0 outline-none border-none bg-transparent;
@apply absolute -top-4 -right-4 p-4 outline-none border-none bg-transparent;
ui-icon {
@apply text-inactive-branch;

View File

@@ -2,8 +2,8 @@
mode="month"
[selected]="selectedDate$ | async"
[displayed]="displayedDate$ | async"
[minDate]="minDate$ | async"
[maxDate]="maxDate$ | async"
[minDate]="minDate"
[maxDate]="maxDate"
[indicators]="indicators$ | async"
(selectedChange)="setSelectedDate($event)"
(displayedChange)="setDisplayedDate($event)"

View File

@@ -1,5 +1,6 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { DateAdapter } from '@ui/common';
import { TaskCalendarStore } from '../../task-calendar.store';
@Component({
@@ -8,18 +9,30 @@ import { TaskCalendarStore } from '../../task-calendar.store';
styleUrls: ['calendar.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CalendarComponent {
export class CalendarComponent implements OnInit {
readonly selectedDate$ = this.taskCalendarStore.selectSelectedDate;
readonly displayedDate$ = this.taskCalendarStore.selectDisplayedDate;
readonly indicators$ = this.taskCalendarStore.selectCalendarIndicators;
readonly minDate$ = this.taskCalendarStore.selectMinDate;
readonly minDate = this.dateAdapter.addCalendarMonths(this.dateAdapter.today(), -6);
readonly maxDate$ = this.taskCalendarStore.selectMaxDate;
readonly maxDate = this.dateAdapter.addCalendarMonths(this.dateAdapter.today(), 6);
constructor(private taskCalendarStore: TaskCalendarStore, private activatedRoute: ActivatedRoute, private router: Router) {
constructor(
private taskCalendarStore: TaskCalendarStore,
private activatedRoute: ActivatedRoute,
private router: Router,
private dateAdapter: DateAdapter
) {}
ngOnInit() {
if (this.activatedRoute.snapshot.queryParams.date) {
this.setDisplayedDate(new Date(this.activatedRoute.snapshot.queryParams.date));
}
this.taskCalendarStore.setMode({ mode: 'month' });
this.taskCalendarStore.loadItems();
}
@@ -31,5 +44,11 @@ export class CalendarComponent {
});
};
setDisplayedDate = (date: Date) => this.taskCalendarStore.setDisplayedDate({ date });
setDisplayedDate = (date: Date) => {
this.taskCalendarStore.setDisplayedDate({ date });
this.taskCalendarStore.loadItems();
this.router.navigate([], {
queryParams: { date },
});
};
}

View File

@@ -2,8 +2,8 @@
mode="week"
[selected]="selectedDate$ | async"
[displayed]="displayedDate$ | async"
[minDate]="minDate$ | async"
[maxDate]="maxDate$ | async"
[minDate]="minDate"
[maxDate]="maxDate"
[indicators]="indicators$ | async"
(selectedChange)="setSelectedDate($event)"
(displayedChange)="setDisplayedDate($event)"

View File

@@ -1,5 +1,7 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { DisplayInfoDTO } from '@swagger/eis';
import { DateAdapter } from '@ui/common';
import { TaskCalendarStore } from '../../task-calendar.store';
@Component({
@@ -8,7 +10,7 @@ import { TaskCalendarStore } from '../../task-calendar.store';
styleUrls: ['tasks.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TasksComponent {
export class TasksComponent implements OnInit {
readonly selectedDate$ = this.taskCalendarStore.selectSelectedDate;
readonly displayedDate$ = this.taskCalendarStore.selectDisplayedDate;
@@ -17,18 +19,37 @@ export class TasksComponent {
readonly items$ = this.taskCalendarStore.selectDisplayInfos;
readonly minDate$ = this.taskCalendarStore.selectMinDate;
readonly minDate = this.dateAdapter.addCalendarMonths(this.dateAdapter.today(), -6);
readonly maxDate$ = this.taskCalendarStore.selectMaxDate;
readonly maxDate = this.dateAdapter.addCalendarMonths(this.dateAdapter.today(), 6);
constructor(private taskCalendarStore: TaskCalendarStore) {}
constructor(
private taskCalendarStore: TaskCalendarStore,
private router: Router,
private activatedRoute: ActivatedRoute,
private dateAdapter: DateAdapter
) {}
ngOnInit() {
if (this.activatedRoute.snapshot.queryParams.date) {
this.setDisplayedDate(new Date(this.activatedRoute.snapshot.queryParams.date));
}
this.taskCalendarStore.setMode({ mode: 'week' });
this.taskCalendarStore.loadItems();
}
setSelectedDate = (date: Date) => {
this.taskCalendarStore.setSelectedDate({ date });
this.taskCalendarStore.setDisplayedDate({ date });
};
setDisplayedDate = (date: Date) => this.taskCalendarStore.setDisplayedDate({ date });
setDisplayedDate = (date: Date) => {
this.taskCalendarStore.setDisplayedDate({ date });
this.taskCalendarStore.loadItems();
this.router.navigate([], {
queryParams: { date },
});
};
open(item: DisplayInfoDTO) {
this.taskCalendarStore.open(item);

View File

@@ -7,18 +7,17 @@ import { CalendarIndicator } from '@ui/calendar';
import { DateAdapter } from '@ui/common';
import { Filter, FilterOption, SelectFilter, UiFilterMappingService } from '@ui/filter';
import { UiMessageModalComponent, UiModalService } from '@ui/modal';
import { Observable } from 'rxjs';
import { debounceTime, switchMap, withLatestFrom } from 'rxjs/operators';
import { combineLatest, Observable } from 'rxjs';
import { debounceTime, distinctUntilChanged, switchMap, withLatestFrom } from 'rxjs/operators';
import { InfoModalComponent } from './modals/info/info-modal.component';
import { PreInfoModalComponent } from './modals/preinfo/preinfo-modal.component';
import { TaskModalComponent } from './modals/task/task-modal.component';
export interface TaskCalendarState {
mode: 'week' | 'month';
selectedDate: Date;
displayedDate: Date;
displayInfos: DisplayInfoDTO[];
minDate: Date;
maxDate: Date;
initialFilter: Filter[];
filter: Filter[];
}
@@ -35,10 +34,6 @@ export class TaskCalendarStore extends ComponentStore<TaskCalendarState> {
readonly selectedCalendarWeek = this.select(this.selectSelectedDate, (selectedDate) => this.dateAdapter.getCalendarWeek(selectedDate));
readonly selectMinDate = this.select((s) => s.minDate);
readonly selectMaxDate = this.select((s) => s.maxDate);
readonly selectDisplayInfos = this.select((s) => s.displayInfos);
readonly selectCalendarIndicators = this.select(this.selectDisplayInfos, (displayItems) =>
@@ -55,6 +50,30 @@ export class TaskCalendarStore extends ComponentStore<TaskCalendarState> {
readonly selectFilter = this.select((s) => s.filter);
readonly selectStartStop = this.select((s) => {
const { mode, displayedDate } = s;
if (mode === 'week') {
const fdow = this.dateAdapter.getFirstDateOfWeek(displayedDate);
const withOffset = this.dateAdapter.addCalendarDays(fdow, -7);
const ldow = this.dateAdapter.getLastDateOfWeek(displayedDate);
return {
start: withOffset,
stop: ldow,
};
} else {
const fdom = this.dateAdapter.getFirstDateOfMonth(displayedDate);
const withOffset = this.dateAdapter.addCalendarDays(fdom, -7);
const ldom = this.dateAdapter.getLastDateOfMonth(displayedDate);
return {
start: withOffset,
stop: ldom,
};
}
});
constructor(
private dateAdapter: DateAdapter,
private domainTaskCalendarService: DomainTaskCalendarService,
@@ -62,11 +81,10 @@ export class TaskCalendarStore extends ComponentStore<TaskCalendarState> {
private uiFilterMappingService: UiFilterMappingService
) {
super({
mode: 'month',
selectedDate: dateAdapter.today(),
displayedDate: dateAdapter.today(),
displayInfos: [],
minDate: dateAdapter.addCalendarMonths(dateAdapter.today(), -6),
maxDate: dateAdapter.addCalendarMonths(dateAdapter.today(), 6),
initialFilter: [],
filter: [],
});
@@ -87,16 +105,21 @@ export class TaskCalendarStore extends ComponentStore<TaskCalendarState> {
filter: filters,
}));
readonly setMode = this.updater((s, { mode }: { mode: 'week' | 'month' }) => ({
...s,
mode,
}));
readonly loadItems = this.effect(($: Observable<void>) =>
$.pipe(
debounceTime(250),
withLatestFrom(this.domainTaskCalendarService.currentBranchId$, this.selectMinDate, this.selectMaxDate, this.selectFilter),
switchMap(([_, branchId, start, stop, filter]) =>
debounceTime(500),
withLatestFrom(this.domainTaskCalendarService.currentBranchId$, this.selectStartStop, this.selectFilter),
switchMap(([_, branchId, date, filter]) =>
this.domainTaskCalendarService
.getInfos({
filter: {
branch_id: String(branchId),
timespan: `"${start?.toISOString()}"-"${stop?.toISOString()}"`,
timespan: `"${date?.start?.toISOString()}"-"${date.stop?.toISOString()}"`,
...this.mapFilterArrayToStringDictionary(filter),
},
})

View File

@@ -17,14 +17,4 @@ export class AppConfiguration {
useMock: false;
endpoints: { [key: string]: string };
};
taskCalendarModuleOptions: {
useMock: false;
endpoints: { [key: string]: string };
};
taskCalendarConfig: {
monthsOffset: number;
weeksOffset: number;
};
}

View File

@@ -52,7 +52,7 @@ export class UiCalendarComponent {
}
}
@Input()
@Output()
displayedChange = new EventEmitter<Date>();
@Input()

View File

@@ -24,6 +24,8 @@ export abstract class DateAdapter<TDate = Date> {
abstract getCalendarWeeksForMonth(date: TDate): number[];
abstract getCalendarWeek(date: TDate): number;
abstract getMonthForCalendarWeek(year: number, week: number): number;
abstract getStartOfTheDay(date: Date): Date;
abstract getEndOfTheDay(date: Date): Date;
compareDate(first: TDate, second: TDate) {
if (isNullOrUndefined(first) || isNullOrUndefined(second)) {

View File

@@ -46,14 +46,14 @@ export class NativeDateAdapter extends DateAdapter<Date> {
const clone = new Date(date);
const day = clone.getDay();
const diff = clone.getDate() - day + (day === 0 ? -6 : 1); // Start of Week = Monday
return new Date(clone.setDate(diff));
return this.getStartOfTheDay(new Date(clone.setDate(diff)));
}
getLastDateOfWeek(date: Date): Date {
const clone = new Date(date);
const day = clone.getDay();
const diff = clone.getDate() - day + (day === 0 ? 0 : 7); // End of Week = Sunday
return new Date(clone.setDate(diff));
return this.getEndOfTheDay(new Date(clone.setDate(diff)));
}
getFirstDateOfMonth(date: Date) {
@@ -72,6 +72,15 @@ export class NativeDateAdapter extends DateAdapter<Date> {
return date.getDay();
}
getStartOfTheDay(date: Date) {
return this.createDate(date?.getFullYear(), date?.getMonth(), date?.getDate());
}
getEndOfTheDay(date: Date) {
const nextDate = this.createDate(date?.getFullYear(), date?.getMonth(), date?.getDate() + 1);
return new Date(nextDate.getTime() - 1);
}
createDate(year: number, month: number, date: number): Date {
const result = new Date(year, month, date);
// abbreviations for 19xx.