[React + REDUX] Data array - What info is available?

Hi!

I’m working with React and REDUX as store for my software. The info wich is render on the Gantt Component is stored at REDUX Store, and I’ve implemented the gantt component as a react component (similar to the React example that is available).

Now, my problem is that some features and methods from the gantt componen are only available at the component scope; for example. “gantt.getPreviousSibling” is one of the methods that I need to access from another scope, specifically to make the indent feature available.

With this intro, what I need to know if the data array’s info is good enough to redo a getPreviousSiblings function.

Thanks in advance!

Hello,
Unfortunately, we don’t have much experience with react, so I’m not sure that I’ll be able to help you.

Probably there is a way to expose such methods by wrapping them into methods of your controller class, but I’m not sure what is the appropriate approach in react.js

In the worst case, you can use a global instance of gantt in all your components - dhtmlxgantt.js defines a default instance of gantt globally (window.gantt). So if you use that instance - you can call it everywhere in your app.
You’ll either need to declare the instance using lint comment:

/* global gantt */

or you can take it from the window object:

const { gantt } = window;

It may be not the cleanest solution, but it should work everywhere.

Regarding your last question:

With this intro, what I need to know if the data array’s info is good enough to redo a getPreviousSiblings function.

I’m not sure I understand what you mean here. Can you please rephrase this?

Hi ramil!

What I’m trying to do is to make compatible the indent/outdent algorithm available from the demos. As I think, various gantt methods available are not compatible with a React+Redux architecture, understanding that the Gantt data is in the redux store, and the “only” way to make modifications on the store is through redux Actions, so the “gantt.something” functions are not compatible with our architecture.

Now, to make compatible the the indent/outdent algorithm we need the “previousSiblings” method, so… the questions is: is posible to make a previousSiblings function with the information available on the Gantt Data Array?

I think that I was able to do it with the next code:

getPreviousSibling = (taskId) => {
let task = _.find(this.props.data.data, x => x.id == taskId)
if (typeof task !== 'undefined') {
  let previous = _.find(this.props.data.data, x => x.$index === (task.$index - 1))
  if (typeof previous !== 'undefined') {
    if (previous.$level === task.$level) {
      return previous
    }
  }
}
return null;}

Thanks for all ramil!

Hi!
well, this may be a bit difficult.
In gantt component we had to implement relatively complex data store module in order to support all the data manipulations the component can do. So if you want to do all actions available in gantt on the data array - you may end up implementing something of comparable complexity.

the questions is: is posible to make a previousSiblings function with the information available on the Gantt Data Array?

Overall - yes.
Gantt data array describes a tree structure - each item has an id (task.id) and a link to a parent element (task.parent).
And getting a previous sibling of a tree node is totally doable, e.g.

  1. you have some taskId and you want to find an id of its previous sibling
  2. go to the parent element
  3. iterate child nodes of Parent
  4. if(children[i].id == taskId) return children[i - 1].id

there is no info you don’t have in tasks array.

So you can implement some kind helper to build a tree structure from the array of tasks and then you can code common operations.

A possible issue with the code you sent, is that I think it relies on gantt instance to work:

if (previous.$level === task.$level) 

From properties $level and $index it seems like this.props.data is a live reference to the data array currently loaded into dhtmlxGantt. Gantt assigns these properties dynamically during work (gantt.parse doesn’t to deep copy).
Looks like records in your tasks array can be modified by gantt and aren’t truly isolated from it.
If the code already relies on gantt, you might as well use gantt methods directly.
For example, you can perform the operation using the gantt instance, after that you can unload {data, links} object from gantt and update your model.

indentTasks = (tasksArray) => {
   ... indent tasks using gantt instance
   
   return gantt.serialize();// return updated array of tasks and links

}

Ideally, if dhtmlxGantt would be modular enough so you could use its core as a helper for calculations but unfortunately we’re not there at the moment.

To answer your question, I can see two ways:

  1. The tasks array contains all required info to interpret it as a tree.
    When you know you’re working with a tree structure implementing common operations will become simpler - i.e. iterate/delete all subtasks, get next-previous siblings.

  2. Or, you can still try using gantt, even though it’s not ideal from the architecture standpoint.
    If you want to get the updated data from gantt you can use gantt.serialize()

Hi Aliaksandr

I’ve actually chose to change the way that we worked with the gantt component, in the way that the “gantt.”'s methods are available to use, and separating the component from the redux store like we used to store and change every state of the Gantt with actions triggered from some buttons.

Thanks for the guidance!