Our powerful JS Calendar component


Post by nick »

Hello,

We are currently in the process of building a clinician scheduling/management system. As we have multiple clinics, we need to be able to display the clinic that a clinician is allocated at alongside their current bookings or meetings. This is what we have in the mockups:

Screen Shot 2022-08-23 at 10.32.36 am.png
Screen Shot 2022-08-23 at 10.32.36 am.png (270.46 KiB) Viewed 875 times

With Bryntum Scheduler we are able to use ResourceTimeRanges and some custom css to display the allocation bar on the side. This second layer cannot be interacted with and allows the allocation to not impact other events on the scheduler. Mats has informed us that ResourceTimeRanges aren't currently supported in Calendar, however it is on the roadmap for the future.

We were wondering if there was any advice as to how we'd implement something like our mockup using the Calendar control?

Currently we've used some custom rendering and css to achieve the screenshot below.

Screen Shot 2022-08-23 at 10.44.22 am.png
Screen Shot 2022-08-23 at 10.44.22 am.png (280.95 KiB) Viewed 875 times

This is the custom css we are using:

@import "~@bryntum/calendar/calendar.material.css";

$allocationWidth: 30px;


// override bryntum css to remove the shadows in order to match our ui.
.b-dayview-day-container.b-calendar-cell .b-cal-tentative-event.b-cal-in-cluster, .b-dayview-day-container .b-calendar-cell .b-cal-event-wrap.b-cal-in-cluster {
  box-shadow: none;
}

.b-dayview-day-container .b-calendar-cell .b-cal-event-body {
  background-color: rgba(0,0,0,0);
  margin: 0 0 0;
}

.b-weekview .b-cal-event-wrap.b-cal-event-reveal.b-cal-in-cluster {
  left: 0 !important;
  z-index: 2 !important;
}

// do not display the time inside the calendar event.
.b-event-time {
  display: none;
}



.clinician-event {
  width: calc(100% - $allocationWidth) !important;
  min-width: calc(100% - $allocationWidth) !important;
  max-width: calc(100% - $allocationWidth) !important;
  left: $allocationWidth !important;
  border-radius: 5px;
  z-index: 2 !important;
  padding-left: 0!important;
}


.clinician-allocation {
  min-width: $allocationWidth !important;
  max-width: $allocationWidth !important;
  width: $allocationWidth !important;
  left: 0 !important;
  padding-right: 0 !important;
  margin-right: 10px;
  writing-mode: vertical-lr;
  transform: rotate(-180deg);
  border-radius: 3px;
  text-align: center;
  z-index: -1 !important;
}

Regular events get the clinician-event css class applied to them, and allocations get the clinician-allocation class applied to them. The z-index makes the allocation sit in the background and not respond to any user interaction; in a similar way to the ResourceTimeRange.

Because we've overidden so many positioning related properties, the calendar's default stacking behavior is not working anymore, so it is possible for events to overlap and hide other events completely. Ideally we'd like the calendar's stacking to still occur, but in a way that does not move the allocation, and does not allow events to sit on top of the allocation. It'd be great if there was a way to potentially split the day column into two sub-columns, and have the allocation sitting in the one column, and everything else in the other.

We appreciate any suggestions here!!

Thanks 😊


Post by Animal »

Seems like you just need to make those selectors more specific so that they only apply to these special events.

.b-dayview-day-container .b-calendar-cell .clinician-allocation .b-cal-event-body {
  background-color: rgba(0,0,0,0);
  margin: 0 0 0;
}

Post by nick »

Thanks for your response!

Unfortunately changing this css selector doesn't solve our positioning challenge. We believe the issue is with how event widths are calculated in the Bryntum JS backend (Equally dividing the column between events at the time.)

Is there a way to allow our "Allocation" event to be fixed width and have the javascript event width calculation take this into account? Please see screenshot below

Is there a way to implement a tweak to the Pack mode / PackMixIn ?

Attachments
Screen Shot 2022-08-24 at 11.58.05 am.png
Screen Shot 2022-08-24 at 11.58.05 am.png (117.12 KiB) Viewed 830 times

Post by Animal »

I think this would require an extra configuration in the day layout class.

I have created a ticket to help with this requirement: https://github.com/bryntum/support/issues/5113


Post by nick »

startGutter looks like exactly what we'd need - thanks! 😊


Post by nick »

Hi Bryntum team, could you please help us with an ETA on this ticket, even just for a nightly or early access release - it will help us be able to put Calendar live in our system.


Post by marcio »

Hello Nick, we'll try our best to release soon, but for now no estimated date, please watch the ticket for updates, one day after is marked as resolved, it will be available in the nightly release. :)

Best regards,
Márcio


Post by dongryphon »

Hi Nick,

It seems like a startGutter would be difficult to use if there are overlapping events. Would rendering nested (parent/child) events fit better?

Proof of concept:

calendar-nested-events.png
calendar-nested-events.png (34.41 KiB) Viewed 668 times

Post by nick »

dongryphon wrote: Wed Sep 21, 2022 3:19 pm

Hi Nick,

It seems like a startGutter would be difficult to use if there are overlapping events. Would rendering nested (parent/child) events fit better?

Proof of concept:

calendar-nested-events.png

Hey,

Sorry for the delay, yesterday was a public holiday in AU. Yes this looks absolutely amazing, thanks! If you don’t mind, the team just had a couple of questions around how the implementation works.

Firstly, what is the behavior for assigning events as children - is there a parentEventId property that we need to set to create a relationship between parents and children, or is it that we simply set an eventType/isParent property which decides how the event renders, and there is no need to assign ids/parents to events?

If the former, what would the behavior be if an event is scheduled during the same time period as a parent event, but that event is not a child of the parent event? Would it still display alongside the parent? Or vice versa, if you had a child event, but it was was outside the range of the parent?

If the latter, I assume that any event that falls within a parent's timerange is automatically considered a child?

Couple other smaller questions

  1. If we have a parent event with no children does the parent stay thin along the side or would it expand to take up the entire width?

  2. Would there be a way to set custom widths on the parent/child events and maintain correct stacking behavior?

Thank you guys so much for looking into this - solution looks really exciting and we can’t wait to use it in our app!! 😊


Post by dongryphon »

For the proof of concept here, I am using the "children" property of an event. This allows one level of nesting only at this point, but an event with children is a parent and it renders vertically. The code currently assumes that the children are basically inside the time range of the parent event (I have not tested it with children outside this range). They would probably need to at least overlap their parent's start/end time for the code to work correctly.

In the POC, I have two parent events (tracks) on 2 days and they layout next to each other with 50% of the day width. The algorithm basically just does a recursive layout of any children and gives those children the calculated width the parent would have had if it had no children.

A parent event is a parent due to the presence of "children" in its data. It is not a flag on an event, so no children = not a parent. Childless events would layout as normal (filling the width). It should be possible to adjust the amount of space given to the vertical parent. That would be assigned as an inline style on the event element (as before).

At this point I will need to chat with the team to see what the plan will be to take the proof of concept beyond this stage. There is also discussion of using time ranges in calendar, but no POC on that one as yet. Thanks for the response - it is important to know that this would fit your use case so we can plan next steps.

I will keep you posted as decisions are made on this.


Post Reply