rollout-ui 0.10.1 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/release.yml +1 -2
- data/.github/workflows/test.yml +1 -2
- data/.mise.toml +1 -1
- data/.ruby-version +1 -1
- data/README.md +25 -0
- data/lib/rollout/ui/config.rb +1 -0
- data/lib/rollout/ui/helpers.rb +4 -0
- data/lib/rollout/ui/version.rb +1 -1
- data/lib/rollout/ui/views/features/index.erb +16 -1
- data/lib/rollout/ui/views/features/partials/warning_icon.erb +3 -0
- data/lib/rollout/ui/views/features/show.erb +9 -0
- data/lib/rollout/ui/views/layout.erb +7 -0
- data/lib/rollout/ui/web.rb +14 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 30014dd8f03ca67cb9bd7152adb431746e9d1ec399201e2a51abb4f3dedab1a4
|
|
4
|
+
data.tar.gz: bfa5ade0416b04978bc47f461513dcb857e88a2aa8838a140564a12fe9101a8f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bf00bea7e987f4569fff37e268e48dccaf5b30c9cf62e545d8276ab66f426da578fc454e5ab1fd2b1db065a58284400ea72e4a0b8cd3eac088715c0f4d50a041
|
|
7
|
+
data.tar.gz: cea39dbe21f1a32be247c019e0fe7ca3073344ab918c4deb9ca7fedc80230b852b0d4e5ac745e1b4b776d41d5352030f25f41c98e70fd7a07479de4d034d67ca
|
data/.github/workflows/test.yml
CHANGED
data/.mise.toml
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
[tools]
|
|
2
|
-
ruby = "3.4.
|
|
2
|
+
ruby = "3.4.11"
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.4.
|
|
1
|
+
3.4.11
|
data/README.md
CHANGED
|
@@ -139,6 +139,31 @@ and check Remove for visible rows. **Update before following page links** to
|
|
|
139
139
|
avoid discarding unsaved form changes. Enrollment pagination remains available
|
|
140
140
|
when nickname lookup fails; unknown IDs are never silently dropped.
|
|
141
141
|
|
|
142
|
+
## Missing definitions
|
|
143
|
+
|
|
144
|
+
The overview and feature page mark stored features that have no definition in
|
|
145
|
+
the current application as **Missing definition**. This is informational: it
|
|
146
|
+
does not change targeting, editing, or deletion, and a missing definition is not
|
|
147
|
+
proof that a feature is unused.
|
|
148
|
+
|
|
149
|
+
With Rollout's `definitions` API, the UI checks `Rollout.definitions` when the
|
|
150
|
+
definitions directory exists. Older Rollout versions, a missing directory, or
|
|
151
|
+
`Rollout.definitions_path = nil` leave checking disabled.
|
|
152
|
+
|
|
153
|
+
Applications that also register features in Ruby can supply their complete list
|
|
154
|
+
of defined names instead:
|
|
155
|
+
|
|
156
|
+
```ruby
|
|
157
|
+
Rollout::UI.configure do
|
|
158
|
+
defined_features { MyApplication.defined_feature_names }
|
|
159
|
+
end
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The callback returns string or symbol names. Returning `nil` disables checking;
|
|
163
|
+
an empty list marks every stored feature as missing. Definitions are read once
|
|
164
|
+
per HTML request, so changes appear on the next request. Loading errors are not
|
|
165
|
+
treated as missing definitions. JSON responses are unchanged.
|
|
166
|
+
|
|
142
167
|
## Concurrent edits
|
|
143
168
|
|
|
144
169
|
Feature forms include a `feature_version` fingerprint of the editable state:
|
data/lib/rollout/ui/config.rb
CHANGED
data/lib/rollout/ui/helpers.rb
CHANGED
|
@@ -34,6 +34,10 @@ module Rollout::UI
|
|
|
34
34
|
config.defined?(:user_search) && config.defined?(:user_lookup)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
def missing_definition?(feature_name)
|
|
38
|
+
@defined_features && !@defined_features.include?(feature_name.to_s)
|
|
39
|
+
end
|
|
40
|
+
|
|
37
41
|
def user_search_min_length
|
|
38
42
|
config.get(:user_search_min_length).to_i.clamp(1, USER_SEARCH_MAX_LENGTH)
|
|
39
43
|
end
|
data/lib/rollout/ui/version.rb
CHANGED
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
<table class="text-sm w-100 text-left w-full">
|
|
12
12
|
<thead class="font-semibold text-gray-500 border-b border-gray-200">
|
|
13
13
|
<th class="pb-2 pr-3">Name</th>
|
|
14
|
+
<% if @defined_features %>
|
|
15
|
+
<th class="w-10 px-3" aria-label="Definition"></th>
|
|
16
|
+
<% end %>
|
|
14
17
|
<th class="pb-2 pr-3">Percentage</th>
|
|
15
18
|
<th class="pb-2 pr-3">Groups</th>
|
|
16
19
|
<th class="pb-2 pr-3">Users</th>
|
|
@@ -25,9 +28,21 @@
|
|
|
25
28
|
<% feature = @rollout.get(feature_name) %>
|
|
26
29
|
<tr class="border-b border-gray-200">
|
|
27
30
|
<td class="py-2">
|
|
28
|
-
<a class="text-blue-600 hover:text-blue-700 hover:underline" href="<%= h(feature_path(feature.name)) %>"><%= h(feature_name) %></a>
|
|
31
|
+
<a class="text-blue-600 hover:text-blue-700 hover:underline whitespace-no-wrap" href="<%= h(feature_path(feature.name)) %>"><%= h(feature_name) %></a>
|
|
29
32
|
<div class="text-gray-500 text-xs"><%= h(feature.data['description']) %></div>
|
|
30
33
|
</td>
|
|
34
|
+
<% if @defined_features %>
|
|
35
|
+
<td class="py-2 px-3">
|
|
36
|
+
<% if missing_definition?(feature_name) %>
|
|
37
|
+
<div class="flex justify-center">
|
|
38
|
+
<span class="definition-warning relative inline-flex text-yellow-800" tabindex="0" role="img" aria-label="Missing definition">
|
|
39
|
+
<%= erb :"features/partials/warning_icon", layout: false %>
|
|
40
|
+
<span class="definition-tooltip hidden absolute right-0 px-3 border border-yellow-700 bg-yellow-100 text-xs text-center leading-normal whitespace-no-wrap rounded-sm" aria-hidden="true">Missing definition</span>
|
|
41
|
+
</span>
|
|
42
|
+
</div>
|
|
43
|
+
<% end %>
|
|
44
|
+
</td>
|
|
45
|
+
<% end %>
|
|
31
46
|
<td class="py-2 whitespace-no-wrap">
|
|
32
47
|
<% if feature.percentage == 0 %>
|
|
33
48
|
<span class="text-gray-400"><%= h(feature.percentage) %>%</span>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg class="w-4 h-4 fill-current" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" aria-hidden="true" focusable="false">
|
|
2
|
+
<path d="M1.267 15H14.74c.942 0 1.548-.962 1.122-1.773L9.126 1.674c-.465-.899-1.794-.899-2.258 0L.132 13.227C-.281 14.038.325 15 1.267 15m7.794-2.685c0 .6-.451 1.061-1.097 1.061s-1.096-.462-1.096-1.061v-.025c0-.6.451-1.062 1.096-1.062.646 0 1.097.462 1.097 1.062zm-1.69-7.806h1.264c.349 0 .555.288.517.65l-.555 4.696c-.04.337-.271.55-.594.55s-.555-.213-.594-.55l-.555-4.696c-.038-.362.169-.65.517-.65"/>
|
|
3
|
+
</svg>
|
|
@@ -4,6 +4,15 @@
|
|
|
4
4
|
<pre class="text-red-500"><%= h(params[:error]) %></pre>
|
|
5
5
|
<% end %>
|
|
6
6
|
<h2 class="font-semibold text-xl text-gray-500 pt-12"><%= h(@feature.name) %></h2>
|
|
7
|
+
<% if missing_definition?(@feature.name) %>
|
|
8
|
+
<section class="mt-4 p-4 max-w-3xl flex items-center border border-yellow-700 bg-yellow-100 text-yellow-800 text-sm rounded-sm" aria-labelledby="missing-definition-heading">
|
|
9
|
+
<div class="mr-4 flex-shrink-0"><%= erb :"features/partials/warning_icon", layout: false %></div>
|
|
10
|
+
<div>
|
|
11
|
+
<h3 id="missing-definition-heading" class="font-semibold">Missing definition</h3>
|
|
12
|
+
<p class="mt-1 leading-relaxed">This feature has no definition in the current application.</p>
|
|
13
|
+
</div>
|
|
14
|
+
</section>
|
|
15
|
+
<% end %>
|
|
7
16
|
|
|
8
17
|
<div class="w-8 h-1 bg-gray-300 my-10"></div>
|
|
9
18
|
<main class="p-6 bg-gray-100 max-w-3xl w-full text-sm rounded-sm">
|
|
@@ -25,6 +25,13 @@
|
|
|
25
25
|
.dark .bg-white { background-color: #333333; }
|
|
26
26
|
.dark .border-gray-300 { border-color: #555555; }
|
|
27
27
|
.dark .hover\:bg-gray-800:hover { background-color: #4a4a4a; }
|
|
28
|
+
.dark .bg-yellow-100 { background-color: #352b16; }
|
|
29
|
+
.dark .border-yellow-700 { border-color: #975a16; }
|
|
30
|
+
.dark .text-yellow-800 { color: #fbd38d; }
|
|
31
|
+
.definition-tooltip { bottom: 100%; z-index: 1; padding-top: 10px; padding-bottom: 6px; }
|
|
32
|
+
.definition-warning:hover .definition-tooltip,
|
|
33
|
+
.definition-warning:focus .definition-tooltip { display: block; }
|
|
34
|
+
.definition-warning:focus { outline: 2px solid currentColor; outline-offset: 2px; }
|
|
28
35
|
</style>
|
|
29
36
|
</head>
|
|
30
37
|
<body>
|
data/lib/rollout/ui/web.rb
CHANGED
|
@@ -2,6 +2,7 @@ require "erb"
|
|
|
2
2
|
require "json"
|
|
3
3
|
require "rack"
|
|
4
4
|
require "rollout"
|
|
5
|
+
require "set"
|
|
5
6
|
|
|
6
7
|
require "rollout/ui/version"
|
|
7
8
|
require "rollout/ui/config"
|
|
@@ -98,6 +99,7 @@ module Rollout::UI
|
|
|
98
99
|
end
|
|
99
100
|
)
|
|
100
101
|
else
|
|
102
|
+
load_defined_features
|
|
101
103
|
@history_events = @rollout.respond_to?(:logging) ? @rollout.logging.global_events.reverse : []
|
|
102
104
|
load_history_user_nicknames(@history_events)
|
|
103
105
|
render_view(:'features/index')
|
|
@@ -120,6 +122,7 @@ module Rollout::UI
|
|
|
120
122
|
if json_request?
|
|
121
123
|
json(feature_to_hash(@feature))
|
|
122
124
|
else
|
|
125
|
+
load_defined_features
|
|
123
126
|
load_selected_users
|
|
124
127
|
@history_events = @rollout.respond_to?(:logging) ? @rollout.logging.events(@feature.name).reverse : []
|
|
125
128
|
load_history_user_nicknames(@history_events)
|
|
@@ -127,6 +130,17 @@ module Rollout::UI
|
|
|
127
130
|
end
|
|
128
131
|
end
|
|
129
132
|
|
|
133
|
+
def load_defined_features
|
|
134
|
+
names = if config.defined?(:defined_features)
|
|
135
|
+
config.get(:defined_features)
|
|
136
|
+
elsif Rollout.respond_to?(:definitions)
|
|
137
|
+
path = Rollout.definitions_path
|
|
138
|
+
Rollout.definitions.keys if path && File.directory?(path)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
@defined_features = names.map(&:to_s).to_set unless names.nil?
|
|
142
|
+
end
|
|
143
|
+
|
|
130
144
|
def search_users
|
|
131
145
|
return not_found unless user_selector_enabled?
|
|
132
146
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rollout-ui
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- FetLife
|
|
@@ -238,6 +238,7 @@ files:
|
|
|
238
238
|
- lib/rollout/ui/views/features/partials/event_log.erb
|
|
239
239
|
- lib/rollout/ui/views/features/partials/user_pagination.erb
|
|
240
240
|
- lib/rollout/ui/views/features/partials/user_selector.erb
|
|
241
|
+
- lib/rollout/ui/views/features/partials/warning_icon.erb
|
|
241
242
|
- lib/rollout/ui/views/features/show.erb
|
|
242
243
|
- lib/rollout/ui/views/layout.erb
|
|
243
244
|
- lib/rollout/ui/web.rb
|