Commit 602ff559bbc868963f70144401537401e98dbfea
1 parent
e8d6bbe2
Exists in
master
and in
7 other branches
Ativação da opção de salvar querys no saiku
Showing
12 changed files
with
913 additions
and
3 deletions
Show diff stats
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/index.html
| ... | ... | @@ -302,9 +302,9 @@ |
| 302 | 302 | <li><a href="#open_query" |
| 303 | 303 | class="i18n open button sprite" |
| 304 | 304 | title="Open query"></a></li> |
| 305 | - <!--<li><a href="#save_query" | |
| 305 | + <li><a href="#save_query" | |
| 306 | 306 | class="i18n save button disabled_toolbar sprite" |
| 307 | - title="Save query"></a></li>--> | |
| 307 | + title="Save query"></a></li> | |
| 308 | 308 | <li class="seperator"><a href="#run_query" |
| 309 | 309 | class="i18n run button disabled_toolbar sprite" |
| 310 | 310 | title="Run query"></a></li> | ... | ... |
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/SessionWorkspace.js
| ... | ... | @@ -142,7 +142,7 @@ var SessionWorkspace = Backbone.Model.extend({ |
| 142 | 142 | url: function() { |
| 143 | 143 | if (this.first) { |
| 144 | 144 | this.first = false; |
| 145 | - return encodeURI(Saiku.session.username + "/discover/"); | |
| 145 | + return encodeURI(Saiku.session.username + "/discover"); | |
| 146 | 146 | } |
| 147 | 147 | else { |
| 148 | 148 | return encodeURI(Saiku.session.username + "/discover/refresh"); | ... | ... |
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/Dimension.js
0 → 100755
| ... | ... | @@ -0,0 +1,65 @@ |
| 1 | +/* | |
| 2 | + * Copyright 2012 OSBI Ltd | |
| 3 | + * | |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 5 | + * you may not use this file except in compliance with the License. | |
| 6 | + * You may obtain a copy of the License at | |
| 7 | + * | |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | + * | |
| 10 | + * Unless required by applicable law or agreed to in writing, software | |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 13 | + * See the License for the specific language governing permissions and | |
| 14 | + * limitations under the License. | |
| 15 | + */ | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * Model which fetches the dimensions for a cube | |
| 19 | + */ | |
| 20 | +var Dimension = Backbone.Model.extend({ | |
| 21 | + initialize: function(args) { | |
| 22 | + this.url = Saiku.session.username + "/discover/" + | |
| 23 | + args.key + "/dimensions"; | |
| 24 | + }, | |
| 25 | + | |
| 26 | + parse: function(response) { | |
| 27 | + this.set({ | |
| 28 | + template: _.template($("#template-dimensions").html())({ | |
| 29 | + dimensions: response | |
| 30 | + }), | |
| 31 | + | |
| 32 | + data: response | |
| 33 | + }); | |
| 34 | + | |
| 35 | + typeof localStorage !== "undefined" && localStorage && localStorage.setItem("dimension." + this.get('key'), | |
| 36 | + JSON.stringify(this)); | |
| 37 | + | |
| 38 | + return response; | |
| 39 | + } | |
| 40 | +}); | |
| 41 | + | |
| 42 | +/** | |
| 43 | + * Model which fetches the measures for a cube | |
| 44 | + */ | |
| 45 | +var Measure = Backbone.Model.extend({ | |
| 46 | + initialize: function(args) { | |
| 47 | + this.url = Saiku.session.username + "/discover/" + | |
| 48 | + args.key + "/measures"; | |
| 49 | + }, | |
| 50 | + | |
| 51 | + parse: function(response) { | |
| 52 | + this.set({ | |
| 53 | + template: _.template($("#template-measures").html())({ | |
| 54 | + measures: response | |
| 55 | + }), | |
| 56 | + | |
| 57 | + data: response | |
| 58 | + }); | |
| 59 | + | |
| 60 | + typeof localStorage !== "undefined" && localStorage && localStorage.setItem("measure." + this.get('key'), | |
| 61 | + JSON.stringify(this)); | |
| 62 | + | |
| 63 | + return response; | |
| 64 | + } | |
| 65 | +}); | ... | ... |
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/Member.js
0 → 100755
| ... | ... | @@ -0,0 +1,36 @@ |
| 1 | +/* | |
| 2 | + * Copyright 2012 OSBI Ltd | |
| 3 | + * | |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 5 | + * you may not use this file except in compliance with the License. | |
| 6 | + * You may obtain a copy of the License at | |
| 7 | + * | |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | + * | |
| 10 | + * Unless required by applicable law or agreed to in writing, software | |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 13 | + * See the License for the specific language governing permissions and | |
| 14 | + * limitations under the License. | |
| 15 | + */ | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * Controls member selections | |
| 19 | + */ | |
| 20 | +var Member = Backbone.Model.extend({ | |
| 21 | + initialize: function(args, options) { | |
| 22 | + this.cube = options.cube; | |
| 23 | + var dimension = options.dimension.split("/"); | |
| 24 | + this.dimension = dimension[0]; | |
| 25 | + this.hierarchy = dimension[2]; | |
| 26 | + this.level = dimension[3]; | |
| 27 | + }, | |
| 28 | + | |
| 29 | + url: function() { | |
| 30 | + var url = encodeURI(Saiku.session.username + "/discover/") + | |
| 31 | + this.cube + encodeURI("/dimensions/" + this.dimension + | |
| 32 | + "/hierarchies/" + this.hierarchy + "/levels/" + this.level); | |
| 33 | + | |
| 34 | + return url; | |
| 35 | + } | |
| 36 | +}); | ... | ... |
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/Properties.js
0 → 100755
| ... | ... | @@ -0,0 +1,66 @@ |
| 1 | +/* | |
| 2 | + * Copyright 2012 OSBI Ltd | |
| 3 | + * | |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 5 | + * you may not use this file except in compliance with the License. | |
| 6 | + * You may obtain a copy of the License at | |
| 7 | + * | |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | + * | |
| 10 | + * Unless required by applicable law or agreed to in writing, software | |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 13 | + * See the License for the specific language governing permissions and | |
| 14 | + * limitations under the License. | |
| 15 | + */ | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * Maintains query properties like non empty and automatic execution | |
| 19 | + */ | |
| 20 | +var Properties = Backbone.Model.extend({ | |
| 21 | + initialize: function(args, options) { | |
| 22 | + // Keep track of parent query | |
| 23 | + this.query = options.query; | |
| 24 | + | |
| 25 | + // Update properties with defaults from settings | |
| 26 | + this.properties = {}; | |
| 27 | + _.extend(this.properties, Settings.QUERY_PROPERTIES); | |
| 28 | + if (typeof args != "undefined" && args) { | |
| 29 | + _.extend(this.properties, args); | |
| 30 | + } | |
| 31 | + }, | |
| 32 | + | |
| 33 | + toggle: function(key) { | |
| 34 | + // Toggle property | |
| 35 | + this.properties[key] = this.properties[key] === 'true' ? | |
| 36 | + 'false' : 'true'; | |
| 37 | + | |
| 38 | + return this; | |
| 39 | + }, | |
| 40 | + | |
| 41 | + update: function(async) { | |
| 42 | + // FIXME - this really sucks | |
| 43 | + // Why can't we just use the body? | |
| 44 | + this.attributes = { | |
| 45 | + properties: _.template( | |
| 46 | + "<% _.each(properties, function(property, name) { %>" + | |
| 47 | + "<%= name %> <%= property %>\n" + | |
| 48 | + "<% }); %>" | |
| 49 | + )({ properties: this.properties }) | |
| 50 | + }; | |
| 51 | + this.save({ async: async }); | |
| 52 | + }, | |
| 53 | + | |
| 54 | + parse: function(response) { | |
| 55 | + // FIXME - POST should return properties as well | |
| 56 | + if (typeof response == "object") { | |
| 57 | + _.extend(this.properties, response); | |
| 58 | + } | |
| 59 | + | |
| 60 | + this.query.workspace.trigger('properties:loaded'); | |
| 61 | + }, | |
| 62 | + | |
| 63 | + url: function() { | |
| 64 | + return encodeURI(this.query.url() + "/properties"); | |
| 65 | + } | |
| 66 | +}); | ... | ... |
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/Query.js
0 → 100755
| ... | ... | @@ -0,0 +1,162 @@ |
| 1 | +/* | |
| 2 | + * Copyright 2012 OSBI Ltd | |
| 3 | + * | |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 5 | + * you may not use this file except in compliance with the License. | |
| 6 | + * You may obtain a copy of the License at | |
| 7 | + * | |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | + * | |
| 10 | + * Unless required by applicable law or agreed to in writing, software | |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 13 | + * See the License for the specific language governing permissions and | |
| 14 | + * limitations under the License. | |
| 15 | + */ | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * Workspace query | |
| 19 | + */ | |
| 20 | +var Query = Backbone.Model.extend({ | |
| 21 | + | |
| 22 | + formatter: Settings.CELLSET_FORMATTER, | |
| 23 | + properties: null, | |
| 24 | + | |
| 25 | + initialize: function(args, options) { | |
| 26 | + // Save cube | |
| 27 | + _.extend(this, options); | |
| 28 | + | |
| 29 | + // Bind `this` | |
| 30 | + _.bindAll(this, "run", "move_dimension", "reflect_properties"); | |
| 31 | + | |
| 32 | + // Generate a unique query id | |
| 33 | + this.uuid = 'xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, | |
| 34 | + function (c) { | |
| 35 | + var r = Math.random() * 16 | 0, | |
| 36 | + v = c == 'x' ? r : (r & 0x3 | 0x8); | |
| 37 | + return v.toString(16); | |
| 38 | + }).toUpperCase(); | |
| 39 | + | |
| 40 | + // Initialize properties, action handler, and result handler | |
| 41 | + this.action = new QueryAction({}, { query: this }); | |
| 42 | + this.result = new Result({ limit: Settings.RESULT_LIMIT }, { query: this }); | |
| 43 | + this.scenario = new QueryScenario({}, { query: this }); | |
| 44 | + | |
| 45 | + this.set({type:'QM'}); | |
| 46 | + }, | |
| 47 | + | |
| 48 | + parse: function(response) { | |
| 49 | + // Assign id so Backbone knows to PUT instead of POST | |
| 50 | + this.id = this.uuid; | |
| 51 | + | |
| 52 | + this.set({ | |
| 53 | + connection: response.cube.connectionName, | |
| 54 | + catalog: response.cube.catalogName, | |
| 55 | + schema: response.cube.schemaName, | |
| 56 | + cube: encodeURIComponent(response.cube.name), | |
| 57 | + axes: response.saikuAxes, | |
| 58 | + type: response.type | |
| 59 | + }); | |
| 60 | + | |
| 61 | + if (typeof response.properties != "undefined" && "saiku.ui.formatter" in response.properties) { | |
| 62 | + this.set({formatter : response.properties['saiku.ui.formatter']}); | |
| 63 | + } | |
| 64 | + | |
| 65 | + this.properties = new Properties(response.properties, { query: this }); | |
| 66 | + this.reflect_properties(); | |
| 67 | + }, | |
| 68 | + | |
| 69 | + reflect_properties: function() { | |
| 70 | + this.workspace.trigger('properties:loaded'); | |
| 71 | + }, | |
| 72 | + | |
| 73 | + setProperty: function(key, value) { | |
| 74 | + if (typeof this.properties != "undefined" && this.properties.properties ) { | |
| 75 | + this.properties.properties[key] = value; | |
| 76 | + } | |
| 77 | + }, | |
| 78 | + | |
| 79 | + run: function(force, mdx) { | |
| 80 | + // Check for automatic execution | |
| 81 | + Saiku.ui.unblock(); | |
| 82 | + if (typeof this.properties != "undefined" && this.properties.properties['saiku.olap.query.automatic_execution'] === 'false'&& | |
| 83 | + ! (force === true)) { | |
| 84 | + return; | |
| 85 | + } | |
| 86 | + this.workspace.unblock(); | |
| 87 | + | |
| 88 | + $(this.workspace.el).find(".workspace_results_info").empty(); | |
| 89 | + this.workspace.trigger('query:run'); | |
| 90 | + this.result.result = null; | |
| 91 | + // TODO - Validate query | |
| 92 | + // maybe we should sync it with the backend query JSON? | |
| 93 | + // this definitely needs improvement | |
| 94 | + if (this.get('type') != "MDX") { | |
| 95 | + var rows = $(this.workspace.el).find('.rows ul li').size(); | |
| 96 | + var columns = $(this.workspace.el).find('.columns ul li').size(); | |
| 97 | + if ((rows == 0 && columns == 0) && !this.workspace.other_dimension) { | |
| 98 | + var axes = this.get('axes'); | |
| 99 | + if (axes) { | |
| 100 | + for (var axis_iter = 0; axis_iter < axes.length; axis_iter++) { | |
| 101 | + var axis = axes[axis_iter]; | |
| 102 | + if (axis.name && axis.name == "ROWS") { | |
| 103 | + rows = axis.dimensionSelections.length; | |
| 104 | + } | |
| 105 | + if (axis.name && axis.name == "COLUMNS") { | |
| 106 | + columns = axis.dimensionSelections.length; | |
| 107 | + } | |
| 108 | + } | |
| 109 | + } | |
| 110 | + } | |
| 111 | + if (rows == 0 || columns == 0) { | |
| 112 | + $(this.workspace.table.el).html(''); | |
| 113 | + $(this.workspace.processing).html('<span class="i18n">You need to put at least one level or measure on Columns and Rows for a valid query.</span>').show(); | |
| 114 | + this.workspace.adjust(); | |
| 115 | + Saiku.i18n.translate(); | |
| 116 | + return; | |
| 117 | + } | |
| 118 | + } | |
| 119 | + | |
| 120 | + | |
| 121 | + // Run it | |
| 122 | + $(this.workspace.table.el) | |
| 123 | + .html(''); | |
| 124 | + $(this.workspace.processing).html('<span class="processing_image"> </span> <span class="i18n">Running query...</span> [ <a class="cancel i18n" href="#cancel">Cancel</a> ]').show(); | |
| 125 | + this.workspace.adjust(); | |
| 126 | + this.workspace.trigger('query:fetch'); | |
| 127 | + Saiku.i18n.translate(); | |
| 128 | + // <a class="cancel" href="#cancel">x</a> | |
| 129 | + | |
| 130 | + var message = '<span class="processing_image"> </span> <span class="i18n">Running query...</span> [ <a class="cancel i18n" href="#cancel">Cancel</a> ]'; | |
| 131 | + this.workspace.block(message); | |
| 132 | + | |
| 133 | + | |
| 134 | + if (this.get('type') == "MDX" && mdx != null) { | |
| 135 | + this.result.save({ mdx: mdx}); | |
| 136 | + } else { | |
| 137 | + this.result.fetch(); | |
| 138 | + } | |
| 139 | + }, | |
| 140 | + | |
| 141 | + move_dimension: function(dimension, target, index) { | |
| 142 | + $(this.workspace.el).find('.run').removeClass('disabled_toolbar'); | |
| 143 | + var url = "/axis/" + target + "/dimension/" + dimension; | |
| 144 | + | |
| 145 | + this.action.post(url, { | |
| 146 | + data: { | |
| 147 | + position: index | |
| 148 | + }, | |
| 149 | + | |
| 150 | + success: function() { | |
| 151 | + if (('MODE' in Settings && (Settings.MODE == 'view' || Settings.MODE == 'table')) || (typeof this.query.properties != "undefined" && this.query.properties | |
| 152 | + .properties['saiku.olap.query.automatic_execution'] === 'true')) { | |
| 153 | + this.query.run(true); | |
| 154 | + } | |
| 155 | + } | |
| 156 | + }); | |
| 157 | + }, | |
| 158 | + | |
| 159 | + url: function() { | |
| 160 | + return encodeURI(Saiku.session.username + "/query/" + this.uuid); | |
| 161 | + } | |
| 162 | +}); | ... | ... |
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/QueryAction.js
0 → 100755
| ... | ... | @@ -0,0 +1,71 @@ |
| 1 | +/* | |
| 2 | + * Copyright 2012 OSBI Ltd | |
| 3 | + * | |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 5 | + * you may not use this file except in compliance with the License. | |
| 6 | + * You may obtain a copy of the License at | |
| 7 | + * | |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | + * | |
| 10 | + * Unless required by applicable law or agreed to in writing, software | |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 13 | + * See the License for the specific language governing permissions and | |
| 14 | + * limitations under the License. | |
| 15 | + */ | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * Model which handles "special" actions against the query | |
| 19 | + * Ex.: selections, swap axis, mdx | |
| 20 | + */ | |
| 21 | +var QueryAction = Backbone.Model.extend({ | |
| 22 | + initialize: function(args, options) { | |
| 23 | + // Keep track of query | |
| 24 | + this.query = options.query; | |
| 25 | + | |
| 26 | + // Set default url | |
| 27 | + this.url = this.query.url; | |
| 28 | + }, | |
| 29 | + | |
| 30 | + get: function(action, options) { | |
| 31 | + this.handle("fetch", action, options); | |
| 32 | + }, | |
| 33 | + | |
| 34 | + post: function(action, options) { | |
| 35 | + this.handle("save", action, options); | |
| 36 | + }, | |
| 37 | + | |
| 38 | + put: function(action, options) { | |
| 39 | + this.id = _.uniqueId('queryaction_'); | |
| 40 | + this.handle("save", action, options); | |
| 41 | + delete this.id; | |
| 42 | + }, | |
| 43 | + | |
| 44 | + del: function(action, options) { | |
| 45 | + this.id = _.uniqueId('queryaction_'); | |
| 46 | + this.handle("delete", action, options); | |
| 47 | + delete this.id; | |
| 48 | + }, | |
| 49 | + | |
| 50 | + // Call arbitrary actions against the query | |
| 51 | + handle: function(method, action, options) { | |
| 52 | + // Set query action | |
| 53 | + this.url = this.query.url() + action; | |
| 54 | + | |
| 55 | + // Clear out old attributes | |
| 56 | + this.attributes = options.data? options.data : {}; | |
| 57 | + | |
| 58 | + // Initiate action | |
| 59 | + if (method == "save") { | |
| 60 | + // Handle response from server | |
| 61 | + this.parse = options.success; | |
| 62 | + | |
| 63 | + this.save(); | |
| 64 | + } else if (method == "delete") { | |
| 65 | + this.destroy(options); | |
| 66 | + } else if (method == "fetch") { | |
| 67 | + this.parse = function() {}; | |
| 68 | + this.fetch(options); | |
| 69 | + } | |
| 70 | + } | |
| 71 | +}); | ... | ... |
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/QueryScenario.js
0 → 100755
| ... | ... | @@ -0,0 +1,84 @@ |
| 1 | +/* | |
| 2 | + * Copyright 2012 OSBI Ltd | |
| 3 | + * | |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 5 | + * you may not use this file except in compliance with the License. | |
| 6 | + * You may obtain a copy of the License at | |
| 7 | + * | |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | + * | |
| 10 | + * Unless required by applicable law or agreed to in writing, software | |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 13 | + * See the License for the specific language governing permissions and | |
| 14 | + * limitations under the License. | |
| 15 | + */ | |
| 16 | + | |
| 17 | +var QueryScenario = Backbone.Model.extend({ | |
| 18 | + initialize: function(args, options) { | |
| 19 | + // Maintain `this` | |
| 20 | + _.bindAll(this, "attach_listeners", "activate", "clicked_cell", "save_writeback", | |
| 21 | + "cancel_writeback", "check_input"); | |
| 22 | + | |
| 23 | + this.query = options.query; | |
| 24 | + }, | |
| 25 | + | |
| 26 | + activate: function() { | |
| 27 | + $(this.query.workspace.el).find("td.data").unbind('click').addClass('cellhighlight').click(this.clicked_cell); | |
| 28 | + }, | |
| 29 | + | |
| 30 | + attach_listeners: function(args) { | |
| 31 | + if (args.workspace.query && args.workspace.query.properties && | |
| 32 | + args.workspace.query.properties.properties['org.saiku.connection.scenario'] === "true" && | |
| 33 | + $(args.workspace.el).find('.query_scenario').hasClass('on')) | |
| 34 | + $(args.workspace.el).find("td.data").click(this.clicked_cell); | |
| 35 | + }, | |
| 36 | + | |
| 37 | + clicked_cell: function(event) { | |
| 38 | + $target = $(event.target).hasClass('data') ? | |
| 39 | + $(event.target).find('div') : $(event.target); | |
| 40 | + var value = $target.attr('alt'); | |
| 41 | + var pos = $target.attr('rel'); | |
| 42 | + | |
| 43 | + var $input = $("<input type='text' value='" + value + "' />") | |
| 44 | + .keyup(this.check_input) | |
| 45 | + .blur(this.cancel_writeback); | |
| 46 | + $target.html('').append($input); | |
| 47 | + $input.focus(); | |
| 48 | + }, | |
| 49 | + | |
| 50 | + check_input: function(event) { | |
| 51 | + if (event.which == 13) { | |
| 52 | + this.save_writeback(event); | |
| 53 | + } else if (event.which == 27 || event.which == 9) { | |
| 54 | + this.cancel_writeback(event); | |
| 55 | + } | |
| 56 | + | |
| 57 | + return false; | |
| 58 | + }, | |
| 59 | + | |
| 60 | + save_writeback: function(event) { | |
| 61 | + var $input = $(event.target).closest('input'); | |
| 62 | + this.set({ | |
| 63 | + value: $input.val(), | |
| 64 | + position: $input.parent().attr('rel') | |
| 65 | + }); | |
| 66 | + this.save(); | |
| 67 | + var value = $input.val(); | |
| 68 | + $input.parent().text(value); | |
| 69 | + }, | |
| 70 | + | |
| 71 | + cancel_writeback: function(event) { | |
| 72 | + var $input = $(event.target).closest('input'); | |
| 73 | + $input.parent().text($input.parent().attr('alt')); | |
| 74 | + }, | |
| 75 | + | |
| 76 | + parse: function() { | |
| 77 | + this.query.run(); | |
| 78 | + }, | |
| 79 | + | |
| 80 | + url: function() { | |
| 81 | + return this.query.url() + "/cell/" + this.get('position') + | |
| 82 | + "/" + this.get('value'); | |
| 83 | + } | |
| 84 | +}); | ... | ... |
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/Repository.js
0 → 100644
| ... | ... | @@ -0,0 +1,104 @@ |
| 1 | +/* | |
| 2 | + * Copyright 2012 OSBI Ltd | |
| 3 | + * | |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 5 | + * you may not use this file except in compliance with the License. | |
| 6 | + * You may obtain a copy of the License at | |
| 7 | + * | |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | + * | |
| 10 | + * Unless required by applicable law or agreed to in writing, software | |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 13 | + * See the License for the specific language governing permissions and | |
| 14 | + * limitations under the License. | |
| 15 | + */ | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * Repository query | |
| 19 | + */ | |
| 20 | + | |
| 21 | +var RepositoryObject = Backbone.Model.extend( { | |
| 22 | + url: function( ) { | |
| 23 | + var segment = Settings.BIPLUGIN ? | |
| 24 | + "/pentahorepository2/resource" : "/repository2/resource"; | |
| 25 | + return encodeURI(Saiku.session.username + segment); | |
| 26 | + } | |
| 27 | +} ); | |
| 28 | + | |
| 29 | +var RepositoryAclObject = Backbone.Model.extend( { | |
| 30 | + url: function( ) { | |
| 31 | + var segment = Settings.BIPLUGIN ? | |
| 32 | + "/pentahorepository2/resource" : "/repository2/resource/acl"; | |
| 33 | + return encodeURI(Saiku.session.username + segment); | |
| 34 | + }, | |
| 35 | + parse: function(response) { | |
| 36 | + if (response != "OK") { | |
| 37 | + _.extend(this.attributes, response); | |
| 38 | + } | |
| 39 | + } | |
| 40 | +} ); | |
| 41 | + | |
| 42 | +var SavedQuery = Backbone.Model.extend({ | |
| 43 | + | |
| 44 | + parse: function(response) { | |
| 45 | + //console.log("response: " + response); | |
| 46 | + //this.xml = response; | |
| 47 | + }, | |
| 48 | + | |
| 49 | + url: function() { | |
| 50 | + var u = Settings.BIPLUGIN ? | |
| 51 | + encodeURI(Saiku.session.username + "/pentahorepository2/resource") | |
| 52 | + : encodeURI(Saiku.session.username + "/repository2/resource"); | |
| 53 | + return u; | |
| 54 | + }, | |
| 55 | + | |
| 56 | + move_query_to_workspace: function(model, response) { | |
| 57 | + var file = response; | |
| 58 | + var filename = model.get('file'); | |
| 59 | + for (var key in Settings) { | |
| 60 | + if (key.match("^PARAM")=="PARAM") { | |
| 61 | + var variable = key.substring("PARAM".length, key.length); | |
| 62 | + var Re = new RegExp("\\$\\{" + variable + "\\}","g"); | |
| 63 | + var Re2 = new RegExp("\\$\\{" + variable.toLowerCase() + "\\}","g"); | |
| 64 | + file = file.replace(Re,Settings[key]); | |
| 65 | + file = file.replace(Re2,Settings[key]); | |
| 66 | + | |
| 67 | + } | |
| 68 | + } | |
| 69 | + //substitui o nome da conexao para usar a atual | |
| 70 | + //i3Geo | |
| 71 | + var xml1 = file.split("connection="); | |
| 72 | + var xml2 = file.split("cube="); | |
| 73 | + var file = xml1[0] + 'connection="' + Settings.NOMECONEXAO + '" cube=' + xml2[1]; | |
| 74 | + var query = new Query({ | |
| 75 | + xml: file, | |
| 76 | + formatter: Settings.CELLSET_FORMATTER | |
| 77 | + },{ | |
| 78 | + name: filename | |
| 79 | + }); | |
| 80 | + | |
| 81 | + var tab = Saiku.tabs.add(new Workspace({ query: query })); | |
| 82 | + } | |
| 83 | +}); | |
| 84 | + | |
| 85 | +/** | |
| 86 | + * Repository adapter | |
| 87 | + */ | |
| 88 | +var Repository = Backbone.Collection.extend({ | |
| 89 | + model: SavedQuery, | |
| 90 | + | |
| 91 | + initialize: function(args, options) { | |
| 92 | + this.dialog = options.dialog; | |
| 93 | + }, | |
| 94 | + | |
| 95 | + parse: function(response) { | |
| 96 | + this.dialog.populate(response); | |
| 97 | + }, | |
| 98 | + | |
| 99 | + url: function() { | |
| 100 | + var segment = Settings.BIPLUGIN ? | |
| 101 | + "/pentahorepository2/?type=saiku" : "/repository2/?type=saiku"; | |
| 102 | + return encodeURI(Saiku.session.username + segment); | |
| 103 | + } | |
| 104 | +}); | ... | ... |
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/Result.js
0 → 100755
| ... | ... | @@ -0,0 +1,54 @@ |
| 1 | +/* | |
| 2 | + * Copyright 2012 OSBI Ltd | |
| 3 | + * | |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 5 | + * you may not use this file except in compliance with the License. | |
| 6 | + * You may obtain a copy of the License at | |
| 7 | + * | |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | + * | |
| 10 | + * Unless required by applicable law or agreed to in writing, software | |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 13 | + * See the License for the specific language governing permissions and | |
| 14 | + * limitations under the License. | |
| 15 | + */ | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * Holds the resultset for a query, and notifies plugins when resultset updated | |
| 19 | + */ | |
| 20 | +var Result = Backbone.Model.extend({ | |
| 21 | + | |
| 22 | + result: null, | |
| 23 | + firstRun: false, | |
| 24 | + | |
| 25 | + initialize: function(args, options) { | |
| 26 | + // Keep reference to query | |
| 27 | + this.query = options.query; | |
| 28 | + }, | |
| 29 | + | |
| 30 | + parse: function(response) { | |
| 31 | + // Show the UI if hidden | |
| 32 | + $(this.workspace).unblock(); | |
| 33 | + Saiku.ui.unblock(); | |
| 34 | + this.result = response; | |
| 35 | + this.firstRun = true; | |
| 36 | + this.query.workspace.trigger('query:result', { | |
| 37 | + workspace: this.query.workspace, | |
| 38 | + data: response | |
| 39 | + }); | |
| 40 | + | |
| 41 | + }, | |
| 42 | + | |
| 43 | + hasRun: function() { | |
| 44 | + return this.firstRun; | |
| 45 | + }, | |
| 46 | + | |
| 47 | + lastresult: function () { | |
| 48 | + return this.result; | |
| 49 | + }, | |
| 50 | + | |
| 51 | + url: function() { | |
| 52 | + return encodeURI(this.query.url() + "/result/" + this.query.get('formatter')); | |
| 53 | + } | |
| 54 | +}); | ... | ... |
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/Session.js
0 → 100755
| ... | ... | @@ -0,0 +1,117 @@ |
| 1 | +/* | |
| 2 | + * Copyright 2012 OSBI Ltd | |
| 3 | + * | |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 5 | + * you may not use this file except in compliance with the License. | |
| 6 | + * You may obtain a copy of the License at | |
| 7 | + * | |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | + * | |
| 10 | + * Unless required by applicable law or agreed to in writing, software | |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 13 | + * See the License for the specific language governing permissions and | |
| 14 | + * limitations under the License. | |
| 15 | + */ | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * Object which handles authentication and stores connections and cubes | |
| 19 | + * @param username | |
| 20 | + * @param password | |
| 21 | + * @returns {Session} | |
| 22 | + */ | |
| 23 | +var Session = Backbone.Model.extend({ | |
| 24 | + username: null, | |
| 25 | + password: null, | |
| 26 | + sessionid: null, | |
| 27 | + | |
| 28 | + initialize: function(args, options) { | |
| 29 | + // Attach a custom event bus to this model | |
| 30 | + _.extend(this, Backbone.Events); | |
| 31 | + _.bindAll(this, "check_session", "process_session", "load_session","login"); | |
| 32 | + // Check if credentials are being injected into session | |
| 33 | + if (options && options.username && options.password) { | |
| 34 | + this.username = options.username; | |
| 35 | + this.password = options.password; | |
| 36 | + this.save({username:this.username, password:this.password},{success: this.check_session, error: this.check_session}); | |
| 37 | + | |
| 38 | + } else { | |
| 39 | + this.check_session(); | |
| 40 | + } | |
| 41 | + }, | |
| 42 | + | |
| 43 | + check_session: function() { | |
| 44 | + if (this.sessionid === null || this.username === null || this.password === null) { | |
| 45 | + this.clear(); | |
| 46 | + this.fetch({ success: this.process_session }) | |
| 47 | + } else { | |
| 48 | + this.username = encodeURIComponent(options.username); | |
| 49 | + this.load_session(); | |
| 50 | + } | |
| 51 | + }, | |
| 52 | + | |
| 53 | + load_session: function() { | |
| 54 | + this.sessionworkspace = new SessionWorkspace(); | |
| 55 | + }, | |
| 56 | + | |
| 57 | + process_session: function(model, response) { | |
| 58 | + if ((response === null || response.sessionid == null)) { | |
| 59 | + // Open form and retrieve credentials | |
| 60 | + Saiku.ui.unblock(); | |
| 61 | + this.form = new LoginForm({ session: this }); | |
| 62 | + this.form.render().open(); | |
| 63 | + } else { | |
| 64 | + this.sessionid = response.sessionid; | |
| 65 | + this.roles = response.roles; | |
| 66 | + this.username = encodeURIComponent(response.username); | |
| 67 | + this.language = response.language; | |
| 68 | + if (typeof this.language != "undefined" && this.language != Saiku.i18n.locale) { | |
| 69 | + Saiku.i18n.locale = this.language; | |
| 70 | + Saiku.i18n.automatic_i18n(); | |
| 71 | + } | |
| 72 | + this.load_session(); | |
| 73 | + } | |
| 74 | + | |
| 75 | + return this; | |
| 76 | + }, | |
| 77 | + | |
| 78 | + error: function() { | |
| 79 | + $(this.form.el).dialog('open'); | |
| 80 | + }, | |
| 81 | + | |
| 82 | + login: function(username, password) { | |
| 83 | + // Set expiration on localStorage to one day in the future | |
| 84 | + var expires = (new Date()).getTime() + | |
| 85 | + Settings.LOCALSTORAGE_EXPIRATION; | |
| 86 | + typeof localStorage !== "undefined" && localStorage && localStorage.setItem('expiration', expires); | |
| 87 | + | |
| 88 | + this.save({username:username, password:password},{success: this.check_session, error: this.check_session}); | |
| 89 | + | |
| 90 | + }, | |
| 91 | + | |
| 92 | + logout: function() { | |
| 93 | + // FIXME - This is a hack (inherited from old UI) | |
| 94 | + Saiku.ui.unblock(); | |
| 95 | + $('#header').empty().hide(); | |
| 96 | + $('#tab_panel').remove(); | |
| 97 | + Saiku.tabs = new TabSet(); | |
| 98 | + Saiku.toolbar.remove(); | |
| 99 | + Saiku.toolbar = new Toolbar(); | |
| 100 | + typeof localStorage !== "undefined" && localStorage && localStorage.clear(); | |
| 101 | + this.id = _.uniqueId('queryaction_'); | |
| 102 | + this.clear(); | |
| 103 | + this.sessionid = null; | |
| 104 | + this.username = null; | |
| 105 | + this.password = null; | |
| 106 | + this.destroy({async: false }); | |
| 107 | + //console.log("REFRESH!"); | |
| 108 | + document.location.reload(false) | |
| 109 | + delete this.id; | |
| 110 | + | |
| 111 | + }, | |
| 112 | + | |
| 113 | + url: function() { | |
| 114 | + | |
| 115 | + return "session"; | |
| 116 | + } | |
| 117 | +}); | ... | ... |
ferramentas/saiku/saiku-server/tomcat/webapps/ROOT/js/saiku/models/SessionWorkspace.js
0 → 100644
| ... | ... | @@ -0,0 +1,151 @@ |
| 1 | +/* | |
| 2 | + * Copyright 2012 OSBI Ltd | |
| 3 | + * | |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 5 | + * you may not use this file except in compliance with the License. | |
| 6 | + * You may obtain a copy of the License at | |
| 7 | + * | |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | + * | |
| 10 | + * Unless required by applicable law or agreed to in writing, software | |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 13 | + * See the License for the specific language governing permissions and | |
| 14 | + * limitations under the License. | |
| 15 | + */ | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * Object which handles sessionworkspace and stores connections and cubes | |
| 19 | + * @param username | |
| 20 | + * @param password | |
| 21 | + * @returns {Session} | |
| 22 | + */ | |
| 23 | +var SessionWorkspace = Backbone.Model.extend({ | |
| 24 | + | |
| 25 | + initialize: function(args, options) { | |
| 26 | + // Attach a custom event bus to this model | |
| 27 | + _.extend(this, Backbone.Events); | |
| 28 | + _.bindAll(this, "process_datasources", "prefetch_dimensions"); | |
| 29 | + this.initialized = false; | |
| 30 | + this.first = true; | |
| 31 | + // Check expiration on localStorage | |
| 32 | + if (typeof localStorage !== "undefined" && localStorage) { | |
| 33 | + if (localStorage.getItem('expiration') && !(localStorage.getItem('expiration') > (new Date()).getTime())) { | |
| 34 | + localStorage.clear(); | |
| 35 | + } else if (!localStorage.getItem('saiku-version') || (localStorage.getItem('saiku-version') !== Settings.VERSION) ) { | |
| 36 | + localStorage.clear(); | |
| 37 | + } | |
| 38 | + } | |
| 39 | + Saiku.ui.block("Loading datasources...."); | |
| 40 | + this.fetch({success:this.process_datasources},{}); | |
| 41 | + this.refresh(); | |
| 42 | + }, | |
| 43 | + | |
| 44 | + refresh: function() { | |
| 45 | + typeof localStorage !== "undefined" && localStorage && localStorage.clear(); | |
| 46 | + this.clear(); | |
| 47 | + localStorage.setItem('saiku-version', Settings.VERSION); | |
| 48 | + this.fetch({success:this.process_datasources},{}); | |
| 49 | + }, | |
| 50 | + | |
| 51 | + destroy: function() { | |
| 52 | + typeof localStorage !== "undefined" && localStorage && localStorage.clear(); | |
| 53 | + return false; | |
| 54 | + }, | |
| 55 | + | |
| 56 | + process_datasources: function(model, response) { | |
| 57 | + // Save session in localStorage for other tabs to use | |
| 58 | + if (typeof localStorage !== "undefined" && localStorage && localStorage.getItem('session') === null) { | |
| 59 | + localStorage.setItem('session', JSON.stringify(response)); | |
| 60 | + } | |
| 61 | + | |
| 62 | + // Generate cube navigation for reuse | |
| 63 | + this.cube_navigation = _.template($("#template-cubes").html())({ | |
| 64 | + connections: response | |
| 65 | + }); | |
| 66 | + | |
| 67 | + | |
| 68 | + // Create cube objects | |
| 69 | + this.dimensions = {}; | |
| 70 | + this.measures = {}; | |
| 71 | + this.connections = response; | |
| 72 | + _.delay(this.prefetch_dimensions, 20); | |
| 73 | + | |
| 74 | + if (!this.initialized) { | |
| 75 | + // Show UI | |
| 76 | + $(Saiku.toolbar.el).prependTo($("#header")); | |
| 77 | + $("#header").show(); | |
| 78 | + Saiku.ui.unblock(); | |
| 79 | + // Add initial tab | |
| 80 | + Saiku.tabs.render(); | |
| 81 | + if (! Settings.ACTION) { | |
| 82 | + Saiku.tabs.add(new Workspace()); | |
| 83 | + } | |
| 84 | + // Notify the rest of the application that login was successful | |
| 85 | + Saiku.events.trigger('session:new', { | |
| 86 | + session: this | |
| 87 | + }); | |
| 88 | + } else { | |
| 89 | + if (! Settings.ACTION) { | |
| 90 | + Saiku.tabs.add(new Workspace()); | |
| 91 | + } | |
| 92 | + | |
| 93 | + } | |
| 94 | + }, | |
| 95 | + | |
| 96 | + prefetch_dimensions: function() { | |
| 97 | + if (! this.measures || ! this.dimensions) { | |
| 98 | + Log.log({ | |
| 99 | + Message: "measures or dimensions not initialized", | |
| 100 | + Session: JSON.stringify(this) | |
| 101 | + }); | |
| 102 | + return; | |
| 103 | + } | |
| 104 | + | |
| 105 | + for(var i = 0; i < this.connections.length; i++) { | |
| 106 | + var connection = this.connections[i]; | |
| 107 | + for(var j = 0; j < connection.catalogs.length; j++) { | |
| 108 | + var catalog = connection.catalogs[j]; | |
| 109 | + for(var k = 0; k < catalog.schemas.length; k++) { | |
| 110 | + var schema = catalog.schemas[k]; | |
| 111 | + for(var l = 0; l < schema.cubes.length; l++) { | |
| 112 | + var cube = schema.cubes[l]; | |
| 113 | + var key = connection.name + "/" + catalog.name + "/" | |
| 114 | + + ((schema.name == "" || schema.name == null) ? "null" : schema.name) | |
| 115 | + + "/" + encodeURIComponent(cube.name); | |
| 116 | + | |
| 117 | + if (typeof localStorage !== "undefined" && localStorage && | |
| 118 | + localStorage.getItem("dimension." + key) !== null && | |
| 119 | + localStorage.getItem("measure." + key) !== null) { | |
| 120 | + this.dimensions[key] = new Dimension(JSON.parse(localStorage.getItem("dimension." + key))); | |
| 121 | + this.measures[key] = new Measure(JSON.parse(localStorage.getItem("measure." + key))); | |
| 122 | + } else { | |
| 123 | + this.dimensions[key] = new Dimension({ key: key }); | |
| 124 | + this.measures[key] = new Measure({ key: key }); | |
| 125 | + if (Settings.DIMENSION_PREFETCH === true) { | |
| 126 | + this.dimensions[key].fetch(); | |
| 127 | + this.measures[key].fetch(); | |
| 128 | + } | |
| 129 | + } | |
| 130 | + } | |
| 131 | + } | |
| 132 | + } | |
| 133 | + } | |
| 134 | + | |
| 135 | + // Start routing | |
| 136 | + if (!this.initialized && Backbone.history) { | |
| 137 | + Backbone.history.start(); | |
| 138 | + this.initialized = true; | |
| 139 | + } | |
| 140 | + }, | |
| 141 | + | |
| 142 | + url: function() { | |
| 143 | + if (this.first) { | |
| 144 | + this.first = false; | |
| 145 | + return encodeURI(Saiku.session.username + "/discover"); | |
| 146 | + } | |
| 147 | + else { | |
| 148 | + return encodeURI(Saiku.session.username + "/discover/refresh"); | |
| 149 | + } | |
| 150 | + } | |
| 151 | +}); | ... | ... |