11<h1 >Feature Flags</h1 >
22 <%
33 var needs_enabling = false ;
4+ var nonreq_feature_flags = [];
45 for (var i = 0 ; i < feature_flags .length ; i++ ) {
5- var feature_flag = feature_flags[i];
6+ if (feature_flags[i].stability == ' required' )
7+ continue ;
8+ nonreq_feature_flags .push (feature_flags[i]);
9+ }
10+ for (var i = 0 ; i < nonreq_feature_flags .length ; i++ ) {
11+ var feature_flag = nonreq_feature_flags[i];
612 if (feature_flag .state == " disabled" && feature_flag .stability != " experimental" ) {
713 needs_enabling = true ;
814 }
1521<div class =" section" >
1622 <h2 >Feature Flags</h2 >
1723 <div class =" hider" >
18- <%= filter_ui (feature_flags ) %>
24+ <%= filter_ui (nonreq_feature_flags ) %>
1925 <div class =" updatable" >
20- <% if (feature_flags .length > 0 ) { % >
26+ <% if (nonreq_feature_flags .length > 0 ) { % >
27+ < %
28+ function fmt_feature_flag (feature_flag ) {
29+ var output = ' {' ;
30+ for (const [key , value ] of Object .entries (feature_flag)) {
31+ output += fmt_string (key) + ' : "' + fmt_string (value) + ' ", ' ;
32+ }
33+ output += ' }' ;
34+ return output;
35+ }
36+ % >
37+
38+ < script>
39+ function handle_feature_flag (checkbox , feature_flag ) {
40+ console .log (checkbox, feature_flag);
41+
42+ if (feature_flag .stability == ' experimental' ) {
43+ var dialog = document .getElementById (" ff-exp-dialog" );
44+ var name_placeholders = document .querySelectorAll (" #ff-exp-dialog .ff-name" );
45+ var confirm_button = document .querySelector (" #ff-exp-dialog button" );
46+
47+ /* Fill name placeholders with the feature flag name. */
48+ name_placeholders .forEach (function (name_placeholder ) {
49+ name_placeholder .innerText = feature_flag .name ;
50+ });
51+
52+ confirm_button .addEventListener (" click" , () => {
53+ dialog .close ();
54+ enable_feature_flag (feature_flag);
55+ });
56+
57+ dialog .showModal ();
58+ } else {
59+ enable_feature_flag (feature_flag);
60+ }
61+ }
62+
63+ function enable_feature_flag (feature_flag ) {
64+ console .log (' Enable' , feature_flag);
65+
66+ var name_field = document .getElementById (' ff-enable-form-name' );
67+ name_field .value = feature_flag .name ;
68+
69+ var form = document .getElementById (' ff-enable-form' );
70+ console .log (form);
71+ form .requestSubmit ();
72+ }
73+ < / script>
74+
2175< table class = " list" >
2276 < thead>
2377 < tr>
2882 < / thead>
2983 < tbody>
3084 < %
31- for (var i = 0 ; i < feature_flags .length ; i++ ) {
32- var feature_flag = feature_flags[i];
33- if (feature_flag .stability == " required" ) {
34- /* Hide required feature flags. There is nothing the user can do
35- * about them and they just add noise to the UI. */
36- continue ;
37- }
85+ for (var i = 0 ; i < nonreq_feature_flags .length ; i++ ) {
86+ var feature_flag = nonreq_feature_flags[i];
3887 if (feature_flag .stability == " experimental" ) {
39- continue ;
88+ /* Experimental feature flags are displayed in a separate table. */
89+ // continue;
4090 }
4191 var state_color = " grey" ;
4292 if (feature_flag .state == " enabled" ) {
4999 % >
50100 < tr< %= alt_rows (i)% >>
51101 < td>< %= fmt_string (feature_flag .name ) % >< / td>
52- < td class = " c" >
53- < % if (feature_flag .stability == " experimental" ) { % >
54- < span> Experimental< / span>
55- < % } else if (feature_flag .stability == " stable" && feature_flag .state == " disabled" ) { % >
56- < p>< span> & #9888 ;< / span> Disabled! < / p>
57- < % } % >
58- < % if (feature_flag .state == " disabled" ) { % >
59- < form action= " #/feature-flags-enable" method= " put" style= " display: inline-block" class = " enable-feature-flag" >
60- < input type= " hidden" name= " name" value= " <%= fmt_string(feature_flag.name) %>" / >
61- < input type= " submit" value= " Enable" class = " c" / >
62- < / form>
63- < % } else { % >
64- < abbr class = " status-<%= fmt_string(state_color) %>"
65- style= " text-transform: capitalize"
66- title= " Feature flag state: <%= fmt_string(feature_flag.state) %>" >
67- < %= fmt_string (feature_flag .state ) % >
68- < / abbr>
69- < % } % >
102+ < td class = " c ff-stability-<%= feature_flag.stability %> ff-state-<%= feature_flag.state %>" >
103+ < input type= " checkbox" class = " toggle"
104+ onchange= ' handle_feature_flag(
105+ this,
106+ <%= fmt_feature_flag(feature_flag) %>);' / >
70107 < / td>
71108 < td>
72109 < p>< %= fmt_string (feature_flag .desc ) % >< / p>
78115 < % } % >
79116 < / tbody>
80117< / table>
118+ < dialog id= " ff-exp-dialog" >
119+ < h1> Enabling an experimental feature flag< / h1>
120+ < p>
121+ The < span class = " ff-name" >< / span> feature flag is experimental!
122+ < button> Enable < span class = " ff-name" >< / span>< / button>
123+ < / p>
124+ < / dialog>
125+ < form id= " ff-enable-form" action= " #/feature-flags-enable" method= " put" >
126+ < input id= " ff-enable-form-name" type= " hidden" name= " name" / >
127+ < / form>
81128< % } else { % >
82129 < p> ... no feature_flags ... < / p>
83130< % } %>
90137<div class =" section" >
91138 <h2 >Opt-in Feature Flags</h2 >
92139 <div class =" hider" >
93- <% if (feature_flags .length > 0 ) { % >
140+ <% if (nonreq_feature_flags .length > 0 ) { % >
94141< p class = " warning" >
95142These feature flags opt- in .
96143
@@ -106,8 +153,8 @@ These flags can be enabled in production deployments after an appropriate amount
106153 < / thead>
107154 < tbody>
108155 < %
109- for (var i = 0 ; i < feature_flags .length ; i++ ) {
110- var feature_flag = feature_flags [i];
156+ for (var i = 0 ; i < nonreq_feature_flags .length ; i++ ) {
157+ var feature_flag = nonreq_feature_flags [i];
111158 if (feature_flag .stability != " experimental" ) {
112159 continue ;
113160 }
0 commit comments