editGraphe/store.js

import { createStore } from 'redux'
import mainReducer from './reducers'

/** @module editGraphe/store */

const store = createStore(mainReducer, window.devToolsExtension && window.devToolsExtension())
export const dispatch = store.dispatch.bind(store)
export const getState = store.getState.bind(store)

export const getCompteurHistorique = () => store.getState().compteurHistorique
export const getCompteurFutur = () => store.getState().compteurFutur

export const getConfig = () => store.getState().config
export const getConfigProp = (prop) => store.getState().config[prop]
export const getConfigGraphTmp = () => getConfigProp('graphTmp')

export const getObjetGraphe = () => store.getState().graphes.present
export const getObjetGrapheBranchement = (nodeId, branchementIndex) => store.getState().graphes.present.nodes[nodeId].branchements[branchementIndex]
/**
 * Retourne le nb de branchements d’un node
 * @param {string} nodeId
 */
export const getObjetGrapheNbBranchements = (nodeId) => store.getState().graphes.present.nodes[nodeId].branchements.length
export const getObjetGrapheNode = (nodeId) => store.getState().graphes.present.nodes[nodeId]
export const getObjetGrapheReindexBranchementsNeeded = (nodeId) => store.getState().graphes.present.nodes[nodeId].branchements.includes(undefined)
export const getObjetGrapheMaxNumeroNode = () => store.getState().graphes.present.maxNumeroNode
export const getObjetGrapheProp = (prop) => store.getState().graphes.present[prop]

export const getPast = () => store.getState().graphes.past
export const getPastLength = () => store.getState().graphes.past.length

export const getPosition = (index) => store.getState().positionNodes[index]
export const getPositions = () => store.getState().positionNodes

export const getRessource = () => store.getState().ressource

export const getTitre = (index) => store.getState().titreNodes[index]
export const getTitres = () => store.getState().titreNodes

export default store

/**
 * L’instance jsPlumb, affectée par l’init de la scene
 * @type {JsPlumb}
 * @private
 */
let instanceJsPlumb
/**
 * Retourne l’instance jsPlumb
 * @throws {Error} Si l’instance n’avait pas été affectée (pas d’init de la scene)
 * @return {JsPlumb}
 */
export const getJsPlumbInstance = () => {
  if (instanceJsPlumb) return instanceJsPlumb
  throw new Error('Pas d’instance jsPlumb')
}
/**
 * Affecte l’instance jsPlumb
 * @param {JsPlumb} instance
 */
export const setJsPlumbInstance = (instance) => {
  instanceJsPlumb = instance
}

/**
 * L’élément root de l’appli, mis par setRootElt
 * @private
 * @type HTMLElement|undefined
 */
let rootElt
// accesseurs rootElt
/**
 * Retourne le container principal
 * @return {HTMLElement}
 */
export const getRootElt = () => rootElt
/**
 * Affecte le container principal (sans détruire le précédent s’il y en avait un)
 * @param {HTMLElement} elt
 */
export const setRootElt = (elt) => {
  // on impose cet id sur l’élément root
  if (elt.id && elt.id !== 'edgRoot') {
    console.warn(Error('L’élément root devrait avoir l’id edgRoot, on l’impose'))
  }
  elt.id = 'edgRoot'
  rootElt = elt
}

/**
 * Boucle sur les nodes
 * @param {nodeCallback} loopCb appelée avec (node, nodeId, nodes)
 * @returns {boolean|undefined} false si la callback a renvoyé false (et que l’on a alors interrompu la boucle), true sinon
 */
export const loopObjetGrapheNodes = (loopCb, objetGraphe = getObjetGraphe()) => {
  const nodes = objetGraphe.nodes
  // every pour arrêter la boucle et retourner false dès que loop retourne false
  return Object.entries(nodes).every(([nodeId, node]) => loopCb(node, nodeId, nodes))
}
/**
 * Boucle sur les branchements d’un node
 * @param nodeId
 * @param {branchementCallback} loopCb appelée avec (branchement, branchementIndex, branchements)
 * @returns {boolean|undefined} undefined si y’avait pas de node ou qu’il n’avait pas de branchements
 *                              false si la callback a renvoyé false (et que l’on a alors interrompu la boucle)
 *                              true sinon
 */
export const loopObjetGrapheBranchements = (nodeId, loopCb, objetGraphe = getObjetGraphe()) => {
  const node = objetGraphe.nodes[nodeId]
  if (node && node.branchements) {
    // every pour arrêter la boucle si la callback retourne false
    return node.branchements.every((branchement, i) => loopCb(node.branchements[i], i, node.branchements, objetGraphe) !== false)
  }
}

/**
 * @typedef Position
 * @type {Array}
 * @property {number} 0 Abscisse
 * @property {number} 1 Ordonnée
 */

/**
 * @callback branchementCallback
 * @param {Branchement} branchement Le branchement (idem branchements[prop])
 * @param {string} branchementKey La propriété du branchement
 * @param {Branchement[]} branchements Tous les branchements du node
 */

/**
 * Le graphe tel qu’il est stocké dans la bibli en tableau
 * @typedef TabGraphe
 * @type {TabNode[]}
 */

/**
 * Le graphe tel qu’il est stocké dans editgraphe en objet
 * @typedef ObjetGraphe
 * @param {Node[]} nodes
 */

/**
 * Un noeud dans le graphe j3p (au format TabGraphe)
 * @typedef TabNode
 * @type {Array}
 * @property {number} 0 numéro du noeud (nodeId ailleurs)
 * @property {string} 1 nom de la section
 * @property {object[]} 2 Les branchements avec les paramètres de la section en dernier
 */

/**
 * Un node dans objetGraphe, son nodeId qui l’indexe dans l’objet objetGraphe.nodes est le numéro du nœud dans Noeud
 * @typedef Node
 * @type {Object}
 * @property {string} title
 * @property {string} section nom de la section (idem noeud[1])
 * @property {object} parametres Les paramètres qui étaient dans tabGraphe
 * @property {Array} branchements
 * @property {number} top
 * @property {number} left
 */

/**
 * Branchement, dans un TabGraphe (les éléments du tableau tabNode[2] sauf le dernier)
 * @typedef Branchement
 * @type {Object}
 * @property {string} nn Vers le noeud nn
 * @property {string} [pe] Condition pour aller vers nn
 * @property {string} conclusion Texte affiché avant de passer à nn
 * @property {string} [snn] Sinon vers le noeud snn
 * @property {string} [sconclusion] Texte affiché avant de passer à snn
 */

/**
 * Connexion, une connexion jsPlumb, avec le branchement dont elle est issue (un branchement avec snn peut donner deux connexions)
 * @typedef Connexion
 * @property {number} sourceNodeId L’index du node dans objetGraphe.nodes
 * @property {number} branchementIndex L’index du branchement dans node.branchements
 * @property {Branchement} branchement Le branchement dont la connexion est issue
 */

/**
 * Une connexion jsPlumb (item d’une liste retournée par un select ou un getConnections)
 * Ne pas modifier ces propriétés directement, passer par les fcts jsPlumb
 * (cf http://jsplumb.github.io/jsplumb/utilities.html)
 * @typedef JspConnexion
 * @property {string} id le domId de la connexion
 * @property {string} sourceId Le domId du node source
 * @property {string} targetId Le domId du node destination
 * @property {HTMLElement} source le node source
 * @property {HTMLElement} target le node destination
 * @property {string} scope
 */