-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Francisco del Castillo
committed
Oct 7, 2024
1 parent
20ebc50
commit a3abfe2
Showing
8 changed files
with
291 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
import { Icon } from "@blueprintjs/core" | ||
import { IconNames } from "@blueprintjs/icons" | ||
import API from "api" | ||
import LinkTo from "components/LinkTo" | ||
import Messages from "components/Messages" | ||
import { mapPageDispatchersToProps } from "components/Page" | ||
import { Event } from "models" | ||
import moment from "moment/moment" | ||
import PropTypes from "prop-types" | ||
import React, { useEffect, useState } from "react" | ||
import { Button, Table } from "react-bootstrap" | ||
import { connect } from "react-redux" | ||
import Settings from "settings" | ||
|
||
const dayNames = [ | ||
"Sunday", | ||
"Monday", | ||
"Tuesday", | ||
"Wednesday", | ||
"Thursday", | ||
"Friday", | ||
"Saturday" | ||
] | ||
|
||
const EventMatrix = props => { | ||
const [weekNumber, setWeekNumber] = useState(null) | ||
const [startDay, setStartDay] = useState(getFirstDayOfCurrentWeek()) | ||
const [events, setEvents] = useState([]) | ||
const [tasks, setTasks] = useState([]) | ||
const [weekDays, setWeekDays] = useState([]) | ||
const [error, setError] = useState(null) | ||
|
||
useEffect(() => { | ||
async function fetchEvents(eventQuery) { | ||
try { | ||
return await API.query(Event.getEventListQuery, { | ||
eventQuery | ||
}) | ||
} catch (error) { | ||
setError(error) | ||
} | ||
} | ||
|
||
// Determine date range | ||
const week = [] | ||
for (let i = 0; i <= 6; i++) { | ||
week.push(moment(startDay).add(i, "days").toDate()) | ||
} | ||
setWeekDays(week) | ||
setWeekNumber(moment(startDay).week()) | ||
|
||
// Get the events | ||
const eventQuery = Object.assign({}, props.queryParams) | ||
eventQuery.startDate = week[0] | ||
eventQuery.endDate = week[6] | ||
eventQuery.onlyWithTasks = true | ||
fetchEvents(eventQuery).then(response => | ||
setEvents(response?.eventList?.list) | ||
) | ||
}, [startDay, props.queryParams]) | ||
|
||
useEffect(() => { | ||
// TODO possibly this can be improved | ||
const tasksSet = new Set() | ||
const tasksArray = [] | ||
events | ||
.map(event => event.tasks) | ||
.flat() | ||
.forEach(task => { | ||
if (!tasksSet.has(task.uuid)) { | ||
tasksSet.add(task.uuid) | ||
tasksArray.push(task) | ||
} | ||
tasksSet.add(task) | ||
}) | ||
tasksArray.sort((a, b) => a.shortName.localeCompare(b.shortName)) | ||
setTasks(tasksArray) | ||
}, [events]) | ||
|
||
function getFirstDayOfCurrentWeek() { | ||
const today = new Date() | ||
const day = today.getDay() | ||
const diff = today.getDate() - day + (day === 0 ? -6 : 1) // adjust when day is sunday | ||
return new Date(today.setDate(diff)) | ||
} | ||
|
||
function isEventIncluded(event, task, dateToCheck) { | ||
return ( | ||
dateToCheck.getTime() >= event.startDate && | ||
dateToCheck.getTime() <= event.endDate && | ||
event.tasks.filter(t => t.uuid === task.uuid).length > 0 | ||
) | ||
} | ||
|
||
function showEventTitle(event, dateToCheck) { | ||
// Case one event starts on this date | ||
if (new Date(event.startDate).toDateString() === dateToCheck.toDateString()) { | ||
return true | ||
} | ||
// Case two event started earlier and we are checking on the Monday | ||
if (dateToCheck.getDay() === 1) { | ||
return true | ||
} | ||
} | ||
|
||
function getEvent(task, dayOfWeek) { | ||
// Get the date | ||
const dateToCheck = new Date(weekDays[dayOfWeek]) | ||
// Now get events including this task | ||
const selectedEvents = events.filter(event => | ||
isEventIncluded(event, task, dateToCheck) | ||
) | ||
if (selectedEvents.length > 0) { | ||
selectedEvents.sort((a, b) => a.name.localeCompare(b.name)) | ||
return ( | ||
<> | ||
<Table className="event-matrix" responsive hover id={dayOfWeek}> | ||
<tbody> | ||
{events.map(event => ( | ||
<tr key={event.uuid}> | ||
{isEventIncluded(event, task, dateToCheck) && ( | ||
<td | ||
height="55px" | ||
style={{ | ||
backgroundColor: "var(--anet-blue)" | ||
}} | ||
> | ||
{showEventTitle(event, dateToCheck) && ( | ||
<LinkTo | ||
style={{ | ||
marginLeft: "10px", | ||
backgroundColor: "var(--anet-blue)", | ||
color: "white" | ||
}} | ||
modelType="Event" | ||
model={event} | ||
/>)} | ||
</td> | ||
)} | ||
{!isEventIncluded(event, task, dateToCheck) && ( | ||
<td height="55px" style={{ backgroundColor: "white" }} /> | ||
)} | ||
</tr> | ||
))} | ||
</tbody> | ||
</Table> | ||
</> | ||
) | ||
} else { | ||
return "" | ||
} | ||
} | ||
|
||
function showPreviousPeriod() { | ||
setStartDay(moment(startDay).subtract(7, "days").toDate()) | ||
} | ||
|
||
function showNextPeriod() { | ||
setStartDay(moment(startDay).add(7, "days").toDate()) | ||
} | ||
|
||
return ( | ||
<div style={{ marginTop: "20px" }}> | ||
<Messages error={error} /> | ||
<div style={{ float: "left" }}> | ||
<div className="rollup-date-range-container"> | ||
<Button | ||
id="previous-period" | ||
onClick={() => showPreviousPeriod()} | ||
variant="outline-secondary" | ||
style={{ marginRight: 5 }} | ||
> | ||
<Icon icon={IconNames.DOUBLE_CHEVRON_LEFT} /> | ||
</Button> | ||
Events in week {weekNumber} | ||
<Button | ||
id="next-period" | ||
onClick={() => showNextPeriod()} | ||
variant="outline-secondary" | ||
style={{ marginLeft: 5 }} | ||
> | ||
<Icon icon={IconNames.DOUBLE_CHEVRON_RIGHT} /> | ||
</Button> | ||
</div> | ||
</div> | ||
<div> | ||
<Table | ||
className="event-matrix" | ||
responsive | ||
hover | ||
id="events-matrix" | ||
> | ||
<thead> | ||
<tr> | ||
<th /> | ||
{weekDays.map(weekDay => ( | ||
<th key={weekDay}>{weekDay.toISOString().slice(0, 10)}</th> | ||
))} | ||
</tr> | ||
<tr> | ||
<th>{Settings.fields.task.shortLabel}</th> | ||
{weekDays.map(weekDay => ( | ||
<th key={weekDay}>{dayNames[weekDay.getDay()]}</th> | ||
))} | ||
</tr> | ||
</thead> | ||
<tbody> | ||
{tasks.map(task => ( | ||
<tr key={task.uuid}> | ||
<td> | ||
<LinkTo modelType="Task" model={task} /> | ||
</td> | ||
<td>{getEvent(task, 0)}</td> | ||
<td>{getEvent(task, 1)}</td> | ||
<td>{getEvent(task, 2)}</td> | ||
<td>{getEvent(task, 3)}</td> | ||
<td>{getEvent(task, 4)}</td> | ||
<td>{getEvent(task, 5)}</td> | ||
<td>{getEvent(task, 6)}</td> | ||
</tr> | ||
))} | ||
</tbody> | ||
</Table> | ||
{events.length === 0 && <em>No events in this week </em>} | ||
</div> | ||
</div> | ||
) | ||
} | ||
|
||
EventMatrix.propTypes = { | ||
// query variables for events, when query & pagination wanted: | ||
queryParams: PropTypes.object | ||
} | ||
export default connect(null, mapPageDispatchersToProps)(EventMatrix) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.