Skip to content

Commit dae56da

Browse files
Update projects
1 parent 253f018 commit dae56da

36 files changed

+1164
-1082
lines changed

Angular/src/app/app.component.html

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1-
<div class="default-style">
2-
<dx-button [text]="buttonText" (onClick)="onClick($event)"></dx-button>
1+
<div id="app-container">
2+
<dx-scheduler
3+
[dataSource]="dataSource"
4+
[views]="views"
5+
[currentView]="currentView"
6+
[currentDate]="currentDate"
7+
[startDayHour]="startDayHour"
8+
[endDayHour]="endDayHour"
9+
[cellDuration]="cellDuration"
10+
[height]="height"
11+
dataCellTemplate="dataCellTemplate"
12+
(onAppointmentFormOpening)="onAppointmentFormOpening($event)"
13+
(onAppointmentAdding)="onAppointmentChanging($event)"
14+
(onAppointmentUpdating)="onAppointmentChanging($event)"
15+
>
16+
<div
17+
*dxTemplate="let dataCell of 'dataCellTemplate'"
18+
[ngClass]="{
19+
dinner: isDinner(dataCell.startDate, dataCell.endDate),
20+
holiday: isHoliday(dataCell.startDate, dataCell.endDate)
21+
}"
22+
>
23+
{{ getCellText(dataCell) }}
24+
</div>
25+
</dx-scheduler>
326
</div>

Angular/src/app/app.component.scss

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,39 @@
1-
.default-style {
2-
margin: 50px;
3-
width: 90vw;
1+
#app-container {
2+
position: relative;
3+
width: 900px;
4+
margin: 50px auto;
5+
padding: 20px;
6+
border: 1px solid #ddd;
7+
}
8+
9+
.holiday,
10+
.dinner {
11+
height: 100%;
12+
width: 100%;
13+
z-index: 1;
14+
font-size: xx-large;
15+
font-weight: 600;
16+
-webkit-text-stroke-width: 1px;
17+
-webkit-text-stroke-color: white;
18+
text-align: center;
19+
}
20+
21+
::ng-deep .dinner {
22+
background-image: repeating-linear-gradient(
23+
65deg,
24+
rgb(170 147 19 / 30%),
25+
rgb(170 147 19 / 30%) 4px,
26+
transparent 4px,
27+
transparent 9px
28+
);
29+
}
30+
31+
::ng-deep .holiday {
32+
background-image: repeating-linear-gradient(
33+
135deg,
34+
rgb(244 67 54 / 10%),
35+
rgb(244 67 54 / 10%) 4px,
36+
transparent 4px,
37+
transparent 9px
38+
);
439
}

Angular/src/app/app.component.ts

Lines changed: 196 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,209 @@
11
import { Component } from '@angular/core';
2-
import { ClickEvent } from 'devextreme/ui/button';
2+
import notify from 'devextreme/ui/notify';
3+
import { DxSchedulerTypes } from 'devextreme-angular/ui/scheduler';
4+
import {
5+
AppointmentData,
6+
Holiday,
7+
DinnerTime,
8+
SchedulerView,
9+
DataCellTemplate,
10+
} from './app.types';
311

412
@Component({
513
selector: 'app-root',
614
templateUrl: './app.component.html',
715
styleUrls: ['./app.component.scss'],
816
})
917
export class AppComponent {
10-
title = 'Angular';
18+
dataSource: AppointmentData[] = [
19+
{
20+
text: 'Website Re-Design Plan',
21+
startDate: new Date(2021, 4, 5, 9, 30),
22+
endDate: new Date(2021, 4, 5, 11, 30),
23+
},
24+
{
25+
text: 'Install New Router in Dev Room',
26+
startDate: new Date(2021, 4, 6, 13),
27+
endDate: new Date(2021, 4, 6, 14),
28+
},
29+
{
30+
text: 'Approve Personal Computer Upgrade Plan',
31+
startDate: new Date(2021, 4, 3, 10),
32+
endDate: new Date(2021, 4, 3, 11),
33+
},
34+
{
35+
text: 'Final Budget Review',
36+
startDate: new Date(2021, 4, 5, 13, 30),
37+
endDate: new Date(2021, 4, 5, 15),
38+
},
39+
{
40+
text: 'New Brochures',
41+
startDate: new Date(2021, 4, 6, 15),
42+
endDate: new Date(2021, 4, 6, 16, 15),
43+
},
44+
{
45+
text: 'Install New Database',
46+
startDate: new Date(2021, 4, 3, 9, 45),
47+
endDate: new Date(2021, 4, 3, 12),
48+
},
49+
{
50+
text: 'Approve New Online Marketing Strategy',
51+
startDate: new Date(2021, 4, 3, 14, 30),
52+
endDate: new Date(2021, 4, 3, 16, 30),
53+
},
54+
{
55+
text: 'Upgrade Personal Computers',
56+
startDate: new Date(2021, 4, 6, 15, 30),
57+
endDate: new Date(2021, 4, 6, 16, 45),
58+
},
59+
{
60+
text: 'Prepare 2021 Marketing Plan',
61+
startDate: new Date(2021, 4, 3, 13),
62+
endDate: new Date(2021, 4, 3, 15),
63+
},
64+
{
65+
text: 'Brochure Design Review',
66+
startDate: new Date(2021, 5, 1, 15, 30),
67+
endDate: new Date(2021, 5, 2),
68+
},
69+
{
70+
text: 'Create Icons for Website',
71+
startDate: new Date(2021, 4, 5, 10),
72+
endDate: new Date(2021, 4, 5, 11),
73+
},
74+
{
75+
text: 'Upgrade Server Hardware',
76+
startDate: new Date(2021, 4, 5, 16, 30),
77+
endDate: new Date(2021, 4, 5, 18),
78+
},
79+
{
80+
text: 'Launch New Website',
81+
startDate: new Date(2021, 4, 5, 14, 30),
82+
endDate: new Date(2021, 4, 5, 16, 10),
83+
},
84+
];
1185

12-
counter = 0;
86+
currentDate: Date = new Date(2021, 4, 3);
1387

14-
buttonText = 'Click count: 0';
88+
views: SchedulerView[] = [
89+
{
90+
type: 'timelineDay',
91+
intervalCount: 3,
92+
},
93+
];
1594

16-
onClick(e: ClickEvent): void {
17-
this.counter++;
18-
this.buttonText = `Click count: ${this.counter}`;
95+
currentView = 'timelineDay';
96+
97+
startDayHour = 9;
98+
99+
endDayHour = 19;
100+
101+
cellDuration = 60;
102+
103+
height = 600;
104+
105+
private readonly dinnerTime: DinnerTime = { start: 12, end: 13 };
106+
107+
private readonly holiday: Holiday = {
108+
date: new Date(2021, 4, 4),
109+
name: 'Star Wars Day',
110+
};
111+
112+
isHoliday(startDate: Date, endDate: Date): boolean {
113+
return (
114+
this.holiday.date.toLocaleDateString() === startDate.toLocaleDateString()
115+
&& this.holiday.date.toLocaleDateString() === endDate.toLocaleDateString()
116+
);
117+
}
118+
119+
hasIntersection(startA: number, endA: number, startB: number, endB: number): boolean {
120+
if (
121+
(startA <= startB && endB <= endA)
122+
|| (startB <= startA && endA <= endB)
123+
) {
124+
return true;
125+
}
126+
127+
return (
128+
(startA < startB && startB < endA)
129+
|| (startA < endB && endB < endA)
130+
);
131+
}
132+
133+
isDinner(startDate: Date, endDate: Date): boolean {
134+
const todayDinnerStart = new Date(startDate).setHours(this.dinnerTime.start, 0, 0, 0);
135+
const todayDinnerEnd = new Date(endDate).setHours(this.dinnerTime.end, 0, 0, 0);
136+
137+
return this.hasIntersection(
138+
todayDinnerStart,
139+
todayDinnerEnd,
140+
startDate.getTime(),
141+
endDate.getTime(),
142+
);
143+
}
144+
145+
onAppointmentChanging(e: any): void {
146+
const startDate = e.appointmentData
147+
? new Date(e.appointmentData.startDate)
148+
: new Date(e.newData.startDate);
149+
150+
const endDate = e.appointmentData
151+
? new Date(e.appointmentData.endDate)
152+
: new Date(e.newData.endDate);
153+
154+
if (!this.isValidAppointmentDate(startDate, endDate)) {
155+
e.cancel = true;
156+
this.notifyDisableDate();
157+
}
158+
}
159+
160+
onAppointmentFormOpening(e: any): void {
161+
const startDate = new Date(e.appointmentData.startDate);
162+
const endDate = new Date(e.appointmentData.endDate);
163+
164+
if (!this.isValidAppointmentDate(startDate, endDate)) {
165+
e.cancel = true;
166+
this.notifyDisableDate();
167+
}
168+
this.applyDisableDatesToDateEditors(e.form);
169+
}
170+
171+
isValidAppointmentDate(startDate: Date, endDate: Date): boolean {
172+
return !this.isHoliday(startDate, endDate) && !this.isDinner(startDate, endDate);
173+
}
174+
175+
applyDisableDatesToDateEditors(form: any): void {
176+
const holidayDate = this.holiday.date;
177+
178+
const startDateEditor = form.getEditor('startDate');
179+
startDateEditor.option('disabledDates', [holidayDate]);
180+
181+
const endDateEditor = form.getEditor('endDate');
182+
endDateEditor.option('disabledDates', [holidayDate]);
183+
}
184+
185+
getCellText(cell: DataCellTemplate): string {
186+
const startDate = cell.startDate;
187+
const endDate = cell.endDate;
188+
189+
const isHolidayCell = this.isHoliday(startDate, endDate);
190+
const isDinnerCell = this.isDinner(startDate, endDate);
191+
192+
if (isHolidayCell) {
193+
return this.holiday.name;
194+
}
195+
if (isDinnerCell) {
196+
return 'Dinner Time';
197+
}
198+
199+
return cell.text;
200+
}
201+
202+
notifyDisableDate(): void {
203+
notify(
204+
'Cannot create or move an appointment/event to disabled time/date regions.',
205+
'warning',
206+
2000,
207+
);
19208
}
20209
}

Angular/src/app/app.module.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { NgModule } from '@angular/core';
22
import { BrowserModule } from '@angular/platform-browser';
3-
import { DxButtonModule } from 'devextreme-angular/ui/button';
3+
import { DxSchedulerModule } from 'devextreme-angular/ui/scheduler';
4+
import { DxTemplateModule } from 'devextreme-angular/core';
45
import { AppRoutingModule } from './app-routing.module';
56
import { AppComponent } from './app.component';
67

@@ -11,7 +12,8 @@ import { AppComponent } from './app.component';
1112
imports: [
1213
BrowserModule,
1314
AppRoutingModule,
14-
DxButtonModule,
15+
DxSchedulerModule,
16+
DxTemplateModule,
1517
],
1618
providers: [],
1719
bootstrap: [AppComponent],

Angular/src/app/app.types.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
export interface AppointmentData {
2+
text: string;
3+
startDate: Date;
4+
endDate: Date;
5+
}
6+
7+
export interface Holiday {
8+
date: Date;
9+
name: string;
10+
}
11+
12+
export interface DinnerTime {
13+
start: number;
14+
end: number;
15+
}
16+
17+
export interface SchedulerView {
18+
type: string;
19+
intervalCount: number;
20+
}
21+
22+
export interface DataCellTemplate {
23+
startDate: Date;
24+
endDate: Date;
25+
text: string;
26+
}

Angular/src/app/orig_app.component.css

Lines changed: 0 additions & 18 deletions
This file was deleted.

Angular/src/app/orig_app.component.html

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)