summaryrefslogtreecommitdiffstats
path: root/web/client.js
diff options
context:
space:
mode:
authorKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2014-02-06 22:27:20 +0200
committerKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2014-02-12 12:38:31 +0200
commit1dc9c3a59137b1cb9a38669938ba865154100c64 (patch)
tree28599445ef4a199ecde352afa495c4a918dd4641 /web/client.js
parent8857a1753ba94c490211b06531995b6ad88506a6 (diff)
downloadaconf-1dc9c3a59137b1cb9a38669938ba865154100c64.tar.bz2
aconf-1dc9c3a59137b1cb9a38669938ba865154100c64.tar.xz
web client: transaction module
Diffstat (limited to 'web/client.js')
-rw-r--r--web/client.js424
1 files changed, 3 insertions, 421 deletions
diff --git a/web/client.js b/web/client.js
index 81ef869..d289890 100644
--- a/web/client.js
+++ b/web/client.js
@@ -21,6 +21,7 @@ require(
[
"acf2/path",
"acf2/statusbar",
+ "acf2/transaction",
"acf2/type",
"jquery",
"underscore",
@@ -28,7 +29,7 @@ require(
"jquery-blockui",
"jquery-ui/sortable"
],
- function(pth, statusBar, type, $, _) {
+ function(pth, statusBar, txnMgr, type, $, _) {
$("#login").submit(function() {
$.ajax("/login", {
@@ -38,429 +39,10 @@ require(
})
}).done(function(data, status, xhr) {
- var txnMgr = (function(token, saveRequired) {
- var txn, changed, invalid;
-
- function reset() {
- txn = null;
- changed = {};
- invalid = {};
- }
- reset();
-
- function isValid() { return !(_.size(invalid)); }
-
- function request(url, options) {
- options = options || {};
- options.headers = {"X-ACF-Auth-Token": token};
- if (txn) options.headers["X-ACF-Transaction-ID"] = txn;
- if (options.data != undefined)
- options.data = JSON.stringify(options.data);
- return $.ajax(url, options);
- }
-
- function abort() {
- request("/transaction", {type: "DELETE"});
- reset();
- }
-
- function objRequest(path, options) {
- return request("/config" + path, options);
- }
-
- function exclusive(task) {
- $.blockUI();
-
- var def = $.Deferred();
- function resolve(txnValid) { def.resolve(txnValid); }
- function reject() { def.reject(); }
-
- var tasks = _.filter(
- _.pluck(_.values(invalid), 1), function(d) {
- return d && d.state() == "pending";
- }
- );
-
- if (tasks.length)
- tasks[0].always(function() {
- exclusive(task).done(resolve).fail(reject);
- });
- else task().always($.unblockUI).done(resolve).fail(reject);
-
- return def;
- }
-
- function query(path) {
- var def = $.Deferred();
-
- objRequest(path).done(function(data) {
- if (type.isTreeNode(data.meta) && !_.size(data.data))
- data.data = type.isList(data.meta) ? [] : {};
-
- function index(name) {
- return _.isArray(data.data) ? name - 1 : name;
- }
-
- data.get = function(name, valid) {
- var p = pth.join(path, name);
- if (!valid && p in invalid) return invalid[p][0];
-
- if (data.meta.type == "set") {
- return _.contains(
- data.data, name
- ) ? name : null;
- }
-
- return data.data[index(name)];
- };
-
- data.metaRequest = function(name) {
- return request("/meta" + pth.join(path, name));
- };
-
- data.match = function(filter) {
- if (!filter) return true;
- return _.every(_.map(filter, function(values, key) {
- return _.contains(values, data.data[key]);
- }));
- };
-
- data.status = function(name) {
- var p = name ? pth.join(path, name) : path;
- function scan(objs) {
- return _.size(_.filter(
- _.keys(objs), function(obj) {
- return pth.isSubordinate(obj, p);
- }
- ));
- }
-
- if (scan(invalid)) return "invalid";
- if (scan(changed)) return "changed";
- return null;
- };
-
- data.validate = function() {
- var valid = true;
- if (data.meta.required) {
- valid = _.size(data.data);
- if (valid) delete invalid[path];
- else invalid[path] = [path];
- }
- return valid && isValid();
- };
-
- data.set = function(name, newValue) {
- var def = $.Deferred();
- function reject(xhr) { def.reject(xhr); }
-
- var mpath = pth.join(path, name);
-
- var value = data.get(name, true);
- if (value == undefined) value = null;
-
- var tn = _.isObject(newValue);
- var npv = tn ? mpath : newValue;
-
- function ignore(path) {
- _.each(_.keys(invalid), function(p) {
- if (pth.isSubordinate(p, path))
- delete invalid[p];
- });
- }
-
- function resolve() {
- if (mpath in invalid &&
- invalid[mpath][1] == def) {
-
- var del = invalid[mpath][0] == null;
-
- delete invalid[mpath];
- if (del) ignore(mpath);
- }
-
- def.resolve(isValid());
- }
-
- function validate() {
- var del = newValue == null;
- var set = data.meta.type == "set";
-
- var options;
- if (!del)
- options = {
- type: set ? "POST" : "PUT",
- data: newValue
- };
- else if (data.get(name, true) != null)
- options = {type: "DELETE"};
-
- if (!options) {
- if (data.meta.type == "model" &&
- _.findWhere(
- data.meta.fields, {name: name}
- ).required)
- def.reject("Required value not set");
- else resolve();
- return;
- }
-
- objRequest(
- set && !del ? path : mpath, options
- ).done(function() {
- if (!(mpath in changed))
- changed[mpath] = value;
- if (!tn && newValue == changed[mpath])
- delete changed[mpath];
-
- if (npv == null)
- _.each(
- _.keys(changed),
- function(p) {
- if (pth.isSubordinate(p, mpath, true))
- delete changed[p];
- }
- );
-
- if (data.meta.type == "list" && del)
- data.data.splice(name - 1, 1);
- else if (!set) data.data[index(name)] = npv;
- else if (del)
- data.data.splice(
- data.data.indexOf(name), 1
- );
- else data.data.push(name);
-
- data.validate();
-
- if (data.meta.type == "model")
- _.each(
- data.meta.fields, function(field) {
- if (field.condition &&
- field.condition[name] &&
- !_.contains(
- field.condition[name],
- newValue
- ))
- ignore(
- pth.join(path, field.name)
- );
- }
- );
-
- if (tn && !set)
- query(mpath).done(function(data) {
-
- if (mpath in invalid) {
- if (data.meta.type == "model")
- _.each(
- data.meta.fields,
- function(field) {
- var mmpath = pth.join(
- mpath,
- field.name
- );
- if (field.required &&
- data.match(
- field.condition
- ) &&
- !(mmpath in invalid) &&
- (type.isCollection(
- field
- ) || data.get(
- field.name
- ) == null)) {
- invalid[
- mmpath
- ] = [
- null
- ];
- }
- });
-
- else if (type.isCollection(data.meta) &&
- data.meta.required)
- invalid[mpath] = [mpath];
- }
-
- resolve();
- }).fail(reject);
-
- else resolve();
-
- }).fail(reject);
- }
-
- var prevTask;
- if (mpath in invalid) prevTask = invalid[mpath][1];
-
- invalid[mpath] = [npv, def];
-
- if (prevTask) prevTask.always(validate);
- else validate();
-
- return def;
- };
-
- data.add = function(name) {
- return data.set(name, name);
- };
-
- function adjustListIndex(oldIndex, newIndex) {
- var opath = pth.join(path, oldIndex);
- var npath = pth.join(path, newIndex);
- _.each(
- [changed, invalid],
- function(map) {
- _.each(
- _.keys(map),
- function(p) {
- if (pth.isSubordinate(
- p, opath
- )) {
- map[npath +
- p.substring(
- opath.length
- )] = map[p];
- delete map[p];
- }
- });
- }
- );
- }
-
- function adjustListIndices(start, end) {
- var offset = start < end ? 1 : -1;
- for (var i = start; i != end; i += offset)
- adjustListIndex(i + offset, i);
- }
-
- function _delete(name) {
- var def = $.Deferred();
- var length = data.data.length;
-
- data.set(name, null).done(function(txnValid) {
- if (type.isTreeNode(data.meta) &&
- data.meta.type != "set") {
-
- delete changed[pth.join(path, name)];
- changed[path] = path;
-
- if (data.meta.type == "list")
- adjustListIndices(name, length);
- }
- def.resolve(txnValid);
-
- }).fail(function() { def.reject(); });
-
- return def;
- }
-
- data.delete = function(name) {
- return exclusive(function() {
- return _delete(name);
- });
- };
-
- data.move = function(oldIndex, newIndex) {
- if (oldIndex == newIndex)
- return $.Deferred().resolve(isValid());
-
- var value = data.get(oldIndex);
- var length = data.data.length;
-
- return exclusive(function() {
- var def = $.Deferred();
- function reject() { def.reject(); }
-
- if (oldIndex > newIndex) oldIndex++;
- else newIndex++;
-
- objRequest(path, {type: "POST", data: {
- index: newIndex,
- data: type.isTreeNode(data.meta.members) ?
- pth.join(path, oldIndex) : value
- }}).done(function() {
-
- data.data.splice(newIndex - 1, 0, value);
-
- adjustListIndices(length + 1, newIndex);
- adjustListIndex(oldIndex, newIndex);
-
- data.delete(oldIndex)
- .done(function(txnValid) {
- def.resolve(txnValid);
- })
- .fail(reject);
-
- }).fail(reject);
-
- return def;
- });
- };
-
- data.invoke = function(name) {
- return objRequest(pth.join(path, name), {type: "POST"});
- };
-
- def.resolve(data);
- }).fail(function() { def.reject(); });
-
- return def;
- }
-
- return {
- start: function() {
- var def = $.Deferred();
- if (txn && isValid() && !(_.size(changed))) abort();
-
- if (txn)
- def.resolve();
-
- else request("/transaction", {type: "POST"})
- .done(function(data, status, xhr) {
- txn = xhr.getResponseHeader(
- "X-ACF-Transaction-ID"
- );
- def.resolve();
- })
- .fail(function() { def.reject(); });
-
- return def;
- },
-
- commit: function() {
- var def = $.Deferred();
- function reject(xhr) { def.reject(xhr); }
- request(
- "/transaction", {type: "PUT"}
- ).done(function() {
- reset();
- if (saveRequired)
- request(
- "/save", {type: "POST"}
- ).done(function() {
- def.resolve();
- }).fail(reject);
- else def.resolve();
- }).fail(reject);
- return def;
- },
-
- abort: abort,
-
- query: query,
-
- logout: function() {
- return request("/login", {type: "DELETE"});
- }
- };
- })(
+ txnMgr = txnMgr(
xhr.getResponseHeader("X-ACF-Auth-Token"),
xhr.getResponseHeader("X-ACF-Save-Required") == "1"
);
-
-
function formatError(msg, xhr) {
msg += " " + xhr.statusCode().status;