-
Notifications
You must be signed in to change notification settings - Fork 855
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RadzenScheduler - Resource Grouping #1994
base: master
Are you sure you want to change the base?
Conversation
@@ -7,13 +7,54 @@ | |||
public override RenderFragment Render() | |||
{ | |||
var appointments = Scheduler.GetAppointmentsInRange(StartDate, EndDate).ToList(); | |||
var resources = Scheduler.ActiveResourceList; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is ActiveResourceList needed? What is an active resource? What is inactive resource?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gone. Related to combined Views.
} | ||
next++; | ||
} | ||
var currentResource = resourceDictionary.FirstOrDefault().Key; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the linked list (which is done via Dictionary ??)? I would just pass the current resource and the whole resource collection. DayViewResourceHeader can determine if it first or last based on the current index and collection.
/// Gets whether the resource is active in grouping | ||
/// </summary> | ||
/// <value>The visibility.</value> | ||
bool IsActive { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is an "active" resource? I don't think this is really a requirement. Dynamic resources can be generated via @foreach
:
<Resources>
@foreach (var schedulerResourceData in resourceData.Where(d => d.Enabled))
{
<RadzenSchedulerResource ... />
}
</Resources>
```
/// Gets the order of grouping | ||
/// </summary> | ||
/// <value>The order.</value> | ||
int Order { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not so sure order is needed either. People can define the resources in the order they need them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gone
/// <summary> | ||
/// List of resource filters. | ||
/// </summary> | ||
public IList<(string Property, string Value)> ResourceFilters { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tuples are not good for a public API. Should be a class instead - SchedulerResourceFilter or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now SchedulerResourceFilter
AppointmentMove=OnAppointmentMove /> | ||
</CascadingValue> | ||
; | ||
if (resources.Count > 0 && ShowResourceGrouping) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any use case for using resources and having ShowResourceGrouping as false
? I don't think of any.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This disappears with having separate Views. When it was one View, it gave the option to ignore any resources and render as normal.
var currentResource = resourceDictionary.FirstOrDefault().Key; | ||
|
||
return | ||
@<div class="rz-resource-scheduler"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is RadzenDayView rendering the resource header? I think RadzeResourceDayView should do that and RadzenDayView should stay mostly untouched. The same goes for the other views.
For example I think RadzenResourceDayView should:
- Render the resource headers
- Render RadzenDayView for every resource.
Hi @paulo-rico, I think there may have been a misunderstanding judging by your latest commits. I still think we should have new Resource based views - RadzenResourceDayView, RadzenResourceWeekView etc. Those should render the resource headers and then render the children views passing them appointments filtered by data. Maybe RadzenResourceDayView can inherit from RadzenDayView to avoid duplicating all parameters. |
font-weight: 600; | ||
} | ||
|
||
.rz-resource-scheduler-diary { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still don't know what "diary" is. We call them "views"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed it to "view".
I used "diary" in order to differentiate between the view and the "diary" portion (for want of a better word). Originally, all we had was a Scheduler
that contained a View
. With the resource views, We have a Scheduler
that contains a View
that comprises a series of "Headers" and a series of "diaries".
{ | ||
draggedAppointment.Start = draggedAppointment.Start + args.TimeSpan; | ||
draggedAppointment.End = draggedAppointment.End + args.TimeSpan; | ||
if(args.ResourceFilters!=null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't look as a good public API. I don't understand what it is doing.
/// Mark that a drag has started. | ||
/// </summary> | ||
/// <value>Has a drag started?</value> | ||
public bool DragStarted { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are those needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to do with tracking the Started and Appointment variables when we're using multiple views in one. As it was, these variables were stored in the DropableViewBase
, so you couldn't drag between the views. They would all have there own local variables. I've moved those tracking variables up the hierarchy so that all the views share these and we can drag-drop appointments between them.
} | ||
} | ||
|
||
public IList<(string Field, string Value)> resourceFilterList |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Properties must follow PascalCase naming convention.
A few things popped up:
Has the drawback of defining multiple children at the same level (which we won't support) but shows the hierarchy in a better way.
What do you think? |
I'm assuming this means we store the reference (Id) in the Appointment record as opposed to the Text. |
Yes. That's it. I am thinking of what is the easiest way to use this from a GUI IDE when you want the resources to come from a database. One would usually have some foreign key relationship between appointments and resources. And we need a way to convey that. About the nested resources - the more I think about it the less I like it. It may cause more harm than good. Let's scrap it for now. |
The nesting gave me some thoughts. Not to actually nest the resources, but to link them in some way. My thoughts are along these lines. As it stands, we are outputting all headers for all "parent" headers, i.e. basically, nested But, as a real world example, this isn't always the best approach. Take a hotel chain, for example. A chain has many hotels. A hotel has many rooms, these rooms have bookings. As it stands with the current grouping method, it will output "Hotel 1" and then output all the rooms in the database under this header. It will then render "Hotel 2" and all the rooms again. Sometimes, like this scenario, there needs to be a link to "filter" child group headers (rooms) for it to make sense in real life. Not output rooms for a hotel that don't exist. Also in the above scenario, Appointment records in a database may not (or shouldn't, if following standard design practices) have the hotel reference as part of it. It would gather the hotel from the hotel reference of the room record, if need be. So this is making me think that not all resource records used for grouping will take part in the filter process of the appointment records, as it does now. An initial idea is as follows. We have the following properties as part of each resource record -
Example Resource and Appointment components / data -
So, in the above example, it will output all the Hotels as header. When it comes to rendering the Rooms, it will see that When it comes to filtering the We're still not nesting. The "Parent" is the preceding I'm sure this offers the flexibility required for this type of view. What do you think? Would this work in the GUI IDE? |
We may be overcomplicating things. Having to set three or four properties per resource seems to be too much. And I got confused again by the hotel / room analogy. I should better check again the API of the scheduler component we developed back in the days. It had cleaner API that wasn't hard to follow and support all kinds of scenarios. |
Found an example that seems flexible enough: https://demos.telerik.com/kendo-ui/scheduler/resources-grouping-hierarchical
|
Hi all
Easiest way to follow through this is to begin at
RadzenDayView.razor
(week view and multi day work the same).If there are no resources or you have elected to not show grouping (
ShowResourceGrouping
) it will output the same as it did before. The slight difference there is that, along withCascadingParameter
forScheduler
, it also passes down itself (SchedulerViewBase
) for theDropableViewBase
. It uses this as a root for holding bothDragStarted
andDraggedAppointment
variables. They had to be moved to a "parent" component in order to move appointments between multiple "diaries" (the bit at the bottom of each header that shows the slots and appointments).The recursion loop then begins until there is no "child" resource, and then it renders the "diary" portion. So the rendering order would be something like this, where the integer is the resource and the decimal is the resource data (assuming two data items per resource)
1.1
2.1
3.1
Diary
1.1
2.1
3.2
Diary
1.1
2.2
3.1
Diary
e.t.c.
At each level, we have access to
Property
andValue
so we can traverse back up the tree to build aFilterDescription[]
in order to pass thesefilteredAppointments
on to the "diary".Although there are a great deal of file changes, the majority of these are to accommodate
ResourceFilterList
in the Scheduler events (which is defaulted to avoid breaking change). This is anIEnumerable<string Property, string Value>
to pass back to identify which resource(s) are relavent to the "Click" or "Move", e.t.c.Hope this is moving in the right direction.
Regards
Paul