70c6c7a7619b521477be5f6a6d6d1adb8bb83123
[ccsdk/features.git] /
1 /**
2  * Copyright 2010-2013 Ben Birch
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this software 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 (function( $, app, i18n, raphael ) {
17
18         var ui = app.ns("ui");
19         var ut = app.ns("ut");
20         var services = app.ns("services");
21
22         ui.AnyRequest = ui.Page.extend({
23                 defaults: {
24                         cluster: null,       // (required) instanceof app.services.Cluster
25                         path: "_search",     // default uri to send a request to
26                         query: { query: { match_all: { }}},
27                         transform: "  return root;" // default transformer function (does nothing)
28                 },
29                 init: function(parent) {
30                         this._super();
31                         this.prefs = services.Preferences.instance();
32                         this.history = this.prefs.get("anyRequest-history") || [ { type: "POST", path: this.config.path, query : JSON.stringify(this.config.query), transform: this.config.transform } ];
33                         this.el = $.joey(this._main_template());
34                         this.base_uriEl = this.el.find("INPUT[name=base_uri]");
35                         this.pathEl = this.el.find("INPUT[name=path]");
36                         this.typeEl = this.el.find("SELECT[name=method]");
37                         this.dataEl = this.el.find("TEXTAREA[name=body]");
38                         this.prettyEl = this.el.find("INPUT[name=pretty]");
39                         this.transformEl = this.el.find("TEXTAREA[name=transform]");
40                         this.asGraphEl = this.el.find("INPUT[name=asGraph]");
41                         this.asTableEl = this.el.find("INPUT[name=asTable]");
42                         this.asJsonEl = this.el.find("INPUT[name=asJson]");
43                         this.cronEl = this.el.find("SELECT[name=cron]");
44                         this.outEl = this.el.find("DIV.uiAnyRequest-out");
45                         this.errEl = this.el.find("DIV.uiAnyRequest-jsonErr");
46                         this.typeEl.val("GET");
47                         this.attach(parent);
48                         this.setHistoryItem(this.history[this.history.length - 1]);
49                 },
50                 setHistoryItem: function(item) {
51                         this.pathEl.val(item.path);
52                         this.typeEl.val(item.type);
53                         this.dataEl.val(item.query);
54                         this.transformEl.val(item.transform);
55                 },
56                 _request_handler: function( ev ) {
57                         if(! this._validateJson_handler()) {
58                                 return;
59                         }
60                         var path = this.pathEl.val(),
61                                         type = this.typeEl.val(),
62                                         query = JSON.stringify(JSON.parse(this.dataEl.val())),
63                                         transform = this.transformEl.val(),
64                                         base_uri = this.base_uriEl.val();
65                         if( ev ) { // if the user click request
66                                 if(this.timer) {
67                                         window.clearTimeout(this.timer); // stop any cron jobs
68                                 }
69                                 delete this.prevData; // remove data from previous cron runs
70                                 this.outEl.text(i18n.text("AnyRequest.Requesting"));
71                                 if( ! /\/$/.test( base_uri )) {
72                                         base_uri += "/";
73                                         this.base_uriEl.val( base_uri );
74                                 }
75                                 for(var i = 0; i < this.history.length; i++) {
76                                         if(this.history[i].path === path &&
77                                                 this.history[i].type === type &&
78                                                 this.history[i].query === query &&
79                                                 this.history[i].transform === transform) {
80                                                 this.history.splice(i, 1);
81                                         }
82                                 }
83                                 this.history.push({
84                                         path: path,
85                                         type: type,
86                                         query: query,
87                                         transform: transform
88                                 });
89                                 this.history.slice(250); // make sure history does not get too large
90                                 this.prefs.set( "anyRequest-history", this.history );
91                                 this.el.find("UL.uiAnyRequest-history")
92                                         .empty()
93                                         .append($( { tag: "UL", children: this.history.map(this._historyItem_template, this) }).children())
94                                         .children().find(":last-child").each(function(i, j) { j.scrollIntoView(false); }).end()
95                                         .scrollLeft(0);
96                         }
97                         this.config.cluster.request({
98                                 url: base_uri + path,
99                                 type: type,
100                                 data: query,
101                                 success: this._responseWriter_handler,
102                                 error: this._responseError_handler
103                         });
104                 },
105                 _responseError_handler: function (response) {
106                         var obj;
107                         try {
108                                 obj = JSON.parse(response.responseText);
109                                 if (obj) {
110                                         this._responseWriter_handler(obj);
111                                 }
112                         } catch (err) {
113                         }
114                 },
115                 _responseWriter_handler: function(data) {
116                         this.outEl.empty();
117                         try {
118                                 data = (new Function("root", "prev", this.transformEl.val()))(data, this.prevData)
119                         } catch(e) {
120                                 this.errEl.text(e.message);
121                                 return;
122                         }
123                         if(this.asGraphEl.attr("checked")) {
124                                 var w = this.outEl.width();
125                                 raphael(this.outEl[0], w - 10, 300)
126                                         .g.barchart(10, 10, w - 20, 280, [data]);
127                         }
128                         if(this.asTableEl.attr("checked")) {
129                                 try {
130                                         var store = new app.data.ResultDataSourceInterface();
131                                         this.outEl.append(new app.ui.ResultTable({
132                                                 width: this.outEl.width() - 23,
133                                                 store: store
134                                         } ) );
135                                         store.results(data);
136                                 } catch(e) {
137                                         this.errEl.text("Results Table Failed: " + e.message);
138                                 }
139                         }
140                         if(this.asJsonEl.attr("checked")) {
141                                 this.outEl.append(new ui.JsonPretty({ obj: data }));
142                         }
143                         if(this.cronEl.val() > 0) {
144                                 this.timer = window.setTimeout(function(){
145                                         this._request_handler();
146                                 }.bind(this), this.cronEl.val());
147                         }
148                         this.prevData = data;
149                 },
150                 _validateJson_handler: function( ev ) {
151                         /* if the textarea is empty, we replace its value by an empty JSON object : "{}" and the request goes on as usual */
152                         var jsonData = this.dataEl.val().trim();
153                         var j;
154                         if(jsonData === "") {
155                                 jsonData = "{}";
156                                 this.dataEl.val( jsonData );
157                         }
158                         try {
159                                 j = JSON.parse(jsonData);
160                         } catch(e) {
161                                 this.errEl.text(e.message);
162                                 return false;
163                         }
164                         this.errEl.text("");
165                         if(this.prettyEl.attr("checked")) {
166                                 this.dataEl.val(JSON.stringify(j, null, "  "));
167                         }
168                         return true;
169                 },
170                 _historyClick_handler: function( ev ) {
171                         var item = $( ev.target ).closest( "LI" ).data( "item" );
172                         this.setHistoryItem( item );
173                 },
174                 _main_template: function() {
175                         return { tag: "DIV", cls: "anyRequest", children: [
176                                 { tag: "DIV", cls: "uiAnyRequest-request", children: [
177                                         new app.ui.SidebarSection({
178                                                 open: false,
179                                                 title: i18n.text("AnyRequest.History"),
180                                                 body: { tag: "UL", onclick: this._historyClick_handler, cls: "uiAnyRequest-history", children: this.history.map(this._historyItem_template, this)       }
181                                         }),
182                                         new app.ui.SidebarSection({
183                                                 open: true,
184                                                 title: i18n.text("AnyRequest.Query"),
185                                                 body: { tag: "DIV", children: [
186                                                         { tag: "INPUT", type: "text", name: "base_uri", value: this.config.cluster.config.base_uri },
187                                                         { tag: "BR" },
188                                                         { tag: "INPUT", type: "text", name: "path", value: this.config.path },
189                                                         { tag: "SELECT", name: "method", children: ["POST", "GET", "PUT", "HEAD", "DELETE"].map(ut.option_template) },
190                                                         { tag: "TEXTAREA", name: "body", rows: 20, text: JSON.stringify(this.config.query) },
191                                                         { tag: "BUTTON", css: { cssFloat: "right" }, type: "button", children: [ { tag: "B", text: i18n.text("AnyRequest.Request") } ], onclick: this._request_handler },
192                                                         { tag: "BUTTON", type: "button", text: i18n.text("AnyRequest.ValidateJSON"), onclick: this._validateJson_handler },
193                                                         { tag: "LABEL", children: [ { tag: "INPUT", type: "checkbox", name: "pretty" }, i18n.text("AnyRequest.Pretty") ] },
194                                                         { tag: "DIV", cls: "uiAnyRequest-jsonErr" }
195                                                 ]}
196                                         }),
197                                         new app.ui.SidebarSection({
198                                                 title: i18n.text("AnyRequest.Transformer"),
199                                                 help: "AnyRequest.TransformerHelp",
200                                                 body: { tag: "DIV", children: [
201                                                         { tag: "CODE", text: "function(root, prev) {" },
202                                                         { tag: "BR" },
203                                                         { tag: "TEXTAREA", name: "transform", rows: 5, text: this.config.transform },
204                                                         { tag: "BR" },
205                                                         { tag: "CODE", text: "}" }
206                                                 ] }
207                                         }),
208                                         new app.ui.SidebarSection({
209                                                 title: i18n.text("AnyRequest.RepeatRequest"),
210                                                 body: { tag: "DIV", children: [
211                                                         i18n.text("AnyRequest.RepeatRequestSelect"), " ",
212                                                         { tag: "SELECT", name: "cron", children: [
213                                                                 { value: 0, text: "do not repeat" },
214                                                                 { value: 1000, text: "second" },
215                                                                 { value: 1000 * 2, text: "2 seconds" },
216                                                                 { value: 1000 * 5, text: "5 seconds" },
217                                                                 { value: 1000 * 20, text: "20 seconds" },
218                                                                 { value: 1000 * 60, text: "minute" },
219                                                                 { value: 1000 * 60 * 10, text: "10 minutes" },
220                                                                 { value: 1000 * 60 * 60, text: "hour" }
221                                                         ].map(function(op) { return $.extend({ tag: "OPTION"}, op); }) }
222                                                 ] }
223                                         }),
224                                         new app.ui.SidebarSection({
225                                                 title: i18n.text("AnyRequest.DisplayOptions"),
226                                                 help: "AnyRequest.DisplayOptionsHelp",
227                                                 body: { tag: "DIV", children: [
228                                                         { tag: "LABEL", children: [ { tag: "INPUT", type: "checkbox", checked: true, name: "asJson" }, i18n.text("AnyRequest.AsJson") ] },
229                                                         { tag: "BR" },
230                                                         { tag: "LABEL", children: [ { tag: "INPUT", type: "checkbox", name: "asGraph" }, i18n.text("AnyRequest.AsGraph") ] },
231                                                         { tag: "BR" },
232                                                         { tag: "LABEL", children: [ { tag: "INPUT", type: "checkbox", name: "asTable" }, i18n.text("AnyRequest.AsTable") ] }
233                                                 ] }
234                                         })
235                                 ] },
236                                 { tag: "DIV", cls: "uiAnyRequest-out" }
237                         ] };
238                 },
239                 _historyItem_template: function(item) {
240                         return { tag: "LI", cls: "booble", data: { item: item }, children: [
241                                 { tag: "SPAN", text: item.path },
242                                 " ",
243                                 { tag: "EM", text: item.query },
244                                 " ",
245                                 { tag: "SPAN", text: item.transform }
246                         ] };
247                 }
248         });
249         
250 })( this.jQuery, this.app, this.i18n, this.Raphael );