Merge pull request #1801 from dibdot/adblock
[project/luci.git] / modules / luci-base / luasrc / view / cbi / apply_widget.htm
1 <% export("cbi_apply_widget", function(redirect_ok) -%>
2 <style type="text/css">
3         #cbi_apply_status {
4                 display: flex;
5                 flex-wrap: wrap;
6                 min-height: 32px;
7                 align-items: center;
8                 margin: 1.5em 0 1.5em 0;
9         }
10
11         #cbi_apply_status > h4,
12         #cbi_apply_status > p,
13         #cbi_apply_status > div {
14                 flex-basis: 100%;
15         }
16
17         #cbi_apply_status > img {
18                 margin-right: 1em;
19                 flex-basis: 32px;
20         }
21
22         #cbi_apply_status + script + .cbi-section {
23                 margin-top: -1em;
24         }
25
26         .alert-message.notice {
27                 background: linear-gradient(#fff 0%, #eee 100%);
28         }
29 </style>
30
31 <script type="text/javascript" src="<%=resource%>/cbi.js"></script>
32 <script type="text/javascript">//<![CDATA[
33         var xhr = new XHR(),
34             stat, indicator,
35             uci_apply_auth = { sid: '<%=luci.dispatcher.context.authsession%>', token: '<%=token%>' },
36             uci_apply_rollback = <%=math.max(luci.config and luci.config.apply and luci.config.apply.rollback or 30, 30)%>,
37             uci_apply_holdoff = <%=math.max(luci.config and luci.config.apply and luci.config.apply.holdoff or 4, 1)%>,
38             uci_apply_timeout = <%=math.max(luci.config and luci.config.apply and luci.config.apply.timeout or 5, 1)%>,
39             uci_apply_display = <%=math.max(luci.config and luci.config.apply and luci.config.apply.display or 1.5, 1)%>;
40
41         function uci_rollback(checked) {
42                 if (checked) {
43                         stat.classList.remove('notice');
44                         stat.classList.add('warning');
45                         stat.innerHTML = '<img src="<%=resource%>/icons/loading.gif" alt="" style="vertical-align:middle" /> ' +
46                                          '<%:Failed to confirm apply within %ds, waiting for rollback…%>'.format(uci_apply_rollback);
47
48                         var call = function(r) {
49                                 if (r.status === 204) {
50                                         stat.innerHTML = '<h4><%:Configuration has been rolled back!%></h4>' +
51                                                 '<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) +
52                                                 '<div class="right">' +
53                                                         '<input type="button" class="btn" onclick="this.parentNode.parentNode.style.display=\'none\'" value="<%:Dismiss%>" /> ' +
54                                                         '<input type="button" class="btn" onclick="uci_revert()" value="<%:Revert changes%>" /> ' +
55                                                         '<input type="button" class="btn danger" onclick="uci_apply(false)" value="<%:Apply unchecked%>" />' +
56                                                 '</div>';
57
58                                         return;
59                                 }
60
61                                 xhr.post('<%=url("admin/uci/confirm")%>', uci_apply_auth, call, uci_apply_timeout * 1000);
62                         };
63
64                         call({ status: 0 });
65                 }
66                 else {
67                         stat.classList.remove('notice');
68                         stat.classList.add('warning');
69                         stat.innerHTML = '<h4><%:Device unreachable!%></h4>' +
70                                 '<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>';
71                 }
72         }
73
74         function uci_confirm(checked, deadline) {
75                 var tt;
76                 var ts = Date.now();
77
78                 stat = document.getElementById('cbi_apply_status');
79                 stat.style.display = '';
80                 stat.classList.remove('warning');
81                 stat.classList.add('notice');
82
83                 indicator = document.querySelector('.uci_change_indicator');
84
85                 var call = function(r) {
86                         if (Date.now() >= deadline) {
87                                 uci_rollback(checked);
88                                 return;
89                         }
90                         else if (r && (r.status === 200 || r.status === 204)) {
91                                 if (indicator)
92                                         indicator.style.display = 'none';
93
94                                 stat.innerHTML = '<%:Configuration has been applied.%>';
95
96                                 window.clearTimeout(tt);
97                                 window.setTimeout(function() {
98                                         stat.style.display = 'none';
99                                         <% if redirect_ok then %>location.href = decodeURIComponent('<%=luci.util.urlencode(redirect_ok)%>');<% end %>
100                                 }, uci_apply_display * 1000);
101
102                                 return;
103                         }
104
105                         xhr.post('<%=url("admin/uci/confirm")%>', uci_apply_auth, call, uci_apply_timeout * 1000);
106                 };
107
108                 var tick = function() {
109                         var now = Date.now();
110
111                         stat.innerHTML = '<img src="<%=resource%>/icons/loading.gif" alt="" style="vertical-align:middle" /> ' +
112                                          '<%:Waiting for configuration to get applied… %ds%>'.format(Math.max(Math.floor((deadline - Date.now()) / 1000), 0));
113
114                         if (now >= deadline)
115                                 return;
116
117                         tt = window.setTimeout(tick, 1000 - (now - ts));
118                         ts = now;
119                 };
120
121                 tick();
122
123                 /* wait a few seconds for the settings to become effective */
124                 window.setTimeout(call, Math.max(uci_apply_holdoff * 1000 - ((ts + uci_apply_rollback * 1000) - deadline), 1));
125         }
126
127         function uci_apply(checked) {
128                 stat = document.getElementById('cbi_apply_status');
129                 stat.style.display = '';
130                 stat.classList.remove('warning');
131                 stat.classList.add('notice');
132                 stat.innerHTML = '<img src="<%=resource%>/icons/loading.gif" alt="" style="vertical-align:middle" /> ' +
133                                  '<%:Starting configuration apply…%>';
134
135                 xhr.post('<%=url("admin/uci")%>/' + (checked ? 'apply_rollback' : 'apply_unchecked'), uci_apply_auth, function(r) {
136                         if (r.status === (checked ? 200 : 204)) {
137                                 uci_confirm(checked, Date.now() + uci_apply_rollback * 1000);
138                         }
139                         else if (checked && r.status === 204) {
140                                 stat.innerHTML = '<%:There are no changes to apply.%>';
141                                 window.setTimeout(function() {
142                                         stat.style.display = 'none';
143                                         <% if redirect_ok then %>location.href = decodeURIComponent('<%=luci.util.urlencode(redirect_ok)%>');<% end %>
144                                 }, uci_apply_display * 1000);
145                         }
146                         else {
147                                 stat.classList.add('warning');
148                                 stat.classList.remove('notice');
149                                 stat.innerHTML = '<%_Apply request failed with status <code>%h</code>%>'.format(r.responseText || r.statusText || r.status);
150                         }
151                 });
152         }
153
154         function uci_revert() {
155                 stat = document.getElementById('cbi_apply_status');
156                 stat.style.display = '';
157                 stat.classList.remove('warning');
158                 stat.classList.add('notice');
159                 stat.innerHTML = '<img src="<%=resource%>/icons/loading.gif" alt="" style="vertical-align:middle" /> ' +
160                                  '<%:Reverting configuration…%>';
161
162                 xhr.post('<%=url("admin/uci/revert")%>', uci_apply_auth, function(r) {
163                         if (r.status === 200) {
164                                 stat.innerHTML = '<%:Changes have been reverted.%>';
165                                 window.setTimeout(function() {
166                                         <% if redirect_ok then -%>
167                                                 location.href = decodeURIComponent('<%=luci.util.urlencode(redirect_ok)%>');
168                                         <%- else -%>
169                                                 window.location = window.location.href.split('#')[0];
170                                         <%- end %>
171                                 }, uci_apply_display * 1000);
172                         }
173                         else {
174                                 stat.classList.add('warning');
175                                 stat.classList.remove('notice');
176                                 stat.innerHTML = '<%_Revert request failed with status <code>%h</code>%>'.format(r.statusText || r.status);
177                         }
178                 });
179         }
180 //]]></script>
181 <%-     end) %>