]> SALOME platform Git repositories - tools/eficas.git/commitdiff
Salome HOME
Gestion des menus...
authorEric Fayolle <eric.fayolle@edf.fr>
Thu, 27 Jan 2022 16:46:19 +0000 (17:46 +0100)
committerEric Fayolle <eric.fayolle@edf.fr>
Thu, 27 Jan 2022 16:46:19 +0000 (17:46 +0100)
testFlask/mdm.py
testFlask/templates/base.html
testFlask/templates/commandes_2.html
testFlask/templates/commands_menu.html [new file with mode: 0644]

index 75c7a5d07032f0febe4aa459598d4fee81725936..236ba8637e8a14bd914552c1552876e535522cd8 100755 (executable)
@@ -9,12 +9,34 @@ code='Essai'
 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
+import os
 from   pprint      import pprint
-from   forms       import BasicForm
+#from   forms       import BasicForm
 from   collections import OrderedDict
 from   markupsafe  import escape
 
 from flask_sse import sse
+from flask_uploads import UploadSet, configure_uploads, IMAGES 
+
+app = Flask(__name__)
+
+CATALOGS_EXT=("py",)
+catalogs = UploadSet("catalogs",CATALOGS_EXT)
+app.config["UPLOADED_CATALOGS_DEST"] = "data/catalogs"
+app.config["SECRET_KEY"]             = os.urandom(24)
+
+
+configure_uploads(app, catalogs)
+
+@app.route("/upload", methods=['POST'])
+def upload():
+    if request.method == 'POST' and 'catalogFile' in request.files:
+        catalogs.save(request.files['catalogFile'])
+        # flash("Catalog saved successfully.")
+    #     return render_template('upload.html')
+    # return render_template('upload.html')
+    return "upload returns", 200
+
 
 # For example, you may want to override how request parameters are handled to preserve their order:
 # from flask import Flask, Request
@@ -30,8 +52,6 @@ def createConnecteur(app):
     monConnecteur=accasConnecteur(code, langue='ang',appWeb=app)
     return monConnecteur
 
-app = Flask(__name__)
-
 monConnecteur=createConnecteur(app)
 print (monConnecteur.getListeCommandes())
 
@@ -173,14 +193,6 @@ def index():
     # 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])
-    # print("---- myTreeDico : ")
-    # pprint.pprint(myTreeDico)
-    # print("---- myTreeJS : ", myTreeJS)
-    # print("---- tree4Fancy     : ", tree4Fancy)
-    # print("---- myNewTreeDico : ", myNewTreeDico)
-    # print("---- myNewTreeJS : ", myNewTreeJS)
     print("---- myFancyTreeDico ----")
     pprint(myFancyTreeDico)
     print("---- myFancyTreeJS ----")
@@ -244,11 +256,11 @@ def removeNode():
         req = request.get_json()
         # Print the dictionary
         print("/removeNode ",req);print("/removeNode ",req['id']);
-        id   =req['id'];
+        id  req['id'];
         ret,message = monConnecteur.suppNode(id);
         print ("/removeNode : ret : ",ret," message : ",message)
         
-        return make_response(json.dumps( {'ret':ret} ))
+        return make_response(json.dumps( {'ret':ret, 'message':message} ))
     else:
         # The request body wasn't JSON so return a 400 HTTP status code
         return "Request was not JSON", 400
@@ -266,7 +278,7 @@ def appendChild():
         # id, value = req.values() # Dangereux correspondance implicite
         #rId,message,changeDone  = monConnecteur.appendChild(id,name,pos);
         newId                    = monConnecteur.appendChild(id,name,pos);
-        print (__file__+"/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} ))
@@ -276,8 +288,8 @@ def appendChild():
         # The request body wasn't JSON so return a 400 HTTP status code
         return "Request was not JSON", 400
         #return make_response(jsonify({"message": "Request body must be JSON"}), 400)
-    
-    
+
+
 @app.route("/forward/", methods=['POST'])
 def move_forward():
     #Moving forward code
index 4635a2006eabb0e433856d40913032425466af75..c866ab8e08cfcb630ebe906ad56789dfea1edb49 100644 (file)
@@ -8,7 +8,7 @@
 
     <!-- Include glyph font definitions, for example matching `preset: "awesome5"` -->
     <!-- <link href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" rel="stylesheet"> -->
-      
+    
     <!-- <script src="{{ url_for('static', filename='jquery/dist/jquery.js') }}"></script> -->
 
     <!-- jQuery library -->
@@ -42,7 +42,7 @@
     <!-- <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='jquery.fancytree/dist/skin-win8/ui.fancytree.min.css') }}"> -->
     <script src="{{ url_for('static', filename='jquery.fancytree/dist/jquery.fancytree-all-deps.js') }}"></script>
     <script src="{{ url_for('static', filename='jquery.fancytree/dist/modules/jquery.fancytree.ariagrid.js') }}"></script>
+    
     <link rel="stylesheet" href="{{ url_for('static', filename= 'css/style.css') }}">
     
     <meta name="description" content={{description}}>
 
     <script>
       $(document).ready(function(){
-        $("#bt1").click(function(){
-        $("#div1").load("{{ url_for('static', filename='demo_test.txt') }}")
-        });
+      $("#bt1").click(function(){
+      $("#div1").load("{{ url_for('static', filename='demo_test.txt') }}")
+      });
       });
     </script>
 
     <style type="text/css">
-    table.fancytree-cell-mode > tbody > tr.fancytree-active > td {
+      table.fancytree-cell-mode > tbody > tr.fancytree-active > td {
       background-color: #eee;
-    }
-    table.fancytree-cell-mode > tbody > tr > td.fancytree-active-cell {
+      }
+      table.fancytree-cell-mode > tbody > tr > td.fancytree-active-cell {
       background-color: #cbe8f6;
-    }
-    table.fancytree-cell-mode.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell {
+      }
+      table.fancytree-cell-mode.fancytree-cell-nav-mode > tbody > tr > td.fancytree-active-cell {
       background-color: #3875d7;
-    }  
+      }  
     </style>
     
     <style type="text/css">
       text-overflow: ellipsis;
       }
     </style>
-
-
-  <!--   <script type="text/javascript"> -->
-  <!--   var glyph_opts = { -->
-  <!--     preset: "bootstrap3", -->
-  <!--     map: { -->
-  <!--     } -->
-  <!--   }; -->
-   
-  <!--   $(function(){ -->
-  <!--     $("#tree10").fancytree({ -->
-  <!--       extensions: ["dnd5", "edit", "glyph", "wide"], -->
-  <!--       checkbox: true, -->
-  <!--       selectMode: 3, -->
-  <!--       dnd5: { -->
-  <!--          dragStart: function(node, data) { return true; }, -->
-  <!--          dragEnter: function(node, data) { return true; }, -->
-  <!--          dragDrop: function(node, data) { data.otherNode.copyTo(node, data.hitMode); } -->
-  <!--     }, -->
-  <!--     glyph: glyph_opts, -->
-  <!--     source: [ -->
-  <!--         {title: "Node 1", key: "1"}, -->
-  <!--         {title: "Folder 2", key: "2", folder: true, children: [ -->
-  <!--           {title: "Node 2.1", key: "3"}, -->
-  <!--           {title: "Node 2.2", key: "4"} -->
-  <!--         ]} -->
-  <!--     ], -->
-  <!--     wide: { -->
-  <!--       iconWidth: "1em",       // Adjust this if @fancy-icon-width != "16px" -->
-  <!--       iconSpacing: "0.5em",   // Adjust this if @fancy-icon-spacing != "3px" -->
-  <!--       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"; -->
-  <!--       // } -->
-  <!--     }, -->
-  <!--     //lazyLoad: function(event, data) { -->
-  <!--     //  data.result = {url: "ajax-sub2.json", debugDelay: 1000}; -->
-  <!--     //} -->
-  <!--    }); -->
-  <!--   }); -->
-  <!-- </script> -->
-  
-    <!-- <script>  -->
-    <!--  $(document).ready(function(){ -->
-    <!--  <\!-- $(".MCSIMPValide").hover(function(){ -\-> -->
-    <!--  $("[data-nodeid]").change(function(){ -->
-    <!--    alert("-6-- :"+ $(this).text() + $(this).attr("class") + $(this).attr("id") ); -->
-    <!--    $.ajax({ -->
-    <!--        type: "POST", -->
-    <!--        url: "{-----{ url_for('updateSimp) }-----}", -->
-    <!--        data: JSON.stringify({id: $(this).attr("id")}), -->
-    <!--        contentType: "application/json; charset=utf-8", -->
-    <!--        dataType: "json", -->
-    <!--        // The callback function when the web service return success. -->
-    <!--        success: function(data, status) { -->
-    <!--           alert("Data: " + data + "\nStatus: " + status +"\nId :", $(this).attr("id") ); -->
-    <!--           $("#tree1").treeview( {'data': data } ); -->
-    <!--        } -->
-    <!--        // The callback function when the web service return fail. -->
-    <!--        failure: function(errMsg) { -->
-    <!--            alert(errMsg); -->
-    <!--        } -->
-    <!--    }); -->
-    <!--  }); -->
-    <!-- }); -->
-    <!-- </script> -->
-  
+    
   </head>
 
-   <style>
-     /* Note: Try to remove the following lines to see the effect of CSS positioning */
-     .affix {
-       top: 0;
-       width: 100%;
-       z-index: 9999 !important;
-     }
-     
-     .affix + .container-fluid {
-       padding-top: 70px;
-     }
-   </style>
-   
-  <nav class="navbar navbar-inverse" data-spy="affix" >
-  <!-- <nav class="navbar navbar-inverse" data-spy="affix" data-offset-top="10"> -->
-  <!-- <nav class="navbar navbar-inverse" > -->
+  <style>
+    .affix {
+    top: 0;
+    width: 100%;
+    z-index: 9999 !important;
+    }
+    
+    .affix + .container-fluid {
+    padding-top: 100px;
+    }
+  </style>
+  
+  <nav class="navbar navbar-inverse flex-column flex-md-row" data-spy="affix" >
+    <!-- <nav class="navbar navbar-inverse" data-spy="affix" data-offset-top="10"> -->
+    <!-- <nav class="navbar navbar-inverse" > -->
     <div class="container-fluid">
-      <div class="navbar-header">
-       <a class="navbar-brand" href="#">MDM/Eficas</a>
-      </div>
-      <ul class="nav navbar-nav">
-       <!-- <li class="active"><a href="#">File</a></li> -->
-       <li class="dropdown">
-          <a class="dropdown-toggle" data-toggle="dropdown" href="#">File<span class="caret"></span></a>
-          <ul class="dropdown-menu">
-           <li class="dropdown-header">Server Side</li> 
-            <!-- <li class="active"><a href="#">File</a></li> -->
-           <li>
-             <!-- <form action=""> -->
-             <div class="from-group">
-               <!-- <input type="file" style="position:relative;opacity:0;z-index:2;" name="Set_Catalog_name" -->
-               <!--        id="Set_Catalog" onchange="$('button_Set_Catalog').value=value"></input> -->
-               <!-- <input type="file" style="display:none;" name="Set_Catalog_name" id="Set_Catalog"></input> -->
-               <!-- Essayer d'ajouter la classe navbar-btn -->
-               <div class="input-group" >
-                 <!-- <span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span> -->
-                 <input type="file" class="filestyle btn btn-primary" name="toto"
-                         id="button_Set_Catalog">Set Catalog</input>
-                 <!-- <button type="file" class="filestyle form-control btn btn-primary" name="toto" -->
-                 <!--    id="button_Set_Catalog">Set Catalog</button> -->
-               </div>
-               <!-- <div class="input-group-btn"> -->
-               <!--   <button class="btn btn-default" type="submit">Set the current catalog</button> -->
-               <!-- </div> -->
-             </div>
-             <!-- </form> -->
-             <!-- <form action=""> -->
-             <!--      <div class="form-group"> -->
-             <!--        <\!-- <label for="catalog">Set the current catalog </label> -\-> -->
-             <!--        <button type="file" class="btn btn-default"  multiple="false" id="catalog" value="Set the current catalog"></button> -->
-             <!--      </div> -->
-             <!-- </form> -->
-           </li>
-           <li role="presentation" class="divider"></li>
-           <li class="dropdown-header">Local Side</li> 
-            <li><a href="#">Set Catalog</a></li>
-            <li><a href="#">Open Dataset</a></li>
-          </ul>
-       </li>
-       <li><a href="#">Editor</a></li>
-       <li><a href="#">Dataset</a></li>
-       <li><a href="#">Help</a></li>
-      </ul>
-      <form class="navbar-form navbar-right" action="">
-      <div class="form-group">
-        <input type="text" class="form-control" placeholder="Search">
-      </div>
-      <button type="submit" class="btn btn-default">Submit</button>
-    </form>
-    </div>
+      <div class="row">
+       <div class="navbar-header">
+         <a class="navbar-brand" href="#">MDM/Eficas</a>
+       </div>
+       <ul class="nav navbar-nav">
+         <!-- <li class="active"><a href="#">File</a></li> -->
+         <li class="dropdown">
+            <a class="dropdown-toggle" data-toggle="dropdown" href="#">File<span class="caret"></span></a>
+            <ul class="dropdown-menu">
+             <li class="dropdown-header">Server Side</li> 
+              <!-- <li class="active"><a href="#">File</a></li> -->
+             <li>
+               <form method="POST" enctype="multipart/form-data" action="{{ url_for('upload') }}">
+                 <div class="form-group">
+                   <!-- <input type="file" style="position:relative;opacity:0;z-index:2;" name="Set_Catalog_name" -->
+                   <!--        id="Set_Catalog" onchange="$('button_Set_Catalog').value=value"></input> -->
+                   <!-- <input type="file" style="display:none;" name="Set_Catalog_name" id="Set_Catalog"></input> -->
+                   <!-- Essayer d'ajouter la classe navbar-btn -->
+                   <div class="input-group" >
+                     <!-- <span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span> -->
+                     <input type="file" class="form-control btn btn-primary" name="catalogFile"
+                            id="button_Set_Catalog">Set Catalog</input>
+                     <button type="submit">Submit</button>
+                     <!-- <button type="file" class="filestyle form-control btn btn-primary" name="toto" -->
+                     <!--        id="button_Set_Catalog">Set Catalog</button> -->
+                   </div>
+                   <!-- <div class="input-group-btn"> -->
+                   <!--   <button class="btn btn-default" type="submit">Set the current catalog</button> -->
+                   <!-- </div> -->
+                 </div>
+                 <!-- </form> -->
+                 <!-- <form action=""> -->
+                 <!--  <div class="form-group"> -->
+                 <!--    <\!-- <label for="catalog">Set the current catalog </label> -\-> -->
+                 <!--    <button type="file" class="btn btn-default"  multiple="false" id="catalog" value="Set the current catalog"></button> -->
+                 <!--  </div> -->
+               </form>
+             </li>
+             <li role="presentation" class="divider"></li>
+             <li class="dropdown-header">Local Side</li> 
+              <li><a href="#">Set Catalog</a></li>
+              <li><a href="#">Open Dataset</a></li>
+            </ul>
+         </li>
+         <li><a href="#">Editor</a></li>
+         <li><a href="#">Dataset</a></li>
+         <li><a href="#">Help</a></li>
+
+       </ul>
+       <form class="navbar-form navbar-right" action="">
+         <div class="form-group">
+            <input type="text" class="form-control" placeholder="Search">
+         </div>
+         <button type="submit" class="btn btn-default">Submit</button>
+       </form>
+      </div> <!-- row -->
+
+    </div> <!-- container-fluid -->
   </nav>
-  
+
   <div class="container-fluid">
+
+    {% block commands_menu %} {% endblock %}
+
+    <div class="affix" style="top: 50px;">                                                             <!-- TODO : style -> CSS -->
+       <div class="row"                             style="margin-top: 0px;">                        <!-- TODO : style -> CSS -->
+         <div class="col-sm-12 panel panel-default" style="padding-top: 10px;padding-bottom: 10px;">  <!-- TODO : style -> CSS -->
+           
+           {% for commande in listeCommandes %}
+           <div class="btn-group" data-toggle="buttons" onclick="clickOnCommand( '#tree1','#tree1-messages', '{{ commande }}' , '' )">
+             <label class="btn btn-primary activate" for={{ commande }}> {{ commande }}</label>
+           </div>
+           {% endfor %}
+         
+         </div>
+       </div> <!-- row -->
+      </div> <!-- affix -->
+  </div> <!-- container-fluid -->
+
+  <div class="container-fluid">
+
     {% block content %} {% endblock %}
-  </div>
+
+  </div> <!-- container-fluid -->
 
 </html>
 
index b627486692876bc8ba579b8697115eca06d26aa9..b45f144c6a979f26c651e9fdc7d7cd6376efaa2f 100644 (file)
 <!-- </div> -->
 <!-- </div> -->
 
-<div class="row">
-  <div class="col-sm-12 panel panel-default">
-    <!-- <h2>Choose Object to add</h2> -->
-    
-    <!--     <h1>Choose command to add </h1> -->
-    <!-- <h2>Commandes en ligne </h2>  -->
-    <!-- <ul> -->
-    <!--   {% for commande in listeCommandes %} -->
-    <!--   <li>{{ commande|e }}</li> -->
-    <!--   {% endfor %} -->
-    <!-- </ul> -->
-    <!-- <h2>Commandes en checkbutton </h2> -->
-    
-    {% for commande in listeCommandes %}
-    <!-- PN : pourquoi  peut-il  avoir plusieurs cheched -> à cause de name -->
-    <div class="btn-group" data-toggle="buttons" onclick="clickOnCommand( '#tree1','#tree1-messages', '{{ commande }}' , '' )">
-      <!-- <input type="radio" name={{ commande }} id={{ commande }} > -->
-      <!-- <input type="radio" class="form-check-input" name='Etapes' id={{ commande }} > -->
-      <label class="btn btn-primary activate" for={{ commande }}> {{ commande }}</label><!-- <br> -->
-      
-      <!-- <label class="btn btn-primary" for={{ commande }}> -->
-      <!--   <input class="form_check_input" type="radio" name='Etapes' id={{ commande }} > {{ commande }} -->
-      <!-- </label> -->
-      
-    </div>
-    {% endfor %}
-  </div>
-</div>
 
 <!-- <div class="row panel panel-default"> -->
 <!--     <h2> </h2> -->
     </div>
   </div>
   
-  <div class="row">  
     <!-- <footer class="footer"> -->
     <!-- <nav class="navbar navbar-inverse navbar-fixed-bottom"> -->
     <!-- <nav class="navbar navbar-inverse"> -->
     <!--   </div> -->
     <!-- </nav> -->
     <!-- </footer> -->
-  </div>
-</div> <!-- fin container-fluid principal-->
 
-       <script>
+    <script>
 
 //$.ui.fancytree.debugLevel=4; // Set the fancyTree debug level
 
@@ -215,8 +184,8 @@ function clickOnRemove(treeCssSelStr, msgCssSelStr, key ) {
     const checkCallBack = function(data) {
        // Tester data == NULL !
        ret = data['ret'];
-       if ( ret == null ) {
-           let message = "Unsuccessfull removeNode processing for key " + _key + ". removeNode has returned a null id.";
+       if ( ret == 0 | ret == null ) {
+           let message = "Unsuccessfull removeNode processing for key " + _key + ". Service removeNode has returned an error ("+data.message+")";
            treeMessage(msgCssSelStr,"alert-danger",message) ;
        };
     };
@@ -231,8 +200,8 @@ function sendAppendChild( key, name, pos) {
     const checkCallBack = function(data) {
        // Tester data == NULL !
        rId = data['id'];
-       if ( rId == null ) {
-           let message = "Unsuccessfull appendChild processing for command " + name + ". appendChild has returned a null id.";
+       if ( rId == 0 || rId == null ) {
+           let message = "Unsuccessfull appendChild processing for command " + name + ". Service appendChild has returned an error ("+data.message+")";
            treeMessage(msgCssSelStr,"alert-danger",message) ;
        };
     };
@@ -288,15 +257,20 @@ const source = new EventSource("{{ url_for('sse.stream') }}");
     let _msgCssSelStr   = msgCssSelStr;  //inutile
     // var  _tree          = $.ui.fancytree.getTree(_treeCssSelStr);
     source.addEventListener('propageValide', function(event) {
-        const data    = JSON.parse(event.data);
-        const id      = data.id;
-        const valid   = data.valid;
-        const message = "The server says " + data.message +" , id: "+id;
-        const tree    = $.ui.fancytree.getTree(_treeCssSelStr);
+        const data     = JSON.parse(event.data);
+        const id       = data.id;
+        const valid    = data.valid;
+        const message  = "The server says " + data.message +" , id: "+id;
+        const msgerror = "Event propageValid : can't find node with key :"+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);
+       if (node == null) {
+           treeMessage(_msgCssSelStr,"alert-danger",msgerror);
+           return;
+       };   
         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 only
@@ -313,13 +287,18 @@ const source = new EventSource("{{ url_for('sse.stream') }}");
         const id      = data.id;
         const info    = data.info;
         const message = "The server says " + data.message +" , id: "+id;
-        const tree    = $.ui.fancytree.getTree(_treeCssSelStr);
+        const msgerror = "Event updateNodeInfo : can't find node with key :"+id;
+       const tree    = $.ui.fancytree.getTree(_treeCssSelStr);
         
         treeMessage(_msgCssSelStr,"alert-info",message);
         const node=tree.getNodeByKey(id);
+       if (node == null) {
+           treeMessage(_msgCssSelStr,"alert-danger",msgerror);
+           return;
+       };   
        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
+        //node.renderStatus();         //CSS element updates only          
     }, false);
 })('#tree1','#tree1-messages');
 
@@ -335,11 +314,16 @@ const source = new EventSource("{{ url_for('sse.stream') }}");
         const pos       = data.pos;
         //var   message = data.message;
         const message   = "The server says " + data.message +" , id: "+id;
+        const msgerror  = "Event appendChildren : can't find node with key :"+id;
        
         treeMessage(_msgCssSelStr,"alert-info",message);
         console.log("_tree : "+ _tree); //?Expliquer pourquoi null: à cause de $.?
         const tree          = $.ui.fancytree.getTree(_treeCssSelStr);
         const node          = tree.getNodeByKey(id);
+       if (node == null) {
+           treeMessage(_msgCssSelStr,"alert-danger",msgerror);
+           return;
+       };      
         const countChildren = node.countChildren(false);
         console.log("countChildren : "+ countChildren); 
         console.log("pos           : "+ pos); 
@@ -366,6 +350,7 @@ const source = new EventSource("{{ url_for('sse.stream') }}");
        const keyList     = data.idList;
        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);
@@ -508,19 +493,21 @@ $(function(){
             //const tree = createTree('#tree', { ... });
             //var node = tree.getActiveNode();      
 
-            const node         = data.node,
-               $tdList         = $(node.tr).find(">td");
-            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                = '';
-           
+            const node          = data.node,
+               $tdList          = $(node.tr).find(">td");
+            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                 = '';
+           const parent         = node.parent;
+           const parentKey      = parent != null ? parent.key : null;
+
             //Render Column #0
             $tdList.eq(0).text(node.getIndexHier());
            
@@ -570,20 +557,23 @@ $(function(){
 
                // THREE ICONS MANAGEMENT : +,Trash,?
                //$tdList.eq(2).prop("colspan", 2).nextAll().remove(); //Merge unused columns for easy keyboard navigation
+               plusFunction  = undefined;
+               trashFunction = undefined;
                if ( classeAccas ==  "PROCEDURE" || classeAccas ==  "OPER" ) {
                    plusFunction  = "clickOnCommand( \"#tree1\", \"#tree1-messages\", \""+name+"\", \""+key+"\" )";
                    trashFunction = "clickOnRemove( \"#tree1\", \"#tree1-messages\", \""+key+"\" )";
-               } else if ( classeAccas ==  "MCFACT"  && repeatable ) {
-                   plusFunction = "sendAppendChild( \""+key+"\", \""+cmdName+"\",null)";
+               } else if ( classeAccas ==  "MCFACT" ) {
+                   if (repeatable) {
+                       plusFunction = "sendAppendChild( \""+parentKey+"\", \""+cmdName+"\",null)";
+                   };
+                   trashFunction = "clickOnRemove( \"#tree1\", \"#tree1-messages\", \""+key+"\" )";
                } else {
-                   plusFunction  = undefined;
                    // plusFunction  = "alert(\"glyphicon-plus-sign : "+key+"\")";
-                   trashFunction = undefined;
                    trashFunction = "alert(\"glyphicon-trash : "+key+"\")";
                };
                
                $tdList.eq(2).prop("colspan", 2); //Merge unused columns for easy keyboard navigation
-               actionListIndex=3;
+               actionListIndex=3;                //TODO : Le paramétrer
                if ( plusFunction != undefined ) {
                    $tdList.eq(actionListIndex)
                        .html("<span class='glyphicon glyphicon-plus-sign' onclick='"+plusFunction+"'></span>");
@@ -835,48 +825,9 @@ $(function(){
          <!-- }); -->
         
        </script>
-       
-<!-- <div id="tree1"></div> -->
-<!-- -------------- -->
-<!-- {{ mcTraiteJson }} -->
-<!-- ---------- -->
-    <script>
-      
-<!-- var tree = [ -->
-<!--   { -->
-<!--     text: "Parent 1", -->
-<!--     nodes: [ -->
-<!--       { -->
-<!--         text: "Child 1", -->
-<!--         nodes: [ -->
-<!--           { -->
-<!--             text: "Grandchild 1" -->
-<!--           }, -->
-<!--           { -->
-<!--             text: "Grandchild 2" -->
-<!--           } -->
-<!--         ] -->
-<!--       }, -->
-<!--       { -->
-<!--         text: "Child 2" -->
-<!--       } -->
-<!--     ] -->
-<!--   }, -->
-<!--   { -->
-<!--     text: "Parent 2" -->
-<!--   }, -->
-<!--   { -->
-<!--     text: "Parent 3" -->
-<!--   }, -->
-<!--   { -->
-<!--     text: "Parent 4" -->
-<!--   }, -->
-<!--   { -->
-<!--     text: "Parent 5" -->
-<!--   } -->
-<!-- ]; -->
 
     </script>
+
 {% endblock %}
 
 // # Différents tests :
diff --git a/testFlask/templates/commands_menu.html b/testFlask/templates/commands_menu.html
new file mode 100644 (file)
index 0000000..837d602
--- /dev/null
@@ -0,0 +1,18 @@
+{% extends 'base.html' %}
+
+
+{% block command_menu %}
+
+<div class="row">
+  <div class="col-sm-12 panel panel-default">
+
+    {% for commande in listeCommandes %}
+    <div class="btn-group" data-toggle="buttons" onclick="clickOnCommand( '#tree1','#tree1-messages', '{{ commande }}' , '' )">
+      <label class="btn btn-primary activate" for={{ commande }}> {{ commande }}</label>
+    </div>
+    {% endfor %}
+    
+  </div>
+</div>
+
+{% endblock %}