Page 1 of 1

[REACT] StateTrackingManager canUndo/canRedo

Posted: Thu Sep 29, 2022 5:34 pm
by ninjakon

Hello,

We have implemented basic undo/redo buttons using the https://bryntum.com/docs/gantt/api/Core/data/stm/StateTrackingManager.
Now we would like to disable those buttons based on the flags stm.canUndo and stm.canRedo.

We make use of React.useState() to trigger a re-render if those flags change:

const [canUndo, setCanUndo] = useState(false);
const [canRedo, setCanRedo] = useState(false);

And subscribe to TaskStore.onChange in a useEffect like this:

useEffect(() => {
    if (gantt) {
      gantt.taskStore.onChange = ({
        source,
      }: {
        source: { stm: StateTrackingManager };
      }) => {
        const { stm } = source;
        setCanUndo(stm.canUndo);
        setCanRedo(stm.canRedo);
      };
    }
 }, [gantt]);

However, after any task store event both flags, stm.canUndo and stm.canRedo, always return false.
But when we output the stm in the dev console canUndo is true after a change event as it should be.

How can we subscribe to task store events in such a fashion that our useState() is set correctly?


Re: [REACT] StateTrackingManager canUndo/canRedo

Posted: Thu Sep 29, 2022 7:11 pm
by marcio

Hello ninjakon,

Thanks for the detailed case, do you have some special configuration set in the Gantt configuration?? In the useEffect code that you shared, you only set in the component state the current state of the stm.

Could you please provide a complete example with your case?? You can check the guidelines here viewtopic.php?f=1&t=772


Re: [REACT] StateTrackingManager canUndo/canRedo

Posted: Mon Oct 03, 2022 11:17 am
by ninjakon

Attached to this post is a zip demonstrating the issue.

You can run it with:

  1. npm install
  2. npm run start

To reproduce the issue follow these steps:

  1. Change a tasks startDate by dragging it in the gantt chart
  2. Check the console.log
  3. taskStore.onChange was triggered but stm.canUndo is still "false"

The button placement is not ideal so I marked it here:

Screenshot 2022-10-03 at 11.07.29.png
Screenshot 2022-10-03 at 11.07.29.png (190.94 KiB) Viewed 256 times

Re: [REACT] StateTrackingManager canUndo/canRedo

Posted: Mon Oct 03, 2022 11:16 pm
by marcio

Hey ninjakon,

Thanks for the sample project and the detailed step-by-step to reproduce. Checking the code, you need to check the STM of the project (that's the one that you enabled in the config), also, the console.log issue is because STM transactions are asynchronous, so when you console them, they aren't finished, so the undo is still false, then after checking the dev console, it displays true. I updated the useEffect to work as you described/coded.

 useEffect(() => {
    if (ganttRef && ganttRef.current) {
      const gantt = ganttRef.current.instance;
        gantt.project.stm.addListener({
          recordingStop: (data: any) => {
              const {stm} = data
              console.log(`STM: canUndo=${stm.canUndo} canRedo=${stm.canRedo}`);  
} }) } }, [ganttRef]);

https://www.bryntum.com/docs/gantt/api/Core/data/stm/StateTrackingManager#event-recordingStop


Re: [REACT] StateTrackingManager canUndo/canRedo

Posted: Fri Oct 07, 2022 9:03 pm
by ninjakon

Yes, but then we still had the problem with react not re-rendering.

However, you nudged me in the right direction with the listeners.
Creating our own StateTrackingManager instance did the trick.

If anyone runs into the same problem, this is the code which worked for us:

const [canUndo, setCanUndo] = useState(false);
const [canRedo, setCanRedo] = useState(false);
const [stateTrackingManager, setStateTrackingManager] = useState<StateTrackingManager>();

useEffect(() => {
  const tmp = new StateTrackingManager({
    autoRecord: true,
    listeners: {
      recordingstop: ({ stm }: { stm: StateTrackingManager }) => {
        setCanUndo(stm.canUndo);
        setCanRedo(stm.canRedo);
      },
      restoringstop: ({ stm }: { stm: StateTrackingManager }) => {
        setCanUndo(stm.canUndo);
        setCanRedo(stm.canRedo);
      },
    },
  });
  tmp.addStore(gantt.project.taskStore);
  tmp.enable();
  setStateTrackingManager(tmp);
}, [gantt]);

Thanks Marcio!


Re: [REACT] StateTrackingManager canUndo/canRedo

Posted: Fri Oct 07, 2022 9:46 pm
by marcio

Thanks ninjakon for sharing your solution too! Glad that you figure it out! :)