Skip to content

Commit

Permalink
Added Apply Pipe (#2786)
Browse files Browse the repository at this point in the history
* Added Apply Pipe

* Fix lint

* Update mark up to remove large conditions

* Minor types fixes
  • Loading branch information
dxArtemiusz authored Sep 6, 2023
1 parent b335d13 commit aa03504
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,30 @@
<div
*dxTemplate="let dataCell of 'dataCellTemplate'"
[ngClass]="{
'disable-date': isDisableDate(dataCell.startDate),
'disable-date': (isDisableDate | apply : dataCell.startDate),
dinner:
!isDisableDate(dataCell.startDate) && isDinner(dataCell.startDate),
'dx-scheduler-date-table-cell-text': isMonthView()
!(isDisableDate | apply : dataCell.startDate) &&
(isDinner | apply : dataCell.startDate),
'dx-scheduler-date-table-cell-text': currentView === 'month'
}"
>
{{ isMonthView() ? dataCell.startDate.getDate() : "" }}
{{ currentView === "month" ? (dataCell.startDate | date) : "" }}
</div>

<div
*dxTemplate="let dateCell of 'dateCellTemplate'"
[ngClass]="{ 'disable-date': isDisabledDateCell(dateCell.date) }"
[ngClass]="{
'disable-date': (isDisabledDateCell | apply : dateCell.date)
}"
>
{{ dateCell.text }}
</div>

<div
*dxTemplate="let timeCell of 'timeCellTemplate'"
[ngClass]="{ dinner: isDinner(timeCell.date) }"
[ngClass]="{ dinner: isDinner | apply : timeCell.date }"
>
{{ timeCell.text }}
<div *ngIf="hasCoffeeCupIcon(timeCell.date)" class="cafe"></div>
<div *ngIf="hasCoffeeCupIcon | apply : timeCell.date" class="cafe"></div>
</div>
</dx-scheduler>
98 changes: 48 additions & 50 deletions JSDemos/Demos/Scheduler/CellTemplates/Angular/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import { NgModule, Component, enableProdMode } from '@angular/core';
import {
NgModule, Component, enableProdMode, Pipe, PipeTransform,
} from '@angular/core';
import { BrowserModule, BrowserTransferStateModule } from '@angular/platform-browser';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { DxSchedulerModule, DxTemplateModule } from 'devextreme-angular';

import {
OptionChangedEvent, AppointmentFormOpeningEvent, AppointmentAddingEvent, AppointmentUpdatingEvent,
} from 'devextreme/ui/scheduler';
import DataSource from 'devextreme/data/data_source';
import notify from 'devextreme/ui/notify';
import { DataService } from './app.service';

@Pipe({ name: 'apply' })
export class ApplyPipe<TArgs, TReturn> implements PipeTransform {
transform(func: ((...args: TArgs[]) => TReturn), ...args: TArgs[]): TReturn { return func(...args); }
}

if (!/localhost/.test(document.location.host)) {
enableProdMode();
}
Expand All @@ -20,6 +29,10 @@ if (!/localhost/.test(document.location.host)) {
export class AppComponent {
dataSource: DataSource;

dinnerTime = this.dataService.getDinnerTime();

holidays = this.dataService.getHolidays();

currentDate = new Date(2021, 3, 27);

views = ['workWeek', 'month'];
Expand All @@ -32,88 +45,75 @@ export class AppComponent {
});
}

onOptionChanged(e: any) {
onOptionChanged = (e: OptionChangedEvent) => {
if (e.name === 'currentView') {
this.currentView = e.value;
}
}
};

onAppointmentFormOpening(e: any) {
const startDate = e.appointmentData.startDate;
onAppointmentFormOpening = (e: AppointmentFormOpeningEvent) => {
const startDate = e.appointmentData.startDate as Date;
if (!this.isValidAppointmentDate(startDate)) {
e.cancel = true;
this.notifyDisableDate();
}
this.applyDisableDatesToDateEditors(e.form);
}
};

onAppointmentAdding(e: any) {
onAppointmentAdding = (e: AppointmentAddingEvent) => {
const isValidAppointment = this.isValidAppointment(e.component, e.appointmentData);
if (!isValidAppointment) {
e.cancel = true;
this.notifyDisableDate();
}
}
};

onAppointmentUpdating(e: any) {
onAppointmentUpdating = (e: AppointmentUpdatingEvent) => {
const isValidAppointment = this.isValidAppointment(e.component, e.newData);
if (!isValidAppointment) {
e.cancel = true;
this.notifyDisableDate();
}
}
};

notifyDisableDate() {
notifyDisableDate = () => {
notify('Cannot create or move an appointment/event to disabled time/date regions.', 'warning', 1000);
}
};

isHoliday(date: Date) {
isHoliday = (date: Date) => {
const localeDate = date.toLocaleDateString();
const holidays = this.dataService.getHolidays();
return holidays.filter((holiday) => holiday.toLocaleDateString() === localeDate).length > 0;
}
return this.holidays.filter((holiday) => holiday.toLocaleDateString() === localeDate).length > 0;
};

isWeekend(date: Date) {
isWeekend = (date: Date) => {
const day = date.getDay();
return day === 0 || day === 6;
}
};

isDisableDate(date: Date) {
return this.isHoliday(date) || this.isWeekend(date);
}
isDinner = (date: Date) => {
const hours = date.getHours();
return hours >= this.dinnerTime.from && hours < this.dinnerTime.to;
};

isDisabledDateCell(date: Date) {
return this.isMonthView()
? this.isWeekend(date)
: this.isDisableDate(date);
}
isDisableDate = (date: Date) => this.isHoliday(date) || this.isWeekend(date);

isDinner(date: Date) {
const hours = date.getHours();
const dinnerTime = this.dataService.getDinnerTime();
return hours >= dinnerTime.from && hours < dinnerTime.to;
}
isDisabledDateCell = (date: Date) => (this.currentView === 'month' ? this.isWeekend(date) : this.isDisableDate(date));

hasCoffeeCupIcon(date: Date) {
hasCoffeeCupIcon = (date: Date) => {
const hours = date.getHours();
const minutes = date.getMinutes();
const dinnerTime = this.dataService.getDinnerTime();

return hours === dinnerTime.from && minutes === 0;
}

isMonthView() {
return this.currentView === 'month';
}
return hours === this.dinnerTime.from && minutes === 0;
};

isValidAppointment(component: any, appointmentData: any) {
isValidAppointment = (component: any, appointmentData: any) => {
const startDate = new Date(appointmentData.startDate);
const endDate = new Date(appointmentData.endDate);
const cellDuration = component.option('cellDuration');
return this.isValidAppointmentInterval(startDate, endDate, cellDuration);
}
};

isValidAppointmentInterval(startDate: Date, endDate: Date, cellDuration: number) {
isValidAppointmentInterval = (startDate: Date, endDate: Date, cellDuration: number) => {
const edgeEndDate = new Date(endDate.getTime() - 1);

if (!this.isValidAppointmentDate(edgeEndDate)) {
Expand All @@ -131,20 +131,18 @@ export class AppComponent {
}

return true;
}
};

isValidAppointmentDate(date: Date) {
return !this.isHoliday(date) && !this.isDinner(date) && !this.isWeekend(date);
}
isValidAppointmentDate = (date: Date) => !this.isHoliday(date) && !this.isDinner(date) && !this.isWeekend(date);

applyDisableDatesToDateEditors(form: any) {
applyDisableDatesToDateEditors = (form: any) => {
const holidays = this.dataService.getHolidays();
const startDateEditor = form.getEditor('startDate');
startDateEditor.option('disabledDates', holidays);

const endDateEditor = form.getEditor('endDate');
endDateEditor.option('disabledDates', holidays);
}
};
}

@NgModule({
Expand All @@ -154,7 +152,7 @@ export class AppComponent {
DxSchedulerModule,
DxTemplateModule,
],
declarations: [AppComponent],
declarations: [AppComponent, ApplyPipe],
bootstrap: [AppComponent],
})
export class AppModule { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
<dxi-resource fieldExpr="movieId" [dataSource]="moviesData"> </dxi-resource>

<div *dxTemplate="let model of 'appointment-template'">
<div class="movie">
<img [src]="getMovieById(model.appointmentData.movieId).image" />
<div class="movie-text">{{
getMovieById(model.appointmentData.movieId).text
}}</div>
</div>
<ng-container
*ngIf="getMovieById | apply : model.appointmentData.movieId as movie"
>
<div class="movie">
<img [src]="movie.image" />
<div class="movie-text">{{ movie.text }}</div>
</div>
</ng-container>
</div>
</dx-scheduler>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
NgModule, ViewChild, Component, enableProdMode,
NgModule, ViewChild, Component, enableProdMode, Pipe, PipeTransform,
} from '@angular/core';
import { BrowserModule, BrowserTransferStateModule } from '@angular/platform-browser';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
Expand All @@ -14,6 +14,11 @@ import {
import Query from 'devextreme/data/query';
import { Appointment, Service, MovieData } from './app.service';

@Pipe({ name: 'apply' })
export class ApplyPipe<TArgs, TReturn> implements PipeTransform {
transform(func: ((...args: TArgs[]) => TReturn), ...args: TArgs[]): TReturn { return func(...args); }
}

if (!/localhost/.test(document.location.host)) {
enableProdMode();
}
Expand Down Expand Up @@ -47,25 +52,23 @@ export class AppComponent {
this.moviesData = service.getMoviesData();
}

onContentReady(e) {
onContentReady = (e) => {
e.component.scrollTo(new Date());
}
};

onAppointmentClick(e) {
onAppointmentClick = (e) => {
e.cancel = true;
}
};

onAppointmentDblClick(e) {
onAppointmentDblClick = (e) => {
e.cancel = true;
}
};

changeIndicatorUpdateInterval(e) {
changeIndicatorUpdateInterval = (e) => {
this.indicatorUpdateInterval = e.value * 1000;
}
};

getMovieById(id) {
return Query(this.moviesData).filter(['id', '=', id]).toArray()[0];
}
getMovieById = (id) => Query(this.moviesData).filter(['id', '=', id]).toArray()[0];
}

@NgModule({
Expand All @@ -77,7 +80,7 @@ export class AppComponent {
DxNumberBoxModule,
DxTemplateModule,
],
declarations: [AppComponent],
declarations: [AppComponent, ApplyPipe],
bootstrap: [AppComponent],
})
export class AppModule { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ <h3>DXCinema Show Times</h3>

<div *dxTemplate="let model of 'appointment-template'">
<div class="showtime-preview">
<div>{{ getMovieById(model.targetedAppointmentData.movieId).text }}</div>
<div>{{
(getMovieById | apply : model.appointmentData.movieId : this).text
}}</div>
<div
>Ticket Price:
<strong>{{ "$" + model.targetedAppointmentData.price }}</strong>
Expand All @@ -51,30 +53,23 @@ <h3>DXCinema Show Times</h3>
</div>

<div *dxTemplate="let model of 'tooltip-template'">
<div class="movie-tooltip">
<img [src]="getMovieById(model.appointmentData.movieId).image" />
<div class="movie-info">
<div class="movie-title">
{{
getMovieById(model.appointmentData.movieId).text +
" (" +
getMovieById(model.appointmentData.movieId).year +
")"
}}
</div>
<div>
{{
"Director: " + getMovieById(model.appointmentData.movieId).director
}}
</div>
<div>
{{
"Duration: " +
getMovieById(model.appointmentData.movieId).duration +
" minutes"
}}
<ng-container
*ngIf="getMovieById | apply : model.appointmentData.movieId as movie"
>
<div class="movie-tooltip">
<img [src]="movie.image" />
<div class="movie-info">
<div class="movie-title">
{{ movie.text + " (" + movie.year + ")" }}
</div>
<div>
{{ "Director: " + movie.director }}
</div>
<div>
{{ "Duration: " + movie.duration + " minutes" }}
</div>
</div>
</div>
</div>
</ng-container>
</div>
</dx-scheduler>
Loading

0 comments on commit aa03504

Please sign in to comment.