Files
calendar/packages/features/calendars/weeklyview/components/event/EventList.tsx
T
sean-brydonGitHubJeroen ReumkenszomarsPeer Richelsenkodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
8fd5d6b5b5 Calendar Weekly Scheduler (#5653)
* storybook v2 init

* Merge config into storybook vite build

* Remove path

* Storybook config tweaks

* Added styles and settings for storybook v2, and started working on button documentation and examples.

* Badges + flex wrap on mobile

* Breadcrumbs+button+avatar

* Checkbox

* Input + moving files around

* WIP table

* WIP table grid

* Replaced imports for new components.

* Added first steps for varianttable.

* Small alignment fix.

* Custom Args Table - With scrollbar

* Adding table to components that need it + darkmode

* Add intro

* Fix types

* Remove V1 storybook and replace with V2

* Fix badge type error

* Fixed storybook dependencies

* Added cover image to storybook

* Remove vita from ts config, we dont use vite.

* Fixed button import.

* Explained postcss pseudo plugin.

* Fixed badge import.

* Add Avatar Stories

* ButtonGroup Stories

* Fixed imports

* Add checkbox stories

* Inital state plannning

* Inital state combined with passed in props

* Start of UI work

* Able to change dates?

* Add dynamic hour props

* Get grid system setup correctly

* Show events on grid

* Weird sizing issue but events placed correctly gridstart

* CAL styled calendar event component

* availability WIP ish

* Blocking days! + Block days < today

* Kinda working time line

* Rename grid stop + formatting

* Handle sorting events if required.

* Add util for getting startDate bassed on weekday

* Remove event stories for now

* Implement gridstops per hour to be dyamic

* New CSS Grid + offsetbased positoning

* Fix weird Z-Index issues on hover

* Implement blocklist again with new format

* Side by side events working - styling needs work

* New design of overlap

* Overlapping? Working :O

* Cleanup

* WIP hover state

* Werid border issue

* fix translate issue

* Kinda working with overflow

* Fix overflow

* Progressive date blocking

* Cleanup

* Fix double render of blocked list

* WIP mobile implementaiton

* Trying to fix CSS

* Extract CSS to styles.css to allow media queries

* Improve documentation - allow args to be changed in storybook

* Fix hover showing even if disabled

* WIP cols auto approach

* Merge blocking dates

* Fix zindex

* Fix hover position

* Fix Z-Index issues on hover and blocking events

* Re add onclick handler

* Fix overlapping blocking dates

* Fix scaling for datevalues columns

* Date values closer to DS

* Blocked List Tidy up

* Storybook + file tidy up

* Little tidy up

* Fix offsets

* Remove event hover

* Fix random bg-red-500

* Fix import

* FIx blocking cells appearing above start Date

* Fix truncation

* Fix border overlap

* Overlap a little nicer

* Condtional 80% sizing

* Nitpicks

* Fix today height and top breaking

* Add text left to time stamp

* Support string dates

* Add shalow to reduce re-renders

* Rename to Calendar instead of scheduler

* Fix 3 overlapping events

* Fix merge type error

* Fix destructuring

* NITS

* Move to features package

Co-authored-by: Jeroen Reumkens <hello@jeroenreumkens.nl>
Co-authored-by: zomars <zomars@me.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2022-12-14 13:36:10 +00:00

108 lines
3.6 KiB
TypeScript

import shallow from "zustand/shallow";
import dayjs from "@calcom/dayjs";
import { useCalendarStore } from "../../state/store";
import { Event } from "./Event";
type Props = {
day: dayjs.Dayjs;
};
export function EventList({ day }: Props) {
const { startHour, events, eventOnClick } = useCalendarStore(
(state) => ({
startHour: state.startHour,
events: state.events,
eventOnClick: state.onEventClick,
}),
shallow
);
return (
<>
{events
.filter((event) => {
return dayjs(event.start).isSame(day, "day") && !event.allDay; // Filter all events that are not allDay and that are on the current day
})
.map((event, idx, eventsArray) => {
let width = 90;
let marginLeft: string | number = 0;
let right = 0;
let zIndex = 61;
const eventStart = dayjs(event.start);
const eventEnd = dayjs(event.end);
const eventDuration = eventEnd.diff(eventStart, "minutes");
const eventStartHour = eventStart.hour();
const eventStartDiff = (eventStartHour - (startHour || 0)) * 60 + eventStart.minute();
const nextEvent = eventsArray[idx + 1];
const prevEvent = eventsArray[idx - 1];
// Check for overlapping events since this is sorted it should just work.
if (nextEvent) {
const nextEventStart = dayjs(nextEvent.start);
const nextEventEnd = dayjs(nextEvent.end);
// check if next event starts before this event ends
if (nextEventStart.isBefore(eventEnd)) {
// figure out which event has the longest duration
const nextEventDuration = nextEventEnd.diff(nextEventStart, "minutes");
if (nextEventDuration > eventDuration) {
zIndex = 65;
marginLeft = "auto";
// 8 looks like a really random number but we need to take into account the bordersize on the event.
// Logically it should be 5% but this causes a bit of a overhang which we don't want.
right = 8;
width = width / 2;
}
}
if (nextEventStart.isSame(eventStart)) {
zIndex = 66;
marginLeft = "auto";
right = 8;
width = width / 2;
}
} else if (prevEvent) {
const prevEventStart = dayjs(prevEvent.start);
const prevEventEnd = dayjs(prevEvent.end);
// check if next event starts before this event ends
if (prevEventEnd.isAfter(eventStart)) {
// figure out which event has the longest duration
const prevEventDuration = prevEventEnd.diff(prevEventStart, "minutes");
if (prevEventDuration > eventDuration) {
zIndex = 65;
marginLeft = "auto";
right = 8;
width = width / 2;
if (eventDuration >= 30) {
width = 80;
}
}
}
}
return (
<div
key={`${event.id}-${eventStart.toISOString()}`}
className="absolute inset-x-1 "
style={{
marginLeft,
zIndex,
right: `calc(${right}% - 1px)`,
width: `${width}%`,
top: `calc(${eventStartDiff}*var(--one-minute-height))`,
height: `calc(${eventDuration}*var(--one-minute-height))`,
}}>
<Event event={event} eventDuration={eventDuration} onEventClick={eventOnClick} />
</div>
);
})}
</>
);
}