1
0
Fork 0
mirror of synced 2024-06-28 11:10:46 +12:00
appwrite/public/scripts/views/service.js

438 lines
13 KiB
JavaScript
Raw Normal View History

(function(window) {
"use strict";
window.ls.view.add({
selector: "data-service",
2020-04-02 10:41:29 +13:00
controller: function(element, view, container, form, alerts, expression, window) {
let action = element.dataset["service"];
2020-04-18 10:19:02 +12:00
let service = element.dataset["name"] || null;
2020-02-27 22:16:06 +13:00
let event = expression.parse(element.dataset["event"]); // load, click, change, submit
let confirm = element.dataset["confirm"] || ""; // Free text
let loading = element.dataset["loading"] || ""; // Free text
let loaderId = null;
let scope = element.dataset["scope"] || "sdk"; // Free text
let success = element.dataset["success"] || "";
let failure = element.dataset["failure"] || "";
2020-03-22 06:23:43 +13:00
let running = false;
let callbacks = {
2020-03-22 06:23:43 +13:00
hide: function() {
return function() {
2020-03-22 10:22:47 +13:00
return element.style.opacity = '0';
2020-03-22 06:23:43 +13:00
};
},
reset: function() {
return function() {
if ("FORM" === element.tagName) {
return element.reset();
}
2019-08-07 22:46:51 +12:00
throw new Error("This callback is only valid for forms");
};
},
alert: function(text, classname) {
return function(alerts) {
alerts.add({ text: text, class: classname || "success" }, 3000);
};
},
redirect: function(url) {
return function(router) {
2019-10-11 06:32:41 +13:00
//router.change(url || "/");
window.location = url || "/";
};
},
reload: function() {
return function(router) {
router.reload();
};
},
state: function(keys) {
let updateQueryString = function(key, value, url) {
var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"),
hash;
if (re.test(url)) {
if (typeof value !== "undefined" && value !== null) {
return url.replace(re, "$1" + key + "=" + value + "$2$3");
} else {
hash = url.split("#");
url = hash[0].replace(re, "$1$3").replace(/(&|\?)$/, "");
if (typeof hash[1] !== "undefined" && hash[1] !== null) {
url += "#" + hash[1];
}
return url;
}
} else {
if (typeof value !== "undefined" && value !== null) {
var separator = url.indexOf("?") !== -1 ? "&" : "?";
hash = url.split("#");
url = hash[0] + separator + key + "=" + value;
if (typeof hash[1] !== "undefined" && hash[1] !== null) {
url += "#" + hash[1];
}
return url;
} else {
return url;
}
}
};
2019-05-09 18:54:39 +12:00
keys = keys.split(",").map(element => element.trim());
2019-05-09 18:54:39 +12:00
return function(serviceForm, router, window) {
let url = window.location.href;
2019-05-09 18:54:39 +12:00
keys.map(node => {
node = node.split("=");
2019-08-08 01:02:14 +12:00
let key = node[0] || "";
let name = node[1] || key;
let value = getValue(key, "param", serviceForm);
url = updateQueryString(name, value ? value : null, url);
});
if (url !== window.location.href) {
window.history.pushState({}, "", url);
router.reset();
}
};
},
trigger: function(events) {
return function(document) {
events = events.trim().split(",");
for (let i = 0; i < events.length; i++) {
if ("" === events[i]) {
continue;
}
document.dispatchEvent(new CustomEvent(events[i]));
2019-05-09 18:54:39 +12:00
}
};
2020-03-30 08:38:15 +13:00
},
2020-04-02 10:41:29 +13:00
setId: function name(params) {
},
2020-03-30 08:38:15 +13:00
default: function() {
let collection = container.get('project-collection');
let document = container.get('project-document');
if(collection && document && collection.$id === document.$id) {
for (const [key, value] of Object.entries(document)) {
delete document[key];
}
if(collection.rules) {
for (let index = 0; index < collection.rules.length; index++) {
const element = collection.rules[index];
switch (element.type) {
case 'text':
case 'email':
case 'url':
case 'ip':
document[element.key] = element.default || '';
break;
case 'numeric':
2020-04-04 08:26:52 +13:00
document[element.key] = element.default || '0';
2020-03-30 08:38:15 +13:00
break;
case 'boolean':
document[element.key] = element.default || false;
break;
case 'document':
document[element.key] = element.default || {'$id': '', '$collection': '', '$permissions': {}};
break;
2020-03-30 08:38:15 +13:00
default:
document[element.key] = null;
break;
}
if(element.array) {
document[element.key] = [];
}
}
}
}
}
};
/**
* Original Solution From:
* @see https://stackoverflow.com/a/41322698/2299554
* Notice: this version add support for $ sign in arg name.
*
* Retrieve a function's parameter names and default values
* Notes:
* - parameters with default values will not show up in transpiler code (Babel) because the parameter is removed from the function.
* - does NOT support inline arrow functions as default values
* to clarify: ( name = "string", add = defaultAddFunction ) - is ok
* ( name = "string", add = ( a )=> a + 1 ) - is NOT ok
* - does NOT support default string value that are appended with a non-standard ( word characters or $ ) variable name
* to clarify: ( name = "string" + b ) - is ok
* ( name = "string" + $b ) - is ok
* ( name = "string" + b + "!" ) - is ok
* ( name = "string" + λ ) - is NOT ok
* @param {function} func
* @returns {Array} - An array of the given function's parameter [key, default value] pairs.
*/
let getParams = function getParams(func) {
const REGEX_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;
const REGEX_FUNCTION_PARAMS = /(?:\s*(?:function\s*[^(]*)?\s*)((?:[^'"]|(?:(?:(['"])(?:(?:.*?[^\\]\2)|\2))))*?)\s*(?=(?:=>)|{)/m;
const REGEX_PARAMETERS_VALUES = /\s*([\w\\$]+)\s*(?:=\s*((?:(?:(['"])(?:\3|(?:.*?[^\\]\3)))((\s*\+\s*)(?:(?:(['"])(?:\6|(?:.*?[^\\]\6)))|(?:[\w$]*)))*)|.*?))?\s*(?:,|$)/gm;
let functionAsString = func.toString();
let params = [];
let match;
2021-02-02 11:34:54 +13:00
functionAsString = functionAsString.replaceAll('={}', "");
functionAsString = functionAsString.replaceAll('=[]', "");
functionAsString = functionAsString.replace(REGEX_COMMENTS, "");
functionAsString = functionAsString.match(REGEX_FUNCTION_PARAMS)[1];
if (functionAsString.charAt(0) === "(") {
functionAsString = functionAsString.slice(1, -1);
}
while ((match = REGEX_PARAMETERS_VALUES.exec(functionAsString))) {
//params.push([match[1], match[2]]); // with default values
params.push(match[1]); // only with arg name
}
return params;
};
let getValue = function(key, prefix, data) {
let result = null;
if (!key) {
return null;
}
let attrKey = prefix + key.charAt(0).toUpperCase() + key.slice(1);
/**
* 1. Get from element data-param-* (expression supported)
* 2. Get from element form object-*
*/
if (element.dataset[attrKey]) {
result = expression.parse(element.dataset[attrKey]);
if (element.dataset[attrKey + "CastTo"] === "array") {
result = result.split(",");
}
}
2021-03-01 04:01:16 +13:00
if (typeof data[key] !== 'undefined') {
result = data[key];
}
2021-03-01 04:01:16 +13:00
if (typeof result === 'undefined') {
result = "";
2019-05-09 18:54:39 +12:00
}
return result;
};
let resolve = function(target, prefix = "param", data = {}) {
if (!target) {
return function() {};
}
let args = getParams(target);
return target.apply(
target,
args.map(function(value) {
let result = getValue(value, prefix, data);
2020-04-02 10:41:29 +13:00
2021-06-24 00:15:27 +12:00
return result ?? undefined;
})
);
};
let exec = function(event) {
2020-03-22 06:23:43 +13:00
2020-04-18 10:19:02 +12:00
let parsedSuccess = expression.parse(success);
let parsedFailure = expression.parse(failure);
let parsedAction = expression.parse(action);
parsedSuccess =
parsedSuccess && parsedSuccess != ""
? parsedSuccess.split(",").map(element => element.trim())
2020-04-18 00:53:39 +12:00
: [];
2020-04-18 10:19:02 +12:00
parsedFailure =
parsedFailure && parsedFailure != ""
? parsedFailure.split(",").map(element => element.trim())
2020-04-18 00:53:39 +12:00
: [];
2020-04-02 10:41:29 +13:00
element.$lsSkip = true;
element.classList.add("load-service-start");
if (!document.body.contains(element)) {
element = undefined;
return false;
}
if (event) {
event.preventDefault();
}
2020-03-22 06:23:43 +13:00
if(running) {
return false;
}
running = true;
element.style.backgroud = 'red';
if (confirm) {
if (window.confirm(confirm) !== true) {
2020-03-09 08:27:21 +13:00
element.classList.add("load-service-end");
2020-05-21 09:12:23 +12:00
element.$lsSkip = false;
running = false;
return false;
}
}
if (loading) {
loaderId = alerts.add({ text: loading, class: "" }, 0);
}
2020-03-17 07:41:56 +13:00
2020-04-18 10:19:02 +12:00
let method = container.path(scope + "." + parsedAction);
2020-03-15 17:54:55 +13:00
if (!method) {
2020-04-18 10:19:02 +12:00
throw new Error('Method "' + scope + "." + parsedAction + '" not found');
}
2020-03-15 17:54:55 +13:00
let formData = "FORM" === element.tagName ? form.toJson(element) : {};
2020-03-15 17:54:55 +13:00
let result = resolve(method, "param", formData);
if (!result) {
return;
}
2020-03-15 17:54:55 +13:00
if(Promise.resolve(result) != result) {
result = new Promise((resolve, reject) => {
resolve(result);
});
}
result.then(
function(data) {
if (loaderId !== null) {
// Remove loader if needed
alerts.remove(loaderId);
}
if (!element) {
return;
}
2020-03-22 06:23:43 +13:00
running = false;
element.style.backgroud = 'transparent';
element.classList.add("load-service-end");
2020-04-18 10:19:02 +12:00
if(service) {
container.set(service.replace(".", "-"), data, true, true);
}
container.set("serviceData", data, true, true);
container.set("serviceForm", formData, true, true);
2020-04-18 10:19:02 +12:00
for (let i = 0; i < parsedSuccess.length; i++) {
// Trigger success callbacks
container.resolve(
resolve(
2020-04-18 10:19:02 +12:00
callbacks[parsedSuccess[i]],
"successParam" +
2020-04-18 10:19:02 +12:00
parsedSuccess[i].charAt(0).toUpperCase() +
parsedSuccess[i].slice(1),
{}
)
);
}
container.set("serviceData", null, true, true);
container.set("serviceForm", null, true, true);
element.$lsSkip = false;
view.render(element);
},
function(exception) {
if (loaderId !== null) {
// Remove loader if needed
alerts.remove(loaderId);
}
if (!element) {
return;
}
2020-03-22 06:23:43 +13:00
running = false;
element.style.backgroud = 'transparent';
element.classList.add("load-service-end");
2020-04-18 10:19:02 +12:00
for (let i = 0; i < parsedFailure.length; i++) {
2020-04-18 00:53:39 +12:00
// Trigger failure callbacks
container.resolve(
resolve(
2020-04-18 10:19:02 +12:00
callbacks[parsedFailure[i]],
"failureParam" +
2020-04-18 10:19:02 +12:00
parsedFailure[i].charAt(0).toUpperCase() +
parsedFailure[i].slice(1),
{}
)
);
}
element.$lsSkip = false;
view.render(element);
}
);
};
let events = event.trim().split(",");
for (let y = 0; y < events.length; y++) {
if ("" === events[y]) {
continue;
}
switch (events[y].trim()) {
case "load":
exec();
break;
case "none":
break;
case "click":
case "change":
case "keypress":
case "keydown":
case "keyup":
case "input":
case "submit":
element.addEventListener(events[y], exec);
break;
default:
document.addEventListener(events[y], exec);
}
}
}
});
})(window);