Hello Team
We are facing problem while fetching the newly added task to the Grid (we have action column to open a Add task modal). Please check the attached Add Task column code and related columns to see what's the problem is.
- My implementation for adding a new task involves opening a Modal (using props.openModal), collecting the details, and then submitting them via an API call. Everything is working till here.
Upon successful submission, I attempt to reflect the new data in the Gantt grid instantly by calling the ganttInstance.taskStore.add method with the task object (data from the Add task modal).
The current behavior is inconsistent: Core fields like the task's Name and importance update as expected, achieving the instant reflection. However, secondary fields—specifically status, functionsCount, and documents Count—are missing from the grid until the application is refreshed. We need these fields to display immediately. (Please check screenshot Bryntum-test, Bryntum Test-2, Bryntum Test 3 - only put 1 as not able to upload more thn 3 files).
After adding a Task the icon is inconsistent, We have after render method which will calculate the icon according to the Level, but as soon as i add any Task it started showing L3 icon all the time till the time i refresh the page.
Column filter : when we are selecting the filters for date column and than delete filter from trash icon. the filter is still displayed on the screen in half broken state. Please see the screenshot attached.
Grid WBS Refresh : WBS for the grids are auto changing even if it is saved correctly in DB. On the bryntum grid WBS changes to something else and reorganise itself.
5.When there is no start date-end date in the grid. I tried to select a start date it will ask me to select end date first. And sometime calendar control also moved to top left corner of the screen while selecting.
Add task column code
{
type: 'action', width: 50, region: 'left',
actions: [{
cls: 'add-new-task',
visible: ({ record }) => (record['level'] === TaskOutlineLevel.Level1) ? false : ((record['level'] < 5) &&
(props.projectData.ProjectAccess === UserProjectAccess.PrimaryLead) ||
(props.projectData.ProjectAccess === UserProjectAccess.SecondaryLead)) ||
(record['level'] > 2 && (record['taskAccess'] === UserTaskAccess.Owner ||
record['taskAccess'] === UserTaskAccess.CoOwner))
,
tooltip: 'Add new task',
onClick: ({ record }) => {
props.openModal(
<AddTask
projectId={props.projectGuid}
webpartContext={props.webpartContext}
popUpDetails={record}
projectAccess={props.projectData.ProjectAccess}
onUpdateAddTask={async (param: any) => {
const ganttInstance = ganttRef.current?.instance;
const isParantLevel = record['level'] === param.Level;
const parentId = isParantLevel ? record.parentId : record.id;
const assignments: string[] = [param.Owner, ...param.CoOwners];
const taskRec = ganttInstance.taskStore.add({
id: param.id,
name: param.TaskName,
parentId,
startDate: param.StartDate,
endDate: param.EndDate,
lastUpdatedBy: props.webpartContext?.pageContext?.user?.email?.toLowerCase() || "",
importance: param.importance,
statusName: TaskStatus.NotStarted,
functionsCount: 0,
documentsCount: 0
});
await ganttInstance.project.commitAsync();
ganttInstance.renderRows();
}}
/>
)
}
}],
filterable: false,
sortable: false,
editor: false,
},
Documentation Column Code
{
text: "Documentation",
field: "documentsCount",
editor: false, readonly: true,
align: "center", width: 150,
renderer: ({ record }) => {
return record['level'] > TaskOutlineLevel.Level1 ?
<div className='documentWrapper'>
<DefaultButton
className='documents-cls'
text={record.documentsCount}
title={`${record.documentsCount} Documents`}
disabled={IsTemplateTask(record)}
onClick={() => onDocumentsActionClicked("view", record)}
/>
{(record["level"] >= 2 && (props.projectData.ProjectAccess === UserProjectAccess.PrimaryLead || props.projectData.ProjectAccess === UserProjectAccess.SecondaryLead ||
record["taskAccess"] === UserTaskAccess.Owner || record["taskAccess"] === UserTaskAccess.CoOwner)) && <ActionButton
iconProps={{ iconName: "CloudUpload" }}
title='Upload Documents'
disabled={IsTemplateTask(record)}
onClick={() => onDocumentsActionClicked("upload", record)}
>
</ActionButton>}
</div>
:
''
}
},
Function column code
{
text: "Functions", field: "functionsCount",
editor: false, readonly: true,
align: "center", width: 100,
renderer: ({ record }) => {
return record['level'] > TaskOutlineLevel.Level1 ? <DefaultButton
className='documents-cls'
text={record.functionsCount}
title={`${record.functionsCount} functions`}
disabled={IsTemplateTask(record)}
onClick={() =>
props.openModal(<TaskFunctionsModal
projectGuid={props.projectGuid}
webpartContext={props.webpartContext}
record={record}
projectData={props.projectData}
onUpdateTaskFunctionsCount={(param: any) => {
record.set({ functionsCount: param });
}} />)
}
/> : ""
}
},
After render method to calculate Task icon logic
{
id: 'activity', type: 'name', text: 'Task', sortable: true, filterable: true, width: 350, region: 'left',
tooltipRenderer: ({ record }) => record["name"],
afterRenderCell: (props) => {
const { cellElement, record, grid, row } = props;
const exp = cellElement.querySelector('.b-tree-expander, .b-tree-toggle, .b-tree-icon');
if (!exp) return;
exp.classList.remove('b-icon-tree-collapse');
exp.classList.remove('b-icon-tree-expand');
exp.classList.remove('b-icon-tree-leaf');
exp.classList.remove('first-level-expand-icon');
exp.classList.remove('first-level-collapsed-icon');
exp.classList.remove('second-level-expand-icon');
exp.classList.remove('second-level-collapsed-icon');
exp.classList.remove('level-expanded');
exp.classList.remove('first-level-icon');
exp.classList.remove('second-level-icon');
exp.classList.remove('third-level-icon');
exp.classList.remove('leaf-level-icon');
const levelClassMap: Record<number, string> = {
[TaskOutlineLevel.Level1]: "first-level-icon",
[TaskOutlineLevel.Level2]: "second-level-icon",
[TaskOutlineLevel.Level3]: "third-level-icon",
[TaskOutlineLevel.Level4]: "leaf-level-icon"
};
const levelClass = levelClassMap[record.level] || "leaf-level-icon";
exp.classList.add(levelClass);
if (record.level >= TaskOutlineLevel.Level3 && record.isLeaf) {
exp.classList.remove('third-level-icon');
exp.classList.remove('leaf-level-icon');
exp.classList.add('leaf-level-icon');
}
const expanded = record.isExpanded(grid.taskStore);
if (expanded) {
exp.classList.add("level-expanded");
}
},
expandIconCls: 'iconCls',
collapseIconCls: 'iconCls',
leafIconCls: 'iconCls leaf-level-icon',
finalizeCellEdit: ({ value }) => {
return value.length === 0 ? 'Please enter a name.' : true;
}
},