Skip to content

Commit ce40b81

Browse files
authored
Scheduler: add scheduler framework toolbar demos (49jbNG3V) (DevExpress#29835)
Co-authored-by: Vladimir Bushmanov <[email protected]>
1 parent b8bea38 commit ce40b81

37 files changed

+1230
-107
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<dx-scheduler
2+
timeZone="America/Los_Angeles"
3+
[dataSource]="dataSource"
4+
[views]="['day', 'week', 'workWeek', 'month']"
5+
currentView="workWeek"
6+
[currentDate]="currentDate"
7+
[startDayHour]="9"
8+
[endDayHour]="19"
9+
[height]="600"
10+
>
11+
<dxi-scheduler-resource
12+
fieldExpr="assigneeId"
13+
label="Assignee"
14+
[allowMultiple]="true"
15+
[dataSource]="assignees"
16+
>
17+
</dxi-scheduler-resource>
18+
<dxo-scheduler-toolbar>
19+
<dxi-scheduler-toolbar-item
20+
location="before"
21+
name="today"
22+
></dxi-scheduler-toolbar-item>
23+
<dxi-scheduler-toolbar-item
24+
location="before"
25+
name="dateNavigator"
26+
></dxi-scheduler-toolbar-item>
27+
<dxi-scheduler-toolbar-item
28+
location="before"
29+
locateInMenu="auto"
30+
widget="dxButton"
31+
[options]="newEventButtonOptions"
32+
>
33+
</dxi-scheduler-toolbar-item>
34+
<dxi-scheduler-toolbar-item location="before" locateInMenu="auto">
35+
<div *dxTemplate>
36+
<dx-select-box
37+
placeholder="Select Employee"
38+
[items]="assignees"
39+
[showClearButton]="true"
40+
displayExpr="text"
41+
valueExpr="id"
42+
[inputAttr]="{ 'aria-label': 'Select Employee' }"
43+
[width]="200"
44+
(onValueChanged)="onAssigneesChange($event)"
45+
>
46+
</dx-select-box>
47+
</div>
48+
</dxi-scheduler-toolbar-item>
49+
<dxi-scheduler-toolbar-item
50+
location="after"
51+
locateInMenu="auto"
52+
name="viewSwitcher"
53+
></dxi-scheduler-toolbar-item>
54+
</dxo-scheduler-toolbar>
55+
</dx-scheduler>
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { NgModule, Component, ViewChild, enableProdMode } from '@angular/core';
2+
import { BrowserModule } from '@angular/platform-browser';
3+
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
4+
import {
5+
DxSchedulerModule,
6+
DxSchedulerComponent,
7+
DxTemplateModule,
8+
DxButtonModule,
9+
} from 'devextreme-angular';
10+
import type { DxButtonTypes } from 'devextreme-angular/ui/button';
11+
import { DxSelectBoxModule, type DxSelectBoxTypes } from 'devextreme-angular/ui/select-box';
12+
import { Service } from './app.service';
13+
14+
const MS_IN_HOUR = 60 * 1000;
15+
16+
if (!/localhost/.test(document.location.host)) {
17+
enableProdMode();
18+
}
19+
20+
let modulePrefix = '';
21+
// @ts-ignore
22+
if (window && window.config?.packageConfigPaths) {
23+
modulePrefix = '/app';
24+
}
25+
26+
@Component({
27+
selector: 'demo-app',
28+
templateUrl: `.${modulePrefix}/app.component.html`,
29+
providers: [Service],
30+
})
31+
export class AppComponent {
32+
@ViewChild(DxSchedulerComponent, { static: true }) scheduler: DxSchedulerComponent;
33+
34+
dataSource = this.service.getAppointmentsDataSource();
35+
36+
assignees = this.service.getAssignees();
37+
38+
currentDate = this.service.getInitialCurrentDate();
39+
40+
newEventButtonOptions: DxButtonTypes.Properties = {
41+
icon: 'plus',
42+
text: 'New Appointment',
43+
stylingMode: 'outlined',
44+
type: 'normal',
45+
onClick: () => { this.onAppointmentAdd(); },
46+
};
47+
48+
constructor(private service: Service) {}
49+
50+
onAppointmentAdd() {
51+
const selected = this.scheduler.instance.option('selectedCellData') ?? [];
52+
53+
if (selected.length) {
54+
const firstSelected = selected[0];
55+
const lastSelected = selected.at(-1);
56+
57+
this.scheduler.instance.showAppointmentPopup({
58+
...firstSelected.groups,
59+
allDay: firstSelected.allDay,
60+
startDate: new Date(firstSelected.startDateUTC),
61+
endDate: new Date(lastSelected.endDateUTC),
62+
}, true);
63+
64+
return;
65+
}
66+
67+
const currentDate = this.scheduler.instance.option('currentDate');
68+
const cellDuration = this.scheduler.instance.option('cellDuration') as number;
69+
const cellDurationMs = cellDuration * MS_IN_HOUR;
70+
const currentTime = new Date(currentDate as Date).getTime();
71+
const roundTime = Math.round(currentTime / cellDurationMs) * cellDurationMs;
72+
73+
this.scheduler.instance.showAppointmentPopup({
74+
startDate: new Date(roundTime),
75+
endDate: new Date(roundTime + cellDurationMs),
76+
}, true);
77+
}
78+
79+
onAssigneesChange(event: DxSelectBoxTypes.ValueChangedEvent) {
80+
const dataSource = this.scheduler.instance.option('dataSource');
81+
const filter = event.value ? ['assigneeId', 'contains', event.value] : null;
82+
83+
dataSource.filter(filter);
84+
this.scheduler.instance.option('dataSource', dataSource);
85+
}
86+
}
87+
88+
@NgModule({
89+
imports: [
90+
BrowserModule,
91+
DxSchedulerModule,
92+
DxTemplateModule,
93+
DxSelectBoxModule,
94+
DxButtonModule,
95+
],
96+
declarations: [AppComponent],
97+
bootstrap: [AppComponent],
98+
})
99+
export class AppModule { }
100+
101+
platformBrowserDynamic().bootstrapModule(AppModule);
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import { Injectable } from '@angular/core';
2+
import DataSource from 'devextreme/data/data_source';
3+
4+
export interface Appointment {
5+
text: string;
6+
startDate: number;
7+
endDate: number;
8+
allDay?: boolean;
9+
assigneeId: number[];
10+
recurrenceRule?: string;
11+
}
12+
13+
export interface Assignee {
14+
id: number;
15+
text: string;
16+
}
17+
18+
const ONE_MONTH_DAYS = 30;
19+
const addDays = (date, days) => new Date(new Date(date).setUTCDate(date.getUTCDate() + days));
20+
const now = new Date(new Date().setUTCHours(0, 0, 0, 0));
21+
const startOfTheWeek = addDays(now, -now.getUTCDay());
22+
const currentDate = addDays(now, ONE_MONTH_DAYS);
23+
const currentStartOfTheWeek = addDays(currentDate, -currentDate.getUTCDay());
24+
const appointments: Appointment[] = [
25+
{
26+
text: 'Website Re-Design Plan',
27+
assigneeId: [4],
28+
startDate: addDays(startOfTheWeek, 1).setUTCHours(16, 30),
29+
endDate: addDays(startOfTheWeek, 1).setUTCHours(18, 30),
30+
}, {
31+
text: 'Book Flights to San Fran for Sales Trip',
32+
assigneeId: [2],
33+
startDate: addDays(startOfTheWeek, 2).setUTCHours(19),
34+
endDate: addDays(startOfTheWeek, 2).setUTCHours(20),
35+
allDay: true,
36+
}, {
37+
text: 'Install New Router in Dev Room',
38+
assigneeId: [1],
39+
startDate: addDays(startOfTheWeek, 2).setUTCHours(21, 30),
40+
endDate: addDays(startOfTheWeek, 2).setUTCHours(22, 30),
41+
}, {
42+
text: 'Approve Personal Computer Upgrade Plan',
43+
assigneeId: [3],
44+
startDate: addDays(startOfTheWeek, 3).setUTCHours(17),
45+
endDate: addDays(startOfTheWeek, 3).setUTCHours(18),
46+
}, {
47+
text: 'Final Budget Review',
48+
assigneeId: [1],
49+
startDate: addDays(startOfTheWeek, 3).setUTCHours(19),
50+
endDate: addDays(startOfTheWeek, 3).setUTCHours(20, 35),
51+
}, {
52+
text: 'New Brochures',
53+
assigneeId: [4],
54+
startDate: addDays(startOfTheWeek, 3).setUTCHours(21, 30),
55+
endDate: addDays(startOfTheWeek, 3).setUTCHours(22, 45),
56+
}, {
57+
text: 'Install New Database',
58+
assigneeId: [2],
59+
startDate: addDays(startOfTheWeek, 4).setUTCHours(16, 45),
60+
endDate: addDays(startOfTheWeek, 4).setUTCHours(18, 15),
61+
}, {
62+
text: 'Approve New Online Marketing Strategy',
63+
assigneeId: [4],
64+
startDate: addDays(currentStartOfTheWeek, 1).setUTCHours(19),
65+
endDate: addDays(currentStartOfTheWeek, 1).setUTCHours(21),
66+
}, {
67+
text: 'Upgrade Personal Computers',
68+
assigneeId: [2],
69+
startDate: addDays(currentStartOfTheWeek, 1).setUTCHours(22, 15),
70+
endDate: addDays(currentStartOfTheWeek, 1).setUTCHours(23, 30),
71+
}, {
72+
text: 'Customer Workshop',
73+
assigneeId: [3],
74+
startDate: addDays(startOfTheWeek, 5).setUTCHours(18),
75+
endDate: addDays(startOfTheWeek, 5).setUTCHours(19),
76+
recurrenceRule: 'FREQ=WEEKLY;INTERVAL=1',
77+
}, {
78+
text: 'Prepare 2021 Marketing Plan',
79+
assigneeId: [1],
80+
startDate: addDays(currentStartOfTheWeek, 2).setUTCHours(18),
81+
endDate: addDays(currentStartOfTheWeek, 2).setUTCHours(20, 30),
82+
}, {
83+
text: 'Brochure Design Review',
84+
assigneeId: [4],
85+
startDate: addDays(startOfTheWeek, 5).setUTCHours(21),
86+
endDate: addDays(startOfTheWeek, 5).setUTCHours(22, 30),
87+
}, {
88+
text: 'Create Icons for Website',
89+
assigneeId: [3],
90+
startDate: addDays(currentStartOfTheWeek, 3).setUTCHours(17),
91+
endDate: addDays(currentStartOfTheWeek, 3).setUTCHours(18, 30),
92+
}, {
93+
text: 'Upgrade Server Hardware',
94+
assigneeId: [4],
95+
startDate: addDays(currentStartOfTheWeek, 2).setUTCHours(16),
96+
endDate: addDays(currentStartOfTheWeek, 2).setUTCHours(17, 30),
97+
}, {
98+
text: 'Submit New Website Design',
99+
assigneeId: [1],
100+
startDate: addDays(currentStartOfTheWeek, 5).setUTCHours(23, 30),
101+
endDate: addDays(currentStartOfTheWeek, 6).setUTCHours(1),
102+
}, {
103+
text: 'Launch New Website',
104+
assigneeId: [2],
105+
startDate: addDays(currentStartOfTheWeek, 4).setUTCHours(19),
106+
endDate: addDays(currentStartOfTheWeek, 4).setUTCHours(21),
107+
},
108+
];
109+
110+
const assignees: Assignee[] = [
111+
{
112+
text: 'Samantha Bright',
113+
id: 1,
114+
}, {
115+
text: 'John Heart',
116+
id: 2,
117+
}, {
118+
text: 'Todd Hoffman',
119+
id: 3,
120+
}, {
121+
text: 'Sandra Johnson',
122+
id: 4,
123+
},
124+
];
125+
126+
@Injectable()
127+
export class Service {
128+
getAppointmentsDataSource(): DataSource {
129+
return new DataSource(appointments);
130+
}
131+
132+
getAssignees(): Assignee[] {
133+
return assignees;
134+
}
135+
136+
getInitialCurrentDate(): Date {
137+
return currentDate;
138+
}
139+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<!DOCTYPE html>
2+
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
3+
<head>
4+
<title>DevExtreme Demo</title>
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" />
8+
<link rel="stylesheet" type="text/css" href="../../../../node_modules/devextreme-dist/css/dx.light.css" />
9+
10+
<script src="../../../../node_modules/core-js/client/shim.min.js"></script>
11+
<script src="../../../../node_modules/zone.js/bundles/zone.umd.js"></script>
12+
<script src="../../../../node_modules/reflect-metadata/Reflect.js"></script>
13+
<script src="../../../../node_modules/systemjs/dist/system.js"></script>
14+
15+
<script src="config.js"></script>
16+
<script>
17+
System.import("app").catch(console.error.bind(console));
18+
</script>
19+
</head>
20+
21+
<body class="dx-viewport">
22+
<div class="demo-container">
23+
<demo-app>Loading...</demo-app>
24+
</div>
25+
</body>
26+
</html>

0 commit comments

Comments
 (0)