Commit 54d6522b authored by Boris Kocherov's avatar Boris Kocherov

add wizard in xmla demo

parent 634dda81
{
"$schema": "http://json-schema.org/draft-07/schema",
"title": "OLAP Query parameters",
"type": "object",
"definitions": {
"choice": {
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "urn:jio:choice.json"
}
}
},
"properties": {
"connection_name": {
"$ref": "urn:jio:remote_connections.json"
},
"parameters": {
"type": "object",
"additionalProperties": false,
"properties": {
"columns": {
"title": "columns",
"$ref": "#/definitions/choice"
},
"rows": {
"title": "rows",
"$ref": "#/definitions/choice"
}
}
}
},
"additionalProperties": false
}
\ No newline at end of file
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Demo UI OLAP Query editor based on JSON Schema form generator</title>
<link rel="stylesheet" href="gadget_erp5_nojqm.css">
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="jio.js"></script>
<script src="Xmla-compiled.js"></script>
<script src="wizard.js"></script>
</head>
<body>
<div data-role="page">
<div role="main" class="ui-content gadget-content">
<section class="ui-content-header-plain">
<h3 class="ui-content-title ui-body-c">
Xmla connection settings form
</h3>
</section>
<div data-gadget-url="jsonform.gadget.html"
data-gadget-scope="olap_wizard"
data-gadget-sandbox="public"></div>
<br>
</div>
</div>
</body>
</html>
\ No newline at end of file
/*jslint nomen: true, maxlen: 200, indent: 2*/
/*global rJS, console, window, document, RSVP, Xmla*/
(function (window, rJS) {
"use strict";
function getConnections() {
return {
"xmla": {
"urls": ["https://d1.erp5.ru/saiku/xmla"],
"properties": {"DataSourceInfo": "FoodMart", "Catalog": "FoodMart", "Cube": "Sales"}
}
};
}
function getCurrentConnectionSettings(gadget) {
var connections;
return RSVP.Queue()
.push(function () {
return getConnections();
})
.push(function (c) {
connections = c;
return gadget.getContent("/connection_name");
})
.push(function (connection_name) {
return connections[connection_name];
});
}
function get_used_dimensions(g) {
var q;
if (g.props.init_value) {
q = RSVP.Queue()
.push(function () {
return g.props.init_value;
});
} else {
q = g.getDeclaredGadget("olap_wizard")
.push(function (gadget) {
return gadget.getContent();
});
}
return q
.push(function (v) {
var dimensions = [],
key,
dimension;
v = v.parameters;
if (v) {
if (v.columns) {
for (key in v.columns) {
if (v.columns.hasOwnProperty(key)) {
dimension = v.columns[key].dimension;
if (dimension) {
dimensions.push(dimension);
}
}
}
}
if (v.rows) {
for (key in v.rows) {
if (v.rows.hasOwnProperty(key)) {
dimension = v.rows[key].dimension;
if (dimension) {
dimensions.push(dimension);
}
}
}
}
}
return dimensions;
});
}
function xmla_request(func, prop) {
var xmla = new Xmla({async: true});
prop = JSON.parse(JSON.stringify(prop));
// return function () {
return new RSVP.Queue()
.push(function () {
return new RSVP.Promise(function (resolve, reject) {
prop.success = function (xmla, options, response) {
resolve(response);
};
prop.error = function (xmla, options, response) {
reject(response);
};
xmla[func](prop);
});
});
}
function xmla_request_retry(func, settings) {
var queue,
urls = settings.urls,
i;
function make_request(url) {
return function (error) {
settings.prop.url = url;
return xmla_request(func, settings.prop)
.push(undefined, function (response) {
// fix mondrian Internal and Sql errors
if (response) {
switch (response["code"]) {
case "SOAP-ENV:Server.00HSBE02":
case "SOAP-ENV:00UE001.Internal Error":
// rarely server error, so try again
return xmla_request(func, settings.prop);
}
}
throw response;
});
};
}
queue = make_request(urls[0])();
for (i = 1; i < settings.urls.length; i += 1) {
queue.push(undefined, make_request(urls[i]));
}
return queue;
}
function print_content(gadget) {
return gadget.getDeclaredGadget("olap_wizard")
.push(function (g) {
return g.getContent();
})
.push(function (v) {
console.log(JSON.stringify(v));
});
}
function discoverDimensions(schema, used_dimensions, opt) {
return xmla_request_retry("discoverMDDimensions", opt)
.push(undefined, function (error) {
console.log(error);
})
.push(function (response) {
if (response && response.numRows > 0) {
schema.properties.dimension = {
title: " ",
oneOf: []
};
var arr = schema.properties.dimension.oneOf,
row;
while (response.hasMoreRows()) {
row = response.readAsObject();
if (row["DIMENSION_TYPE"] !== 2) {
if (used_dimensions.indexOf(row["DIMENSION_UNIQUE_NAME"]) < 0) {
arr.push({
const: row["DIMENSION_UNIQUE_NAME"] || undefined,
title: row["DIMENSION_NAME"] || undefined
});
}
}
response.nextRow();
}
}
});
}
function discoverHierarchies(schema, opt) {
return xmla_request_retry("discoverMDHierarchies", opt)
.push(undefined, function (error) {
console.log(error);
})
.push(function (response) {
if (response && response.numRows > 0) {
schema.properties.hierarchy = {
title: " ",
oneOf: []
};
var arr = schema.properties.hierarchy.oneOf,
row;
while (response.hasMoreRows()) {
row = response.readAsObject();
arr.push({
const: row["HIERARCHY_UNIQUE_NAME"] || undefined,
title: row["HIERARCHY_NAME"] || undefined
});
response.nextRow();
}
}
});
}
function discoverLevels(schema, opt) {
return xmla_request_retry("discoverMDLevels", opt)
.push(undefined, function (error) {
console.log(error);
})
.push(function (response) {
if (response && response.numRows > 0) {
schema.properties.level = {
title: " ",
oneOf: []
};
var arr = schema.properties.level.oneOf,
row;
while (response.hasMoreRows()) {
row = response.readAsObject();
arr.push({
const: row["LEVEL_UNIQUE_NAME"] || undefined,
title: row["LEVEL_NAME"] || undefined
});
response.nextRow();
}
}
});
}
function generateChoiceSchema(connection_settings, used_dimensions, choice_settings) {
var schema = {
"type": "object",
"additionalProperties": false,
"properties": {}
},
current_dimension;
if (!connection_settings) {
return new RSVP.Queue()
.push(function () {
return schema;
});
}
if (!connection_settings.hasOwnProperty('properties')) {
connection_settings.properties = {};
}
if (!choice_settings) {
choice_settings = {};
}
current_dimension = choice_settings.dimension;
if (current_dimension) {
used_dimensions = used_dimensions
.filter(function (d) {
return d !== current_dimension;
});
}
return new RSVP.Queue()
.push(function () {
var tasks = [discoverDimensions(schema, used_dimensions, {
urls: connection_settings.urls,
prop: {
restrictions: {
CATALOG_NAME: connection_settings.properties.Catalog,
CUBE_NAME: connection_settings.properties.Cube
}
}
})];
if (choice_settings.dimension) {
tasks.push(
discoverHierarchies(schema, {
urls: connection_settings.urls,
prop: {
restrictions: {
CATALOG_NAME: connection_settings.properties.Catalog,
CUBE_NAME: connection_settings.properties.Cube,
DIMENSION_UNIQUE_NAME: choice_settings.dimension
}
}
})
);
}
if (choice_settings.hierarchy) {
tasks.push(discoverLevels(schema, {
urls: connection_settings.urls,
prop: {
restrictions: {
CATALOG_NAME: connection_settings.properties.Catalog,
CUBE_NAME: connection_settings.properties.Cube,
DIMENSION_UNIQUE_NAME: choice_settings.dimension,
HIERARCHY_UNIQUE_NAME: choice_settings.hierarchy
}
}
}));
}
return RSVP.all(tasks);
})
.push(function () {
return schema;
});
}
function decodeJsonPointer(_str) {
// https://tools.ietf.org/html/rfc6901#section-5
return _str.replace(/~1/g, '/').replace(/~0/g, '~');
}
function convertOnMultiLevel(d, key, value) {
var ii,
kk,
prev_value,
key_list = key.split("/");
for (ii = 1; ii < key_list.length; ii += 1) {
kk = decodeJsonPointer(key_list[ii]);
if (ii === key_list.length - 1) {
if (value !== undefined) {
prev_value = d[kk];
d[kk] = value[0];
return prev_value;
}
return d[kk];
}
if (!d.hasOwnProperty(kk)) {
if (value !== undefined) {
d[kk] = {};
} else {
return;
}
}
d = d[kk];
}
}
rJS(window)
.ready(function (g) {
g.props = {};
g.props.xmla_connections = {};
return g.render({
schema_url: new URL("olap_wizard.json", window.location).toString(),
value: {}
});
})
.allowPublicAcquisition("notifyValid", function (arr, scope) {
})
.allowPublicAcquisition("notifyInvalid", function (arr, scope) {
})
.declareMethod("render", function (opt) {
var g = this;
g.props.init_value = opt.value;
return get_used_dimensions(g)
.push(function (v) {
g.props.used_dimensions = v;
return g.getDeclaredGadget("olap_wizard");
})
.push(function (gadget) {
return gadget.render(opt);
})
.push(function () {
delete g.props.init_value;
delete g.props.used_dimensions;
});
})
.declareMethod("getContent", function (path) {
return this.getDeclaredGadget("olap_wizard")
.push(function (g) {
return g.getContent(path);
});
})
.declareAcquiredMethod("notifyChange", "notifyChange")
.allowPublicAcquisition("notifyChange", function (arr, s) {
var g = this,
p = arr[0].path,
scope = arr[0].scope,
relPath = arr[0].rel_path,
action = arr[0].action,
gadget_settings,
used_diemensions,
path;
function rereneder(sub_scope, rerender_path) {
var queue;
if (!used_diemensions) {
queue = get_used_dimensions(g)
.push(function (v) {
used_diemensions = v;
});
} else {
queue = RSVP.Queue();
}
queue
.push(function () {
return g.getDeclaredGadget("olap_wizard");
})
.push(function (gadget) {
gadget_settings = gadget;
return RSVP.all([
getCurrentConnectionSettings(gadget),
gadget.getContent(rerender_path)
]);
})
.push(function (arr) {
return generateChoiceSchema(arr[0], used_diemensions, arr[1]);
})
.push(function (schema) {
return gadget_settings.rerender({
scope: sub_scope,
schema: schema
});
})
.push(function () {
// return g.notifyChange();
return print_content(g);
});
}
function allRerender() {
var tasks = [],
i;
for (i in g.props.xmla_connections) {
if (g.props.xmla_connections.hasOwnProperty(i)) {
s = g.props.xmla_connections[i];
if (s) {
tasks.push(rereneder(s, i));
}
}
}
return get_used_dimensions(g)
.push(function (v) {
used_diemensions = v;
return RSVP.all(tasks);
});
}
if (p === "/connection_name") {
return allRerender();
}
for (path in g.props.xmla_connections) {
if (g.props.xmla_connections.hasOwnProperty(path)) {
if (p === path && action === "add") {
g.props.xmla_connections[path] = scope;
return rereneder(scope, path);
}
s = g.props.xmla_connections[path];
if (scope === s) {
if (action === "delete") {
// xxx memory leak
g.props.xmla_connections[path] = false;
}
if (relPath === "/dimension") {
return allRerender();
}
return rereneder(s, path);
}
}
}
// return g.notifyChange();
return print_content(g);
})
.allowPublicAcquisition("resolveExternalReference", function (arr) {
var g = this,
url = arr[0],
schema_path = arr[1],
path = arr[2];
if ("urn:jio:remote_connections.json" === url) {
return new RSVP.Queue()
.push(function () {
return getConnections();
})
.push(function (connections) {
var key,
schema = {
enum: []
};
for (key in connections) {
if (connections.hasOwnProperty(key)) {
schema.enum.push(key);
}
}
return schema;
});
}
if ("urn:jio:choice.json" === url) {
return new RSVP.Queue()
.push(function () {
return getConnections();
})
.push(function (connections) {
var connection_settings,
choice_settings;
if (path !== "/parameters/columns/" && path !== "/parameters/rows/") {
g.props.xmla_connections[path] = false;
}
if (g.props.init_value) {
connection_settings =
connections[convertOnMultiLevel(g.props.init_value, "/connection_name")];
if (path !== "/parameters/columns/" && path !== "/parameters/rows/") {
choice_settings = convertOnMultiLevel(g.props.init_value, path);
}
return generateChoiceSchema(connection_settings, g.props.used_dimensions, choice_settings);
}
return {};
});
}
throw new Error("urn: '" + url + "' not supported");
});
}(window, rJS));
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment