Skip to content

Commit 3dd52b1

Browse files
author
Artyom Borisevich
committed
changed class components to functional
1 parent b48095b commit 3dd52b1

File tree

8 files changed

+145
-186
lines changed

8 files changed

+145
-186
lines changed

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@dhx:registry=https://npm.dhtmlx.com/

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
"version": "0.1.0",
44
"private": true,
55
"dependencies": {
6+
"@dhx/trial-scheduler": "^7.0.3",
67
"@testing-library/jest-dom": "^5.16.1",
78
"@testing-library/react": "^12.1.2",
89
"@testing-library/user-event": "^13.5.0",
9-
"dhtmlx-gantt": "^7.1.9",
10-
"dhtmlx-scheduler": "^7.0.2",
1110
"react": "^17.0.2",
1211
"react-dom": "^17.0.2",
1312
"react-scripts": "5.0.0"

src/App.js

Lines changed: 35 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,41 @@
1-
import React, { Component } from 'react';
2-
import Scheduler from './components/Scheduler';
3-
import Toolbar from './components/Toolbar';
4-
import MessageArea from './components/MessageArea';
5-
import './App.css';
1+
import { useState } from "react";
2+
import { getData } from "./data.js";
3+
import Scheduler from "./components/Scheduler";
4+
import Toolbar from "./components/Toolbar";
5+
import MessageArea from "./components/MessageArea";
6+
import "./App.css";
67

7-
const data = [
8-
{ start_date:'2020-06-10 6:00', end_date:'2020-06-10 8:00', text:'Event 1', id: 1},
9-
{ start_date:'2020-06-13 10:00', end_date:'2020-06-13 18:00', text:'Event 2', id: 2 }
10-
];
8+
function App() {
9+
const [currentTimeFormatState, setTimeFormat] = useState(true);
10+
const [messages, setMessages] = useState([]);
1111

12-
class App extends Component {
13-
state = {
14-
currentTimeFormatState: true,
15-
messages: []
16-
};
12+
function addMessage(message) {
13+
setMessages((arr) => [...arr, message]);
14+
}
1715

18-
addMessage(message) {
19-
const maxLogLength = 5;
20-
const newMessage = { message };
21-
const messages = [
22-
newMessage,
23-
...this.state.messages
24-
];
16+
function logDataUpdate(action, ev, id) {
17+
const text = ev && ev.text ? ` (${ev.text})` : "";
18+
const message = `event ${action}: ${id} ${text}`;
19+
addMessage(message);
20+
}
2521

26-
if (messages.length > maxLogLength) {
27-
messages.length = maxLogLength;
28-
}
29-
this.setState({ messages });
30-
}
31-
32-
logDataUpdate = (action, ev, id) => {
33-
const text = ev && ev.text ? ` (${ev.text})` : '';
34-
const message = `event ${action}: ${id} ${text}`;
35-
this.addMessage(message);
36-
}
37-
38-
handleTimeFormatStateChange = (state) => {
39-
this.setState({
40-
currentTimeFormatState: state
41-
});
42-
}
43-
44-
render() {
45-
const { currentTimeFormatState, messages } = this.state;
46-
return (
47-
<div>
48-
<div className="tool-bar">
49-
<Toolbar
50-
timeFormatState={currentTimeFormatState}
51-
onTimeFormatStateChange={this.handleTimeFormatStateChange}
52-
/>
53-
</div>
54-
<div className='scheduler-container'>
55-
<Scheduler
56-
events={data}
57-
timeFormatState={currentTimeFormatState}
58-
onDataUpdated={this.logDataUpdate}
59-
/>
60-
</div>
61-
<MessageArea
62-
messages={messages}
63-
/>
64-
</div>
65-
);
66-
}
22+
return (
23+
<div>
24+
<div className="tool-bar">
25+
<Toolbar
26+
timeFormatState={currentTimeFormatState}
27+
onTimeFormatStateChange={setTimeFormat}
28+
/>
29+
</div>
30+
<div className="scheduler-container">
31+
<Scheduler
32+
events={getData()}
33+
timeFormatState={currentTimeFormatState}
34+
onDataUpdated={logDataUpdate}
35+
/>
36+
</div>
37+
<MessageArea messages={messages} />
38+
</div>
39+
);
6740
}
6841
export default App;
Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,12 @@
1-
import React, { Component } from 'react';
2-
3-
export default class MessageArea extends Component {
4-
render() {
5-
const messages = this.props.messages.map(({ message }) => {
6-
return <li key={ Math.random() }>{message}</li>
7-
});
8-
9-
return (
10-
<div className="message-area">
11-
<h3>Messages:</h3>
12-
<ul>
13-
{ messages }
14-
</ul>
15-
</div>
16-
);
17-
}
1+
export default function MessageArea({ messages }) {
2+
let formattedmessages = messages.map((message) => {
3+
return <li key={Math.random()}>{message}</li>;
4+
});
5+
6+
return (
7+
<div className="message-area">
8+
<h3>Messages:</h3>
9+
<ul>{formattedmessages}</ul>
10+
</div>
11+
);
1812
}
19-
20-
MessageArea.defaultProps = {
21-
messages: []
22-
};

src/components/Scheduler/Scheduler.js

Lines changed: 61 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,62 @@
1-
import React, { Component } from 'react';
2-
import 'dhtmlx-scheduler';
3-
import 'dhtmlx-scheduler/codebase/dhtmlxscheduler.css';
4-
5-
const scheduler = window.scheduler;
6-
7-
export default class Scheduler extends Component {
8-
9-
initSchedulerEvents() {
10-
if (scheduler._$initialized) {
11-
return;
12-
}
13-
14-
const onDataUpdated = this.props.onDataUpdated;
15-
16-
scheduler.attachEvent('onEventAdded', (id, ev) => {
17-
if (onDataUpdated) {
18-
onDataUpdated('create', ev, id);
19-
}
20-
});
21-
22-
scheduler.attachEvent('onEventChanged', (id, ev) => {
23-
if (onDataUpdated) {
24-
onDataUpdated('update', ev, id);
25-
}
26-
});
27-
28-
scheduler.attachEvent('onEventDeleted', (id, ev) => {
29-
if (onDataUpdated) {
30-
onDataUpdated('delete', ev, id);
31-
}
32-
});
33-
scheduler._$initialized = true;
34-
}
35-
36-
componentDidMount() {
37-
scheduler.skin = 'terrace';
38-
scheduler.config.header = [
39-
'day',
40-
'week',
41-
'month',
42-
'date',
43-
'prev',
44-
'today',
45-
'next'
46-
];
47-
scheduler.config.hour_date = '%g:%i %A';
48-
scheduler.xy.scale_width = 70;
49-
50-
this.initSchedulerEvents();
51-
52-
const { events } = this.props;
53-
scheduler.init(this.schedulerContainer, new Date(2020, 5, 10));
54-
scheduler.clearAll();
55-
scheduler.parse(events);
56-
}
57-
58-
shouldComponentUpdate(nextProps) {
59-
return this.props.timeFormatState !== nextProps.timeFormatState;
60-
}
61-
62-
componentDidUpdate() {
63-
scheduler.render();
64-
}
65-
66-
setHoursScaleFormat(state) {
67-
scheduler.config.hour_date = state ? '%H:%i' : '%g:%i %A';
68-
scheduler.templates.hour_scale = scheduler.date.date_to_str(scheduler.config.hour_date);
69-
}
70-
71-
render() {
72-
const { timeFormatState } = this.props;
73-
this.setHoursScaleFormat(timeFormatState);
74-
return (
75-
<div
76-
ref={ (input) => { this.schedulerContainer = input } }
77-
style={ { width: '100%', height: '100%' } }
78-
></div>
79-
);
80-
}
1+
import { useEffect, useRef } from "react";
2+
import { Scheduler } from "@dhx/trial-scheduler";
3+
import "@dhx/trial-scheduler/codebase/dhtmlxscheduler.css";
4+
5+
export default function SchedulerView( {events, timeFormatState, onDataUpdated,} ) {
6+
let container = useRef();
7+
useEffect(() => {
8+
let scheduler = Scheduler.getSchedulerInstance();
9+
10+
scheduler.skin = "terrace";
11+
scheduler.config.header = [
12+
"day",
13+
"week",
14+
"month",
15+
"date",
16+
"prev",
17+
"today",
18+
"next",
19+
];
20+
scheduler.config.hour_date = "%g:%i %A";
21+
scheduler.xy.scale_width = 70;
22+
23+
scheduler.init(container.current, new Date(2024, 5, 10));
24+
scheduler.clearAll();
25+
scheduler.parse(events);
26+
27+
scheduler.attachEvent("onEventAdded", (id, ev) => {
28+
if (onDataUpdated) {
29+
onDataUpdated("create", ev, id);
30+
}
31+
});
32+
33+
scheduler.attachEvent("onEventChanged", (id, ev) => {
34+
if (onDataUpdated) {
35+
onDataUpdated("update", ev, id);
36+
}
37+
});
38+
39+
scheduler.attachEvent("onEventDeleted", (id, ev) => {
40+
if (onDataUpdated) {
41+
onDataUpdated("delete", ev, id);
42+
}
43+
});
44+
45+
function setHoursScaleFormat(state) {
46+
scheduler.config.hour_date = state ? "%H:%i" : "%g:%i %A";
47+
scheduler.templates.hour_scale = scheduler.date.date_to_str(
48+
scheduler.config.hour_date
49+
);
50+
scheduler.render();
51+
}
52+
setHoursScaleFormat(timeFormatState);
53+
return () => {
54+
scheduler.destructor();
55+
container.current.innerHTML = "";
56+
};
57+
}, [timeFormatState]);
58+
59+
return (
60+
<div ref={container} style={{ width: "100%", height: "100%" }}></div>
61+
);
8162
}

src/components/Toolbar/Toolbar.js

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,15 @@
1-
import React, { Component } from 'react';
2-
export default class Toolbar extends Component {
3-
handleTimeFormatStateChange = (e) => {
4-
if (this.props.onTimeFormatStateChange) {
5-
this.props.onTimeFormatStateChange(e.target.checked)
6-
}
7-
}
8-
render() {
9-
return (
10-
<div className='time-format-section'>
11-
<label className='time-format-chkbx'>
12-
Time format:
13-
<input type='checkbox'
14-
checked={ this.props.timeFormatState }
15-
onChange={ this.handleTimeFormatStateChange }
16-
/>
17-
<div className='chkbx-text'></div>
18-
</label>
19-
</div>
20-
);
21-
}
1+
export default function Toolbar({ timeFormatState, onTimeFormatStateChange }) {
2+
return (
3+
<div className="time-format-section">
4+
<label className="time-format-chkbx">
5+
Time format:
6+
<input
7+
type="checkbox"
8+
checked={timeFormatState}
9+
onChange={(e) => onTimeFormatStateChange(e.target.checked)}
10+
/>
11+
<div className="chkbx-text"></div>
12+
</label>
13+
</div>
14+
);
2215
}

src/data.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export function getData() {
2+
const data = [
3+
{
4+
start_date: "2024-06-10 6:00",
5+
end_date: "2024-06-10 8:00",
6+
text: "Event 1",
7+
id: 1,
8+
},
9+
{
10+
start_date: "2024-06-13 10:00",
11+
end_date: "2024-06-13 18:00",
12+
text: "Event 2",
13+
id: 2,
14+
},
15+
];
16+
return data;
17+
}

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,11 @@
10651065
resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-12.0.0.tgz#a9583a75c3f150667771f30b60d9f059473e62c4"
10661066
integrity sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg==
10671067

1068+
"@dhx/trial-scheduler@^7.0.3":
1069+
version "7.0.3"
1070+
resolved "https://npm.dhtmlx.com/@dhx%2ftrial-scheduler/-/trial-scheduler-7.0.3.tgz#1fdb0fcc1eea4fcd27d144bfbadc3fab08323c7b"
1071+
integrity sha512-JzDMFJk2Dk8FGLG1MfzwZ7g96NrS/jr+17XBqNJPl6z0kDSsR4sRHOffdzMnJyo4sfqWyWRjzIMD4WYeLpctNA==
1072+
10681073
"@eslint/eslintrc@^1.0.5":
10691074
version "1.0.5"
10701075
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.5.tgz#33f1b838dbf1f923bfa517e008362b78ddbbf318"

0 commit comments

Comments
 (0)