]> gitweb @ CieloNegro.org - Rakka.git/blobdiff - js/systemConfig.js
stylesheet changes
[Rakka.git] / js / systemConfig.js
index e9254e3837d867236cc4645eb0a28ca28917af54..7771f8efeae5c4779f2ff84ca74edd230f5de4e3 100644 (file)
 (function () {
 
-     var identityDecoder = function (src) {
-         return src;
-     };
+    var identityDecoder = function (src) {
+        return src;
+    };
 
-     var identityEncoder = function (src) {
-         return src;
-     };
+    var identityEncoder = function (src) {
+        return src;
+    };
 
-     var mapDecoder = function (src) {
-         var map   = {};
-         var lines = src.split(/\n/);
+    var mapDecoder = function (src) {
+        var map   = {};
+        var lines = src.split(/\n/);
 
-         $.each(lines, function () {
-                    var m = this.match(/^(\S+)\s+(\S+)$/);
+        $.each(lines, function () {
+            var m = this.match(/^(\S+)\s+(\S+)$/);
 
-                    map[ m[1] ] = m[2];
-                });
+            if (m) {
+                map[ m[1] ] = m[2];
+            }
+        });
 
-         return map;
-     };
+        return map;
+    };
 
-     var mapEncoder = function (map) {
-         var lines = [];
+    var mapEncoder = function (map) {
+        var lines = [];
 
-         $.each(map, function (key) {
-                    lines.push(key + " " + this);
-                });
+        $.each(map, function (key) {
+                   lines.push(key + " " + this);
+               });
 
-         return lines.join("\n");
-     };
+        return lines.join("\n");
+    };
 
-     var boolDecoder = function (src) {
-         return src == "*";
-     };
+    var boolDecoder = function (src) {
+        return src == "*";
+    };
 
-     var boolEncoder = function (bool) {
-         return bool ? "*" : "";
-     };
+    var boolEncoder = function (bool) {
+        return bool ? "*" : "";
+    };
 
-     var decoder_of = {
-         siteName   : identityDecoder,
-         baseURI    : identityDecoder,
-         defaultPage: identityDecoder,
-         styleSheet : identityDecoder,
-         languages  : mapDecoder,
-         globalLock : boolDecoder
-     };
+    var decoder_of = {
+        siteName   : identityDecoder,
+        baseURI    : identityDecoder,
+        defaultPage: identityDecoder,
+        styleSheet : identityDecoder,
+        languages  : mapDecoder,
+        globalLock : boolDecoder
+    };
 
-     var encoder_of = {
-         siteName   : identityEncoder,
-         baseURI    : identityEncoder,
-         defaultPage: identityEncoder,
-         styleSheet : identityEncoder,
-         languages  : mapEncoder,
-         globalLock : boolEncoder
-     };
+    var encoder_of = {
+        siteName   : identityEncoder,
+        baseURI    : identityEncoder,
+        defaultPage: identityEncoder,
+        styleSheet : identityEncoder,
+        languages  : mapEncoder,
+        globalLock : boolEncoder
+    };
+
+    var cachedConf = null;
+
+    var isValidBaseURI = function (str) {
+        parseUri.options.strictMode = true;
+        var uri = parseUri(str);
+
+        return (uri.protocol  != "" &&
+                uri.authority != "" &&
+                uri.path      != "" &&
+                uri.path.match(/\/$/) &&
+                uri.query     == "" &&
+                uri.anchor    == "");
+    };
+
+     // FIXME: Don't let user to manipulate directly this structure.
+     // FIXME: Values may include spaces.
+    var isValidMap = function (src) {
+        return src.match(/^(?:\S+\s+\S+(?:\n\S+\s+\S+)*\n?)?$/) != null;
+    };
+
+    Rakka.getUserList = function () {
+        var users = [];
 
-     var cachedConf = null;
+        $.ajax({
+           type: "GET",
+           url: Rakka.baseURI + "users",
+           async: false,
+           beforeSend: function (req) {
+               Rakka.setAuthorization(req);
+           },
+           success: function (xml) {
+               $(xml).find("user").each(function () {
+                   users.push(this.getAttribute("id"));
+               });
+           },
+           error: function (req) {
+               throw new Error(req.status + " " + req.statusText);
+           }
+        });
+
+        return users;
+    };
 
     Rakka.getSystemConfig = function () {
         if (cachedConf != null) {
         return conf;
     };
 
-     Rakka.showConfigPanel = function () {
-         var conf  = Rakka.getSystemConfig();
-         var $area = Rakka.switchScreen();
-
-         $area.append($.H1({}, "Configuration"));
-
-         var fldSiteName
-             = $.INPUT({type: "text", value: conf.siteName});
-
-         var fldBaseURI
-             = $.INPUT({type: "text", value: conf.baseURI});
-
-         var fldDefaultPage
-             = $.INPUT({type: "text", value: conf.defaultPage});
+    var appendConfigPanel = function ($area) {
+        $area.append($.H1({}, "Configuration"));
+
+        var fldSiteName
+            = $.INPUT({type: "text"});
+
+        var fldBaseURI
+            = $.INPUT({type: "text"});
+
+        var fldDefaultPage
+            = $.INPUT({type: "text"});
+
+        var fldStyleSheet
+            = $.INPUT({type: "text"});
+
+        var fldLanguages
+            = $.TEXTAREA({});
+
+        var chkGlobalLock
+            = $.INPUT({type: "checkbox"});
+
+        var btnSave
+            = $.INPUT({type: "button", value: "Save changes"});
+
+        var btnRevert
+            = $.INPUT({type: "button", value: "Revert changes"});
+
+        var makeClean = function () {
+            $(btnSave).attr({disabled: "disabled"});
+            $(btnRevert).attr({disabled: "disabled"});
+        };
+
+        var updateConfig = function () {
+            var conf  = Rakka.getSystemConfig();
+
+            fldSiteName.value     = conf.siteName;
+            fldBaseURI.value      = conf.baseURI;
+            fldDefaultPage.value  = conf.defaultPage;
+            fldStyleSheet.value   = conf.styleSheet;
+            fldLanguages.value    = encoder_of.languages(conf.languages);
+            chkGlobalLock.checked = conf.globalLock;
+
+            makeClean();
+        };
+        updateConfig();
+
+        var validate = function () {
+            var isValid = (function () {
+                               if (!isValidBaseURI(fldBaseURI.value)) {
+                                   return false;
+                               }
+
+                               if (fldDefaultPage.value.match(Rakka.rePageName) == null) {
+                                   return false;
+                               }
+
+                               if (fldStyleSheet.value.match(Rakka.rePageName) == null) {
+                                   return false;
+                               }
+
+                               if (!isValidMap(fldLanguages.value)) {
+                                   return false;
+                               }
+
+                               return true;
+                           })();
+
+            $(btnSave).attr({disabled: (isValid ? "" : "disabled")});
+        };
+
+        var makeDirty = function () {
+            $(btnRevert).attr({disabled: ""});
+            validate();
+        };
+
+        $(btnSave).click(function () {
+            var NS  = "http://cielonegro.org/schema/Rakka/Config/1.0";
+            var doc = document.implementation.createDocument(NS, "systemConfig", null);
+            var sc  = doc.documentElement;
+
+            var mkValue = function (path, value) {
+                var elem = doc.createElementNS(NS, "value");
+                elem.setAttribute("path", path);
+                elem.appendChild(doc.createTextNode(value));
+                return elem;
+            };
+
+            sc.appendChild(mkValue("siteName"   , fldSiteName.value));
+            sc.appendChild(mkValue("baseURI"    , fldBaseURI.value));
+            sc.appendChild(mkValue("defaultPage", fldDefaultPage.value));
+            sc.appendChild(mkValue("styleSheet" , fldStyleSheet.value));
+            sc.appendChild(mkValue("languages"  , fldLanguages.value));
+            sc.appendChild(mkValue("globalLock" , encoder_of["globalLock"](chkGlobalLock.checked)));
+
+            Rakka.displayWaitingMessage("Submitting... please wait.");
+
+            var url = Rakka.baseURI + "systemConfig";
+            $.ajax({ type       : "PUT",
+                     url        : url,
+                     contentType: "text/xml",
+                     data       : doc,
+                     processData: false,
+                     beforeSend : function (req) {
+                         Rakka.setAuthorization(req);
+                     },
+                     success    : function () {
+                         cachedConf = null;
+                         Rakka.hideWaitingMessage();
+                         makeClean();
+                     },
+                     error      : function (req) {
+                         Rakka.hideWaitingMessage();
+
+                         // FIXME: better error handling
+                         var $area = Rakka.switchScreen();
+                         $area.text("Error: " + req.status + " " + req.statusText);
+                     }
+            });
+        });
 
-         var fldStyleSheet
-             = $.INPUT({type: "text", value: conf.styleSheet});
+        $(btnRevert).click(function () {
+            if (window.confirm("Do you really want to discard changes?")) {
+                updateConfig();
+            }
+        });
 
-         var fldLanguages
-             = $.TEXTAREA({value: encoder_of.languages(conf.languages)});
+        var configPanel
+            = $.TABLE({className: "pageEditor"},
+                      $.TBODY({},
+                              $.TR({},
+                                   $.TH({}, "Site name"),
+                                   $.TD({}, fldSiteName)),
+                              $.TR({},
+                                   $.TH({}, "Base URI"),
+                                   $.TD({}, fldBaseURI)),
+                              $.TR({},
+                                   $.TH({}, "Default page"),
+                                   $.TD({}, fldDefaultPage)),
+                              $.TR({},
+                                   $.TH({}, "Style sheet"),
+                                   $.TD({}, fldStyleSheet)),
+                              $.TR({},
+                                   $.TH({}, "Languages"),
+                                   $.TD({}, fldLanguages)),
+                              $.TR({},
+                                   $.TH({}, "Global lock"),
+                                   $.TD({},
+                                        $.LABEL({},
+                                                chkGlobalLock,
+                                                "Disallow guest users to edit pages."))),
+                              $.TR({},
+                                   $.TH({}),
+                                   $.TD({}, btnSave, btnRevert))));
+
+         $(fldSiteName)
+             .add(fldBaseURI)
+             .add(fldDefaultPage)
+             .add(fldStyleSheet)
+             .add(fldLanguages)
+             .keyup(makeDirty)
+             .change(makeDirty);
 
-         var chkGlobalLock
-             = $.INPUT({type: "checkbox", checked: conf.globalLock});
+         $area.append(configPanel);
+     };
 
-         var btnSave
-             = $.INPUT({type: "button", value: "Save"});
+     var appendUsersPanel = function ($area) {
+         $area.append($.H2({}, "Users"));
+         $area.append($.H3({}, "Existing Users"));
 
-         var btnCancel
-             = $.INPUT({type: "button", value: "Cancel"});
+         var tbody = $.TBODY();
 
-         var configPanel
-             = $.TABLE({className: "pageEditor"},
-                       $.TBODY({},
-                               $.TR({},
-                                    $.TH({}, "Site name"),
-                                    $.TD({}, fldSiteName)
-                                   ),
-                               $.TR({},
-                                    $.TH({}, "Base URI"),
-                                    $.TD({}, fldBaseURI)
-                                   ),
-                               $.TR({},
-                                    $.TH({}, "Default page"),
-                                    $.TD({}, fldDefaultPage)
-                                   ),
-                               $.TR({},
-                                    $.TH({}, "Style sheet"),
-                                    $.TD({}, fldStyleSheet)
-                                   ),
-                               $.TR({},
-                                    $.TH({}, "Languages"),
-                                    $.TD({}, fldLanguages)
-                                   ),
-                               $.TR({},
-                                    $.TH({}, "Global lock"),
-                                    $.TD({},
-                                         $.LABEL({},
-                                                 chkGlobalLock,
-                                                 "Disallow guest users to edit pages."))
-                                   ),
+         var usersPanel
+             = $.TABLE({className: "pageEditor vertical"},
+                       $.THEAD({},
                                $.TR({},
-                                    $.TH({}),
-                                    $.TD({}, btnSave, btnCancel)
-                                   )
-                              )
-                      );
-
-         $area.append(configPanel);
+                                    $.TH({}, "User ID"),
+                                    $.TH({}, "Change Password"),
+                                    $.TH({}, "Delete User"))),
+                       tbody);
+
+         var updateUserList = function () {
+             var users = Rakka.getUserList();
+
+             $(tbody).empty();
+
+             for (var i = 0; i < users.length; i++) {
+                 var pass1  = $.INPUT({type: "password"});
+                 var pass2  = $.INPUT({type: "password"});
+                 var change = $.INPUT({type: "button", value: "Change"});
+
+                 var chpass = $.TABLE({className: "pageEditor"},
+                                      $.TR({},
+                                           $.TD({}, pass1),
+                                           $.TD({rowSpan: 2}, change)),
+                                      $.TR({},
+                                           $.TD({}, pass2)));
+
+                 var delUser = $.INPUT({type: "button", value: "Delete"});
+
+                 var validatePassword = function () {
+                     var isValid = (function () {
+                                       if (pass1.value == "") {
+                                           return false;
+                                       }
+
+                                       if (pass1.value != pass2.value) {
+                                           return false;
+                                       }
+
+                                       return true;
+                                    })();
+                     $(change).attr({disabled: (isValid ? "" : "disabled")});
+                 };
+                 validatePassword();
+                 $(pass1)
+                     .add(pass2)
+                     .change(validatePassword)
+                     .keyup(validatePassword);
+
+                 $.each(users, function () {
+                     var id = users[i];
+                     var tr = $.TR({},
+                                   $.TD({}, id),
+                                   $.TD({}, chpass),
+                                   $.TD({}, delUser)
+                                  );
+                     tbody.appendChild(tr);
+                 });
+             }
+         };
+         updateUserList();
+
+         $area.append(usersPanel);
+
+         $area.append($.H3({}, "Add new user"));
+
+         var userID  = $.INPUT({type: "text"});
+         var pass1   = $.INPUT({type: "password"});
+         var pass2   = $.INPUT({type: "password"});
+         var addUser = $.INPUT({type: "button", value: "Add"});
+         var addUserPanel = $.TABLE({className: "pageEditor"},
+                                    $.TR({},
+                                         $.TH({}, "User ID"),
+                                         $.TD({}, userID)),
+                                    $.TR({},
+                                         $.TH({}, "Password"),
+                                         $.TD({}, pass1)),
+                                    $.TR({},
+                                         $.TH({}, "Password (retype)"),
+                                         $.TD({}, pass2)),
+                                    $.TR({},
+                                         $.TH({}),
+                                         $.TD({}, addUser)));
+
+         $area.append(addUserPanel);
      };
 
-    $(document).ready(function () {
-        $("input.configButton")
-            .click(function () {
-                       Rakka.showConfigPanel();
-                   });
-    });
+     Rakka.showConfigPanel = function () {
+         var $area = Rakka.switchScreen();
+
+         appendConfigPanel($area);
+         appendUsersPanel($area);
+     };
 
+     $(document).ready(function () {
+         $("input.configButton")
+             .click(function () {
+                        Rakka.showConfigPanel();
+                    });
+     });
 })();
\ No newline at end of file