Our state of the art Gantt chart


Post by arcady »

Hello

Then On Scheduling Cycle Popup window, when I click on the Apply button, the sync should trigger.
If there is really no workaround, please give me confirmation so that from our end we can just do a workaround like manually deleting those records from the backend, then we can both move on.

You have silenceInitialCommit enabled which is made specifically for preventing autoSync-ing when loading the data.
So a proper way of solving cases w/ dirty data that need normalization is setting silenceInitialCommit to false.

I don't know why your application removes dependencies when you change the flag and we cannot investigate that w/o a test case.

So yes you can of course add a custom application level processing of conflicts/cycles if you don't want to use the suggested way.

The reason project.sync() doesn't work is "Apply" button handler is called in the middle of the Engine transaction. And sync() method inside calls project.commitChanges which messes the transaction up.

You can send a sync request using using a bit lower level but still public API:

            const { project } = this;

            // sending a sync request manually
            await project.sendRequest({
                type : 'sync',
                data : project.encode(project.changes)
            });

Also worth mentioning that some changes have not reached the data level at the stage "Apply" button gets clicked.
This happens since changes are first written to the Engine (record field changes) and some (record removals for example) are first made on the data level in a store.

Best regards,
Arcady


Post by rodel.ocfemia »

This fix works. Thanks a lot.

class customCycleResolutionPopup extends CycleResolutionPopup {
    async onApplyButtonClick() {
      // eslint-disable-next-line @typescript-eslint/no-this-alias
      const me = this;
      const { selectedResolutions } = me;
      let project: any;

  if (selectedResolutions.size) {
    selectedResolutions.forEach((resolution: any) => {
      const resolutionParameters = me.getResolutionParameters(resolution);
      if (!project) {
        project = resolutionParameters[0].project;
      }
      return resolution.resolve(...resolutionParameters);
    });

    me.continueWithResolutionResult('Resume');
    me.doResolve(selectedResolutions);
    await project.sendRequest({
      type: 'sync',
      data: project.encode(project.changes),
    });
  } else {
    me.onCancelButtonClick();
  }
}
  }

Post by rodel.ocfemia »

Hi,
We found another issue related to scheduling cycle. If the dependency is from child task to parent task with dependency type start to start, the Scheduling Cycle popup is different.

Please note, I have manually created this dependency in the launch-saas.json because in our real data, we have existing the same dependencies. Right now, Bryntum does not allow creating child task to parent task.

Dependency-child-to-parent-StartToStart.PNG
Dependency-child-to-parent-StartToStart.PNG (36.63 KiB) Viewed 41 times

I tried the following fix, but it is throwing error "Cannot read properties of undefined (reading 'project')"

class customCycleResolutionPopup extends CycleResolutionPopup {
    async onApplyButtonClick() {
      const me = this as any,
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        { selectedResolutions } = me;

  let project: any;
  if (selectedResolutions.size) {
    // apply selected resolutions
    selectedResolutions.forEach((resolution: any) => {
      const resolutionParameters = me.getResolutionParameters(resolution);
      if (!project) {
        project = resolutionParameters[0].project;
      }
      return resolution.resolve(...resolutionParameters);
    });

    me.continueWithResolutionResult('Resume');
    me.doResolve(selectedResolutions);
    await project.sendRequest({
      type: 'sync',
      data: project.encode(project.changes),
    });
  } else {
    me.onCancelButtonClick();
  }
}
}

Please find attached testable code.

SchedulingCycle3.zip
(2.24 MiB) Downloaded 8 times

Post by arcady »

Hello,

There are different types of resolutions. Some of them require additional argument and some don't.
Yes parent-child dependencies are treated in a different way and their resolutions don't need extra arguments.
So this code won't work:

        if (!project) {
          project = resolutionParameters[0].project;
        }

Project instance is stored in project property of the resolution popup so the following code should work (part of the code I posted above):

project = me.project;

Best regards,
Arcady


Post by rodel.ocfemia »

This one works for both dependency scenarios. Thanks

project = me.project;

Post Reply