from flask import Flask, request, render_template, url_for, jsonify, make_response, session, g, Response
# from flask import Flask, request, render_template, url_for, json, jsonify
import json
-from pprint import pprint
-from forms import BasicForm
-from collections import OrderedDict
+from pprint import pprint
+from forms import BasicForm
+from collections import OrderedDict
from markupsafe import escape
from flask_sse import sse
# """Flask subclass using the custom request class"""
# request_class = MyReq
-def createConnecteur(app):
+def createConnecteur(app):
monConnecteur=accasConnecteur(code, langue='ang',appWeb=app)
return monConnecteur
#print ('Flask/propageValide: ', id, valid)
sse.publish( {'id':id, 'valid':valid, 'message': "Hello from propageValide!"}, type='propageValide')
+def updateNodeInfo(id, info):
+ #print ('Flask/updateNodeInfo: ', id, info)
+ sse.publish( {'id':id, 'info':info, 'message': "Hello from updateNodeInfo!"}, type='updateNodeInfo')
+
def appendChildren(id, fcyTreeJson, pos):
print ('Flask/appendChildren: ', id, fcyTreeJson, pos)
sse.publish( {'id':id, 'fcyTreeSrc':fcyTreeJson, 'pos':pos, 'message': "Hello from appendChildren!"}, type='appendChildren')
-
+
def deleteChildren(idList):
#print ('Flask/deleteChildren: ', idList)
sse.publish( {'idList':idList,'message': "Hello from deleteChildren!"}, type='deleteChildren')
-
+
# # Pour test curl
# @app.route('/update')
# def publish_update():
myFancyTreeDico=monConnecteur.getDicoForFancy(monConnecteur.monEditeur.tree.racine)
myTreeJS=json.dumps([myTreeDico])
- myFancyTreeJS=json.dumps([myFancyTreeDico])
+ # myFancyTreeJS=json.dumps([myFancyTreeDico])
+ myFancyTreeJS=json.dumps([myFancyTreeDico],indent=4) #TODO : remove indent if not DEBUG
# myNewTreeDico=OrderedDict([('text', 'MonProc2'), ('nodes', OrderedDict([('text', 'MonProc22'), ('nodes', [{'text': 'param1 1.0'}, [OrderedDict([('text', 'Fact1'), ('nodes', [{'text': 'param3 43.0'}])]), OrderedDict([('text', 'Fact1'), ('nodes', [{'text': 'param3 44.0'}])])]])]))])
# myNewTreeJS=json.dumps([myNewTreeDico])
# Parse the JSON into a Python dictionary
req = request.get_json()
# Print the dictionary
- print(req);print(req['id']);print(req['name']);print(req['pos'])
+ print(__file__+"/appendChild : ",req);
id=req['id'];name=req['name'];pos=req['pos'];
# id, value = req.values() # Dangereux correspondance implicite
#rId,message,changeDone = monConnecteur.appendChild(id,name,pos);
newId = monConnecteur.appendChild(id,name,pos);
- print ("/appendChild : newId : ",newId)
+ print (__file__+"/appendChild : newId : ",newId)
return make_response(json.dumps( {'id':newId} ))
# return make_response(json.dumps( {'source':node, 'changeIsAccepted' : changeDone, 'message': message} ))
<!-- </div> -->
<!-- <h2>Messages</h2> -->
<!-- <span id="tree1-messages" class="nav navbar-nav col-sm-12 navbar-right alert alert-success" >....</span> -->
- <footer id="tree1-messages" class="container-fluid footer col-sm-12 alert alert-success" >....</footer>
+ <footer id="tree1-messages" class="container-fluid footer col-sm-12 alert alert-success" >No message.</footer>
<!-- alert alert-success alert-info alert-warning alert-danger -->
<!-- </div> -->
<!-- </nav> -->
// on récupère bien l'evenement appendChild --> validation, promise...
// TODO : ?async?
function callService(serviceName, obj, callBack) {
- let msgCssSelStr = '#tree1-messages';
- var success = function(data, status) {
+ const msgCssSelStr = '#tree1-messages';
+ const success = function(data, status) {
message="Successfull "+serviceName+" call with status : " + status;
treeMessage(msgCssSelStr,"alert-success",message) ;
callBack(data);
};
- let url = "{{ url_for('appendChild') }}";
- let newurl = url.replace("appendChild", serviceName); //TODO : Trouver une meilleure solution !
+ const url = "{{ url_for('appendChild') }}";
+ const newurl = url.replace("appendChild", serviceName); //TODO : Trouver une meilleure solution !
$.ajax({
type : "POST",
url : newurl,
// APPELS EXPLICITES AU SERVER
function clickOnRemove(treeCssSelStr, msgCssSelStr, key ) {
- var tree = $.ui.fancytree.getTree(treeCssSelStr);
- var _key = key;
+ const tree = $.ui.fancytree.getTree(treeCssSelStr);
+ const _key = key;
if ( key == "") {
activeNode = tree.activeNode;
if ( activeNode != null) {
};
};
- let checkCallBack = function(data) {
+ const checkCallBack = function(data) {
// Tester data == NULL !
ret = data['ret'];
if ( ret == null ) {
// TODO : Il faudrait s'assurer que si une requête de ce type est envoyée au serveur
// on récupère bien l'evenement appendChild --> validation, promise...
function sendAppendChild( key, name, pos) {
- let msgCssSelStr = '#tree1-messages';
+ const msgCssSelStr = '#tree1-messages';
- let checkCallBack = function(data) {
+ const checkCallBack = function(data) {
// Tester data == NULL !
rId = data['id'];
if ( rId == null ) {
function getParentCommandNode(node) {
if ( node == null ) return null;
- let parentList = node.getParentList(false,true); // default : (false,false)==(rootNode exclus, not self)
+ const parentList = node.getParentList(false,true); // default : (false,false)==(rootNode exclus, not self)
return parentList[1]; // parentList()[0] is always the efficas <code> name
};
// TODO Vérif assertion : Les functions clickOn ont des arguments en chaîne de caractères pour être facilement
// utilsées dans les attributs des elements html on="clickOn('arg1','arg2',)"
function clickOnCommand(treeCssSelStr, msgCssSelStr, cmdName, key ) {
- tree = $.ui.fancytree.getTree(treeCssSelStr);
+ const tree = $.ui.fancytree.getTree(treeCssSelStr);
if ( key != "") {
- activeNode=tree.getNodeByKey(key);
+ fromNode = tree.getNodeByKey(key);
} else {
- activeNode = tree.activeNode;
+ fromNode = tree.activeNode;
};
- if ( activeNode == null) {
+ if ( fromNode == null) {
index=0; pos=0;
} else {
- parentList = activeNode.getParentList(); // default : (false,false)==(rootNode exclus, not self)
+ parentList = fromNode.getParentList(); // default : (false,false)==(rootNode exclus, not self)
console.log("clickOnCommand : parentList "+parentList)
if ( parentList.length == 0 ) { // TODO : Verif, ne devrait pas être possible
console.log("clickOnCommand : index is forced = 0");
index=0; pos=0; // The first node is always the code name
} else {
if ( parentList.length == 1 ) {
- activeCommandKey = activeNode.key;
+ activeCommandKey = fromNode.key;
} else {
- activeCommandKey = parentList[1].key; //activeNode.getParentList()[0] is always the <efficas code> node so [1] is always the first level, the eficas command level
+ activeCommandKey = parentList[1].key; //fromNode.getParentList()[0] is always the <efficas code> node so [1] is always the first level, the eficas command level
};
console.log("clickOnCommand : activeCommandKey "+activeCommandKey)
commandList = tree.rootNode.getChildren()[0].getChildren(); // le premier node est actuellement le nom de code
//GESTION DES EVENEMENTS PROVENANT DU SERVEUR
-var source = new EventSource("{{ url_for('sse.stream') }}");
+const source = new EventSource("{{ url_for('sse.stream') }}");
// --- propageValid ---
(function (treeCssSelStr, msgCssSelStr) {
// var _tree = $.ui.fancytree.getTree(_treeCssSelStr);
source.addEventListener('propageValide', function(event) {
const data = JSON.parse(event.data);
- var id = data.id;
- var valid = data.valid;
- var message = "The server says " + data.message +" , id: "+id;
- var tree = $.ui.fancytree.getTree(_treeCssSelStr);
+ const id = data.id;
+ const valid = data.valid;
+ const message = "The server says " + data.message +" , id: "+id;
+ const tree = $.ui.fancytree.getTree(_treeCssSelStr);
treeMessage(_msgCssSelStr,"alert-info",message);
// console.log("_tree : "+ _tree); //?Expliquer pourquoi null: à cause de $.?
node=tree.getNodeByKey(id);
node.data.validite=valid; //TODO : ?? Pas encore réussi à tester ... ??
node.render(true,false); //force rendering the node (not parents nor descendants)
- //node.renderStatus(); //CSS element updates
+ //node.renderStatus(); //CSS element updates only
+ }, false);
+})('#tree1','#tree1-messages');
+
+// --- updateNodeInfo ---
+(function (treeCssSelStr, msgCssSelStr) {
+ const _treeCssSelStr = treeCssSelStr; //inutile
+ const _msgCssSelStr = msgCssSelStr; //inutile
+ // var _tree = $.ui.fancytree.getTree(_treeCssSelStr);
+ source.addEventListener('updateNodeInfo', function(event) {
+ const data = JSON.parse(event.data);
+ const id = data.id;
+ const info = data.info;
+ const message = "The server says " + data.message +" , id: "+id;
+ const tree = $.ui.fancytree.getTree(_treeCssSelStr);
+
+ treeMessage(_msgCssSelStr,"alert-info",message);
+ const node=tree.getNodeByKey(id);
+ Object.assign(node.data,info); //merge new options to node.data
+ node.render(true,false); //force rendering the node (not parents nor descendants)
+ //node.renderStatus(); //CSS element updates only
}, false);
})('#tree1','#tree1-messages');
// --- appendChildren ---
(function (treeCssSelStr, msgCssSelStr) {
- let _treeCssSelStr = treeCssSelStr; //inutile
- let _msgCssSelStr = msgCssSelStr; //inutile
- var _tree = $.ui.fancytree.getTree(_treeCssSelStr);
+ const _treeCssSelStr = treeCssSelStr; //inutile
+ const _msgCssSelStr = msgCssSelStr; //inutile
+ const _tree = $.ui.fancytree.getTree(_treeCssSelStr);
source.addEventListener('appendChildren', function(event) {
const data = JSON.parse(event.data);
- var id = data.id;
+ const id = data.id;
const source = data.fcyTreeSrc;
- var pos = data.pos;
+ const pos = data.pos;
//var message = data.message;
- var message = "The server says " + data.message +" , id: "+id;
+ const message = "The server says " + data.message +" , id: "+id;
treeMessage(_msgCssSelStr,"alert-info",message);
console.log("_tree : "+ _tree); //?Expliquer pourquoi null: à cause de $.?
- var tree = $.ui.fancytree.getTree(_treeCssSelStr);
- var node = tree.getNodeByKey(id);
- var countChildren = node.countChildren(false);
+ const tree = $.ui.fancytree.getTree(_treeCssSelStr);
+ const node = tree.getNodeByKey(id);
+ const countChildren = node.countChildren(false);
console.log("countChildren : "+ countChildren);
console.log("pos : "+ pos);
if ( pos >= countChildren) {
// --- deleteChildren ---
(function (treeCssSelStr, msgCssSelStr) {
- let _treeCssSelStr = treeCssSelStr; //inutile
- let _msgCssSelStr = msgCssSelStr; //inutile
- var _tree = $.ui.fancytree.getTree(_treeCssSelStr);
+ const _treeCssSelStr = treeCssSelStr; //inutile
+ const _msgCssSelStr = msgCssSelStr; //inutile
+ const _tree = $.ui.fancytree.getTree(_treeCssSelStr);
source.addEventListener('deleteChildren', function(event) {
const data = JSON.parse(event.data);
// const keySet = new Set(data.idList);
const keyList = data.idList;
- var tree = $.ui.fancytree.getTree("#tree1");
- var message = "The server says " + data.message +" , keyList: "+keyList;
+ const tree = $.ui.fancytree.getTree("#tree1");
+ const message = "The server says " + data.message +" , keyList: "+keyList;
treeMessage(_msgCssSelStr,"alert-info",message);
// const nodeAsKey = function (node,keys) {
// //?keySet = _isFunction(match) ? keys : _makeNodeTitleMatcher(match);
nodeList.map( (x) => { x.remove()} );
//tree.findAll(match);
- //var activeNode = tree.getActiveNode();
- //activeNode.addChildren({
+ //var fromNode = tree.getActiveNode();
+ //fromNode.addChildren({
// title: "Document using a custom icon",
// icon: "customdoc1.gif"
//});
}
-
// function getTree2() {
// // Some logic to retrieve, or generate tree structure
// return {{ mcTraiteJson|tojson }};
map: {
}
};
-
+
+function iconRendering(event, data) {
+ // if( data.node.isFolder() ) {
+ // return "glyphicon glyphicon-book";
+ // }
+ if( data.node.data.classeAccas == "MCSIMP") {
+ return "glyphicon glyphicon-leaf";
+ } else if( data.node.data.classeAccas == "PROCEDURE") {
+ return "glyphicon glyphicon-tree-deciduous";
+ } else if( data.node.data.classeAccas == "MCFACT") {
+ return "glyphicon glyphicon-grain";
+ } else {
+ return "glyphicon glyphicon-tree-deciduous";
+ };
+};
+
$(function(){
$("#tree1").fancytree({
//focusOnSelect:true,
// labelSpacing: "0.1em", // Adjust this if padding between icon and label != "3px"
// levelOfs: "1.5em" // Adjust this if ul padding != "16px"
//},
- icon: function(event, data) {
- // if( data.node.isFolder() ) {
- // return "glyphicon glyphicon-book";
- // }
- if( data.node.data.classeAccas == "MCSIMP") {
- return "glyphicon glyphicon-leaf";
- } else if( data.node.data.classeAccas == "PROCEDURE") {
- return "glyphicon glyphicon-tree-deciduous";
- } else if( data.node.data.classeAccas == "MCFACT") {
- return "glyphicon glyphicon-grain";
- } else {
- return "glyphicon glyphicon-tree-deciduous";
- };
- },
+ icon: function(event, data) { return iconRendering(event, data); }, //TODO : trouver une meilleure formulation
// icon: function(event, data) {
// if( data.node.type ) {
// return "ft-ico-" + data.node.type;
//const tree = createTree('#tree', { ... });
//var node = tree.getActiveNode();
- var node = data.node,
+ const node = data.node,
$tdList = $(node.tr).find(">td");
- let classeAccas = node.data.classeAccas;
- let validite = node.data.validite;
- let wValue = node.data.wValue;
- let statut = node.data.statut;
- let cmdName = node.data.nomCommande; // undefined if classeAccas != 'MCFACT'
- let repeatable = node.data.repetable; // ?? undefined if classeAccas != 'MCFACT' ??
- let infoOptionnels = node.data.infoOptionnels;
- let key = node.key;
- let name = node.title;
- var _attr = ''
+ const classeAccas = node.data.classeAccas;
+ const validite = node.data.validite;
+ const wValue = node.data.wValue;
+ const statut = node.data.statut;
+ const cmdName = node.data.nomCommande; // undefined if classeAccas != 'MCFACT'
+ const repeatable = node.data.repetable; // ?? undefined if classeAccas != 'MCFACT' ??
+ const infoOptionnels = node.data.infoOptionnels;
+ const key = node.key;
+ const name = node.title;
+ var _attr = '';
//Render Column #0
$tdList.eq(0).text(node.getIndexHier());
.html("<span class='glyphicon glyphicon-question-sign' onclick='alert(\"glyphicon-question-sign : "+key+"\")'></span>");
} else { // Not classeAccas == "MCSIMP"
-
+
+ // THREE ICONS MANAGEMENT : +,Trash,?
//$tdList.eq(2).prop("colspan", 2).nextAll().remove(); //Merge unused columns for easy keyboard navigation
if ( classeAccas == "PROCEDURE" || classeAccas == "OPER" ) {
plusFunction = "clickOnCommand( \"#tree1\", \"#tree1-messages\", \""+name+"\", \""+key+"\" )";
};
+ // OPTIONALS MANAGEMENT :
+
// La souris entre dans un row :
// cmdHasOptional: Si mon topLevelParent (ma Commande) a des facultatifs, le optTopLevelParent doit être le mien // topLevelParent peut être moi
// cmdHasNoOptional: Si mon topLevelParent (ma Commande) n'a pas de facultatifs, le optTopLevelParent doit être vide // topLevelParent peut être moi
};
$(node.tr).mouseenter(function(){
- // if ( parentCommandNode.hasOpt() ) {
- // BUG: !!!!!! Ts les noeuds du chemin
- // if ( hasOpt(parentCommandNode) ) {
- // // TODO : Optimiser un arbre complet avec masquage/demasquage en fction du row
- // // if ( parentCommandName != optTreeCommandName ) {
- // // buildOptionalTree(parentCommandNode);
- // // } else {
- // // // expand first parent optionals node
- // // }
- // buildOptionalTree(node)
- // } else {
- // if ( optTree != null) { optTree.destroy();}; // Supress optional keywords
- // };
optTreeSrc=buildOptionalTreeSrc(node);
optFunction = "sendAppendChild( \""+key+"\", \""+cmdName+"\",null)";
- optTreeOptions = {};
+ optTreeOptions = {
+ glyph: glyph_opts,
+ icon: function(event, data) { return iconRendering(event, data); },
+ click:function(event, data) {
+ const targetType = data.targetType;
+ const node = data.node;
+ const title = node.title ;
+ const parent = node.parent;
+ const parentKey = parent != null ? parent.key : null;
+ // const parentTitle = parent != null ? parent.title : "" ;
+ if ( targetType == 'title' ) {
+ sendAppendChild( parentKey, title, null);
+ };
+ },
+ source: optTreeSrc, };
//$("#bebe").text("---------"+optTreeSrc);
//console.debug('optTreeSrc :'+optTreeSrc);
// if ( optTreeSrc.length == 0 ) {
let optTree = $.ui.fancytree.getTree("#Optionals");
if (optTree != null) { optTree.destroy();};
// } else {
- let $optTree = $("#Optionals").fancytree( { source: optTreeSrc } );
+ // let $optTree = $("#Optionals").fancytree( { source: optTreeSrc } );
+ let $optTree = $("#Optionals").fancytree( optTreeOptions );
//let optTree = $optTree.fancytree;
optTree = $.ui.fancytree.getTree("#Optionals");
optTree.expandAll();
} else {
optKeywords = [];
};
- return [{"title": node.title,
- "children": _optToChild(optKeywords).concat(_build(parentList.slice(1))) }];
+ return [{"title" : node.title,
+ "key" : node.key,
+ "classeAccas" : node.data.classeAccas,
+ "children" : _optToChild(optKeywords).concat(_build(parentList.slice(1))) }];
};
return _build(parentList);
};
},
defaultGridAction: function( event, data ) { //(used by ext-aria) The user hit enter on the active row or cell.
- var node = data.node
- var rValue,rValidite,rChangeIsAccepted
- let _msgCssSelStr='#tree1-messages'; //TODO: A déplacer
+ const node = data.node
+ // var rValue,rValidite,rChangeIsAccepted
+ const _msgCssSelStr='#tree1-messages'; //TODO: A déplacer
if (node.data.classeAccas == "MCSIMP") {
$input=$(node.tr).find('input');