Page 1 of 2

[VUE] Gantt multi field filter error with gridfieldfilterpickergroup: Uncaught (in promise) TypeError: Cannot read props

Posted: Sat Mar 25, 2023 1:27 pm
by seany84

We have use the example from: https://www.bryntum.com/products/gantt/examples/fieldfilters/ to implement the gridfieldfilterpickergroup on our tradeDiscipline column in the Gantt's grid.

We are using v5.2.9 of the Bryntum Gantt package.

In our class that extends TaskModel, we have applied our relations:

    static relations = {
        tradeDiscipline : {
            foreignKey   : 'tradeDisciplineId',
            foreignStore : tradeDisciplineStore
        }
    }

We have implemented our Grid feature:

    get filterFeature() {
        const filterPickerFields = {
            tradeDisciplineId: {
                relatedDisplayField: 'description'
            }
        };
        return {
            isMulti: {
                allowedFieldNames: ['activityName', 'startDate', 'endDate', 'duration', 'responsible', 'tradeDisciplineId', 'progress'],
                fields: filterPickerFields
            }
        }
    }

Our columns are defined as follows:

    get columns() {
        const data = this.data;
        return [
            { id: "id", field : "id", text : 'ID', hidden: true },
            { id: "activityName", type: "name", field: 'activityName', text: 'Activity Name' },
            { id: "issueConstraints", type: "issue-column", width: "50px", text: "Issues/Constraints" },
            { id: "comment", type: "comment-column", width: "50px", text: "Comment"},
            { id: "startDate", type: "startdate", field : 'startDate', text : 'Start Date', format: bryntumDateFormat },
            { id: "endDate", type: "enddate", field : 'endDate', text : 'End Date', format: bryntumDateFormat },
            { id: "duration", type: "duration", field : "duration", text : "Duration", width: "50px"},
            {
                id: "discipline",
                field : 'tradeDisciplineId',
                type: 'number',
                text : 'Discipline',
                renderer : ({ record }) => record.tradeDiscipline?.description
            },
            {
                id: 'responsible',
                field: 'responsible',
                text: 'Responsible'
            },
            { id: "progress", type: "percentdone", field:'progress', showCircle: true, width: 70, text: "Progress" }
        ];
    }

Our new store:

import {Model, Store} from "@bryntum/gantt";

class TradeDiscipline extends Model {
    static $name = 'TradeDiscipline';

static fields = [
    'id', 'description'
];
}

// Define a separate store holding additional data that we can attach to the main TaskModel, to
// demonstrate setting up relations between models and filtering on them
const tradeDisciplineStore = new Store({
    modelClass : TradeDiscipline,
    data:
        window.clientModel.tradeDisciplines.map(x => {
            return {id: x.tradeDisciplineId, description: x.description}
        })
});

export default tradeDisciplineStore;

From our project-component.vue which wraps the Bryntum Project:

computed: {
        projectConfig() {
            return {
                ...this.$attrs
            };
        },
        taskStore() {
            const vm = this;
            return {
                modelClass: ActivityModel,
                tradeDisciplineStore: tradeDisciplineStore,
                listeners: {
                  .....
            };
        },

Steps to reproduce:

  1. When clicking the filter button on the tradeDiscipline column
  2. Selecting "is one of"
  3. Selecting a value from the dropdown

We get the following error in the console:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'sort')
    at eval (gantt.module.js?3374:99129:1)
    at Array.map (<anonymous>)
    at eval (gantt.module.js?3374:99107:1)
    at Array.forEach (<anonymous>)
    at Filter.refreshHeaders (gantt.module.js?3374:99092:1)
    at Filter.onStoreFilter (gantt.module.js?3374:99875:1)
    at TaskStore.trigger (gantt.module.js?3374:6056:1)
    at TaskStore.trigger (gantt.module.js?3374:127400:1)
    at TaskStore.triggerFilterEvent (gantt.module.js?3374:29113:1)
    at TaskStore.afterPerformFilter (gantt.module.js?3374:29105:1)

gantt.module.js?3374:99129:1

if (isColumnFiltered) {
              const bullet = '&#x2022 ';
              filterText = `${me.L('L{filter}')}: ` + (columnFilters.length > 1 ? '<br/><br/>' : '') + columnFilters.map(columnFilter => {
                var _columnFilter$value, _me$store, _me$store$modelRelati;
                let value = (_columnFilter$value = columnFilter.value) !== null && _columnFilter$value !== void 0 ? _columnFilter$value : '';
                const isArray = Array.isArray(value),
                  relation = (_me$store = me.store) === null || _me$store === void 0 ? void 0 : (_me$store$modelRelati = _me$store.modelRelations) === null || _me$store$modelRelati === void 0 ? void 0 : _me$store$modelRelati.find(({
                    foreignKey
                  }) => foreignKey === columnFilter.property);
                if (columnFilter.displayValue) {
                  value = columnFilter.displayValue;
                } else {
                  if (me.isMulti && relation) {
                    var _me$isMulti$fields;
                    // Look up remote display value per filterable-field config (FieldFilterPicker.js#FieldOption)
                    const {
                      relatedDisplayField
                    } = (_me$isMulti$fields = me.isMulti.fields) === null || _me$isMulti$fields === void 0 ? void 0 : _me$isMulti$fields[columnFilter.property];
                    if (relatedDisplayField) {
                      const getDisplayValue = foreignId => {
                        var _relation$foreignStor;
                        return (_relation$foreignStor = relation.foreignStore.getById(foreignId)) === null || _relation$foreignStor === void 0 ? void 0 : _relation$foreignStor[relatedDisplayField];
                      };
                      if (isArray) {
                          //relatedDisplayField is "description"
[EXCEPTION LINE]                          value = value[relatedDisplayField].sort((a, b) => (a !== null && a !== void 0 ? a : '').localeCompare(b !== null && b !== void 0 ? b : ''));
                      } else {
                        value = getDisplayValue(value);
                      }
                    }
                  } else if (column.formatValue && value) {
                    value = isArray ? value.map(val => column.formatValue(val)) : column.formatValue(value);
                  }
                  if (isArray) {
                    value = `[ ${value.join(', ')} ]`;
                  }
                }
                return (columnFilters.length > 1 ? bullet : '') + (typeof columnFilter === 'string' ? columnFilter : `${columnFilter.operator} ${value}`);
              }).join('<br/><br/>');
            }

However the filter dialog does appear and items can be selected to filter by, but the filter is not actually applied to the data in the grid:

(There is data in the Trade Discipline columns, behind the filter pop-up)

Untitled.png
Untitled.png (77.16 KiB) Viewed 767 times

Re: [VUE] Gantt multi field filter error with gridfieldfilterpickergroup: Uncaught (in promise) TypeError: Cannot read p

Posted: Sun Mar 26, 2023 6:29 am
by emil

Hi seany84,

I believe this is an issue that is being fixed right now. I'll update this ticket as soon as I have an expected release date for the fix.

Thanks,

Emil


Re: [VUE] Gantt multi field filter error with gridfieldfilterpickergroup: Uncaught (in promise) TypeError: Cannot read p

Posted: Mon Mar 27, 2023 11:40 am
by seany84
emil wrote: Sun Mar 26, 2023 6:29 am

Hi seany84,

I believe this is an issue that is being fixed right now. I'll update this ticket as soon as I have an expected release date for the fix.

Thanks,

Emil

Thank you Emil, would you have an estimated release date/version that this fix is being tracked against?

There is a second issue which I believe could be related to this one. The 'Duration' column filter is just showing "No results". This column type is duration and there is no custom store etc.

Can you tell me if this is related or if I should create a new thread for this?

Untitled2.png
Untitled2.png (10.22 KiB) Viewed 711 times

Re: [VUE] Gantt multi field filter error with gridfieldfilterpickergroup: Uncaught (in promise) TypeError: Cannot read p

Posted: Tue Mar 28, 2023 4:14 am
by emil

I've inquired about the target version and will report back here once I know more.

Regarding the duration issue, is the underlying field on your custom TaskModel actually "duration" (as specified in your column definition)? Normally a DurationColumn would use the "fullDuration" field and I think the filter feature expects a Duration-type field like fullDuration. As a test, if you remove the "field: 'duration'" from your Gantt's columns definition, does it change anything?


Re: [VUE] Gantt multi field filter error with gridfieldfilterpickergroup: Uncaught (in promise) TypeError: Cannot read p

Posted: Tue Mar 28, 2023 8:01 pm
by emil

Update: the fix is currently targeting release with 5.3.2. I don't have a date for that yet. I expect the fix to appear in nightlies in the next day or two.


Re: [VUE] Gantt multi field filter error with gridfieldfilterpickergroup: Uncaught (in promise) TypeError: Cannot read p

Posted: Tue Mar 28, 2023 11:07 pm
by seany84
emil wrote: Tue Mar 28, 2023 4:14 am

I've inquired about the target version and will report back here once I know more.

Regarding the duration issue, is the underlying field on your custom TaskModel actually "duration" (as specified in your column definition)? Normally a DurationColumn would use the "fullDuration" field and I think the filter feature expects a Duration-type field like fullDuration. As a test, if you remove the "field: 'duration'" from your Gantt's columns definition, does it change anything?

This worked perfectly for 'duration', as you mentioned, once I removed the 'field' property from the Gantt column and used the 'fullDuration' type it worked 100%.

We have a third and final issue with custom column filtering. Should I post the details here on this thread or raise a new thread?


Re: [VUE] Gantt multi field filter error with gridfieldfilterpickergroup: Uncaught (in promise) TypeError: Cannot read p

Posted: Wed Mar 29, 2023 5:48 am
by emil

A new thread is probably best, but either way is OK. Thanks.


Re: [VUE] Gantt multi field filter error with gridfieldfilterpickergroup: Uncaught (in promise) TypeError: Cannot read p

Posted: Wed Mar 29, 2023 1:30 pm
by seany84

Thanks Emil, I have posted the custom column multi filtering issue here: viewtopic.php?t=24417


Re: [VUE] Gantt multi field filter error with gridfieldfilterpickergroup: Uncaught (in promise) TypeError: Cannot read p

Posted: Thu Mar 30, 2023 12:22 pm
by seany84
emil wrote: Tue Mar 28, 2023 8:01 pm

Update: the fix is currently targeting release with 5.3.2. I don't have a date for that yet. I expect the fix to appear in nightlies in the next day or two.

As a workaround for us here, is it possible to have the gridfieldfilterpickergroup applied to an individual column and have the other columns use the default?


Re: [VUE] Gantt multi field filter error with gridfieldfilterpickergroup: Uncaught (in promise) TypeError: Cannot read p

Posted: Tue Apr 04, 2023 3:00 am
by emil
seany84 wrote: Thu Mar 30, 2023 12:22 pm

As a workaround for us here, is it possible to have the gridfieldfilterpickergroup applied to an individual column and have the other columns use the default?

Hi seany84,

There's no way to achieve that right now. We're making some changes to this feature currently and I'll see if per-column UI selection is something we can/want to support there.

Thanks,

Emil