]> gitweb @ CieloNegro.org - Rakka.git/blob - js/systemConfig.js
Global JavaScript
[Rakka.git] / js / systemConfig.js
1 (function () {
2
3     var identityDecoder = function (src) {
4         return src;
5     };
6
7     var identityEncoder = function (src) {
8         return src;
9     };
10
11     var mapDecoder = function (src) {
12         var map   = {};
13         var lines = src.split(/\n/);
14
15         $.each(lines, function () {
16                    var m = this.match(/^(\S+)\s+(\S+)$/);
17
18                    map[ m[1] ] = m[2];
19                });
20
21         return map;
22     };
23
24     var mapEncoder = function (map) {
25         var lines = [];
26
27         $.each(map, function (key) {
28                    lines.push(key + " " + this);
29                });
30
31         return lines.join("\n");
32     };
33
34     var boolDecoder = function (src) {
35         return src == "*";
36     };
37
38     var boolEncoder = function (bool) {
39         return bool ? "*" : "";
40     };
41
42     var decoder_of = {
43         siteName   : identityDecoder,
44         baseURI    : identityDecoder,
45         defaultPage: identityDecoder,
46         styleSheet : identityDecoder,
47         languages  : mapDecoder,
48         globalLock : boolDecoder
49     };
50
51     var encoder_of = {
52         siteName   : identityEncoder,
53         baseURI    : identityEncoder,
54         defaultPage: identityEncoder,
55         styleSheet : identityEncoder,
56         languages  : mapEncoder,
57         globalLock : boolEncoder
58     };
59
60     var cachedConf = null;
61
62     var isValidBaseURI = function (str) {
63         parseUri.options.strictMode = true;
64         var uri = parseUri(str);
65
66         return (uri.protocol != "" &&
67                 uri.authority != "" &&
68                 uri.path != "" &&
69                 uri.path.match(/\/$/) &&
70                 uri.query == "" &&
71                 uri.anchor == "");
72     };
73
74     var isValidMap = function (src) {
75         return src.match(/^\S+\s+\S+(?:\n\S+\s+\S+)*\n?$/) != null;
76     };
77
78     Rakka.getUserList = function () {
79         var users = [];
80
81         $.ajax({
82                    type: "GET",
83                    url: Rakka.baseURI + "users",
84                    async: false,
85                    beforeSend: function (req) {
86                        Rakka.setAuthorization(req);
87                    },
88                    success: function (xml) {
89                        $(xml).find("user").each(function () {
90                            users.push(this.getAttribute("id"));
91                        });
92                    },
93                    error: function (req) {
94                        throw new Error(req.status + " " + req.statusText);
95                    }
96         });
97
98         return users;
99     };
100
101     Rakka.getSystemConfig = function () {
102         if (cachedConf != null) {
103             return cachedConf;
104         }
105
106         var conf = {};
107         cachedConf = conf;
108
109         $.ajax({
110             type   : "GET",
111             url    : Rakka.baseURI + "systemConfig",
112             async  : false,
113             success: function (xml) {
114                 $(xml).find("value").each(function () {
115                     var path    = this.getAttribute("path");
116                     var decoder = decoder_of[path];
117
118                     if (decoder == null) {
119                         throw new Error("unknown config path: " + path);
120                     }
121                     else {
122                         conf[path] = decoder($(this).text());
123                     }
124                 });
125             },
126             error  : function (req) {
127                 throw new Error(req.status + " " + req.statusText);
128             }
129         });
130
131         return conf;
132     };
133
134     var appendConfigPanel = function ($area) {
135         var conf  = Rakka.getSystemConfig();
136         $area.append($.H1({}, "Configuration"));
137
138          var fldSiteName
139              = $.INPUT({type: "text", value: conf.siteName});
140
141          var fldBaseURI
142              = $.INPUT({type: "text", value: conf.baseURI});
143
144          var fldDefaultPage
145              = $.INPUT({type: "text", value: conf.defaultPage});
146
147          var fldStyleSheet
148              = $.INPUT({type: "text", value: conf.styleSheet});
149
150          var fldLanguages
151              = $.TEXTAREA({value: encoder_of.languages(conf.languages)});
152
153          var chkGlobalLock
154              = $.INPUT({type: "checkbox", checked: conf.globalLock});
155
156          var btnSave
157              = $.INPUT({type: "button", value: "Save"});
158
159          $(btnSave).click(function () {
160                               var NS  = "http://cielonegro.org/schema/Rakka/Config/1.0";
161                               var doc = document.implementation.createDocument(NS, "systemConfig", null);
162                               var sc  = doc.documentElement;
163
164                               var mkValue = function (path, value) {
165                                   var elem = doc.createElementNS(NS, "value");
166                                   elem.setAttribute("path", path);
167                                   elem.appendChild(doc.createTextNode(value));
168                                   return elem;
169                               };
170
171                               sc.appendChild(mkValue("siteName"   , fldSiteName.value));
172                               sc.appendChild(mkValue("baseURI"    , fldBaseURI.value));
173                               sc.appendChild(mkValue("defaultPage", fldDefaultPage.value));
174                               sc.appendChild(mkValue("styleSheet" , fldStyleSheet.value));
175                               sc.appendChild(mkValue("languages"  , fldLanguages.value));
176                               sc.appendChild(mkValue("globalLock" , encoder_of["globalLock"](chkGlobalLock.checked)));
177
178                               Rakka.displayWaitingMessage("Submitting... please wait.");
179
180                               var url = Rakka.baseURI + "systemConfig";
181                               $.ajax({ type       : "PUT",
182                                        url        : url,
183                                        contentType: "text/xml",
184                                        data       : doc,
185                                        processData: false,
186                                        beforeSend : function (req) {
187                                            Rakka.setAuthorization(req);
188                                        },
189                                        success    : function () {
190                                            cachedConf = null;
191                                            Rakka.hideWaitingMessage();
192                                            Rakka.restoreScreen();
193                                        },
194                                        error      : function (req) {
195                                            Rakka.hideWaitingMessage();
196
197                                            var $area = Rakka.switchScreen();
198                                            $area.text("Error: " + req.status + " " + req.statusText);
199                                        }
200                                      });
201                           });
202
203          var btnCancel
204              = $.INPUT({type: "button", value: "Cancel"});
205
206          $(btnCancel).click(function () {
207              if (isDirty) {
208                  if (window.confirm("Do you really want to discard changes?")) {
209                     Rakka.restoreScreen();
210                  }
211              }
212              else {
213                  Rakka.restoreScreen();
214              }
215          });
216
217          var configPanel
218              = $.TABLE({className: "pageEditor"},
219                        $.TBODY({},
220                                $.TR({},
221                                     $.TH({}, "Site name"),
222                                     $.TD({}, fldSiteName)
223                                    ),
224                                $.TR({},
225                                     $.TH({}, "Base URI"),
226                                     $.TD({}, fldBaseURI)
227                                    ),
228                                $.TR({},
229                                     $.TH({}, "Default page"),
230                                     $.TD({}, fldDefaultPage)
231                                    ),
232                                $.TR({},
233                                     $.TH({}, "Style sheet"),
234                                     $.TD({}, fldStyleSheet)
235                                    ),
236                                $.TR({},
237                                     $.TH({}, "Languages"),
238                                     $.TD({}, fldLanguages)
239                                    ),
240                                $.TR({},
241                                     $.TH({}, "Global lock"),
242                                     $.TD({},
243                                          $.LABEL({},
244                                                  chkGlobalLock,
245                                                  "Disallow guest users to edit pages."))
246                                    ),
247                                $.TR({},
248                                     $.TH({}),
249                                     $.TD({}, btnSave, btnCancel)
250                                    )
251                               )
252                       );
253
254          var validate = function () {
255              var isValid = (function () {
256                                 if (!isValidBaseURI(fldBaseURI.value)) {
257                                     return false;
258                                 }
259
260                                 if (fldDefaultPage.value.match(Rakka.rePageName) == null) {
261                                     return false;
262                                 }
263
264                                 if (fldStyleSheet.value.match(Rakka.rePageName) == null) {
265                                     return false;
266                                 }
267
268                                 if (!isValidMap(fldLanguages.value)) {
269                                     return false;
270                                 }
271
272                                 return true;
273                             })();
274
275              $(btnSave).attr({disabled: (isValid ? "" : "disabled")});
276          };
277
278          var isDirty = null;
279          var makeDirty = function () {
280              isDirty = true;
281          };
282
283          $(fldSiteName)
284              .add(fldBaseURI)
285              .add(fldDefaultPage)
286              .add(fldStyleSheet)
287              .add(fldLanguages)
288              .change(validate)
289              .keyup(validate)
290              .change(makeDirty);
291
292          $area.append(configPanel);
293      };
294
295      var appendUsersPanel = function ($area) {
296          $area.append($.H2({}, "Users"));
297              $area.append($.H3({}, "Existing Users"));
298
299              var tbody = $.TBODY();
300
301              var usersPanel
302              = $.TABLE({className: "pageEditor"},
303                                $.THEAD({},
304                                            $.TR({},
305                                                     $.TH({}, "User ID"),
306                                                     $.TH({}, "Change Password"),
307                                                     $.TH({}, "Delete User")
308                                                    )
309                                           ),
310                                       tbody
311                               );
312
313              var updateUserList = function () {
314              var users = Rakka.getUserList();
315
316                  $(tbody).empty();
317
318                  for (var i = 0; i < users.length; i++) {
319                          var pass1  = $.INPUT({type: "password"});
320                          var pass2  = $.INPUT({type: "password"});
321                          var change = $.INPUT({type: "button", value: "Change"});
322
323                          var chpass = $.TABLE({className: "pageEditor"},
324                                       $.TR({},
325                                                            $.TD({}, pass1),
326                                                                $.TD({rowSpan: 2}, change)),
327                                                       $.TR({},
328                                                                $.TD({}, pass2)));
329
330                          var delUser = $.INPUT({type: "button", value: "Delete"});
331
332                  var validatePassword = function () {
333                      var isValid = (function () {
334                                         if (pass1.value == "") {
335                                             return false;
336                                         }
337
338                                         if (pass1.value != pass2.value) {
339                                             return false;
340                                         }
341
342                                         return true;
343                                     })();
344                      $(change).attr({disabled: (isValid ? "" : "disabled")});
345                  };
346                  validatePassword();
347                  $(pass1)
348                      .add(pass2)
349                      .change(validatePassword)
350                      .keyup(validatePassword);
351
352                          $.each(users, function () {
353                                  var id = users[i];
354                                  var tr = $.TR({},
355                                                    $.TD({}, id),
356                                                        $.TD({}, chpass),
357                                                        $.TD({}, delUser)
358                                                       );
359                                  tbody.appendChild(tr);
360                              });
361                  }
362              };
363              updateUserList();
364
365              $area.append(usersPanel);
366
367              $area.append($.H3({}, "Add new user"));
368
369              var userID  = $.INPUT({type: "text"});
370              var pass1   = $.INPUT({type: "password"});
371              var pass2   = $.INPUT({type: "password"});
372              var addUser = $.INPUT({type: "button", value: "Add"});
373              var addUserPanel = $.TABLE({className: "pageEditor"},
374                                     $.TR({},
375                                                              $.TH({}, "User ID"),
376                                                              $.TD({}, userID)),
377                                                     $.TR({},
378                                                              $.TH({}, "Password"),
379                                                              $.TD({}, pass1)),
380                                                     $.TR({},
381                                                  $.TH({}, "Password (retype)"),
382                                                              $.TD({}, pass2)),
383                                                     $.TR({},
384                                                              $.TH({}),
385                                                              $.TD({}, addUser)));
386
387              $area.append(addUserPanel);
388      };
389
390      Rakka.showConfigPanel = function () {
391          var $area = Rakka.switchScreen();
392
393              appendConfigPanel($area);
394              appendUsersPanel($area);
395      };
396
397      $(document).ready(function () {
398                            $("input.configButton")
399                                .click(function () {
400                                           Rakka.showConfigPanel();
401                                       });
402                        });
403 })();