trailguide 0.1.22 → 0.1.23
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/trail_guide/admin/application.js +4 -0
- data/app/controllers/trail_guide/admin/application_controller.rb +1 -1
- data/app/views/layouts/trail_guide/admin/_header.erb +1 -1
- data/app/views/layouts/trail_guide/admin/application.html.erb +1 -0
- data/app/views/trail_guide/admin/experiments/_combined_experiment.html.erb +36 -14
- data/app/views/trail_guide/admin/experiments/_experiment.html.erb +36 -14
- data/app/views/trail_guide/admin/experiments/index.html.erb +11 -1
- data/lib/trail_guide/catalog.rb +32 -6
- data/lib/trail_guide/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58c9c8c98d0955f2f43194bbea245101c16227c103a885376f5c7bfdfdfa6de2
|
4
|
+
data.tar.gz: 55511233504312e35c9ceda5ba5a08dcb27c0afdec04fb0684c201ac4575ae94
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f44e0158dd4c7a25fd3a02a2f8a518c9bd46acd40a1680603f60aa01d0836e49a1dd5a4472816a6479fb0159e20bdff68051e923aae84ab5ddee7a0daf3b6a5
|
7
|
+
data.tar.gz: 2801b067ab586c24775621b6a5355a2256db75d568b7093f10c04870b4881df4f31d42b660324e19123845b4a3c80cd0f12f89b8baa52497b12d91e1f39ccb27
|
@@ -39,7 +39,7 @@ module TrailGuide
|
|
39
39
|
|
40
40
|
def experiment_metric(experiment, metric)
|
41
41
|
return metric if experiment_metrics_visible?(experiment)
|
42
|
-
return '
|
42
|
+
return helpers.content_tag('span', nil, class: 'fas fa-eye-slash', data: {toggle: 'tooltip'}, title: "metrics are hidden until this experiment reaches it's target sample size")
|
43
43
|
end
|
44
44
|
helper_method :experiment_metric
|
45
45
|
|
@@ -4,7 +4,7 @@
|
|
4
4
|
<%= TrailGuide::Admin.configuration.title %>
|
5
5
|
<% end %>
|
6
6
|
<div class="col-sm text-center">
|
7
|
-
<strong class="total"><%= TrailGuide.catalog.
|
7
|
+
<strong class="total"><%= TrailGuide.catalog.count %></strong> experiments
|
8
8
|
<span>/</span>
|
9
9
|
<strong class="running"><%= TrailGuide.catalog.running.count %></strong> running
|
10
10
|
<span>/</span>
|
@@ -8,6 +8,7 @@
|
|
8
8
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
9
9
|
|
10
10
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
11
|
+
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
|
11
12
|
<%= stylesheet_link_tag "trail_guide/admin/application", media: "all" %>
|
12
13
|
</head>
|
13
14
|
<body>
|
@@ -10,19 +10,33 @@
|
|
10
10
|
<% if combined_experiment.running? %>
|
11
11
|
<% if experiment_peekable?(combined_experiment) %>
|
12
12
|
<% if experiment_peeking?(combined_experiment) %>
|
13
|
-
<%= link_to
|
13
|
+
<%= link_to trail_guide_admin.experiments_path(anchor: combined_experiment.experiment_name), class: 'btn btn-sm btn-outline-primary', method: :put, data: {toggle: :tooltip}, title: "hide this experiment's metrics" do %>
|
14
|
+
<span class="fas fa-eye-slash" />
|
15
|
+
<% end %>
|
14
16
|
<% else %>
|
15
|
-
<%= link_to
|
17
|
+
<%= link_to peek_url(combined_experiment), class: 'btn btn-sm btn-primary', method: :put, data: {toggle: :tooltip}, title: "peek at this experiment's metrics" do %>
|
18
|
+
<span class="fas fa-eye" />
|
19
|
+
<% end %>
|
16
20
|
<% end %>
|
17
21
|
<% end %>
|
18
|
-
<%= link_to
|
19
|
-
|
22
|
+
<%= link_to trail_guide_admin.stop_experiment_path(combined_experiment.experiment_name), class: 'btn btn-sm btn-warning', method: :put, data: {toggle: :tooltip}, title: 'pause this experiment - you will have the option to resume or reset' do %>
|
23
|
+
<span class="fas fa-pause" />
|
24
|
+
<% end %>
|
25
|
+
<%= link_to trail_guide_admin.restart_experiment_path(combined_experiment.experiment_name), class: 'btn btn-sm btn-danger',method: :put, data: {toggle: :tooltip}, title: 'restart this experiment - will reset all data and restart the experiment' do %>
|
26
|
+
<span class="fas fa-redo" />
|
27
|
+
<% end %>
|
20
28
|
<% elsif combined_experiment.started? %>
|
21
|
-
<%= link_to
|
29
|
+
<%= link_to trail_guide_admin.resume_experiment_path(combined_experiment.experiment_name), class: 'btn btn-sm btn-success',method: :put, data: {toggle: :tooltip}, title: 'resume this experiment to start bucketing users and serving variants again' do %>
|
30
|
+
<span class="fas fa-redo" />
|
31
|
+
<% end %>
|
22
32
|
<% else %>
|
23
|
-
<%= link_to
|
33
|
+
<%= link_to trail_guide_admin.start_experiment_path(combined_experiment.experiment_name), class: 'btn btn-sm btn-success',method: :put, data: {toggle: :tooltip}, title: 'start this experiment' do %>
|
34
|
+
<span class="fas fa-play" />
|
35
|
+
<% end %>
|
36
|
+
<% end %>
|
37
|
+
<%= link_to trail_guide_admin.reset_experiment_path(combined_experiment.experiment_name), class: 'btn btn-sm btn-outline-danger',method: :put, data: {toggle: :tooltip}, title: "stop this experiment if it's running and reset all data" do %>
|
38
|
+
<span class="fas fa-ban" />
|
24
39
|
<% end %>
|
25
|
-
<%= link_to "reset", trail_guide_admin.reset_experiment_path(combined_experiment.experiment_name), class: 'btn btn-sm btn-outline-danger',method: :put %>
|
26
40
|
</div>
|
27
41
|
</div>
|
28
42
|
|
@@ -81,13 +95,13 @@
|
|
81
95
|
<% end %>
|
82
96
|
|
83
97
|
<% if experiment.running? && !experiment.winner? && participant.variant(experiment) == variant %>
|
84
|
-
<span class="
|
98
|
+
<span class="fas fa-user text-muted" data-toggle="tooltip" title="you are currently in this cohort"></span>
|
85
99
|
<% end %>
|
86
100
|
<% if experiment.winner? && variant == experiment.winner %>
|
87
|
-
<span class="
|
101
|
+
<span class="fas fa-star text-primary" data-toggle="tooltip" title="this variant has been promoted as the winner of the experiment"></span>
|
88
102
|
<% end %>
|
89
103
|
<% if variant.control? %>
|
90
|
-
<
|
104
|
+
<span class="fas fa-cog text-muted" data-toggle="tooltip" title="this variant is the control group for this experiment"></span>
|
91
105
|
<% end %>
|
92
106
|
</th>
|
93
107
|
|
@@ -104,16 +118,24 @@
|
|
104
118
|
<td class="text-right">
|
105
119
|
<% if experiment.running? && !experiment.winner? %>
|
106
120
|
<% if participant.variant(experiment) == variant %>
|
107
|
-
<%= link_to
|
121
|
+
<%= link_to trail_guide_admin.leave_experiment_path(experiment.experiment_name), class: "btn btn-sm btn-outline-secondary", method: :put, data: {toggle: :tooltip}, title: 'leave this cohort' do %>
|
122
|
+
<span class="fas fa-sign-out-alt" />
|
123
|
+
<% end %>
|
108
124
|
<% else %>
|
109
|
-
<%= link_to
|
125
|
+
<%= link_to trail_guide_admin.join_experiment_path(experiment.experiment_name, variant.name), class: "btn btn-sm btn-secondary", method: :put, data: {toggle: :tooltip}, title: 'join this cohort' do %>
|
126
|
+
<span class="fas fa-sign-in-alt" />
|
127
|
+
<% end %>
|
110
128
|
<% end %>
|
111
129
|
<% end %>
|
112
130
|
|
113
131
|
<% if !experiment.winner? || variant != experiment.winner %>
|
114
|
-
<%= link_to
|
132
|
+
<%= link_to trail_guide_admin.winner_experiment_path(experiment.experiment_name, variant.name), class: "btn btn-sm btn-#{experiment.winner? ? "outline-" : ""}primary", method: :put, data: {toggle: :tooltip}, title: 'rollout this variant as the winner for this experiment' do %>
|
133
|
+
<span class="fas fa-star" />
|
134
|
+
<% end %>
|
115
135
|
<% elsif experiment.winner? && variant == experiment.winner %>
|
116
|
-
<%= link_to
|
136
|
+
<%= link_to trail_guide_admin.clear_experiment_path(experiment.experiment_name), class: "btn btn-sm btn-warning", method: :put, data: {toggle: :tooltip}, title: 'remove this variant as the selected winner' do %>
|
137
|
+
<span class="fas fa-window-close" />
|
138
|
+
<% end %>
|
117
139
|
<% end %>
|
118
140
|
</td>
|
119
141
|
</tr>
|
@@ -10,19 +10,33 @@
|
|
10
10
|
<% if experiment.running? %>
|
11
11
|
<% if experiment_peekable?(experiment) %>
|
12
12
|
<% if experiment_peeking?(experiment) %>
|
13
|
-
<%= link_to
|
13
|
+
<%= link_to trail_guide_admin.experiments_path(anchor: experiment.experiment_name), class: 'btn btn-sm btn-outline-primary', method: :put, data: {toggle: :tooltip}, title: "hide this experiment's metrics" do %>
|
14
|
+
<span class="fas fa-eye-slash" />
|
15
|
+
<% end %>
|
14
16
|
<% else %>
|
15
|
-
<%= link_to
|
17
|
+
<%= link_to peek_url(experiment), class: 'btn btn-sm btn-primary', method: :put, data: {toggle: :tooltip}, title: "peek at this experiment's metrics" do %>
|
18
|
+
<span class="fas fa-eye" />
|
19
|
+
<% end %>
|
16
20
|
<% end %>
|
17
21
|
<% end %>
|
18
|
-
<%= link_to
|
19
|
-
|
22
|
+
<%= link_to trail_guide_admin.stop_experiment_path(experiment.experiment_name), class: 'btn btn-sm btn-warning', method: :put, data: {toggle: :tooltip}, title: 'pause this experiment - you will have the option to resume or reset' do %>
|
23
|
+
<span class="fas fa-pause" />
|
24
|
+
<% end %>
|
25
|
+
<%= link_to trail_guide_admin.restart_experiment_path(experiment.experiment_name), class: 'btn btn-sm btn-danger',method: :put, data: {toggle: :tooltip}, title: 'restart this experiment - will reset all data and restart the experiment' do %>
|
26
|
+
<span class="fas fa-redo" />
|
27
|
+
<% end %>
|
20
28
|
<% elsif experiment.started? %>
|
21
|
-
<%= link_to
|
29
|
+
<%= link_to trail_guide_admin.resume_experiment_path(experiment.experiment_name), class: 'btn btn-sm btn-success',method: :put, data: {toggle: :tooltip}, title: 'resume this experiment to start bucketing users and serving variants again' do %>
|
30
|
+
<span class="fas fa-redo" />
|
31
|
+
<% end %>
|
22
32
|
<% else %>
|
23
|
-
<%= link_to
|
33
|
+
<%= link_to trail_guide_admin.start_experiment_path(experiment.experiment_name), class: 'btn btn-sm btn-success',method: :put, data: {toggle: :tooltip}, title: 'start this experiment' do %>
|
34
|
+
<span class="fas fa-play" />
|
35
|
+
<% end %>
|
36
|
+
<% end %>
|
37
|
+
<%= link_to trail_guide_admin.reset_experiment_path(experiment.experiment_name), class: 'btn btn-sm btn-outline-danger',method: :put, data: {toggle: :tooltip}, title: "stop this experiment if it's running and reset all data" do %>
|
38
|
+
<span class="fas fa-ban" />
|
24
39
|
<% end %>
|
25
|
-
<%= link_to "reset", trail_guide_admin.reset_experiment_path(experiment.experiment_name), class: 'btn btn-sm btn-outline-danger',method: :put %>
|
26
40
|
</div>
|
27
41
|
</div>
|
28
42
|
|
@@ -75,13 +89,13 @@
|
|
75
89
|
<% end %>
|
76
90
|
|
77
91
|
<% if experiment.running? && !experiment.winner? && participant.variant(experiment) == variant %>
|
78
|
-
<span class="
|
92
|
+
<span class="fas fa-user text-muted" data-toggle="tooltip" title="you are currently in this cohort"></span>
|
79
93
|
<% end %>
|
80
94
|
<% if experiment.winner? && variant == experiment.winner %>
|
81
|
-
<span class="
|
95
|
+
<span class="fas fa-star text-primary" data-toggle="tooltip" title="this variant has been promoted as the winner of the experiment"></span>
|
82
96
|
<% end %>
|
83
97
|
<% if variant.control? %>
|
84
|
-
<
|
98
|
+
<span class="fas fa-cog text-muted" data-toggle="tooltip" title="this variant is the control group for this experiment"></span>
|
85
99
|
<% end %>
|
86
100
|
</th>
|
87
101
|
|
@@ -98,16 +112,24 @@
|
|
98
112
|
<td class="text-right">
|
99
113
|
<% if experiment.running? && !experiment.winner? %>
|
100
114
|
<% if participant.variant(experiment) == variant %>
|
101
|
-
<%= link_to
|
115
|
+
<%= link_to trail_guide_admin.leave_experiment_path(experiment.experiment_name), class: "btn btn-sm btn-outline-secondary", method: :put, data: {toggle: :tooltip}, title: 'leave this cohort' do %>
|
116
|
+
<span class="fas fa-sign-out-alt" />
|
117
|
+
<% end %>
|
102
118
|
<% else %>
|
103
|
-
<%= link_to
|
119
|
+
<%= link_to trail_guide_admin.join_experiment_path(experiment.experiment_name, variant.name), class: "btn btn-sm btn-secondary", method: :put, data: {toggle: :tooltip}, title: 'join this cohort' do %>
|
120
|
+
<span class="fas fa-sign-in-alt" />
|
121
|
+
<% end %>
|
104
122
|
<% end %>
|
105
123
|
<% end %>
|
106
124
|
|
107
125
|
<% if !experiment.winner? || variant != experiment.winner %>
|
108
|
-
<%= link_to
|
126
|
+
<%= link_to trail_guide_admin.winner_experiment_path(experiment.experiment_name, variant.name), class: "btn btn-sm btn-#{experiment.winner? ? "outline-" : ""}primary", method: :put, data: {toggle: :tooltip}, title: 'rollout this variant as the winner for this experiment' do %>
|
127
|
+
<span class="fas fa-star" />
|
128
|
+
<% end %>
|
109
129
|
<% elsif experiment.winner? && variant == experiment.winner %>
|
110
|
-
<%= link_to
|
130
|
+
<%= link_to trail_guide_admin.clear_experiment_path(experiment.experiment_name), class: "btn btn-sm btn-warning", method: :put, data: {toggle: :tooltip}, title: 'remove this variant as the selected winner' do %>
|
131
|
+
<span class="fas fa-window-close" />
|
132
|
+
<% end %>
|
111
133
|
<% end %>
|
112
134
|
</td>
|
113
135
|
</tr>
|
@@ -1,5 +1,15 @@
|
|
1
|
+
<% if TrailGuide.configuration.disabled %>
|
2
|
+
<div class="row justify-content-center">
|
3
|
+
<div class="col-sm-12 col-md-10 col-lg-8">
|
4
|
+
<div class="alert alert-danger">
|
5
|
+
TrailGuide is globally disabled. Your experiments are not running, and control variants will be returned for all users until it is enabled again.
|
6
|
+
</div>
|
7
|
+
</div>
|
8
|
+
</div>
|
9
|
+
<% end %>
|
10
|
+
|
1
11
|
<div class="experiments">
|
2
|
-
<% TrailGuide.catalog.each do |experiment| %>
|
12
|
+
<% TrailGuide.catalog.by_started.each do |experiment| %>
|
3
13
|
<% if experiment.combined? %>
|
4
14
|
<%= render 'combined_experiment', combined_experiment: experiment %>
|
5
15
|
<% else %>
|
data/lib/trail_guide/catalog.rb
CHANGED
@@ -80,25 +80,49 @@ module TrailGuide
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def all
|
83
|
-
experiments.map do |exp|
|
83
|
+
exploded = experiments.map do |exp|
|
84
84
|
if exp.combined?
|
85
85
|
exp.combined.map { |name| combined_experiment(exp, name) }
|
86
86
|
else
|
87
87
|
exp
|
88
88
|
end
|
89
89
|
end.flatten
|
90
|
+
|
91
|
+
self.class.new(exploded)
|
90
92
|
end
|
91
93
|
|
92
94
|
def started
|
93
|
-
to_a.select(&:started?)
|
95
|
+
self.class.new(to_a.select(&:started?))
|
94
96
|
end
|
95
97
|
|
96
98
|
def running
|
97
|
-
to_a.select(&:running?)
|
99
|
+
self.class.new(to_a.select(&:running?))
|
98
100
|
end
|
99
101
|
|
100
102
|
def stopped
|
101
|
-
to_a.select(&:stopped?)
|
103
|
+
self.class.new(to_a.select(&:stopped?))
|
104
|
+
end
|
105
|
+
|
106
|
+
def by_started
|
107
|
+
scoped = to_a.sort do |a,b|
|
108
|
+
if a.running? && !b.running?
|
109
|
+
1
|
110
|
+
elsif !a.running? && b.running?
|
111
|
+
-1
|
112
|
+
else
|
113
|
+
if a.started? && !b.started?
|
114
|
+
1
|
115
|
+
elsif !a.started? && b.started?
|
116
|
+
-1
|
117
|
+
elsif a.started? && b.started?
|
118
|
+
a.started_at <=> b.started_at
|
119
|
+
else
|
120
|
+
b.experiment_name.to_s <=> a.experiment_name.to_s
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end.reverse
|
124
|
+
|
125
|
+
self.class.new(scoped)
|
102
126
|
end
|
103
127
|
|
104
128
|
def find(name)
|
@@ -124,10 +148,10 @@ module TrailGuide
|
|
124
148
|
|
125
149
|
def select(name)
|
126
150
|
if name.is_a?(Class)
|
127
|
-
experiments.select { |exp| exp == name }
|
151
|
+
selected = experiments.select { |exp| exp == name }
|
128
152
|
else
|
129
153
|
# TODO we can be more efficient than mapping twice here
|
130
|
-
experiments.select do |exp|
|
154
|
+
selected = experiments.select do |exp|
|
131
155
|
exp.experiment_name == name.to_s.underscore.to_sym ||
|
132
156
|
exp.metric == name.to_s.underscore.to_sym ||
|
133
157
|
exp.name == name.to_s.classify ||
|
@@ -140,6 +164,8 @@ module TrailGuide
|
|
140
164
|
end
|
141
165
|
end
|
142
166
|
end
|
167
|
+
|
168
|
+
self.class.new(selected)
|
143
169
|
end
|
144
170
|
|
145
171
|
def register(klass)
|
data/lib/trail_guide/version.rb
CHANGED