aleph_analytics 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +1 -0
- data/app/assets/javascripts/angular/controllers/controllers.js.es6 +9 -2
- data/app/assets/javascripts/angular/directives/query/query_details_directive.js.es6 +54 -6
- data/app/assets/javascripts/angular/directives/query/query_version_sidebar_directive.js.es6 +8 -0
- data/app/assets/javascripts/angular/services/query/query.js.es6 +16 -5
- data/app/assets/javascripts/angular/services/query/query_request_transformers.js.es6 +1 -1
- data/app/assets/javascripts/angular/services/query/tags_roles_comparator.js.es6 +32 -0
- data/app/assets/javascripts/angular/services/services.js.es6 +1 -0
- data/app/assets/stylesheets/alert_bar.css.sass +3 -3
- data/app/assets/stylesheets/application.css.sass +1 -0
- data/app/assets/stylesheets/comments.css.sass +4 -0
- data/app/assets/stylesheets/queries.css.sass +12 -9
- data/app/assets/stylesheets/results.css.sass +0 -2
- data/app/assets/stylesheets/scheduled.css.sass +39 -0
- data/app/assets/stylesheets/shared.css.sass +67 -0
- data/app/assets/stylesheets/sidebar.css.sass +12 -0
- data/app/assets/stylesheets/variables.css.sass +1 -1
- data/app/mailers/alert_mailer.rb +1 -1
- data/app/mailers/query_mailer.rb +10 -0
- data/app/models/query.rb +21 -1
- data/app/models/result.rb +11 -4
- data/app/models/scheduled_query_execution.rb +23 -0
- data/app/serializers/query_serializer.rb +1 -1
- data/app/views/layouts/application.html.haml +3 -1
- data/app/views/queries/_comments.html.haml +9 -3
- data/app/views/queries/_index_item.html.haml +3 -3
- data/app/views/queries/_index_sort_bar.html.haml +3 -3
- data/app/views/queries/_query_details.html.haml +31 -21
- data/app/views/queries/_query_version_sidebar.html.haml +34 -16
- data/app/views/queries/_scheduled.html.haml +31 -0
- data/app/views/query_mailer/query_result_email.html.haml +7 -0
- data/config/environments/development.rb +3 -0
- data/config/example/{alerts.yml → email.yml} +0 -0
- data/config/initializers/01_internalize_configurations.rb +6 -6
- data/db/migrate/20190131003650_add_set_latest_result_to_queries.rb +5 -0
- data/db/migrate/20190205234108_add_query_scheduling_columns.rb +13 -0
- data/lib/aws_s3.rb +44 -3
- data/lib/clock.rb +1 -0
- data/lib/csv_helper/aws.rb +3 -18
- data/lib/interaction/query_interaction.rb +3 -0
- data/lib/interaction/query_update.rb +3 -0
- data/public/assets/.sprockets-manifest-331daedd75cbbd8f5318863713f13576.json +1 -0
- data/public/assets/angular/controllers/{controllers.js-45fce398a9c2c371df9ffc32e8dbed84.es6 → controllers.js-f00a5ac91d427dcb9694fc1849f5bbd1.es6} +9 -2
- data/public/assets/angular/directives/query/{query_details_directive.js-9ed5b4d1ee4b86889d0de38bc93bac26.es6 → query_details_directive.js-a6604f8ceb6af34a2e97360c6ed459f6.es6} +54 -6
- data/public/assets/angular/directives/query/{query_version_sidebar_directive.js-b19ba8a9bf4e66c5740e9b9f9495cee1.es6 → query_version_sidebar_directive.js-282fe948431cbd43335f8d99503fc87a.es6} +8 -0
- data/public/assets/angular/services/query/{query.js-7b6228d0a5c1a6ea76242f4aa49aafd0.es6 → query.js-0dd29232f8dbf0527a1324d509a8a74b.es6} +16 -5
- data/public/assets/angular/services/query/{query_request_transformers.js-522901477c7848324cd5c014005a85c8.es6 → query_request_transformers.js-110a99334386d4391d47d48df8b57ddf.es6} +1 -1
- data/public/assets/angular/services/query/tags_roles_comparator.js-d1e086bdbad13b7e1ed60fa24c660a71.es6 +32 -0
- data/public/assets/angular/services/{services.js-855551e8fa01a9a3c05115c4c9fdf7db.es6 → services.js-5230e6db8f737e8378ef2a17c2fc847e.es6} +1 -0
- data/public/assets/{application-8bc9d85ca89b3c85e03f7d06948d2e87.js → application-55739fd5c21580dfacbf85238f9e5575.js} +23 -23
- data/public/assets/{application-b3586e5b2749cef985bebb24246f95b6.css → application-a3b45a0034f70e5f423c4e0427ca5ccf.css} +1 -1
- data/public/assets/resque_web/{application-4218536633ae4c535133fe1455d54cbc.js → application-91fe987abb3becd4e530ec6a4a6a3da7.js} +4 -4
- metadata +23 -16
- data/lib/tasks/resque.rake +0 -22
- data/public/assets/.sprockets-manifest-61519c86aab355aa148c9e7c78293a9e.json +0 -1
@@ -23,11 +23,23 @@
|
|
23
23
|
span
|
24
24
|
font-size: small
|
25
25
|
|
26
|
+
.version-item
|
27
|
+
padding-left: 4px
|
28
|
+
padding-top: 2px
|
29
|
+
|
30
|
+
.octicon
|
31
|
+
padding-right: 3px
|
32
|
+
|
26
33
|
.current-version
|
27
34
|
padding: 15px
|
28
35
|
background-color: lighten($slate-blue, 15%)
|
29
36
|
border-bottom: 1px solid lighten($navbar-inverse-bg, 5%)
|
30
37
|
|
38
|
+
.scheduled-info
|
39
|
+
padding: 15px
|
40
|
+
background-color: lighten($slate-blue, 30%)
|
41
|
+
border-bottom: 1px solid lighten($navbar-inverse-bg, 15%)
|
42
|
+
|
31
43
|
.github-links
|
32
44
|
padding: 15px
|
33
45
|
background-color: lighten($slate-blue, 25%)
|
data/app/mailers/alert_mailer.rb
CHANGED
@@ -0,0 +1,10 @@
|
|
1
|
+
class QueryMailer < ActionMailer::Base
|
2
|
+
default from: EMAIL_CONFIG['from']
|
3
|
+
|
4
|
+
def query_result_email(query)
|
5
|
+
@query = query
|
6
|
+
@presigned_url = AwsS3.presigned_url(@query.latest_result_key, "result_for_query_#{@query.id}.csv", 3600 * 24)
|
7
|
+
Rails.logger.error("Could not generate presigned_url for query id = #{@query.id}, make sure #{@query.latest_result_object_url} exists?") unless @presigned_url.present?
|
8
|
+
mail(to: @query.email, subject: "Scheduled Aleph query '#{@query.title}'")
|
9
|
+
end
|
10
|
+
end
|
data/app/models/query.rb
CHANGED
@@ -20,8 +20,10 @@ class Query < ActiveRecord::Base
|
|
20
20
|
delegate :version, :author_name, :results, to: :latest_query_version, prefix: :latest, allow_nil: true
|
21
21
|
delegate :id, to: :latest_query_version, prefix: true, allow_nil: true
|
22
22
|
delegate :to_csv, to: :latest_completed_result, allow_nil: true
|
23
|
+
delegate :user, to: :latest_query_version
|
23
24
|
|
24
25
|
scope :with_role, ->(role) { includes(:query_roles).where(query_roles: { role: role }) }
|
26
|
+
scope :scheduled, -> { where(scheduled_flag: true) }
|
25
27
|
|
26
28
|
LOCATIONS_FOR_ATTRIBUTES = {
|
27
29
|
title: { association: :base, column: :title, type: :text },
|
@@ -36,6 +38,12 @@ class Query < ActiveRecord::Base
|
|
36
38
|
|
37
39
|
paginate_with LOCATIONS_FOR_ATTRIBUTES
|
38
40
|
|
41
|
+
def self.run_scheduled
|
42
|
+
scheduled.each do |query|
|
43
|
+
Resque.enqueue(ScheduledQueryExecution, query.id, query.user.role)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
39
47
|
def latest_completed_result
|
40
48
|
latest_results.completed.last
|
41
49
|
end
|
@@ -48,10 +56,22 @@ class Query < ActiveRecord::Base
|
|
48
56
|
end
|
49
57
|
end
|
50
58
|
|
59
|
+
def send_result_email
|
60
|
+
QueryMailer.query_result_email(self).deliver_now!
|
61
|
+
end
|
62
|
+
|
51
63
|
def latest_query_version
|
52
64
|
query_versions.last
|
53
65
|
end
|
54
66
|
|
67
|
+
def latest_result_key
|
68
|
+
@latest_result_key ||= "latest_#{AwsS3::S3_FOLDER}/query_#{id}.csv"
|
69
|
+
end
|
70
|
+
|
71
|
+
def latest_result_object_url
|
72
|
+
@latest_result_object_url ||= "https://s3.amazonaws.com/#{AwsS3::S3_BUCKET}/#{latest_result_key}"
|
73
|
+
end
|
74
|
+
|
55
75
|
def roles
|
56
76
|
query_roles.map(&:role).uniq
|
57
77
|
end
|
@@ -77,7 +97,7 @@ class Query < ActiveRecord::Base
|
|
77
97
|
|
78
98
|
def summary
|
79
99
|
Summarizer.new(query_versions).reduce(version: 0, comments: 0) do |qv|
|
80
|
-
{ versions: 1, comments: qv.comment.blank? ? 0 : 1}
|
100
|
+
{ versions: 1, comments: qv.comment.blank? ? 0 : 1 }
|
81
101
|
end
|
82
102
|
end
|
83
103
|
|
data/app/models/result.rb
CHANGED
@@ -24,6 +24,7 @@ class Result < ActiveRecord::Base
|
|
24
24
|
|
25
25
|
def mark_complete_with_count(row_count)
|
26
26
|
update_attributes!(status: 'complete', row_count: row_count, completed_at: Time.now)
|
27
|
+
copy_latest_result
|
27
28
|
end
|
28
29
|
|
29
30
|
def mark_failed!(message)
|
@@ -34,10 +35,6 @@ class Result < ActiveRecord::Base
|
|
34
35
|
super || ongoing_row_count
|
35
36
|
end
|
36
37
|
|
37
|
-
def result_csv
|
38
|
-
@result_csv ||= ResultCsv.new(id)
|
39
|
-
end
|
40
|
-
|
41
38
|
def redis_result_row_count
|
42
39
|
@redis_result_row_count ||= RedisResultRowCount.new(self)
|
43
40
|
end
|
@@ -50,6 +47,12 @@ class Result < ActiveRecord::Base
|
|
50
47
|
duration(:created_at, :started_at)
|
51
48
|
end
|
52
49
|
|
50
|
+
def copy_latest_result
|
51
|
+
if AwsS3.s3_enabled? && query.present? && query.scheduled_flag
|
52
|
+
AwsS3.copy(current_result_s3_key, query.latest_result_key)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
53
56
|
private
|
54
57
|
|
55
58
|
def duration(start_field, end_field)
|
@@ -64,4 +67,8 @@ class Result < ActiveRecord::Base
|
|
64
67
|
0
|
65
68
|
end
|
66
69
|
end
|
70
|
+
|
71
|
+
def current_result_s3_key
|
72
|
+
@result_key ||= CsvHelper::Aws.new(id).key
|
73
|
+
end
|
67
74
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class ScheduledQueryExecution
|
2
|
+
@queue = :query_exec
|
3
|
+
|
4
|
+
def self.perform(query_id, role)
|
5
|
+
query = Query.find(query_id)
|
6
|
+
|
7
|
+
interaction = Interaction::ResultCreation.new(
|
8
|
+
query_version_id: query.latest_query_version.id,
|
9
|
+
owner: query.user
|
10
|
+
)
|
11
|
+
|
12
|
+
result = interaction.execute
|
13
|
+
|
14
|
+
if interaction.errors.any?
|
15
|
+
query.error(interaction.errors.join(', '))
|
16
|
+
else
|
17
|
+
query.add_result(result)
|
18
|
+
query.save!
|
19
|
+
QueryExecution.perform(result.id, role)
|
20
|
+
query.send_result_email if query.email.present?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -3,6 +3,6 @@ class QuerySerializer < ActiveModel::Serializer
|
|
3
3
|
object.performant_tag_list
|
4
4
|
end
|
5
5
|
|
6
|
-
attributes :id, :title, :created_at, :updated_at, :tags, :roles
|
6
|
+
attributes :id, :title, :created_at, :updated_at, :tags, :roles, :latest_result_object_url, :email, :scheduled_flag
|
7
7
|
has_one :version
|
8
8
|
end
|
@@ -42,6 +42,8 @@
|
|
42
42
|
= render partial: 'running_results/index'
|
43
43
|
%script#comments-template{type: 'text/ng-template'}
|
44
44
|
= render partial: 'queries/comments'
|
45
|
+
%script#scheduled-template{type: 'text/ng-template'}
|
46
|
+
= render partial: 'queries/scheduled'
|
45
47
|
:javascript
|
46
48
|
window.flash = #{flash.to_hash.to_json};
|
47
49
|
%body{ 'ng-controller' => 'BodyController',
|
@@ -80,7 +82,7 @@
|
|
80
82
|
%uib-alert.alert-fade-out.ellipsis{ 'ng-repeat' => 'alert in alerts',
|
81
83
|
'type' => '{{alert.type}}',
|
82
84
|
'close' => 'dismiss()',
|
83
|
-
'dismiss-on-timeout' =>
|
85
|
+
'dismiss-on-timeout' => 5000,
|
84
86
|
'ng-bind' => 'alert.message' }
|
85
87
|
%div.content.container-fluid
|
86
88
|
= yield
|
@@ -1,5 +1,11 @@
|
|
1
1
|
.comments
|
2
|
+
%span.control-btn.glyphicon.pull-right.subdued-clickable{ 'ng-click' => 'queryDetailsCtrl.updateCommentDialogAndClose()',
|
3
|
+
'ng-class' => "{ 'glyphicon-remove': queryDetailsCtrl.query.isPristine(), 'glyphicon-save': queryDetailsCtrl.query.isDirty()}",
|
4
|
+
'uib-tooltip' => "{{queryDetailsCtrl.query.isDirty() ? 'Save' : 'Close'}}",
|
5
|
+
'tooltip-placement' => 'top' }
|
6
|
+
%span.control-btn.glyphicon.glyphicon-refresh.pull-right.subdued-clickable{ 'ng-click' => 'queryDetailsCtrl.query.revert()',
|
7
|
+
'uib-tooltip' => 'Refresh',
|
8
|
+
'ng-if' => 'queryDetailsCtrl.query.isDirty()',
|
9
|
+
'tooltip-placement' => 'top' }
|
2
10
|
%textarea.form-control{ 'ng-model' => 'queryDetailsCtrl.query.item.version.comment',
|
3
|
-
'placeholder' => 'Add a comment'
|
4
|
-
'ng-blur' => 'queryDetailsCtrl.updateQuery()' }
|
5
|
-
.btn-group
|
11
|
+
'placeholder' => 'Add a comment' }
|
@@ -14,16 +14,16 @@
|
|
14
14
|
.ellipsis{ 'ng-bind' => 'query.title' }
|
15
15
|
.col-md-4
|
16
16
|
%div#author
|
17
|
-
%a{ 'href' => '#',
|
17
|
+
%a.column-spacer{ 'href' => '#',
|
18
18
|
'ng-bind' => 'query.latest_author_name',
|
19
19
|
'ng-click' => "queryIdxCtrl.pagination.setSearch('author:' + query.latest_author_name, true)",
|
20
20
|
'uib-tooltip' => "Filter by {{query.latest_author_name}}",
|
21
21
|
'tooltip-delay' => 700,
|
22
22
|
'tooltip-placement' => 'top' }
|
23
23
|
%div#updated-at
|
24
|
-
%span{ 'ng-bind' => 'query.updated_at | date:dateFormat: "UTC"' }
|
24
|
+
%span.column-spacer{ 'ng-bind' => 'query.updated_at | date:dateFormat: "UTC"' }
|
25
25
|
%div#created-at
|
26
|
-
%span{ 'ng-bind' => 'query.created_at | date:dateFormat: "UTC"' }
|
26
|
+
%span.column-spacer{ 'ng-bind' => 'query.created_at | date:dateFormat: "UTC"' }
|
27
27
|
.col-md-2
|
28
28
|
%span.label.tag{ 'ng-repeat' => 'tag in query.tags | limitTo:5 | orderBy',
|
29
29
|
'ng-bind' => 'tag',
|
@@ -10,17 +10,17 @@
|
|
10
10
|
.col-md-4
|
11
11
|
%div#author
|
12
12
|
%strong
|
13
|
-
%a{ 'ng-click' => 'queryIdxCtrl.pagination.setSort("author")', 'title' => 'Sort By Author' }
|
13
|
+
%a.column-spacer{ 'ng-click' => 'queryIdxCtrl.pagination.setSort("author")', 'title' => 'Sort By Author' }
|
14
14
|
AUTHOR
|
15
15
|
.glyphicon.glyphicon-sort.tiny-icon
|
16
16
|
%div#updated-at
|
17
17
|
%strong
|
18
|
-
%a{ 'ng-click' => 'queryIdxCtrl.pagination.setSort("updated_at")', 'title' => 'Sort By Updated' }
|
18
|
+
%a.column-spacer{ 'ng-click' => 'queryIdxCtrl.pagination.setSort("updated_at")', 'title' => 'Sort By Updated' }
|
19
19
|
UPDATED
|
20
20
|
.glyphicon.glyphicon-sort.tiny-icon
|
21
21
|
%div#created-at
|
22
22
|
%strong
|
23
|
-
%a{ 'ng-click' => 'queryIdxCtrl.pagination.setSort("created_at")', 'title' => 'Sort By Created' }
|
23
|
+
%a.column-spacer{ 'ng-click' => 'queryIdxCtrl.pagination.setSort("created_at")', 'title' => 'Sort By Created' }
|
24
24
|
CREATED
|
25
25
|
.glyphicon.glyphicon-sort.tiny-icon
|
26
26
|
.col-md-2
|
@@ -1,9 +1,9 @@
|
|
1
|
-
.panel.panel-default
|
1
|
+
.panel.panel-default
|
2
2
|
%form{ 'ng-submit' => 'queryDetailsCtrl.updateQuery()',
|
3
3
|
'name' => 'queryDetailsCtrl.form',
|
4
4
|
'id' => 'form',
|
5
5
|
'novalidate' => '' }
|
6
|
-
= text_field_tag :query_title, '', placeholder: 'Query title', 'ng-model' => 'queryDetailsCtrl.query.item.title', 'ng-blur' => 'queryDetailsCtrl.
|
6
|
+
= text_field_tag :query_title, '', placeholder: 'Query title', 'ng-model' => 'queryDetailsCtrl.query.item.title', 'ng-blur' => 'queryDetailsCtrl.updateTitle()', class: 'query-title-form'
|
7
7
|
%div{ 'uib-popover' => 'Read Only!',
|
8
8
|
'popover-trigger' => 'mouseenter',
|
9
9
|
'popover-popup-delay' => 500,
|
@@ -31,22 +31,32 @@
|
|
31
31
|
'tooltip-append-to-body' => 'true',
|
32
32
|
'tooltip-popup-delay' => 800 }
|
33
33
|
%span.glyphicon.glyphicon-trash.glyphicons-lg.glyphicon-low
|
34
|
-
%span.btn-group
|
35
|
-
%button.btn.btn-sm
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
34
|
+
%span.btn-group.white-btns.pull-right
|
35
|
+
%button.btn.btn-sm{ 'uib-tooltip' => 'Schedule',
|
36
|
+
'tooltip-append-to-body' => 'true',
|
37
|
+
'tooltip-placement' => 'top',
|
38
|
+
'tooltip-popup-delay' => 800,
|
39
|
+
'uib-popover-template' => "'scheduled-template'",
|
40
|
+
'popover-title' => 'Schedule Query',
|
41
|
+
'popover-is-open' => 'queryDetailsCtrl.scheduleDialogOpen',
|
42
|
+
'ng-click' => 'queryDetailsCtrl.toggleScheduleDialog()' }
|
43
|
+
%span.glyphicon.glyphicon-time.glyphicons-lg.glyphicon-low
|
44
|
+
%span.btn-group.white-btns.pull-right
|
45
|
+
%button.btn.btn-sm{ 'uib-tooltip' => 'Comment',
|
46
|
+
'tooltip-append-to-body' => 'true',
|
47
|
+
'tooltip-placement' => 'top',
|
48
|
+
'tooltip-popup-delay' => 800,
|
49
|
+
'uib-popover-template' => "'comments-template'",
|
50
|
+
'popover-is-open' => 'queryDetailsCtrl.commentDialogOpen',
|
51
|
+
'popover-title' => 'Comment',
|
52
|
+
'ng-click' => 'queryDetailsCtrl.toggleCommentDialog()' }
|
43
53
|
%span.glyphicon.glyphicon-comment.glyphicons-lg.glyphicon-low
|
44
|
-
%span.btn-group
|
45
|
-
%button.btn.btn-sm
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
54
|
+
%span.btn-group.white-btns.pull-right
|
55
|
+
%button.btn.btn-sm{ 'uib-tooltip' => 'Clone',
|
56
|
+
'tooltip-append-to-body' => 'true',
|
57
|
+
'tooltip-placement' => 'top',
|
58
|
+
'tooltip-popup-delay' => 800,
|
59
|
+
'ng-click' => 'queryDetailsCtrl.cloneQuery()' }
|
50
60
|
%span.glyphicon.glyphicon-duplicate.glyphicons-lg.glyphicon-low
|
51
61
|
.row
|
52
62
|
.col-md-4
|
@@ -73,16 +83,16 @@
|
|
73
83
|
.panel-heading.bold Tags
|
74
84
|
%tags-input{ 'ng-model' => 'queryDetailsCtrl.query.item.tags',
|
75
85
|
'template' => 'tag-template',
|
76
|
-
'on-tag-added' => 'queryDetailsCtrl.
|
77
|
-
'on-tag-removed' => 'queryDetailsCtrl.
|
86
|
+
'on-tag-added' => 'queryDetailsCtrl.updateTagsAndRoles()',
|
87
|
+
'on-tag-removed' => 'queryDetailsCtrl.updateTagsAndRoles()' }
|
78
88
|
%auto-complete{'source' => 'queryDetailsCtrl.loadTags($query)'}
|
79
89
|
.col-md-4
|
80
90
|
.panel.panel-default.tag-panel.small-font
|
81
91
|
.panel-heading.bold Roles
|
82
92
|
%tags-input{ 'ng-model' => 'queryDetailsCtrl.query.item.roles',
|
83
93
|
'template' => 'role-template',
|
84
|
-
'on-tag-added' => 'queryDetailsCtrl.
|
85
|
-
'on-tag-removed' => 'queryDetailsCtrl.
|
94
|
+
'on-tag-added' => 'queryDetailsCtrl.updateTagsAndRoles()',
|
95
|
+
'on-tag-removed' => 'queryDetailsCtrl.updateTagsAndRoles()',
|
86
96
|
'placeholder' => 'Add a role',
|
87
97
|
'add-from-autocomplete-only' => 'true' }
|
88
98
|
%auto-complete{'source' => 'queryDetailsCtrl.loadRoles($query)'}
|
@@ -3,24 +3,42 @@
|
|
3
3
|
.current-version
|
4
4
|
%strong Current Version: {{qvSidebarCtrl.query.item.version.version}}
|
5
5
|
%p
|
6
|
-
.
|
7
|
-
|
8
|
-
|
9
|
-
.
|
10
|
-
|
6
|
+
.version-item
|
7
|
+
.octicon.octicon-calendar
|
8
|
+
{{qvSidebarCtrl.query.item.version.created_at | date:dateFormat: "UTC"}}
|
9
|
+
.version-item
|
10
|
+
.octicon.octicon-pencil
|
11
|
+
{{qvSidebarCtrl.query.item.version.author_name}}
|
12
|
+
.row{ 'ng-if' => 'qvSidebarCtrl.queryIsPersistedAsScheduled()' }
|
13
|
+
.scheduled-info
|
14
|
+
.version-item
|
15
|
+
.octicon.octicon-clock
|
16
|
+
Scheduled
|
17
|
+
.version-item
|
18
|
+
.octicon.octicon-clippy
|
19
|
+
%a{ 'href' => '',
|
20
|
+
'text' => 'qvSidebarCtrl.query.item.latest_result_object_url',
|
21
|
+
'supported' => 'supported',
|
22
|
+
'on-copied' => 'qvSidebarCtrl.alertResultLinkCopied()',
|
23
|
+
'clipboard' => '',
|
24
|
+
'tooltip-append-to-body' => 'true',
|
25
|
+
'uib-tooltip' => 'Copy latest result s3 URL',
|
26
|
+
'tooltip-placement' => 'left' }
|
27
|
+
Result S3 URL
|
11
28
|
.row{ 'ng-if' => 'qvSidebarCtrl.githubIsEnabled()' }
|
12
29
|
.github-links
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
30
|
+
.version-item
|
31
|
+
.octicon.octicon-mark-github
|
32
|
+
%a{'ng-href' => '{{qvSidebarCtrl.githubHistory}}'} Git History
|
33
|
+
.version-item
|
34
|
+
.octicon.octicon-mark-github
|
35
|
+
%a{'ng-href' => '{{qvSidebarCtrl.githubCommit}}'} Git Commit
|
36
|
+
.version-item
|
37
|
+
.octicon.octicon-mark-github
|
38
|
+
%span{ 'ng-if' => 'qvSidebarCtrl.selectedVersions.length !== 2',
|
39
|
+
'style' => 'opacity:0.5' } Git Compare
|
40
|
+
%a{ 'ng-if' => 'qvSidebarCtrl.selectedVersions.length === 2',
|
41
|
+
'ng-href' => '{{qvSidebarCtrl.githubCompare}}' } Git Compare
|
24
42
|
.row
|
25
43
|
.versions
|
26
44
|
%ul
|
@@ -0,0 +1,31 @@
|
|
1
|
+
.scheduled
|
2
|
+
.row.container.control-bar
|
3
|
+
%span.glyphicon.pull-right.control-btn.subdued-clickable{ 'ng-click' => 'queryDetailsCtrl.updateScheduleDialogAndClose()',
|
4
|
+
'ng-class' => "{ 'glyphicon-remove': queryDetailsCtrl.query.isPristine(), 'glyphicon-save': queryDetailsCtrl.query.isDirty()}",
|
5
|
+
'uib-tooltip' => "{{queryDetailsCtrl.query.isDirty() ? 'Save' : 'Close'}}",
|
6
|
+
'tooltip-placement' => 'top' }
|
7
|
+
%span.glyphicon.glyphicon-refresh.pull-right.control-btn.subdued-clickable{ 'ng-click' => 'queryDetailsCtrl.query.revert()',
|
8
|
+
'uib-tooltip' => 'Refresh',
|
9
|
+
'ng-if' => 'queryDetailsCtrl.query.isDirty()',
|
10
|
+
'tooltip-placement' => 'top' }
|
11
|
+
.row.container.toggle-bar
|
12
|
+
.col-sm-3
|
13
|
+
.col-sm-1.pad1
|
14
|
+
Off
|
15
|
+
.col-sm-4.toggle-center
|
16
|
+
%label.switch.switch-section
|
17
|
+
%input{ 'type' => 'checkbox',
|
18
|
+
'ng-model' => 'queryDetailsCtrl.query.item.scheduled_flag' }
|
19
|
+
%span.slider.round
|
20
|
+
.col-sm-1.pad1
|
21
|
+
On
|
22
|
+
.col-sm-3
|
23
|
+
.row.container.email-bar
|
24
|
+
.col-sm-1.email-label
|
25
|
+
%span.glyphicon.glyphicon-envelope.glyphicons-lg.glyphicon-low
|
26
|
+
.col-sm-11.email-input-col
|
27
|
+
%form{ name: 'queryEmailForm', id: 'queryEmailForm', novalidate: '' }
|
28
|
+
%input.input-xs{ 'type' => 'text',
|
29
|
+
'ng-model' => 'queryDetailsCtrl.query.item.email',
|
30
|
+
'class' => 'form-control',
|
31
|
+
'placeholder' => 'Email' }
|
@@ -34,4 +34,7 @@ Rails.application.configure do
|
|
34
34
|
|
35
35
|
# Raises error for missing translations
|
36
36
|
# config.action_view.raise_on_missing_translations = true
|
37
|
+
|
38
|
+
# Propagate errors raised within `after_rollback`/`after_commit` callbacks
|
39
|
+
config.active_record.raise_in_transactional_callbacks = true
|
37
40
|
end
|