1 <% export(
"cbi_apply_widget", function(redirect_ok, rollback_token) -%
>
2 <style type=
"text/css">
9 background: rgba(
0,
0,
0,
0.7);
14 #cbi_apply_overlay .alert-message {
25 #cbi_apply_overlay .alert-message
> h4,
26 #cbi_apply_overlay .alert-message
> p,
27 #cbi_apply_overlay .alert-message
> div {
31 #cbi_apply_overlay .alert-message
> img {
36 body.apply-overlay-active {
41 body.apply-overlay-active #cbi_apply_overlay {
46 <script type=
"text/javascript" src=
"<%=resource%>/cbi.js?v=git-18.138.59467-72fe5dd"></script>
47 <script type=
"text/javascript">//<![CDATA[
49 uci_apply_auth = { sid: '<%=luci.dispatcher.context.authsession%
>', token: '<%=token%
>' },
50 uci_apply_rollback = <%=math.max(luci.config and luci.config.apply and luci.config.apply.rollback or
30,
30)%
>,
51 uci_apply_holdoff = <%=math.max(luci.config and luci.config.apply and luci.config.apply.holdoff or
4,
1)%
>,
52 uci_apply_timeout = <%=math.max(luci.config and luci.config.apply and luci.config.apply.timeout or
5,
1)%
>,
53 uci_apply_display = <%=math.max(luci.config and luci.config.apply and luci.config.apply.display or
1.5,
1)%
>,
54 uci_confirm_auth = <% if rollback_token then %
>{ token: '<%=rollback_token%
>' }<% else %
>null<% end %
>,
55 was_xhr_poll_running = false;
57 function uci_status_message(type, content) {
58 var overlay = document.getElementById('cbi_apply_overlay') || document.body.appendChild(E('
<div id=
"cbi_apply_overlay"><div class=
"alert-message"></div></div>')),
59 message = overlay.querySelector('.alert-message');
61 if (message && type) {
62 if (!message.classList.contains(type)) {
63 message.classList.remove('notice');
64 message.classList.remove('warning');
65 message.classList.add(type);
69 message.innerHTML = content;
71 document.body.classList.add('apply-overlay-active');
73 if (!was_xhr_poll_running) {
74 was_xhr_poll_running = XHR.running();
79 document.body.classList.remove('apply-overlay-active');
81 if (was_xhr_poll_running)
86 function uci_rollback(checked) {
88 uci_status_message('warning',
89 '
<img src=
"<%=resource%>/icons/loading.gif" alt=
"" style=
"vertical-align:middle" /> ' +
90 '<%:Failed to confirm apply within %ds, waiting for rollback…%
>'.format(uci_apply_rollback));
92 var call = function(r, data, duration) {
93 if (r.status ===
204) {
94 uci_status_message('warning',
95 '
<h4><%:Configuration has been rolled back!%
></h4>' +
96 '
<p><%:The device could not be reached within %d seconds after applying the pending changes, which caused the configuration to be rolled back for safety reasons. If you believe that the configuration changes are correct nonetheless, perform an unchecked configuration apply. Alternatively, you can dismiss this warning and edit changes before attempting to apply again, or revert all pending changes to keep the currently working configuration state.%
></p>'.format(uci_apply_rollback) +
97 '
<div class=
"right">' +
98 '
<input type=
"button" class=
"btn" onclick=
"uci_status_message(false)" value=
"<%:Dismiss%>" /> ' +
99 '
<input type=
"button" class=
"btn cbi-button-action important" onclick=
"uci_revert()" value=
"<%:Revert changes%>" /> ' +
100 '
<input type=
"button" class=
"btn cbi-button-negative important" onclick=
"uci_apply(false)" value=
"<%:Apply unchecked%>" />' +
106 var delay = isNaN(duration) ?
0 : Math.max(
1000 - duration,
0);
107 window.setTimeout(function() {
108 xhr.post('<%=url(
"admin/uci/confirm")%
>', uci_apply_auth, call, uci_apply_timeout *
1000);
115 uci_status_message('warning',
116 '
<h4><%:Device unreachable!%
></h4>' +
117 '
<p><%:Could not regain access to the device after applying the configuration changes. You might need to reconnect if you modified network related settings such as the IP address or wireless security credentials.%
></p>');
121 function uci_confirm(checked, deadline) {
125 uci_status_message('notice');
127 var call = function(r, data, duration) {
128 if (Date.now()
>= deadline) {
129 uci_rollback(checked);
132 else if (r && (r.status ===
200 || r.status ===
204)) {
133 var indicator = document.querySelector('.uci_change_indicator');
134 if (indicator) indicator.style.display = 'none';
136 uci_status_message('notice', '<%:Configuration has been applied.%
>');
138 window.clearTimeout(tt);
139 window.setTimeout(function() {
140 <% if redirect_ok then -%
>
141 location.href = decodeURIComponent('<%=luci.util.urlencode(redirect_ok)%
>');
143 window.location = window.location.href.split('#')[
0];
145 }, uci_apply_display *
1000);
150 var delay = isNaN(duration) ?
0 : Math.max(
1000 - duration,
0);
151 window.setTimeout(function() {
152 xhr.post('<%=url(
"admin/uci/confirm")%
>', uci_confirm_auth, call, uci_apply_timeout *
1000);
156 var tick = function() {
157 var now = Date.now();
159 uci_status_message('notice',
160 '
<img src=
"<%=resource%>/icons/loading.gif" alt=
"" style=
"vertical-align:middle" /> ' +
161 '<%:Waiting for configuration to get applied… %ds%
>'.format(Math.max(Math.floor((deadline - Date.now()) /
1000),
0)));
166 tt = window.setTimeout(tick,
1000 - (now - ts));
172 /* wait a few seconds for the settings to become effective */
173 window.setTimeout(call, Math.max(uci_apply_holdoff *
1000 - ((ts + uci_apply_rollback *
1000) - deadline),
1));
176 function uci_apply(checked) {
177 uci_status_message('notice',
178 '
<img src=
"<%=resource%>/icons/loading.gif" alt=
"" style=
"vertical-align:middle" /> ' +
179 '<%:Starting configuration apply…%
>');
181 xhr.post('<%=url(
"admin/uci")%
>/' + (checked ? 'apply_rollback' : 'apply_unchecked'), uci_apply_auth, function(r, tok) {
182 if (r.status === (checked ?
200 :
204)) {
183 if (checked && tok !== null && typeof(tok) === 'object' && typeof(tok.token) === 'string')
184 uci_confirm_auth = tok;
186 uci_confirm(checked, Date.now() + uci_apply_rollback *
1000);
188 else if (checked && r.status ===
204) {
189 uci_status_message('notice', '<%:There are no changes to apply.%
>');
190 window.setTimeout(function() {
191 <% if redirect_ok then -%
>
192 location.href = decodeURIComponent('<%=luci.util.urlencode(redirect_ok)%
>');
194 uci_status_message(false);
196 }, uci_apply_display *
1000);
199 uci_status_message('warning', '<%_Apply request failed with status
<code>%h
</code>%
>'.format(r.responseText || r.statusText || r.status));
200 window.setTimeout(function() { uci_status_message(false); }, uci_apply_display *
1000);
205 function uci_revert() {
206 uci_status_message('notice',
207 '
<img src=
"<%=resource%>/icons/loading.gif" alt=
"" style=
"vertical-align:middle" /> ' +
208 '<%:Reverting configuration…%
>');
210 xhr.post('<%=url(
"admin/uci/revert")%
>', uci_apply_auth, function(r) {
211 if (r.status ===
200) {
212 uci_status_message('notice', '<%:Changes have been reverted.%
>');
213 window.setTimeout(function() {
214 <% if redirect_ok then -%
>
215 location.href = decodeURIComponent('<%=luci.util.urlencode(redirect_ok)%
>');
217 window.location = window.location.href.split('#')[
0];
219 }, uci_apply_display *
1000);
222 uci_status_message('warning', '<%_Revert request failed with status
<code>%h
</code>%
>'.format(r.statusText || r.status));
223 window.setTimeout(function() { uci_status_message(false); }, uci_apply_display *
1000);