Our pure JavaScript Scheduler component


Post by stephan.goseberg »

Hi,
I have a weird issue with the groupSummary feature.
When the scheduler is loaded the events object of the renderer function is always empty.
When I then collapse and expand the group it will show the correct amount of events.
I have the following inside the scheduler object:
let scheduler = new bryntum.scheduler.Scheduler({
    appendTo: sched,
    height: window.innerHeight - 22,
    rowHeight: 90,
    viewPreset: 'week2',
    features: {
        eventTooltip: {
            template: function (dataObj) {
                var itemType = dataObj.eventRecord.data.ItemType;
                var customer = dataObj.eventRecord.data.CustomerName;
                var subItemName = dataObj.eventRecord.data.SubItemName;
                var pm = dataObj.eventRecord.data.PM;
                var projectType = dataObj.eventRecord.data.ProjectType;
                var finBas = dataObj.eventRecord.data.FinancialBasis;
                var totPlannedHours = dataObj.eventRecord.data.TotalPlannedHours;
                var totStart = Ext.Date.format(dataObj.eventRecord.data.TotalStartDate,'j M Y');
                var totEnd = Ext.Date.format(dataObj.eventRecord.data.TotalEndDate, 'j M Y');
                var billable = dataObj.eventRecord.data.Billable;
                var isComm = dataObj.eventRecord.data.IsCommitted;
                var name = dataObj.eventRecord.data.name;

                var tpl = '<div class="b-sch-event-tooltip"><table>';
                if (itemType != 'NTI') {
                    tpl += '<tr><td width="120px">Customer:</td><td>' + customer + '</td></tr>';
                }
                tpl += '<tr><td>Name:</td><td>' + name + '</td></tr>';
                if (itemType === 'PRJ' || itemType === 'PTI') {
                    tpl += '<tr><td>Task:</td><td>' + subItemName + '</td></tr>';
                    tpl += '<tr><td>PM:</td><td>' + pm + '</td></tr>';
                    tpl += '<tr><td>Project Classification:</td><td>' + projectType + '</td></tr>';
                    tpl += '<tr><td>Financial Basis:</td><td>' + finBas + '</td></tr>';
                    if (itemType === 'PRJ') {
                        tpl += '<tr><td>Overall Planned Hours:</td><td>' + totPlannedHours + '</td></tr>';
                        tpl += '<tr><td>Overall Start:</td><td>' + totStart + '</td></tr>';
                        tpl += '<tr><td>Overall Finish:</td><td>' + totEnd + '</td></tr>';
                    } else {
                        tpl += '<tr><td>Total Actual Hours:</td><td>' + totPlannedHours + '</td></tr>';
                    }

                    if (isComm === true) {
                        tpl += '<tr><td>Committed:</td><td><img src="/images/pw/check.png" alt="checked"></td></tr>';
                    } else {
                        tpl += '<tr><td>Committed:</td><td><img src="/images/pw/delete.png" alt="notchecked"></td></tr>';
                    }
                }
                if (itemType === 'REQ' || itemType === 'RTI') {
                    tpl += '<tr><td>Request:</td><td>' + subItemName + '</td></tr>';
                    if (itemType === 'REQ') {
                        tpl += '<tr><td>Overall Planned Hours:</td><td>' + totPlannedHours + '</td></tr>';
                        tpl += '<tr><td>Overall Start:</td><td>' + totStart + '</td></tr>';
                        tpl += '<tr><td>Overall Finish:</td><td>' + totEnd + '</td></tr>';
                    } else {
                        tpl += '<tr><td>Total Actual Hours:</td><td>' + totPlannedHours + '</td></tr>';
                    }
                    
                }
                if (itemType === 'OPP' ) {
                    tpl += '<tr><td>Overall Planned Hours:</td><td>' + totPlannedHours + '</td></tr>';
                    tpl += '<tr><td>Overall Start:</td><td>' + totStart + '</td></tr>';
                    tpl += '<tr><td>Overall Finish:</td><td>' + totEnd + '</td></tr>';

                }
                if (itemType === 'NTI') {
                    tpl += '<tr><td>Total Actual Hours:</td><td>' + totPlannedHours + '</td></tr>';
                }
                if (billable === true) {
                    tpl += '<tr><td>Billable:</td><td><img src="/images/pw/check.png" alt="checked"></td></tr>';
                } else {
                    tpl += '<tr><td>Billable:</td><td><img src="/images/pw/delete.png" alt="notchecked"></td></tr>';
                }
                tpl += '</table></div>';

                return tpl;
            },
        },
        timeRanges: {
            showCurrentTimeLine: true,
            showHeaderElements: true,
            enableResizing: true,
            timeRanges: [
                { id: 1, startDate: today, duration: 1, durationUnit: 'day' }
            ]
        },
        resourceTimeRanges: {
            store: nonWorkingDaysStore
        },
        group: 'name',
        groupSummary: {
            showTooltip: false,
            summaries: [{
                label: 'Total hours',
                renderer: resourceSummaryRenderer
            }]
        }
    },
    columns: [
        { text: 'Resource', sortable: false, width: 230, minWidth: 230, renderer: resourceNameRenderer, htmlEncode:false },
        { text: 'Information', sortable: false, width: 100, minWidth: 100, renderer: resourceInfoRenderer, htmlEncode: false },
        { text: 'Month 1', sortable: false, width: 130, minWidth: 130, renderer: resourceMonth1Renderer, htmlEncode: false },
        { text: 'Month 2', sortable: false, width: 130, minWidth: 130, renderer: resourceMonth2Renderer, htmlEncode: false }
    ],

    resourceStore: resourceStore,
    eventStore: eventStore,
    
    startDate: startingDate,
    endDate: endDate,
    eventRenderer: eventRenderer
});
And the renderer function
function resourceSummaryRenderer(configObj) {
    var count = 0,
        maxPerDay = 3;
    var resources = configObj.resourceStore._data;
    var startDate = configObj.startDate;
    var endDate = configObj.endDate;
    var css = '';
    if (configObj.events.length > 0) {
        if (m_groupproject === false) {
            Ext.each(configObj.events, function (eventRec) {
                count += eventRec.data.DemandHours;
                maxPerDay = scheduler.resourceStore.getById(eventRec.data.resourceId).data.DailyCapacity;
            });
            if (count > maxPerDay) {
                css = 'overallocated';
            } else {
                css = 'notoverallocated';
            }
            count = Math.round(count * 100) / 100;
            if (!count) { count = 0; }
            var tooltipString = 'Total hours: ' + count;
            return count;
            //return '<span data-qtip="' + Ext.htmlEncode(tooltipString) + '" class="' + css + '>' + count + '</span>';
        }
    }
    return 0;
}
My problem is that without collapse/expand configObj.events.length is always 0.
Store load sequence is:
eventStore --> nonWorkingDaysStore --> resourceStore
I'm loading the next store within the load listener of the previous store.

What can I do so the events are also filled on initial load without collapsing the group?

Post by mats »

Known issue, it should be fixed in the next release!

Post by stephan.goseberg »

Ah, OK.
Another question: By default the summary row is added below the group. Is it possible to have the summary row in the group name row on top like it is for the Ext JS Scheduler?
ExtJSSchedulerSummaryRow.jpg
ExtJSSchedulerSummaryRow.jpg (212.67 KiB) Viewed 1162 times

Post by mats »

Yes, you can implement this with the 'renderer' method: https://www.bryntum.com/docs/scheduler/#Grid/feature/Group#config-renderer

Post by stephan.goseberg »

It first looked promising but unfortunately the
group
feature's renderer is only called for each locked column (my 4 resource columns name, information, month1 and month2) but not the time line columns.
What I want to achieve is to have the total hours per resource per day displayed just above. Like is shown in the screenshot. How could I do that if the renderer is not called for the timeline columns?

Post by mats »

Seems like we don't support it at the moment but I've opened a ticket to look into this: https://app.assembla.com/spaces/bryntum/tickets/8751-group-feature-groupingrenderer-only-called-for-columns-in-first-sub-grid/details#

Post Reply