bryntum / support

An issues-only repository for the Bryntum project management component suite which includes powerful Grid, Scheduler, Calendar, Kanban Task Board and Gantt chart components all built in pure JS / CSS / TypeScript
https://www.bryntum.com
53 stars 6 forks source link

Applying a default/initial filter to resources in tree group doesn't clear afterwards #6985

Closed marciogurka closed 1 year ago

marciogurka commented 1 year ago

Forum post

"Hello,

I am using scheduler pro, with the treeGroup feature. My resource column is of type tree. When a default filter is applied initially, the filtered view is correctly displayed on the UI. However, subsequent filters can only be applied to the resources that are currently visible, meaning those that have been filtered recently. For example, if the default filter was set to capacity=100, any subsequent filters will be applied to this already filtered set with capacity=100. The clearFilters() function does not remove the first filter (capacity=100), but it does clear any filters applied afterwards.

I was able to reproduce similar behaviour in the tree grouping demo by adding some lines. https://bryntum.com/products/schedulerpro/examples-scheduler/tree-grouping/.

Here's the code with the modifications:

import { StringHelper, SchedulerResourceModel, Scheduler } from '../../build/schedulerpro.module.js';
import shared from '../_shared/shared.module.js';

class Gate extends SchedulerResourceModel {
    static get fields() {
        return [
            { name : 'capacity', type : 'number' },
            { name : 'waiting', type : 'number' },
            { name : 'domestic', type : 'boolean' }
        ];
    }
}

const
    // Group by capacity, in steps of 50
    sizeGrouper = ({ capacity }) => `Capacity ${Math.floor(capacity / 50) * 50} - ${(Math.floor(capacity / 50) + 1) * 50 - 1}`,
    // Group by waiting time, None, Less than an hour or More than an hour
    waitingTimeGrouper = ({ waiting }) => waiting === 0 ? 'None' : waiting < 60 ? 'Less than an hour' : 'More than an hour',
    // Group by domestic or international
    domesticGrouper = ({ domestic }) => domestic ? 'Domestic' : 'International';

const scheduler = new Scheduler({
    appendTo   : 'container',
    eventColor : null,
    eventStyle : null,

features : {
    tree      : true,
    // Enable the TreeGroup feature, which can transform the tree's structure
    treeGroup : {
        // Initially transformed with a single parent level based on capacity
        levels : [sizeGrouper]
    }
},

rowHeight : 45,
barMargin : 5,

columns : [
    {
        type  : 'tree',
        text  : 'Name',
        width : 220,
        field : 'name'
    },
    {
        type  : 'number',
        text  : 'Capacity',
        width : 90,
        field : 'capacity',
        align : 'right'
    },
    {
        type  : 'number',
        text  : 'Waiting time',
        width : 90,
        field : 'waiting',
        align : 'right'
    },
    {
        text   : 'Domestic',
        width  : 90,
        field  : 'domestic',
        align  : 'center',
        editor : null,
        renderer({ value }) {
            if (value) {
                return {
                    tag       : 'i',
                    className : 'b-fa b-fa-times'
                };
            }

            return '';
        }
    }
],

startDate  : new Date(2022, 8, 12, 8),
viewPreset : 'hourAndDay',

crudManager : {
    autoLoad      : true,
    resourceStore : {
        modelClass : Gate
    },
    loadUrl : 'data/data.json'
},

// Custom eventRenderer, used to colorize the flights depending on the waiting time at the gate
eventRenderer({ eventRecord, resourceRecord, renderData }) {
    renderData.cls.add(
        resourceRecord.waiting > 60 ? 'purple'
            : resourceRecord.waiting > 30 ? 'apricot'
                : resourceRecord.waiting > 5 ? 'cyan'
                    : 'green'
    );

    return StringHelper.encodeHtml(eventRecord.name);
},

tbar : [
    {
        type        : 'buttongroup',
        ref         : 'buttons',
        toggleGroup : true,
        items       : [
            {
                text    : 'Capacity',

                async onToggle({ pressed }) {
                    if (pressed) {
                        // The buttons are disabled during grouping, since it is an async operation
                        buttons.disable();
                        await scheduler.group([sizeGrouper]);
                        buttons.enable();
                    }
                }
            },
            {
                text : 'Waiting time',
                async onToggle({ pressed }) {
                    if (pressed) {
                        buttons.disable();
                        await scheduler.group([waitingTimeGrouper]);
                        buttons.enable();
                    }

                }
            },
            {
                text : 'Domestic + capacity',
                async onToggle({ pressed }) {
                    if (pressed) {
                        buttons.disable();
                        await scheduler.group([domesticGrouper, sizeGrouper]);
                        buttons.enable();
                    }

                }
            },
            {
                text : 'None',
                async onToggle({ pressed }) {
                    if (pressed) {
                        buttons.disable();
                        await scheduler.clearGroups();
                        buttons.enable();
                    }
                }
            },
{
                    text : 'Remove filter',
                    async onToggle({ pressed }) {
                        if (pressed) {
                            buttons.disable();
                            scheduler.store.clearFilters().then(() => console.log('removing')
);
                            buttons.enable();
                        }
                    }
                },
            ]
        }, 
    ]
}); 

const { buttons } = scheduler.widgetMap;

scheduler.store.filter((record) => record.capacity == 100 )

What happens: The scheduler loads with the filtered data (i.e. capacity = 100) removing filters via the button or from the console does not do anything to the view. Any filtering hence forth happens within the data that the first filter renders.

What I expect to happen: The scheduler loads with the filtered data (i.e. capacity = 100) The button that says 'remove filters' should remove capacity =100 filter and load all resources. "

Finn-but commented 1 year ago

This bug might be resolved in scheduler pro, but not in the regular scheduler.

matsbryntse commented 1 year ago

@Finn-but Can you still repro? How?

Finn-but commented 1 year ago

@matsbryntse I posted a testcase and explanation on the initial forum post.