From 7ec6fd4d02febb0dca5cf2c9fed998594b6f1b5c Mon Sep 17 00:00:00 2001
From: Anthony Borghi <anthony.borghi@veremes.com>
Date: Fri, 16 Nov 2018 15:41:39 +0100
Subject: [PATCH] Squashed 'src/vitis/' changes from 9862a97c..5e14ccdd
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

5e14ccdd Merge branch 'next_version' into 'next_app_dtnet'
4a400f14 Merge branch 'next_app_dtnet' into 'next_version'
dc9e09bb Merge branch 'next_app_vmap' into 'next_version'
ed3718ef Next app vmap
6909aeec Correctif sur la concaténation de filtres
68d6ee11 Retouche attribut comparator sur les formulaires de filtres
REVERT: 9862a97c Remove gitignore
REVERT: 1e0dea62 Merge branch 'next_version' into 'master'
REVERT: 40e7d46e pull subtree
REVERT: 68214db2 Update crontab.txt - Changement nom balise
REVERT: 771a5655 Merge branch 'Sebastien-master-patch-58096' into 'master'
REVERT: 4398b26d Merge branch 'bug/4-formreader-champs-date-non-pris-en-compte-si-on-met-la-date-du-jour-en-insertion' into 'master'
REVERT: d17933b9 Edit datetime picker event
REVERT: b3b6ec06 Merge branch '1-js-sous-formulaire' into 'master'
REVERT: 41a15530 Load BO Javascript on subforms
REVERT: 064924ec Mise à jour du fichier de version pour fonctionnait avec la version 11.0 de PostgreSQL

git-subtree-dir: src/vitis
git-subtree-split: 5e14ccddd6bc4323d7334c25af5fd97113e6ac7a
---
 .gitignore                                    |   6 +
 _install/dependencies/pycron/crontab.txt      |  15 +-
 client/javascript/app/script_client.js        |  85 ++--
 .../studio/javascript/app/JsonLoader.js       | 153 ++++---
 .../externs/studio/lang/lang-en.json          |  10 +-
 .../externs/studio/lang/lang-fr.json          |  10 +-
 .../externs/studio/less/studio.less           |  46 +-
 .../externs/studio/templates/JsonLoader.html  |  22 +-
 client/less/main.less                         |  21 +
 vas/rest/ws/vitis/Versions.class.inc          | 404 +++++++++---------
 vas/sql/sqlQueries.xml                        |   2 +-
 11 files changed, 422 insertions(+), 352 deletions(-)

diff --git a/.gitignore b/.gitignore
index e69de29b..fb23a1f3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1,6 @@
+vas/rest/class/*
+vas/rest/class/!*/
+vas/rest/class/!*.*
+vas/sql/*
+vas/sql/!*/
+vas/sql/!*.*
diff --git a/_install/dependencies/pycron/crontab.txt b/_install/dependencies/pycron/crontab.txt
index dff3a495..7f7bab4c 100755
--- a/_install/dependencies/pycron/crontab.txt
+++ b/_install/dependencies/pycron/crontab.txt
@@ -1,9 +1,6 @@
-#<gtf_subscription [SERVER_NAME] [ENGINE_DIR]>
-0 23 * * * "[PHP_PATH]" "[ENGINE_DIR]/subscription.php" 1
-0 23 * * mon "[PHP_PATH]" "[ENGINE_DIR]/subscription.php" 2
-0 23 1 * * "[PHP_PATH]" "[ENGINE_DIR]/subscription.php" 3
-*/5 * * * * "[PHP_PATH]" "[ENGINE_DIR]/subscription.php" 4
-#</gtf_subscription [ServerName] [ENGINE_DIR]>
-#<gtf_message [SERVER_NAME] [MESSAGE_DIR]>
-*/1 * * * * "[PHP_PATH]" "[MESSAGE_DIR]/processMessages.php" 4
-#</gtf_message [SERVER_NAME] [MESSAGE_DIR]>
\ No newline at end of file
+#<gtf_subscription [ServerName] [vasDir]>
+0 23 * * * "[engineDir]/php/php" "[engineDir]/subscription.php" 1
+0 23 * * mon "[engineDir]/php/php" "[engineDir]/subscription.php" 2
+0 23 1 * * "[engineDir]/php/php" "[engineDir]/subscription.php" 3
+*/5 * * * * "[engineDir]/php/php" "[engineDir]/subscription.php" 4
+#</gtf_subscription [ServerName] [vasDir]>
\ No newline at end of file
diff --git a/client/javascript/app/script_client.js b/client/javascript/app/script_client.js
index 02bda1b1..d139ae71 100644
--- a/client/javascript/app/script_client.js
+++ b/client/javascript/app/script_client.js
@@ -875,52 +875,53 @@ vitisApp.on('appInitCtrlLoaded', function () {
 
             if (typeof (sValue) !== "undefined" && (sValue.toString()) !== "") {
                 if (goog.isDefAndNotNull(oFormElement["comparator"])) {
-                    if (goog.isDefAndNotNull(oFormElement["comparator"]["formater"])) {
-                        sValue = oFormElement["comparator"]["formater"].replace(/<VALUE_TO_REPLACE>/g, sValue);
+                    var aOperators = [];
+                    for (var j = 0;j < oFormElement["comparator"].length;j++){
+                        if(goog.isObject(oFormElement["comparator"][j])){
+                            var oOperator = {};
+                            if (goog.isDefAndNotNull(oFormElement["comparator"][j]["formater"])) {
+                                sValue = oFormElement["comparator"][j]["formater"].replace(/<VALUE_TO_REPLACE>/g, sValue);
+                            }
+
+                            if(goog.isArray(oFormElement["comparator"][j]["compare_operator"])){
+                                oOperator["relation"] = (goog.isDefAndNotNull(oFormElement["comparator"][j]["relation"]) ? oFormElement["comparator"][j]["relation"] : "AND");
+                                oOperator["operators"] = [];
+                                for (var k = 0; k < oFormElement["comparator"][j]["compare_operator"].length; k++){
+                                    oOperator["operators"].push({
+                                        "column": (goog.isArray(oFormElement["comparator"][j]["column"]) ? oFormElement["comparator"][j]["column"][k] : oFormElement["name"]),
+                                        "compare_operator": oFormElement["comparator"][j]["compare_operator"][k],
+                                        "value": sValue
+                                    });
+                                }
+                            }else{
+                                oOperator["column"] = (goog.isDefAndNotNull(oFormElement["comparator"][j]["column"]) ? oFormElement["comparator"][j]["column"] : oFormElement["name"]);
+                                oOperator["compare_operator"] = oFormElement["comparator"][j]["compare_operator"];
+                                oOperator["value"] = sValue;
+                            }
+
+                            if(goog.isDefAndNotNull(oFormElement["comparator"][j]["compare_operator_options"])){
+                                oOperator["compare_operator_options"] = oFormElement["comparator"][j]["compare_operator_options"];
+                            }
+
+                            aOperators.push(oOperator);
+                        }else{
+                            // deprecated branch
+                            console.warn("This use of compare attribute is deprecated in json form")
+                            aOperators.push({
+                                "column": (goog.isDefAndNotNull(oFormElement["attrToCompare"]) ? oFormElement["attrToCompare"][j] : oFormElement["name"]),
+                                "compare_operator": oFormElement["comparator"][j],
+                                "value": sValue
+                            });
+                        }
                     }
-                    //
-                    for (var j = 0; j < oFormElement["comparator"].length; j++) {
+                    if(goog.isDefAndNotNull(oFormElement["comparator_relation"])){
                         oFilter["operators"].push({
-                            "column": (goog.isDefAndNotNull(oFormElement["attrToCompare"]) ? oFormElement["attrToCompare"][j] : oFormElement["name"]),
-                            "compare_operator": oFormElement["comparator"][j],
-                            "value": sValue
+                            "relation": oFormElement["comparator_relation"],
+                            "operators": aOperators
                         });
+                    }else{
+                        oFilter["operators"] = oFilter["operators"].concat(aOperators);
                     }
-                    /*
-                    oFormElement["comparator"]["value"] = sValue;
-                    oFilter["operators"].push(oFormElement["comparator"]);
-                    
-                     for (var j = 0; j < oFormElement["comparator"].length; j++) {
-                     var sFormElement = "";
-                     if (goog.isDefAndNotNull(oFormElement["attrToCompare"])) {
-                     sFormElement = (goog.isDefAndNotNull(oFormElement["attrToCompare"][j]) ? oFormElement["attrToCompare"][j] : oFormElement["name"]);
-                     } else {
-                     sFormElement = oFormElement["name"];
-                     }
-                     var bIsNotNumber = true;
-                     if (goog.isDefAndNotNull(oFormElement["NaNForced"])) {
-                     bIsNotNumber = (goog.isDefAndNotNull(oFormElement["NaNForced"][j]) ? oFormElement["NaNForced"][j] : isNaN(sValue));
-                     } else {
-                     bIsNotNumber = isNaN(sValue);
-                     }
-                     switch (oFormElement["comparator"][j]) {
-                     case 'LIKE' :
-                     oFilter.push('lower("' + sFormElement + '") LIKE lower(\'%' + sValue + '%\')');
-                     break;
-                     case 'SQL' :
-                     oFilter.push(sFormElement.replace(/<VALUE_TO_REPLACE>/g, sValue));
-                     break;
-                     // ajouter d'autre comparateur si besoin ex: BETWEEN ______ AND ______
-                     default:
-                     // = < <= > >= basique
-                     if (bIsNotNumber) {
-                     sValue = "'" + sValue + "'";
-                     }
-                     oFilter.push(sFormElement + oFormElement["comparator"][j] + sValue);
-                     break;
-                     }
-                     }
-                     */
                 } else {
                     if (oFormElement["type"] == "text") {
                         oFilter["operators"].push({
diff --git a/client/javascript/externs/studio/javascript/app/JsonLoader.js b/client/javascript/externs/studio/javascript/app/JsonLoader.js
index 8dd8de68..ff0407e2 100755
--- a/client/javascript/externs/studio/javascript/app/JsonLoader.js
+++ b/client/javascript/externs/studio/javascript/app/JsonLoader.js
@@ -248,7 +248,7 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.requestToJson = functi
                             cmd = "Perso_Reset";
                             break;
                     }
-                    this_.putRequest(cmd, undefined, function (data) {
+                    this_.putRequest(cmd, this_.$scope_["FormSelected"], undefined, function (data) {
 
                         // Cas d'erreur du put
                         if (goog.isDefAndNotNull(data['errorMessage'])) {
@@ -584,18 +584,6 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.save = function (succe
     oVFB.unselectAll();
     tmp = oVFB.cleanFormToSave(tmp);
 
-    /*if ($("#boolean-JS-include").prop("checked")) {
-     tmp[this_.$rootScope_["selected_form_type"]]["javascript"] = true;
-     } else {
-     tmp[this_.$rootScope_["selected_form_type"]]["javascript"] = false;
-     }
-
-     if ($("#boolean-CSS-include").prop("checked")) {
-     tmp[this_.$rootScope_["selected_form_type"]]["style"] = true;
-     } else {
-     tmp[this_.$rootScope_["selected_form_type"]]["style"] = false;
-     }*/
-
     if (this['applicationName'] === 'gtf') {
         tmp[this_.$rootScope_["selected_form_type"]]["name"] = "WSubform";
         tmp["display"] = tmp[this_.$rootScope_["selected_form_type"]];
@@ -623,7 +611,7 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.save = function (succe
     oVFB.valid = this.isValid(tmp);
 
     if (oVFB.valid && tmp !== null) {
-        this_.putRequest("Perso_Save", data, success, error);
+        this_.putRequest("Perso_Save", this_.$scope_["FormSelected"], data, success, error);
     } else {
         $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["Validation_Error"] + ': ' + oVFB.aNotValid, {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
     }
@@ -646,18 +634,6 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.publish = function ()
     // Supprime les elements selectionnés
     oVFB.unselectAll();
 
-    /*if ($("#boolean-JS-include").prop("checked")) {
-     tmp[this_.$rootScope_["selected_form_type"]]["javascript"] = true;
-     } else {
-     tmp[this_.$rootScope_["selected_form_type"]]["javascript"] = false;
-     }
-
-     if ($("#boolean-CSS-include").prop("checked")) {
-     tmp[this_.$rootScope_["selected_form_type"]]["style"] = true;
-     } else {
-     tmp[this_.$rootScope_["selected_form_type"]]["style"] = false;
-     }*/
-
     if (this['applicationName'] === 'gtf') {
         tmp[this_.$rootScope_["selected_form_type"]]["name"] = "WSubform";
         tmp["display"] = tmp[this_.$rootScope_["selected_form_type"]];
@@ -669,7 +645,6 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.publish = function ()
     data.append("Css", oVFB.getCss());
 
     var success = function () {
-//        $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["SaveData"], {"className": "success", "autoHideDelay": oVFB.TimeNotify_});
         var data = "";
         var success = function () {
             this_.requestToJson();
@@ -679,17 +654,16 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.publish = function ()
             $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["Publish_Error"] + status, {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
         };
 
-        this_.putRequest(this_.$scope_["FormSelected"] + "_Published", data, success, error);
+        this_.putRequest(this_.$scope_["FormSelected"] + "_Published", this_.$scope_["FormSelected"], data, success, error);
     };
     var error = function (data, status) {
         $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["SaveData_Error"] + status, {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
     };
     if (oVFB.valid) {
         if (this_.$scope_["FormSelected"] != "Default") {
-            this_.putRequest("Perso_Save", data, success, error);
+            this_.putRequest("Perso_Save", this_.$scope_["FormSelected"], data, success, error);
         } else {
-            this_.putRequest("Default_Published", data, success, error);
-
+            this_.putRequest("Default_Published", this_.$scope_["FormSelected"], data, success, error);
         }
     } else {
         $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["Validation_Error"], {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
@@ -763,7 +737,7 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.reset = function () {
                 var error = function (data, status) {
                     $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["Reset_Error"] + status, {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
                 };
-                this_.putRequest(this_.$scope_["FormSelected"] + "_Reset", data, success, error);
+                this_.putRequest(this_.$scope_["FormSelected"] + "_Reset", this_.$scope_["FormSelected"], data, success, error);
             }
         }
     });
@@ -771,14 +745,63 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.reset = function () {
     oVFB.studioMainController.prototype.moveBootboxModalToStudioContainer(oModal);
 };
 
+/**
+ * Remove the published form on the server
+ *
+ * @export
+ */
+nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.deletePublishedForm = function () {
+    oVFB.log('nsVFB.JsonLoader.jsonLoaderController.deletePublishedForm');
+
+    var this_ = this;
+    var oModal = bootbox.confirm('<h4>' + this["text"]["InfoBulle"]["Published"]["DeletePublishedForm"] + ' ?</h4>', function (result) {
+        if (result === true) {
+            var data = "";
+            var success = function () {
+                $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["Delete"], {"className": "success", "autoHideDelay": oVFB.TimeNotify_});
+                this_.requestToJson();
+            };
+            var error = function (data, status) {
+                $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["Delete_Error"] + status, {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
+            };
+            this_.putRequest('Published_Delete', 'Published', data, success, error);
+        }
+    });
+}
+
+/**
+ * Remove the form JS on the server
+ *
+ * @export
+ */
+nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.deleteJS = function () {
+    oVFB.log('nsVFB.JsonLoader.jsonLoaderController.deleteJS');
+
+    var this_ = this;
+    var oModal = bootbox.confirm('<h4>' + this["text"]["InfoBulle"]["Perso"]["Delete_JS"] + ' ?</h4>', function (result) {
+        if (result === true) {
+            var data = "";
+            var success = function () {
+                $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["Delete_JS"], {"className": "success", "autoHideDelay": oVFB.TimeNotify_});
+                this_.requestToJson();
+            };
+            var error = function (data, status) {
+                $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["Delete_JS_Error"] + status, {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
+            };
+            this_.putRequest('Delete_JS', this_.$scope_["FormSelected"], data, success, error);
+        }
+    });
+}
+
 /**
  * Make a put request on the server
  * @param {string} cmd command to load (Perso_Save, Perso_Published, Default_Published, Perso_Reset etc...)
+ * @param {string} sForm form to update
  * @param {object} data FormData to send
  * @param {function} functSuccess function to load in case of success
  * @param {function} functError function to load in case of error
  */
-nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.putRequest = function (cmd, data, functSuccess, functError) {
+nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.putRequest = function (cmd, sForm, data, functSuccess, functError) {
     oVFB.log('nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.putRequest');
 
     var url = '';
@@ -810,15 +833,6 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.putRequest = function
         'success': functSuccess,
         'error': functError
     });
-
-//    this.$http_({
-//        url: url,
-//        method: 'PUT',
-//        data: data,
-//        headers: {
-//            "Content-Type": "undefined"
-//        }
-//    }).success(functSuccess).error(functError);
 };
 
 /**
@@ -829,14 +843,34 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.suggestGenerateForm =
     oVFB.log('nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.suggestGenerateForm');
 
     var this_ = this;
-    var oModal = bootbox.confirm('<h4>' + this.$scope_['text']['Loader']['Notify']['generate_form'] + '</h4>', function (result) {
-        if (result === true) {
-            this_.suggestColumnsToGenerateForm();
-        } else {
-            this_['aSuggestedTableFields'] = [];
-            this_.generateFormByBusinessObject();
+    var oModal = bootbox['dialog']({
+        'message': '<h4>' + this.$scope_['text']['Loader']['Notify']['generate_form'] + '</h4>',
+        'buttons': {
+            'cancel': {
+                'label': this.$scope_['text']['Loader']['Cancel'],
+                'className': 'btn-default',
+                'callback': function(){
+                    this_.useEmptyForm();
+                }
+            },
+            'create_empty': {
+                'label': this.$scope_['text']['Loader']['CreateEmptyForm'],
+                'className': 'btn-primary',
+                'callback': function(){
+                    this_['aSuggestedTableFields'] = [];
+                    this_.generateFormByBusinessObject();
+                }
+            },
+            'generate_from_columns': {
+                'label': this.$scope_['text']['Loader']['GenerateForm'],
+                'className': 'btn-primary',
+                'callback': function(){
+                    this_.suggestColumnsToGenerateForm();
+                }
+            }
         }
     });
+
     // Déplace la popup dans l'élément principal du studio (sinon elle est masquée en mode plein écran).
     oVFB.studioMainController.prototype.moveBootboxModalToStudioContainer(oModal);
 };
@@ -860,10 +894,16 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.useEmptyForm = functio
         'javascript': false,
         'name': 'custom-form',
         'nb_cols': 12,
-        'rows': [],
+        'rows': [{
+            'fields': []
+        }],
         'title': ''
     };
 
+    if (!goog.isArray(data)) {
+        data = [];
+    }
+
     data[0] = {
         'datasources': {}
     };
@@ -1017,7 +1057,7 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.generateFormByBusiness
         var error = function (data, status) {
             $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["Reset_Error"] + status, {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
         };
-        this_.putRequest(this_.$scope_["FormSelected"] + "_Reset", {"field": sFieldsToUse, "label": afieldsLabel}, success, error);
+        this_.putRequest(this_.$scope_["FormSelected"] + "_Reset", this_.$scope_["FormSelected"], {"field": sFieldsToUse, "label": afieldsLabel}, success, error);
     } else {
 
         ajaxRequest({
@@ -1035,19 +1075,6 @@ nsVFB.JsonLoader.prototype.jsonLoaderController.prototype.generateFormByBusiness
                 $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["CreateJson_Error"] + status, {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
             }
         });
-
-//        this.$http_({
-//            url: url,
-//            method: 'POST',
-//            data: {
-//                'fields': sFieldsToUse,
-//                'label': afieldsLabel
-//            }
-//        }).success(function () {
-//            this_.requestToJson();
-//        }).error(function () {
-//            $["notify"](this_.$scope_["text"]["Loader"]["Notify"]["CreateJson_Error"] + status, {"className": "error", "autoHideDelay": oVFB.TimeNotify_});
-//        });
     }
 };
 
diff --git a/client/javascript/externs/studio/lang/lang-en.json b/client/javascript/externs/studio/lang/lang-en.json
index f33be9b3..b6d34b37 100755
--- a/client/javascript/externs/studio/lang/lang-en.json
+++ b/client/javascript/externs/studio/lang/lang-en.json
@@ -10,6 +10,8 @@
         "WabState": "State",
         "Validate": "Validate",
         "Cancel": "Cancel",
+        "GenerateForm": "Generate form",
+        "CreateEmptyForm": "Create empty form",
         "AddTab": "Add tab",
         "EditTab": "Edit",
         "RemoveTab": "Remove",
@@ -34,6 +36,7 @@
                 "Button_gtf": "FME generated form"
             },
             "Published": {
+                "DeletePublishedForm": "Delete published form",
                 "Button": "Used form",
                 "Button_gtf": "Used form"
             },
@@ -42,7 +45,8 @@
                 "Reload": "Reload files from server",
                 "Publish": "Publish the custom form",
                 "Reset": "Replace the custom form by the default form",
-                "Button": "Modification used form"
+                "Button": "Modification used form",
+                "Delete_JS": "Remove JavaScript"
             }
         },
         "Form": {
@@ -87,6 +91,10 @@
             "ProblemId": "ID problem, try again or contact an admin",
             "Reset": "Was reset",
             "Reset_Error": "Error while resetting : ",
+            "Delete": "Le formulaire a été supprimé",
+            "Delete_Error": "Erreur lors de la suppression du formulaire : ",
+            "Delete_JS": "JavaScript file deleted",
+            "Delete_JS_Error": "Erorr while deleting JavaScript file : ",
             "Publish": " Has been published",
             "PublishAndSave": " Has been published and saved",
             "Publish_Error": "Error while publishing : ",
diff --git a/client/javascript/externs/studio/lang/lang-fr.json b/client/javascript/externs/studio/lang/lang-fr.json
index 43a99c1e..ddaad289 100755
--- a/client/javascript/externs/studio/lang/lang-fr.json
+++ b/client/javascript/externs/studio/lang/lang-fr.json
@@ -10,6 +10,8 @@
         "WabState": "État wab",
         "Validate": "Valider",
         "Cancel": "Annuler",
+        "GenerateForm": "Générer un formulaire",
+        "CreateEmptyForm": "Créer un formulaire vide",
         "AddTab": "Ajouter un onglet",
         "EditTab": "Éditer",
         "RemoveTab": "Supprimer",
@@ -34,6 +36,7 @@
                 "Button_gtf": "Afficher le formulaire par défaut"
             },
             "Published": {
+                "DeletePublishedForm": "Supprimer le formulaire publié",
                 "Button": "Afficher le formulaire par publié",
                 "Button_gtf": "Afficher le formulaire par publié"
             },
@@ -44,7 +47,8 @@
                 "Reset": "Remplacer le formulaire personnalisé par le formulaire par défaut",
                 "ResetWab": "Regénérer le formulaire depuis la base",
                 "Button": "Afficher le formulaire par personnalisé",
-                "Button_gtf": "Afficher le formulaire par personnalisé"
+                "Button_gtf": "Afficher le formulaire par personnalisé",
+                "Delete_JS": "Supprimer la partie JavaScript du formulaire"
             }
         },
         "Form": {
@@ -89,6 +93,10 @@
             "ProblemId": "Problème d'ID, réessayer ou contacter un administrateur",
             "Reset": " a été réinitialisé",
             "Reset_Error": "Erreur lors de la réinitialisation : ",
+            "Delete": "Le formulaire a été supprimé",
+            "Delete_Error": "Erreur lors de la suppression du formulaire : ",
+            "Delete_JS": "Le fichier JavaScript a été supprimé",
+            "Delete_JS_Error": "Erreur lors de la suppression du fichier JavaScript : ",
             "Publish": " a été publié",
             "PublishAndSave": " a été publié et sauvegardé",
             "Publish_Error": "Erreur lors de la publication : ",
diff --git a/client/javascript/externs/studio/less/studio.less b/client/javascript/externs/studio/less/studio.less
index 39431d7e..25844881 100755
--- a/client/javascript/externs/studio/less/studio.less
+++ b/client/javascript/externs/studio/less/studio.less
@@ -3,7 +3,7 @@ To change this license header, choose License Headers in Project Properties.
 To change this template file, choose Tools | Templates
 and open the template in the editor.
 */
-/* 
+/*
     Created on : 5 janv. 2016, 12:08:09
     Author     : a_borghi
 */
@@ -23,7 +23,7 @@ and open the template in the editor.
 //@import (less) '../css/lib/bootstrap/css/bootstrap.css';
 
 
-//définit la taille de la fenêtre 
+//définit la taille de la fenêtre
 .app_window{
     /*Skin scrollBar*/
     ::-webkit-scrollbar {
@@ -39,11 +39,11 @@ and open the template in the editor.
     ::-webkit-scrollbar-thumb {
         -webkit-border-radius: 10px;
         border-radius: 10px;
-        background: @studio-color-purple; 
-        -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5); 
+        background: @studio-color-purple;
+        -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
     }
     ::-webkit-scrollbar-thumb:window-inactive {
-        background: @studio-color-purple; 
+        background: @studio-color-purple;
     }
 
     input[type=number]::-webkit-outer-spin-button,
@@ -61,7 +61,7 @@ and open the template in the editor.
 
 /*Laisse une marge sous un composant*/
 .element-margin {
-    margin-bottom: 10px; 
+    margin-bottom: 10px;
 }
 
 //align un div sur la droite avec une petite marge
@@ -199,19 +199,14 @@ and open the template in the editor.
 }
 
 // rend un élément non selectable
-.unselectable { 
-    -moz-user-select: none; 
-    -khtml-user-select: none; 
-    -webkit-user-select: none; 
-    -o-user-select: none; 
-}
-
-// décalage pour les checkbox et radio 
-.checkbox_margin {
-    margin-left: 30px;
+.unselectable {
+    -moz-user-select: none;
+    -khtml-user-select: none;
+    -webkit-user-select: none;
+    -o-user-select: none;
 }
 
-// Permet à code Mirror de prendre toute la place dans la div 
+// Permet à code Mirror de prendre toute la place dans la div
 .CodeMirror {
     border: 1px solid #eee;
     height: auto;
@@ -241,7 +236,7 @@ and open the template in the editor.
 }
 
 .invalid_input{
-    background-color: rgba(255,0,0,0.5); 
+    background-color: rgba(255,0,0,0.5);
 }
 
 /*th, td{
@@ -343,15 +338,6 @@ and open the template in the editor.
     font-size:11px
 }
 
-.checkbox label::before, .checkbox label::after{
-    width:13px;
-    height: 13px;
-}
-
-.checkbox {
-    padding-left: 12px;
-}
-
 .collapser-form-wab-modal{
     font-size: 40px;
     padding-top: 10px;
@@ -359,8 +345,8 @@ and open the template in the editor.
 }
 
 .transition-form-wab-collapser{
-    transition: width 0.5s; 
-    //transition: display 1s; 
+    transition: width 0.5s;
+    //transition: display 1s;
 }
 .form-tools-tree-container{
     overflow-y: auto;
@@ -381,4 +367,4 @@ and open the template in the editor.
     background-color: initial;
     top: initial;
     //border: initial;
-}
\ No newline at end of file
+}
diff --git a/client/javascript/externs/studio/templates/JsonLoader.html b/client/javascript/externs/studio/templates/JsonLoader.html
index f5b18f1b..6e320cda 100755
--- a/client/javascript/externs/studio/templates/JsonLoader.html
+++ b/client/javascript/externs/studio/templates/JsonLoader.html
@@ -1,8 +1,4 @@
 <div class="panel panel-veremes" id="FilesURL">
-    <!--    <div class="panel-heading unselectable" ng-click="ctrl.resize()">{{::ctrl.text.Title}}
-            <span ng-if="collapsed" id="colapse_uploader_icon" class="fa fa-angle-right fa-lg" style="float:right"></span>
-            <span ng-if="!collapsed" id="colapse_uploader_icon" class="fa fa-angle-down fa-lg" style="float:right"></span>
-        </div>-->
     <div class="panel-heading unselectable">
         <!--Fichier-->
         <div class="btn-group dropdown margin-right-10">
@@ -50,6 +46,24 @@
                         {{::ctrl.text.InfoBulle.Perso.Publish}}
                     </a>
                 </li>
+                <li ng-hide="ctrl.buttonHide"
+                    ng-show="(FormSelected === 'Perso' || FormSelected === 'Published') && ctrl.applicationName === 'vmap'">
+                    <a title="{{::ctrl.text.InfoBulle.Published.Delete}}"
+                       href="javascript:void(0);"
+                       ng-click="ctrl.deletePublishedForm()">
+                        <span class="fa icon-trash" aria-hidden="true"></span>
+                        {{::ctrl.text.InfoBulle.Published.DeletePublishedForm}}
+                    </a>
+                </li>
+                <li ng-hide="ctrl.buttonHide"
+                    ng-show="(FormSelected === 'Perso' || FormSelected === 'Published') && ctrl.applicationName === 'vmap'">
+                    <a title="{{::ctrl.text.InfoBulle.Perso.Delete_JS}}"
+                       href="javascript:void(0);"
+                       ng-click="ctrl.deleteJS()">
+                        <span class="fa icon-trash" aria-hidden="true"></span>
+                        {{::ctrl.text.InfoBulle.Perso.Delete_JS}}
+                    </a>
+                </li>
                 <li ng-hide="ctrl.buttonHide" ng-show="FormSelected === 'Perso'">
                     <a title="{{::ctrl.text.InfoBulle.Perso.Reset}}"
                        href="javascript:void(0);"
diff --git a/client/less/main.less b/client/less/main.less
index d567b91f..56042ea6 100644
--- a/client/less/main.less
+++ b/client/less/main.less
@@ -1046,3 +1046,24 @@ div[data-app-html-form]>div[app-form-reader]>.modal>.modal-dialog{
 /*@supports (-ms-accelerator:true) and (not (color:unset)) {
   .selector { property:value; }
 }*/
+
+.checkbox {
+    padding-left: 12px;
+}
+
+.checkbox_margin {
+    margin-left: 30px;
+}
+
+.checkbox-inline label::before{
+    top: 3px;
+    left: 1px
+}
+.checkbox-inline label::after{
+    top: 2px;
+}
+
+.checkbox label::before, .checkbox label::after{
+    width:13px;
+    height: 13px;
+}
diff --git a/vas/rest/ws/vitis/Versions.class.inc b/vas/rest/ws/vitis/Versions.class.inc
index 3a20a659..62b9cfcc 100755
--- a/vas/rest/ws/vitis/Versions.class.inc
+++ b/vas/rest/ws/vitis/Versions.class.inc
@@ -1,202 +1,204 @@
-<?php
-
-require_once 'Vitis.class.inc';
-require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
-require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
-
-/**
- * \file versions.class.inc
- * \class Versions
- *
- * \author Yoann Perollet <yoann.perollet@veremes.com>.
- *
- * 	\brief This file contains the Versions php class
- *
- * This class defines the rest api for versions
- * 
- */
-class Versions extends Vitis {
-    /**
-     * @SWG\Definition(
-     *   definition="/versions",
-     *   allOf={
-     *     @SWG\Schema(ref="#/definitions/versions")
-     *   }
-     * )
-     * @SWG\Tag(
-     *   name="Versions",
-     *   description="Operations about versions"
-     * )
-     */
-
-    /**
-     * construct
-     * @param type $aPath url of the request
-     * @param type $aValues parameters of the request
-     * @param type $versions ptroperties
-     */
-    function __construct($aPath, $aValues, $properties) {
-        $this->aValues = $aValues;
-        $this->aPath = $aPath;
-        $this->aProperties = $properties;
-        if (!empty($this->aValues['token'])) {
-            $this->oConnection = new Connection($this->aValues, $this->aProperties);
-        }
-    }
-
-    /**
-     * @SWG\Get(path="/versions",
-     *   tags={"Versions"},
-     *   summary="Get versions",
-     *   description="Request to get versions",
-     *   operationId="GET",
-     *   produces={"application/xml", "application/json", "application/x-vm-json"},
-     *   @SWG\Parameter(
-     *     name="token",
-     *     in="query",
-     *     description="user token",
-     *     required=false,
-     *     type="string"
-     *   ),
-     *  @SWG\Response(
-     *         response=200,
-     *         description="Poprerties Response",
-     *         @SWG\Schema(ref="#/definitions/versions")
-     *     )
-     *  )
-     */
-
-    /**
-     * 
-     * @return versions
-     */
-    function GET() {
-        if ($this->oConnection->oError == null) {
-            $this->getVersion();
-            if (!empty($this->aValues['token']) && in_array("vitis_admin", $this->oConnection->aPrivileges)) {
-
-                //$this->aFields = $this->aVersions;
-                $this->aFields['php_version'] = phpversion();
-
-                //*** PDO
-                $bPdo = false;
-                if (extension_loaded('pdo'))
-                    $bPdo = true;
-                else
-                    $bVeremap = false;
-                $this->aFields['pdo_extension_loaded'] = $bPdo;
-
-                //*** PDO Postgresql
-                $bPdoPgsql = false;
-                if (extension_loaded('pdo_pgsql'))
-                    $bPdoPgsql = true;
-                else
-                    $bVeremap = false;
-                $this->aFields['pdo_pgsql_extension_loaded'] = $bPdoPgsql;
-
-                //*** Curl
-                $bCurl = false;
-                if (extension_loaded('curl'))
-                    $bCurl = true;
-                else
-                    $bVeremap = false;
-                $this->aFields['curl_extension_loaded'] = $bCurl;
-
-                //*** Xsl
-                $bXsl = false;
-                if (extension_loaded('xsl'))
-                    $bXsl = true;
-                $this->aFields['xsl_extension_loaded'] = $bXsl;
-
-                //*** Ldap
-                $bLdap = false;
-                if (extension_loaded('ldap'))
-                    $bLdap = true;
-                $this->aFields['ldap_extension_loaded'] = $bLdap;
-
-                // OS.
-                $this->aFields['os_version'] = php_uname();
-
-                // Info disque.
-                $this->aFields['disk_free_space'] = round(disk_free_space("/") / 1073741824) . ' Go';
-                $this->aFields['disk_total_space'] = round(disk_total_space("/") / 1073741824) . ' Go';
-
-                //
-                $this->aFields['server_software'] = $_SERVER['SERVER_SOFTWARE'];
-                $this->aFields['server_addr'] = $_SERVER['SERVER_ADDR'];
-                $this->aFields['server_name'] = $_SERVER['SERVER_NAME'];
-                $this->aFields['server_port'] = $_SERVER['SERVER_PORT'];
-
-                //** Postgresql et Postgis
-                $bPostgresql = false;
-                $bPostgis = false;
-                if (!$this->oConnection->oBd->erreurRencontree) {
-                    $bPostgresql = true;
-                    $sSql = "SHOW server_version";
-                    $oPDOresult = $this->oConnection->oBd->executeWithParams($sSql, array());
-                    $oPgVersion = $this->oConnection->oBd->objetSuivant($oPDOresult);
-                    $sPostgresql = $oPgVersion->server_version;
-                    $this->aFields['postgresql_version'] = $sPostgresql;
-                    $this->oConnection->oBd->fermeResultat();
-
-                    $aVersion = explode(".", $sPostgresql);
-                    $bExtension = false;
-                    if ($aVersion[0] . $aVersion[1] >= 91) {
-                        $bExtension = true;
-                    }
-                    if ($bExtension == true) {
-                        $sSql = "SELECT default_version FROM pg_catalog.pg_available_extensions where name = 'postgis';";
-                        $oPDOresult = $this->oConnection->oBd->executeWithParams($sSql, array());
-                        if ($aPostgis = $this->oConnection->oBd->ligneSuivante($oPDOresult)) {
-                            $bPostgis = true;
-                            $sPostgis = $aPostgis['default_version'];
-                        } else {
-                            $bPostgis = false;
-                        }
-                    } else {
-                        $sSql = "SELECT datname FROM pg_catalog.pg_database where datname = 'template_postgis_20';";
-                        $oPDOresult = $this->oConnection->oBd->executeWithParams($sSql, array());
-                        if ($aPostgis = $this->oConnection->oBd->ligneSuivante($oPDOresult)) {
-                            $bPostgis = true;
-                            $sPostgis = '2.0';
-                        } else {
-                            $bPostgis = false;
-                        }
-                    }
-                    $this->aFields['postgis_version'] = $sPostgis;
-                    $this->oConnection->oBd->fermeResultat();
-                    $sSql = 'SELECT distinct module_id from [sSchemaFramework].vm_mode';
-                    $aParams['sSchemaFramework'] = array('value' => $this->aProperties['schema_framework'], 'type' => 'schema_name');
-                    $oPDOresult = $this->oConnection->oBd->executeWithParams($sSql, $aParams);
-                    while ($aLigne = $this->oConnection->oBd->ligneSuivante($oPDOresult)) {
-                        $aModules[] = $aLigne['module_id'];
-                    }
-                    $iRecordset = $this->oConnection->oBd->fermeResultat();
-                }
-                $this->aFields['postgresql'] = $bPostgresql;
-                $this->aFields['postgis'] = $bPostgis;
-
-                // Recherche de mise à jour
-                // 
-                if (!empty($this->aValues['app'])) {
-                    $sUrl = "http://update.veremes.net/vai/" . $this->aValues['app'] . ".json";
-                    $json = file_get_contents($sUrl);
-                    $data = json_decode($json, TRUE);
-                    $this->aFields['appVersion'] = $data['version'];
-                }
-            }
-            $aXmlRacineAttribute['status'] = 1;
-            $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
-        } else {
-            http_response_code(403);
-            $aXmlRacineAttribute['status'] = 0;
-            $this->aFields['errorMessage'] = "ERROR : invalid token";
-            $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
-        }
-
-        return $sMessage;
-    }
-
-}
-
+<?php
+
+require_once 'Vitis.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+/**
+ * \file versions.class.inc
+ * \class Versions
+ *
+ * \author Yoann Perollet <yoann.perollet@veremes.com>.
+ *
+ * 	\brief This file contains the Versions php class
+ *
+ * This class defines the rest api for versions
+ * 
+ */
+class Versions extends Vitis {
+    /**
+     * @SWG\Definition(
+     *   definition="/versions",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/versions")
+     *   }
+     * )
+     * @SWG\Tag(
+     *   name="Versions",
+     *   description="Operations about versions"
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $versions ptroperties
+     */
+    function __construct($aPath, $aValues, $properties) {
+        $this->aValues = $aValues;
+        $this->aPath = $aPath;
+        $this->aProperties = $properties;
+        if (!empty($this->aValues['token'])) {
+            $this->oConnection = new Connection($this->aValues, $this->aProperties);
+        }
+    }
+
+    /**
+     * @SWG\Get(path="/versions",
+     *   tags={"Versions"},
+     *   summary="Get versions",
+     *   description="Request to get versions",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *  @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/versions")
+     *     )
+     *  )
+     */
+
+    /**
+     * 
+     * @return versions
+     */
+    function GET() {
+        if ($this->oConnection->oError == null) {
+            $this->getVersion();
+            if (!empty($this->aValues['token']) && in_array("vitis_admin", $this->oConnection->aPrivileges)) {
+
+                //$this->aFields = $this->aVersions;
+                $this->aFields['php_version'] = phpversion();
+
+                //*** PDO
+                $bPdo = false;
+                if (extension_loaded('pdo'))
+                    $bPdo = true;
+                else
+                    $bVeremap = false;
+                $this->aFields['pdo_extension_loaded'] = $bPdo;
+
+                //*** PDO Postgresql
+                $bPdoPgsql = false;
+                if (extension_loaded('pdo_pgsql'))
+                    $bPdoPgsql = true;
+                else
+                    $bVeremap = false;
+                $this->aFields['pdo_pgsql_extension_loaded'] = $bPdoPgsql;
+
+                //*** Curl
+                $bCurl = false;
+                if (extension_loaded('curl'))
+                    $bCurl = true;
+                else
+                    $bVeremap = false;
+                $this->aFields['curl_extension_loaded'] = $bCurl;
+
+                //*** Xsl
+                $bXsl = false;
+                if (extension_loaded('xsl'))
+                    $bXsl = true;
+                $this->aFields['xsl_extension_loaded'] = $bXsl;
+
+                //*** Ldap
+                $bLdap = false;
+                if (extension_loaded('ldap'))
+                    $bLdap = true;
+                $this->aFields['ldap_extension_loaded'] = $bLdap;
+
+                // OS.
+                $this->aFields['os_version'] = php_uname();
+
+                // Info disque.
+                $this->aFields['disk_free_space'] = round(disk_free_space("/") / 1073741824) . ' Go';
+                $this->aFields['disk_total_space'] = round(disk_total_space("/") / 1073741824) . ' Go';
+
+                //
+                $this->aFields['server_software'] = $_SERVER['SERVER_SOFTWARE'];
+                $this->aFields['server_addr'] = $_SERVER['SERVER_ADDR'];
+                $this->aFields['server_name'] = $_SERVER['SERVER_NAME'];
+                $this->aFields['server_port'] = $_SERVER['SERVER_PORT'];
+
+                //** Postgresql et Postgis
+                $bPostgresql = false;
+                $bPostgis = false;
+                if (!$this->oConnection->oBd->erreurRencontree) {
+                    $bPostgresql = true;
+                    $sSql = "SHOW server_version";
+                    $oPDOresult = $this->oConnection->oBd->executeWithParams($sSql, array());
+                    $oPgVersion = $this->oConnection->oBd->objetSuivant($oPDOresult);
+                    $sPostgresql = $oPgVersion->server_version;
+                    $this->aFields['postgresql_version'] = $sPostgresql;
+                    $this->oConnection->oBd->fermeResultat();
+
+                    $aVersion = explode(".", $sPostgresql);
+                    $bExtension = false;
+                    if ($aVersion[0] >= 9) {
+                        if ($aVersion[1] >= 1) {
+                            $bExtension = true;
+                        }
+                    }
+                    if ($bExtension == true) {
+                        $sSql = "SELECT default_version FROM pg_catalog.pg_available_extensions where name = 'postgis';";
+                        $oPDOresult = $this->oConnection->oBd->executeWithParams($sSql, array());
+                        if ($aPostgis = $this->oConnection->oBd->ligneSuivante($oPDOresult)) {
+                            $bPostgis = true;
+                            $sPostgis = $aPostgis['default_version'];
+                        } else {
+                            $bPostgis = false;
+                        }
+                    } else {
+                        $sSql = "SELECT datname FROM pg_catalog.pg_database where datname = 'template_postgis_20';";
+                        $oPDOresult = $this->oConnection->oBd->executeWithParams($sSql, array());
+                        if ($aPostgis = $this->oConnection->oBd->ligneSuivante($oPDOresult)) {
+                            $bPostgis = true;
+                            $sPostgis = '2.0';
+                        } else {
+                            $bPostgis = false;
+                        }
+                    }
+                    $this->aFields['postgis_version'] = $sPostgis;
+                    $this->oConnection->oBd->fermeResultat();
+                    $sSql = 'SELECT distinct module_id from [sSchemaFramework].vm_mode';
+                    $aParams['sSchemaFramework'] = array('value' => $this->aProperties['schema_framework'], 'type' => 'schema_name');
+                    $oPDOresult = $this->oConnection->oBd->executeWithParams($sSql, $aParams);
+                    while ($aLigne = $this->oConnection->oBd->ligneSuivante($oPDOresult)) {
+                        $aModules[] = $aLigne['module_id'];
+                    }
+                    $iRecordset = $this->oConnection->oBd->fermeResultat();
+                }
+                $this->aFields['postgresql'] = $bPostgresql;
+                $this->aFields['postgis'] = $bPostgis;
+
+                // Recherche de mise à jour
+                // 
+                if (!empty($this->aValues['app'])) {
+                    $sUrl = "http://update.veremes.net/vai/" . $this->aValues['app'] . ".json";
+                    $json = file_get_contents($sUrl);
+                    $data = json_decode($json, TRUE);
+                    $this->aFields['appVersion'] = $data['version'];
+                }
+            }
+            $aXmlRacineAttribute['status'] = 1;
+            $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+        } else {
+            http_response_code(403);
+            $aXmlRacineAttribute['status'] = 0;
+            $this->aFields['errorMessage'] = "ERROR : invalid token";
+            $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+        }
+
+        return $sMessage;
+    }
+
+}
+
 ?>
\ No newline at end of file
diff --git a/vas/sql/sqlQueries.xml b/vas/sql/sqlQueries.xml
index 4e745ccc..15c2ea3f 100644
--- a/vas/sql/sqlQueries.xml
+++ b/vas/sql/sqlQueries.xml
@@ -67,7 +67,7 @@
 				ALTER TABLE v_user OWNER TO u_vitis;
 				CREATE VIEW v_user_group AS SELECT user_group.group_id,    user_group.user_id   FROM ((user_group     LEFT JOIN "user" ON ((user_group.user_id = "user".user_id)))     LEFT JOIN "group" ON (("group".group_id = user_group.group_id)))  WHERE ((("user".login)::name)::text = ("current_user"())::text);
 				ALTER TABLE v_user_group OWNER TO u_vitis;
-				CREATE TABLE version (    version character varying(10) NOT NULL,    build integer NOT NULL,    date timestamp with time zone NOT NULL,    active boolean);
+				CREATE TABLE version (    version character varying(100) NOT NULL,    build integer NOT NULL,    date timestamp with time zone NOT NULL,    active boolean);
 				ALTER TABLE version OWNER TO u_vitis;
 				CREATE TABLE vm_application (    name character varying(100) NOT NULL);
 				ALTER TABLE vm_application OWNER TO u_vitis;
-- 
GitLab