aleph_analytics 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -1
  3. data/app/assets/javascripts/angular/aleph.js.es6 +9 -4
  4. data/app/assets/javascripts/angular/controllers/alerts/alert_show_controller.js.es6 +4 -4
  5. data/app/assets/javascripts/angular/controllers/controllers.js.es6 +1 -0
  6. data/app/assets/javascripts/angular/controllers/query/query_index_controller.js.es6 +2 -5
  7. data/app/assets/javascripts/angular/controllers/query/query_repl_controller.js.es6 +33 -9
  8. data/app/assets/javascripts/angular/controllers/result/single_result_show_controller.js.es6 +26 -0
  9. data/app/assets/javascripts/angular/directives/query/query_details_directive.js.es6 +0 -1
  10. data/app/assets/javascripts/angular/directives/result/results_directive.js.es6 +17 -0
  11. data/app/assets/javascripts/angular/services/lib/open_repl_service.js.es6 +4 -27
  12. data/app/assets/javascripts/angular/services/query/query_handler.js.es6 +2 -2
  13. data/app/assets/stylesheets/shared.css.sass +45 -0
  14. data/app/assets/stylesheets/sidebar.css.sass +0 -30
  15. data/app/controllers/results_controller.rb +1 -0
  16. data/app/models/alert.rb +1 -1
  17. data/app/models/query_version.rb +1 -1
  18. data/app/models/result.rb +1 -1
  19. data/app/models/visualization.rb +1 -1
  20. data/app/views/layouts/application.html.haml +2 -0
  21. data/app/views/queries/_query_version_sidebar.html.haml +1 -1
  22. data/app/views/queries/_results.html.haml +9 -0
  23. data/app/views/results/_show.html.haml +2 -0
  24. data/app/views/results/_single_result_show.html.haml +9 -0
  25. data/public/assets/.sprockets-manifest-f2e907b8dd5ccd1b5394fc3d2f4c2f5b.json +1 -0
  26. data/public/assets/angular/{aleph.js-19b4df67407de5dab249abfc391c0eaf.es6 → aleph.js-5c6fb1f7eaa833a4e9fc35bca222deb7.es6} +9 -4
  27. data/public/assets/angular/controllers/alerts/{alert_show_controller.js-a984dc82fbcac380cdc8682bf8986933.es6 → alert_show_controller.js-550f7fd183df9504c71d18ce7251b3d0.es6} +4 -4
  28. data/public/assets/angular/controllers/{controllers.js-7431ae468ea2f0d392661448a61cfdf3.es6 → controllers.js-94cb19ce7a5c88bfe6832a75a90b39d6.es6} +1 -0
  29. data/public/assets/angular/controllers/query/{query_index_controller.js-828eadeee6a971b11b5c07f65f0c6def.es6 → query_index_controller.js-75f9ac815f2e2dd3eae846d16e07ac25.es6} +2 -5
  30. data/public/assets/angular/controllers/query/{query_repl_controller.js-3c4bac22e41766e2e83e720d53acade3.es6 → query_repl_controller.js-0448a8eed79f78efe189d454626a714f.es6} +33 -9
  31. data/public/assets/angular/controllers/result/single_result_show_controller.js-e18738b84c1ebe7c12707706cb876188.es6 +26 -0
  32. data/public/assets/angular/directives/query/{query_details_directive.js-2dd979e2463826558f166d9dc9e2c8a9.es6 → query_details_directive.js-0f6ac0f0515854a026ec6582e07e76b8.es6} +0 -1
  33. data/public/assets/angular/directives/result/{results_directive.js-fcbf9750790823a11ca313e630bd2b0f.es6 → results_directive.js-1931bff514e14d41ecf47f73fd7e24e2.es6} +17 -0
  34. data/public/assets/angular/services/lib/open_repl_service.js-cf17778946bb990beecd1c32bfcc668d.es6 +33 -0
  35. data/public/assets/angular/services/query/{query_handler.js-d8cb3c66bcf6d16cd13bb5bcd0921496.es6 → query_handler.js-23a60003545f1f1381bc0c98be8f121c.es6} +2 -2
  36. data/public/assets/{application-ef5c2ae95804ac9785f190a9aea7ad8b.js → application-119e0de54b9da9bf755ed98f87f1fab2.js} +8 -8
  37. data/public/assets/{application-9153e0bf570016651e5eb8c67e037d3a.css → application-dfbb8b5c9f13286f32601250c5aef5e8.css} +2 -2
  38. data/public/assets/resque_web/{application-d2bc6e68cf7c6215e804fe9e3f46f1d0.js → application-705d1a4a22a72f773a8cd5c70ef9b284.js} +4 -4
  39. data/vendor/assets/javascripts/angular-clipboard/angular-clipboard.js +83 -0
  40. data/vendor/assets/stylesheets/angular-spinner/treasure-overlay-spinner.css +2 -2
  41. metadata +19 -16
  42. data/public/assets/.sprockets-manifest-bd008d70493ba1dbee54c64e00f373a4.json +0 -1
  43. data/public/assets/angular/services/lib/open_repl_service.js-2332490470ea58f3e5ce7f6fe5dd2659.es6 +0 -56
  44. data/vendor/assets/javascripts/ng-clip/ngClip.js +0 -84
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: aff91fd86b2c89e2a9f4494a530e41978d1ce6f0
4
- data.tar.gz: d1f6a6537ffac3f48c552f6e847d922a1ba375a7
3
+ metadata.gz: ba0eaef53bed7d98b1a209c8b4bdb4bd23d8b59c
4
+ data.tar.gz: d581fabceec434ea16c4cc5e915d8b14517cb9db
5
5
  SHA512:
6
- metadata.gz: 162c1b83ddfc2617742b6ce37ab34c6c4edf7221dc80ea044de62278a500db732d5577361b1400d6aa80d1841a417849941c779f15cfafec73d0e4e0e526179d
7
- data.tar.gz: 0eab26a9f59f613ad9bff947bff1881595d62a1d96e438805108c83020d8c6afc9614e23709416f0710676a249ccc9f17c2d8f7916b5e5ffee84cd70f4340c05
6
+ metadata.gz: eb813201164b87f46061fe0ce6743120daa8774c5bcd3260dad1d9484fe2288f00c71752aa08186ab60701596f4460dd4c9741a385d2df9e29b85a17409bf977
7
+ data.tar.gz: 308a0d37c2c5bbb5cd4b3a09e089cc7c189522fafa2e55469e2576c20b6b036f6a1db339b47caf87970e7c6ef7e0b70c82f039a650b538a92913c54a2c9899a6
data/CHANGELOG.md CHANGED
@@ -1,8 +1,17 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file using [Semantic Versioning](http://semver.org/).
3
3
 
4
+ ## [0.0.5] - 2016-09-26
5
+ ### Features
6
+ - [Link to specific result / single result page](https://github.com/lumoslabs/aleph/issues/12)
7
+ - [Use shift enter as hotkey to run queries in REPL](https://github.com/lumoslabs/aleph/issues/16)
8
+
9
+ ### Fixed
10
+ - [Alerts searching bug](https://github.com/lumoslabs/aleph/issues/15)
11
+ - [Alerts sorting bug](https://github.com/lumoslabs/aleph/issues/13)
12
+ - [Query saving after REPL closes issue](https://github.com/lumoslabs/aleph/issues/14)
4
13
 
5
14
  ## [0.0.4] - 2016-07-12
6
15
  ### Fixed
7
- - Saving QueryRoles bug
16
+ - Saving QueryRoles bug
8
17
  - Streamline sign out page
@@ -8,7 +8,7 @@
8
8
  'alephServices',
9
9
  'alephFilters',
10
10
  'ngAnimate',
11
- 'ngClipboard',
11
+ 'angular-clipboard',
12
12
  'ui.bootstrap',
13
13
  'infinite-scroll',
14
14
  'ngTagsInput',
@@ -27,9 +27,9 @@
27
27
  }])
28
28
 
29
29
  .value('KeyBindings', {
30
- saveQuery: new KeyBinding('Save Query', {mac: 'command+shift+s', win:'ctrl+shift+s'}),
31
- runQuery: new KeyBinding('Run Query', {mac: 'command+shift+k', win:'ctrl+shift+k'}),
32
- detectParameters: new KeyBinding('Detect Parameters', {mac: 'command+shift+p', win:'ctrl+shift+p'})
30
+ saveQuery: new KeyBinding('Save Query', { mac: 'command+shift+s', win: 'ctrl+shift+s' }),
31
+ runQuery: new KeyBinding('Run Query', { mac: 'shift+enter', win: 'shift+enter' }),
32
+ detectParameters: new KeyBinding('Detect Parameters', { mac: 'command+shift+p', win: 'ctrl+shift+p' })
33
33
  })
34
34
 
35
35
  .config(['$locationProvider', $locationProvider => {
@@ -79,6 +79,11 @@
79
79
  controller: 'AlertShowController',
80
80
  controllerAs: 'alertShowCtrl'
81
81
  })
82
+ .when('/results/query/:queryId/query_version/:queryVersionId/result/:resultId', {
83
+ templateUrl: 'singleResultShow',
84
+ controller: 'SingleResultShowController',
85
+ controllerAs: 'singleResultShowCtrl'
86
+ })
82
87
  .when('/snippets', {
83
88
  title: 'Snippets',
84
89
  templateUrl: 'snippetIndex',
@@ -19,8 +19,8 @@
19
19
  if ($routeParams.alertId === 'new') {
20
20
  this.alert.initItem()
21
21
  .then(this.query.initItem.bind(this.query, null))
22
- .then(this._openReplService.open.bind(this._openReplService, {}))
23
- .then(({query, _}) => {
22
+ .then(this._openReplService.open.bind(this._openReplService, { skipSave: true }))
23
+ .then(query => {
24
24
  this.query = query;
25
25
  this.alert.item.query_title = query.item.title;
26
26
  this.query.item.tags.push('alert-query');
@@ -59,9 +59,9 @@
59
59
  editAlert() {
60
60
  this._openReplService.open({
61
61
  query: this.query
62
- }).then(({query, result}) => {
62
+ }).then(query => {
63
63
  this.query = query;
64
- return this.query.save({result_id: result.id});
64
+ return this.query.save();
65
65
  }).then(this.alert.save.bind(this.alert));
66
66
  }
67
67
 
@@ -10,6 +10,7 @@
10
10
  'alephControllers.alertIndexController',
11
11
  'alephControllers.alertShowController',
12
12
  'alephControllers.snippetIndexController',
13
+ 'alephControllers.singleResultShowController',
13
14
  'alephServices',
14
15
  'ui.ace',
15
16
  'ngRoute',
@@ -24,7 +24,7 @@
24
24
  this._roleModel = RoleModel;
25
25
  this._tagResource = TagResource;
26
26
  this._$q = $q;
27
- this._openReplService = OpenReplService;
27
+ this._repl = OpenReplService;
28
28
 
29
29
  RoleModel.initCollection();
30
30
  }
@@ -61,10 +61,7 @@
61
61
  }
62
62
 
63
63
  openRepl() {
64
- this._openReplService.open()
65
- .then(({query, result}) => {
66
- return query.save({ result_id: result.id });
67
- })
64
+ this._repl.open()
68
65
  .then(this._handler.navigateToLatestVersion.bind(this._handler))
69
66
  .then(this._handler.success.bind(this._handler, 'create', true))
70
67
  .catch(this._handler.handleReplExit.bind(this._handler));
@@ -2,12 +2,11 @@
2
2
  'use strict';
3
3
 
4
4
  class QueryReplController {
5
- constructor($uibModalInstance, getResultCsv, DefaultAceConfigurator, ResultRunner, query,
6
- Results, NavigationGuard, KeyBindings, hotkeys, $scope) {
5
+ constructor($uibModalInstance, getResultCsv, DefaultAceConfigurator, ResultRunner, Query,
6
+ Results, NavigationGuard, KeyBindings, hotkeys, options, $scope) {
7
+ this._initQuery(options, Query);
7
8
  this._modalInstance = $uibModalInstance;
8
-
9
9
  this.results = new Results();
10
- this.query = query;
11
10
  this.resultRunner = new ResultRunner(this.query, this.results, {
12
11
  sandbox: true,
13
12
  enablePolling: true
@@ -78,11 +77,19 @@
78
77
  this._navigationGuard.disable();
79
78
  this._setParameterDefaultValues(this.query.item.version.parameters, this.resultRunner.substitutionValues);
80
79
  let result = this.results.collection.shift();
80
+ if(this._options.skipSave) {
81
+ /* FIXME: this is for alerts where we want to pop up the repl and save later
82
+ We probably have to rethink the alerts UI/UX to take this hack out */
83
+ this._toModelAndClose(angular.copy(this.query.item));
84
+ } else {
85
+ this.query.save(_.exists(result) ? { result_id: result.item.id } : {})
86
+ .then(this._toModelAndClose.bind(this))
87
+ .catch(err => {
88
+ console.error('query save failed', err);
89
+ alert('Query save failed!');
90
+ });
91
+ }
81
92
 
82
- this._modalInstance.close({
83
- query: this.query,
84
- result: _.exists(result) ? result.item : {},
85
- });
86
93
  }
87
94
 
88
95
  exit() {
@@ -99,6 +106,12 @@
99
106
 
100
107
  // private methods
101
108
 
109
+ _toModelAndClose(item) {
110
+ let model = new this._Query();
111
+ model.internalize(item);
112
+ this._modalInstance.close(model);
113
+ }
114
+
102
115
  _queryBody() {
103
116
  return this.query.item.version.body;
104
117
  }
@@ -112,6 +125,17 @@
112
125
  });
113
126
  }
114
127
 
128
+ _initQuery(options, Query) {
129
+ this._Query = Query;
130
+ this._options = options;
131
+ this.query = new Query();
132
+ if(_.exists(options.query)) {
133
+ this.query.internalize(angular.copy(options.query.item));
134
+ } else {
135
+ this.query.initItem();
136
+ }
137
+ }
138
+
115
139
  _initKeyBindings(KeyBindings, hotkeys, $scope) {
116
140
  this._saveKb = KeyBindings.saveQuery.withKeyFn(() => {
117
141
  if(this.validToSave()) {
@@ -138,7 +162,7 @@
138
162
  }
139
163
 
140
164
  QueryReplController.$inject = ['$uibModalInstance', 'getResultCsv', 'DefaultAceConfigurator', 'ResultRunner',
141
- 'query', 'Results', 'NavigationGuard', 'KeyBindings', 'hotkeys', '$scope'];
165
+ 'Query', 'Results', 'NavigationGuard', 'KeyBindings', 'hotkeys', 'options', '$scope'];
142
166
 
143
167
  angular
144
168
  .module('alephControllers.queryReplController', ['alephServices'])
@@ -0,0 +1,26 @@
1
+ !(angular => {
2
+ 'use strict';
3
+
4
+ class SingleResultShowController {
5
+ constructor($routeParams, Query, Result, PageTitleManager) {
6
+ this.resultId = $routeParams.resultId;
7
+ this.queryId = $routeParams.queryId;
8
+ this.queryVersionId = $routeParams.queryVersionId;
9
+
10
+ this.query = new Query();
11
+ this.query.initItem(this.queryId, this.queryVersionId).then(query => {
12
+ this.panelTitle = 'Result id=' + this.resultId + ' for "' + query.title + '"';
13
+ PageTitleManager.title = this.panelTitle ;
14
+ });
15
+
16
+ this.result = new Result();
17
+ this.result.initItem(this.resultId);
18
+ }
19
+ }
20
+
21
+ SingleResultShowController.$inject = ['$routeParams', 'Query', 'Result', 'PageTitleManager'];
22
+
23
+ angular
24
+ .module('alephControllers.singleResultShowController', ['alephServices'])
25
+ .controller('SingleResultShowController', SingleResultShowController);
26
+ }(angular));
@@ -18,7 +18,6 @@
18
18
 
19
19
  openRepl() {
20
20
  this._repl.open( { query: this.query } )
21
- .then(({query, result}) => query.save({ result_id: result.id }))
22
21
  .then(this._handler.navigateToLatestVersion.bind(this._handler))
23
22
  .then(this._handler.success.bind(this._handler, 'update', false))
24
23
  .catch(this._handler.handleReplExit.bind(this._handler))
@@ -2,11 +2,28 @@
2
2
  'use strict';
3
3
 
4
4
  class ResultsController {
5
+
6
+ constructor(AlertFlash) {
7
+ this._alertFlash = AlertFlash;
8
+ this._hostname = angular.copy(location.host);
9
+ }
10
+
5
11
  runQuery() {
6
12
  this.resultRunner.run();
7
13
  }
14
+
15
+ generateResultLink(result) {
16
+ return this._hostname + '/results/query/' + this.query.item.id +
17
+ '/query_version/' + this.query.item.version.id + '/result/' + result.item.id;
18
+ }
19
+
20
+ alertCopied() {
21
+ this._alertFlash.emitSuccess('Result link copied to clipboard!');
22
+ }
8
23
  }
9
24
 
25
+ ResultsController.$inject = ['AlertFlash'];
26
+
10
27
  function resultsComponent() {
11
28
  return {
12
29
  restrict: 'E',
@@ -3,9 +3,8 @@
3
3
 
4
4
  class OpenReplService {
5
5
 
6
- constructor($uibModal, Query, AceCompleters) {
6
+ constructor($uibModal, AceCompleters) {
7
7
  this._$modal = $uibModal;
8
- this._Query = Query;
9
8
  this._AceCompleters = AceCompleters;
10
9
  }
11
10
 
@@ -21,36 +20,14 @@
21
20
  windowClass: 'query-repl-dialog',
22
21
  backdrop: 'static',
23
22
  keyboard: false,
24
- resolve: {
25
- query: () => _.exists(options.query) ? this._clone(options.query) : this._newQuery()
26
- }
23
+ resolve: { options: () => options }
27
24
  });
28
25
 
29
- return modalInstance.result.then(({query, result}) => {
30
- return {
31
- query: this._clone(query),
32
- result: result
33
- };
34
- });
35
- }
36
-
37
- // private methods
38
-
39
- _clone(q) {
40
- let copiedItem = angular.copy(q.item);
41
- let m = new this._Query();
42
- m.internalize(copiedItem);
43
- return m;
44
- }
45
-
46
- _newQuery() {
47
- let m = new this._Query();
48
- m.initItem();
49
- return m;
26
+ return modalInstance.result;
50
27
  }
51
28
  }
52
29
 
53
- OpenReplService.$inject = ['$uibModal', 'Query', 'AceCompleters'];
30
+ OpenReplService.$inject = ['$uibModal', 'AceCompleters'];
54
31
  angular.module('alephServices.openReplService', []).service('OpenReplService', OpenReplService);
55
32
 
56
33
  }(angular));
@@ -12,7 +12,7 @@
12
12
  let _action = action || 'action';
13
13
  let _schedule = _.exists(schedule) ? schedule : false;
14
14
 
15
- this._alertFlash.emitSuccess('Query "' + query.title + '" ' + _action + 'd!', _schedule);
15
+ this._alertFlash.emitSuccess('Query "' + query.item.title + '" ' + _action + 'd!', _schedule);
16
16
  return query;
17
17
  }
18
18
 
@@ -26,7 +26,7 @@
26
26
  }
27
27
 
28
28
  navigateToLatestVersion(query) {
29
- this._$location.path('/queries/' + query.id + '/query_versions/' + query.version.id);
29
+ this._$location.path('/queries/' + query.item.id + '/query_versions/' + query.item.version.id);
30
30
  return query;
31
31
  }
32
32
 
@@ -148,6 +148,9 @@ a.navbar-text.active
148
148
  .no-list-style
149
149
  list-style: none
150
150
 
151
+ .inline
152
+ display: inline
153
+
151
154
  .looks-like-clickable
152
155
  cursor: pointer
153
156
  &:hover
@@ -155,3 +158,45 @@ a.navbar-text.active
155
158
  color: tomato
156
159
  &:active
157
160
  opacity: $opacity-high
161
+
162
+ // pulsating stuff
163
+
164
+ // Chrome, Safari, Opera
165
+ @-webkit-keyframes pulsate
166
+ from
167
+ opacity: 0.0
168
+ color: tomato
169
+
170
+ to
171
+ opacity: $opacity-high
172
+ color: $slate-blue
173
+
174
+
175
+ // Standard syntax
176
+ @keyframes pulsate
177
+ from
178
+ opacity: 0.0
179
+ color: tomato
180
+
181
+ to
182
+ opacity: $opacity-high
183
+ color: $slate-blue
184
+
185
+ .pulsating
186
+ -webkit-animation-name: pulsate
187
+ -webkit-animation-duration: 3s
188
+ -webkit-animation-direction: alternate
189
+ animation-name: pulsate
190
+ animation-duration: 3s
191
+ animation-direction: alternate
192
+ animation-iteration-count: infinite
193
+
194
+ // you know, just give them a taste
195
+ .finite-pulsating
196
+ -webkit-animation-name: pulsate
197
+ -webkit-animation-duration: 3s
198
+ -webkit-animation-direction: alternate
199
+ animation-name: pulsate
200
+ animation-duration: 3s
201
+ animation-direction: alternate
202
+ animation-iteration-count: 3
@@ -36,36 +36,6 @@
36
36
  .versions
37
37
  padding: 15px 0px 15px 0px
38
38
 
39
- // Chrome, Safari, Opera
40
- @-webkit-keyframes pulsate
41
- from
42
- opacity: 0.0
43
- color: tomato
44
-
45
- to
46
- opacity: $opacity-high
47
- color: $slate-blue
48
-
49
-
50
- // Standard syntax
51
- @keyframes pulsate
52
- from
53
- opacity: 0.0
54
- color: tomato
55
-
56
- to
57
- opacity: $opacity-high
58
- color: $slate-blue
59
-
60
- .pulsating-comment
61
- -webkit-animation-name: pulsate
62
- -webkit-animation-duration: 3s
63
- -webkit-animation-direction: alternate
64
- animation-name: pulsate
65
- animation-duration: 3s
66
- animation-direction: alternate
67
- animation-iteration-count: infinite
68
-
69
39
  .versions
70
40
  ul
71
41
  list-style-type: none
@@ -17,6 +17,7 @@ class ResultsController < ApplicationController
17
17
 
18
18
  def show
19
19
  respond_to do |format|
20
+ format.html { render :index }
20
21
  format.json { render json: @result }
21
22
  end
22
23
  end
data/app/models/alert.rb CHANGED
@@ -18,7 +18,7 @@ class Alert < ActiveRecord::Base
18
18
  delegate :latest_query_version, to: :query
19
19
  delegate :user, to: :latest_query_version
20
20
 
21
- scope :with_role, ->(role) { joins(:query).includes(:query_roles).where(query_roles: { role: role }) }
21
+ scope :with_role, ->(role) { references(:query).includes(:query_roles).where(query_roles: { role: role }) }
22
22
 
23
23
  LOCATIONS_FOR_ATTRIBUTES = {
24
24
  title: { association: :query, column: :title, type: :text },