Page 1 of 1

[ANGULAR]- Undo not consistently working in recordingStop for unauthorized task edits

Posted: Fri Sep 12, 2025 2:43 pm
by gokulnaths

Hi Bryntum team,

I’m using STM (StateTrackingManager) in Gantt with autoRecord: true to validate edits against custom authorization logic. My goal is:

When a user edits a task or dependency, I check if they have permission.

If unauthorized, I want to cancel/undo the entire transaction and show an error popup.

Here’s a simplified snippet of my STM config:

stm: {
  autoRecord: true,
  listeners: {
    recordingStop: ({ stm, transaction }) => {
      this.unauthorizedTasks = [];

  if (this.readOnlyTagVisible == false && !this.isCurrentUserAdmin) {
    let invalid = false;

    transaction.queue.forEach((queueItem: any) => {
      // Case 1: Task updates
      if (queueItem.$$name === "EventUpdateAction" && queueItem.model) {
        const editorIds = [
          ...(queueItem.model?.editor || []),
          ...(queueItem.model?.inheritedEditor || [])
        ];
        if (!this.isUserAuthorized(editorIds)) {
          invalid = true;
          this.unauthorizedTasks.push({
            name: queueItem.model?.name,
            wbs: queueItem.model?.wbsValue?._value,
            sequenceNumber: queueItem.model?.sequenceNumber
          });
        }
      }

      // Case 2: Dependency changes
      else if (
        queueItem.store._id === "dependencies" &&
        (queueItem.$$name === "AddAction" || queueItem.$$name === "RemoveAction") &&
        queueItem.modelList
      ) {
        const fromEvent = queueItem.modelList[0]?.fromEvent;
        const toEvent = queueItem.modelList[0]?.toEvent;

        const fromEditorIds = [
          ...(fromEvent?.editor || []),
          ...(fromEvent?.inheritedEditor || [])
        ];
        const toEditorIds = [
          ...(toEvent?.editor || []),
          ...(toEvent?.inheritedEditor || [])
        ];

        if (fromEvent && !this.isUserAuthorized(fromEditorIds)) {
          invalid = true;
          this.unauthorizedTasks.push({
            name: fromEvent.name,
            wbs: fromEvent.wbsValue?._value,
            sequenceNumber: fromEvent.sequenceNumber
          });
        }
        if (toEvent && !this.isUserAuthorized(toEditorIds)) {
          invalid = true;
          this.unauthorizedTasks.push({
            name: toEvent.name,
            wbs: toEvent.wbsValue?._value,
            sequenceNumber: toEvent.sequenceNumber
          });
        }
      }
    });

    if (invalid) {
      stm.undo(); // rollback
      this.isUnauthorizedEditVisible = true; // show popup
      console.warn("Invalid transaction, undoing...");
    }
  }
}
  }
}

Problem I’m facing:

The first time unauthorized changes are made, stm.undo() works correctly.

But on the second attempt, the changes are still applied in the Gantt and stm.undo() does not revert them.

It seems like after the first undo, STM does not always record the next invalid transaction, so there’s nothing to undo.

Question:

Is there a recommended way to cancel/rollback an STM transaction before it’s committed (so changes are never reflected in the Gantt)?

If not, how should I correctly use STM to ensure multiple consecutive unauthorized edits are always undone?

Thanks in advance!


Re: [ANGULAR]- Undo not consistently working in recordingStop for unauthorized task edits

Posted: Fri Sep 12, 2025 4:09 pm
by alex.l

Hi,

Is there a recommended way to cancel/rollback an STM transaction before it’s committed (so changes are never reflected in the Gantt)?

It feels like validate rights using this https://bryntum.com/products/gantt/docs/api/Gantt/model/ProjectModel#event-beforeSync async and preventable event might be easier. Just check it here and if not valid, return false and undo changes.

What do you think, will that work for you?