fix more quirks in right column parsing
[APKPM.git] / public / user.html
1 <!doctype html>
2 <html xmlns:ng="http://angularjs.org">
3  <script src="http://code.angularjs.org/angular-0.9.17.min.js" ng:autobind></script>
4  <body>
5   <script>
6     function user($xhr,$resource,$log) {
7         var self = this;
8    
9         self.r = {};
10
11         self.r.CRM_search = $resource('/g/CRM_search/:username', {username:'@search_username'});
12         self.CRM_search = function(username) {
13                 if ( ! username ) username = self.search_username;
14                 $log.info( 'CRM_search', username );
15                 self.clear();
16                 self.message.CRM = 'search for '+username;
17                 self.r.CRM_search.query({username: username}, function(CRM) {
18                         self.CRM = CRM;
19                         $log.info( 'CRM', CRM )
20                         if ( ! CRM.length ) {
21                                 self.message.CRM = 'no results';
22                                 return;
23                         }
24                         self.message.CRM = null;
25                         if ( CRM.length == 1 ) {
26                                 self.selected_username = CRM[0].USERNAME;
27                                 $log.info( 'auto-selected ', self.selected_username );
28                         }
29                 });
30         };
31
32         self.r.LDAP_search = $resource('/g/LDAP_search/:username', {username:'@selected_username'});
33         self.LDAP_search = function(username) {
34                 if ( self.selected_username == username ) {
35                         $log.error("LDAP_search - not changed", username);
36                         return;
37                 }
38
39                 if ( ! username ) username = self.selected_username;
40
41                 if ( ! username ) {
42                         self.message.LDAP = 'no username';
43                         return;
44                 }
45                 $log.info( 'LDAP_search', username );
46                 self.clear_LDAP();
47                 self.selected_username = username;
48                 self.message.LDAP = 'search '+username;
49                 self.r.LDAP_search.query({ username: username }, function(LDAP) {
50                         self.LDAP = LDAP;
51                         $log.info( 'LDAP', LDAP );
52                         if ( self.LDAP.length == 0 ) {
53                                 self.message.LDAP ='no results for '+username;
54                                 return;
55                         }
56                         self.cpe.parser = LDAP[0]._cpe_parser;
57                         self.cpe.table_name  = 'cpe_' + LDAP[0]._cpe_parser;
58                         self.username = LDAP[0].cn;
59                         self.message.LDAP = null;
60                         $log.info( 'cpe', self.cpe );
61                 });
62         };
63         self.$watch('selected_username', self.LDAP_search );
64
65         self.gnuplot_changed = function() {
66                 var h_cols = self.gnuplot.cols;
67                 $log.info( 'gnuplot_changed', h_cols );
68                 if ( ! h_cols || h_cols.length < 1) {
69                         $log.warn("no columns for gnuplot");
70                         return;
71                 }
72
73                 var cols = [ 'timestamp' ];
74                 for ( var i = 0; i < h_cols.length; i++ ) {
75                         cols.push( 'h->\'' + h_cols[i] + '\' as "' + h_cols[i] + '"' );
76                 }
77                 self.gnuplot.sql = 'select ' + cols.join(',') + ' from cpe_' + self.cpe.parser + ' where username = \'' + self.username + '\' order by timestamp desc limit 100';
78                 $log.info( 'gnuplot', cols, self.gnuplot );
79         };
80         self.gnuplot_refresh = function() {
81                 if ( ! self.gnuplot || ! self.gnuplot.cols || ! self.gnuplot.sql) return;
82                 self.message.gnuplot = self.gnuplot.cols.join(' ');
83                 self.gnuplot.img = '/gnuplot?hide=1;with='+self.gnuplot.with+';sql=' + self.gnuplot.sql;
84                 $log.info('gnuplot_refresh', self.gnuplot.img);
85         };
86         self.$watch('gnuplot.sql', self.gnuplot_refresh );
87         self.$watch('gnuplot.with', self.gnuplot_refresh );
88
89         self.gnuplot_onload = function() {
90                 $log.info( 'gnuplot_onload' );
91                 self.message.gnuplot = '<a href="#gnuplot">ready</a>';
92         };
93
94         self.r.table = $resource('/table/:table');
95         self.table_update = function () {
96                 if ( ! self.username || ! self.cpe.table_name ) return;
97
98                 self.message.ping = self.username+' loading';
99                 self.r.table.get({ username: self.username, table: 'ping', limit: 1 }, function(ping) {
100                         $log.info('ping', ping);
101                         self.message.ping = null;
102                         var hash = {};
103                         for(var i = 0; i <= ping.columns.length; i++) {
104                                 hash[ping.columns[i]] = ping.rows[0][i];
105                         }
106                         self.cpe.ping = hash;
107                         $log.info('ping hash', hash);
108                 });
109
110                 self.message.table = self.username + ' loading from ' + self.cpe.table_name;
111                 self.r.table.get({ username: self.username, table: self.cpe.table_name, limit: self.cpe_limit }, function(table) {
112                         $log.info( 'table', table );
113                         self.cpe.table = table;
114                         self.message.table = null;
115                         if ( table.rows.length == 0 ) {
116                                 self.message.table = 'no results for '+self.username;
117                                 return;
118                         }
119
120                         if ( h_cols = self.cpe_hash[self.cpe.parser] ) {
121                                 self.gnuplot.cols = h_cols;
122                                 self.gnuplot_changed();
123                         } else {
124                                 self.message.gnuplot = 'no graph for ' + self.cpe.parser;
125                         }
126                 });
127         };
128         self.$watch('username', self.table_update );
129  
130         this.clear = function() {
131                 $log.info('clear');
132                 self.CRM = null;
133                 this.clear_LDAP();
134         }
135
136         this.clear_LDAP = function() {
137                 $log.info('clear_LDAP');
138                 self.LDAP = null;
139                 self.selected_username = null;
140                 self.gnuplot = { 'with': 'points', cols: [] };
141                 self.cpe = {};
142                 self.cpe_limit = 1;
143         };
144
145         self.message = {};
146
147         self.$watch('selected_username', function() {
148                 if ( self.selected_username == null ) self.clear_LDAP();
149         });
150
151         self.clear();
152         self.$watch('cpe_limit', function() {
153                 $log.info( 'cpe_limit', self.cpe_limit );
154                 self.table_update();
155         });
156
157         this.columns = [
158                 'USERNAME',
159                 'BROJ',
160                 'USLUGA',
161                 'IP_MANAGEMENT',
162                 'IP_VOICE',
163                 'KOLOKACIJA',
164                 'OPT82'
165         ];
166
167         this.cpe_hash = {
168                 'Davolink': [ 'Max_down', 'Max_up' ],
169                 'EasyGateway': [ 'upstreamCurrRate', 'upstreamMaxRate', 'upstreamNoiseMargin' ],
170         };
171
172       this.keys = function(h) {
173              if ( angular.isArray(h) ) h = h[0];
174              var keys = [];
175              for(i in h) if (h.hasOwnProperty(i))
176              {
177                keys.push(i);
178              }
179              return keys;
180       };
181
182     }
183
184     user.$inject = ['$xhr','$resource','$log'];
185
186 // http://jsfiddle.net/gronky/cLEck/
187 angular.formatter('include', {
188     parse: function(apply, value, list) {
189         angular.Array[apply ? 'add' : 'remove'](list, value);
190         return apply;
191     },
192     format: function(apply, value, list) {
193         return angular.Array.indexOf(list, value) != -1;
194     },
195 });
196
197   </script>
198
199 <style type="text/css">
200
201 table {
202         border-collapse:collapse;
203 }
204
205 th {
206         border-bottom: 2px solid gray;
207 }
208
209 th, td {
210         border-left: 1em solid white;
211         border-right: 1em solid white;
212 }
213
214 .zebra {
215         background: #eee;
216 }
217
218 #message {
219         padding: 3px;
220         background: #ff8;
221
222         margin-left: 1em;
223         position: fixed;
224 }
225
226 .panel_right {
227         z-index: 10;
228         position: absolute;
229         right: 0;
230         background: #ffc;
231         padding: 3px;
232 }
233
234 .panel_right ul {
235         padding: 0;
236 }
237
238 .panel_right ul > li {
239         list-style-type: none;
240 }
241
242 .panel_right > label {
243         float: right;
244 }
245
246 li > tt {
247         font-weight: bold;
248 }
249
250 </style>
251
252   <div ng:controller="user">
253
254    <form ng:submit="CRM_search()">
255     <label for="args">username:
256     <input type="text" name="search_username" placeholder="test" size="10" autofocus ng:required />
257     </label>
258     <input type="submit" value="search in CRM">
259     <input type="reset"  ng:click="clear()" value="clear">
260
261     <span id="message" ng:show="message.$size()" ng:click="message={}" title="click to close">
262       <div ng:repeat="(category,status) in message" ng:show="status"><b>{{category}}</b> {{status}}</div>
263     </span>
264
265    </form>
266
267
268 <div class="panel_right" ng:show="CRM">
269  <label>
270   Add columns
271   <input type=checkbox name=show_columns>
272  </label>
273  <ul ng:show="show_columns">
274   <li ng:repeat="c in keys(CRM)" ng:show="columns.indexOf(c) < 0" ng:click="columns.push(c)">{{c}}
275  </ul>
276 </div>
277
278     <table ng:show="CRM">
279     <tr>
280         <th ng:repeat="c in columns" ng:click="columns.$remove(c)">{{c}}</th>
281     </tr>
282     <tr ng:repeat="u in CRM" ng:click="LDAP_search(u.USERNAME)" ng:class-even="'zebra'">
283         <td ng:repeat="c in columns" ng:show="! selected_username || selected_username == u.USERNAME">{{u[c]}}</td>
284     </tr>
285     </table>
286
287     <input type=button value="Show ALL results, not just {{selected_username}}" ng:click="selected_username=''" ng:show="selected_username">
288
289   <div ng:show="selected_username">
290
291     <h2><tt>{{selected_username}}</tt> LDAP entry</h2>
292
293     <ul ng:show="LDAP">
294      <li ng:repeat="c in keys(LDAP)"><tt>{{c}}</tt> {{LDAP[0][c]}}</li>
295     </ul>
296
297     <div ng:show="cpe.ping">
298      ping <tt>{{cpe.ping.ip}}</tt> rtt <tt>{{cpe.ping.rtt}}</tt> at <tt>{{cpe.ping.timestamp}}</tt>
299     </div>
300
301     <h2 ng:show="cpe.table_name">{{cpe.table_name}} {{username}}</h2>
302
303     <table ng:show="cpe.table">
304      <tr>
305       <th ng:repeat="c in cpe.table.columns">{{c}}</th>
306      </tr>
307      <tr ng:repeat="r in cpe.table.rows" ng:class-even="'zebra'">
308       <td ng:repeat="v in r">{{v}}</td>
309      </tr>
310      <tr>
311       <td colspan="{{cpe.table.columns.length}}">
312       limit:
313         <label>1<input name="cpe_limit" type="radio" value=1></label>
314         &middot; &middot; &middot;
315         <label>5<input name="cpe_limit" type="radio" value=5></label>
316         &middot; &middot; &middot;
317         <label>10<input name="cpe_limit" type="radio" value=10></label>
318       </td>
319     </tr>
320     </table>
321
322     <div class="panel_right" ng:show="cpe.table">
323      <label>
324       Graph columns
325       <input type=checkbox name=show_gnuplot_cols>
326      </label>
327
328      <ul ng:show="show_gnuplot_cols">
329       with <select name="gnuplot.with">
330        <option ng:repeat="with in ['points','dots','steps','lines']">{{with}}</option>
331       </select>
332
333       <li ng:repeat="(k,v) in cpe.table.rows[0][cpe.table.hash_col]">
334          <label>
335          <input type="checkbox" name="checked_cols" ng:format="include:k:gnuplot.cols" ng:click="gnuplot_changed()">
336         {{k}} <tt>{{v}}</tt>
337          </label>
338       </li>
339      </ul>
340     </div>
341
342     <a name="gnuplot"> 
343     <ng:include src="gnuplot.img" ng:show="gnuplot.img" onload="message.gnuplot = gnuplot_onload" ></ng:include>
344
345   </div>
346
347     <input type=checkbox name=debug value=1>
348     <pre ng:show=debug>
349 CRM={{CRM}}
350 LDAP={{LDAP}}
351 cpe={{cpe}}
352 gnuplot={{gnuplot}}
353     </pre>
354   </div>
355  </body>
356 </html>