luci2: implement LuCI2.session.updateACLs() and LuCI2.session.hasACL()
[project/luci2/ui.git] / luci2 / htdocs / luci2 / view / system.software.js
1 L.ui.view.extend({
2         title: L.tr('Package management'),
3
4         updateDiskSpace: function()
5         {
6                 return L.system.getDiskInfo().then(function(info) {
7                         $('#package_space').empty().append(
8                                 new L.ui.progress({
9                                         value:  info.root.used / 1024,
10                                         max:    info.root.total / 1024,
11                                         format: '%d ' + L.tr('kB') + ' / %d ' + L.tr('kB') + ' ' + L.trc('Used disk space', 'used') + ' (%d%%)'
12                                 }).render());
13                 });
14         },
15
16         installRemovePackage: function(pkgname, installed)
17         {
18                 var dspname   = pkgname.replace(/^.+\//, '');
19                 var action    = installed ? L.opkg.removePackage : L.opkg.installPackage;
20                 var title     = (installed ? L.tr('Removing package "%s" …') : L.tr('Installing package "%s" …')).format(dspname);
21                 var confirm   = (installed ? L.tr('Really remove package "%h" ?') : L.tr('Really install package "%h" ?')).format(dspname);
22
23                 var self = this;
24
25                 L.ui.dialog(title, confirm, {
26                         style:   'confirm',
27                         confirm: function() {
28                                 L.ui.dialog(title, L.tr('Waiting for package manager …'), { style: 'wait' });
29
30                                 action(pkgname).then(function(res) {
31                                         self.fetchInstalledList().then(function() { return self.fetchPackageList(); }).then(function() {
32                                                 var output = [ ];
33
34                                                 if (res.stdout)
35                                                         output.push($('<pre />').text(res.stdout));
36
37                                                 if (res.stderr)
38                                                         output.push($('<pre />').addClass('alert-message').text(res.stderr));
39
40                                                 output.push(res.code ? L.tr('Package manager failed with status %d.').format(res.code) : L.tr('Package manager finished successfully.'));
41
42                                                 L.ui.dialog(title, output, { style: 'close' });
43
44                                                 if (name)
45                                                         $('#package_url').val('');
46                                         });
47                                 });
48                         }
49                 });
50         },
51
52         fetchInstalledList: function()
53         {
54                 var self = this;
55                 return L.opkg.installedPackages(0, 0, '*').then(function(list) {
56                         self.installedList = { };
57                         for (var i = 0; i < list.length; i++)
58                                 self.installedList[list[i][0]] = true;
59                 });
60         },
61
62         fetchPackageList: function(offset, interactive)
63         {
64                 if (interactive)
65                         L.ui.loading(true);
66
67                 if (typeof(offset) == 'undefined')
68                         offset = parseInt($('#package_filter').attr('offset')) || 0;
69
70                 var pattern = $('#package_filter').val() || '';
71                 var action;
72
73                 if (pattern.length)
74                 {
75                         action = $('#package_which').prop('checked') ? L.opkg.installedPackages : L.opkg.findPackages;
76                         pattern = '*' + pattern + '*';
77
78                         $('#package_filter').next().attr('src', L.globals.resource + '/icons/cbi/remove.gif');
79                 }
80                 else
81                 {
82                         action = $('#package_which').prop('checked') ? L.opkg.installedPackages : L.opkg.listPackages;
83                         pattern = '*';
84
85                         $('#package_filter').next().attr('src', L.globals.resource + '/icons/cbi/find.gif');
86                 }
87
88                 $('#package_filter').attr('offset', offset);
89
90                 var install_disabled = $('#package_install').attr('disabled');
91                 var self = this;
92
93                 return action(offset, 100, pattern).then(function(list) {
94                         var packageTable = new L.ui.table({
95                                 placeholder: L.tr('No matching packages found.'),
96                                 columns: [ {
97                                         caption: L.trc('Package table header', 'Package'),
98                                         key:     0
99                                 }, {
100                                         caption: L.trc('Package table header', 'Version'),
101                                         key:     1,
102                                         format:  function(v) {
103                                                 return (v.length > 15 ? v.substring(0, 14) + '…' : v);
104                                         }
105                                 }, {
106                                         caption: L.trc('Package table header', 'Description'),
107                                         key:     2
108                                 }, {
109                                         caption: L.trc('Package table header', 'Installation Status'),
110                                         key:     0,
111                                         width:   '120px',
112                                         format: function(v, n) {
113                                                 var inst = self.installedList[list[n][0]];
114                                                 return L.ui.button(inst ? L.trc('Package state', 'Installed') : L.trc('Package state', 'Not installed'), inst ? 'success' : 'danger')
115                                                         .css('width', '100%')
116                                                         .attr('disabled', install_disabled)
117                                                         .attr('pkgname', list[n][0])
118                                                         .attr('installed', inst)
119                                                         .click(function() {
120                                                                 self.installRemovePackage(this.getAttribute('pkgname'), this.getAttribute('installed') == 'true');
121                                                         });
122                                         }
123                                 } ]
124                         });
125
126                         packageTable.rows(list);
127                         packageTable.insertInto('#package_table');
128
129                         if (offset > 0)
130                                 $('#package_prev')
131                                         .attr('offset', offset - 100)
132                                         .attr('disabled', false)
133                                         .text('« %d - %d'.format(offset - 100 + 1, offset));
134                         else
135                                 $('#package_prev')
136                                         .attr('disabled', true)
137                                         .text('« %d - %d'.format(1, Math.min(100, list.total)));
138
139                         if ((offset + 100) < list.total)
140                                 $('#package_next')
141                                         .attr('offset', offset + 100)
142                                         .attr('disabled', false)
143                                         .text('%d - %d »'.format(offset + 100 + 1, Math.min(offset + 200, list.total)));
144                         else
145                                 $('#package_next')
146                                         .attr('disabled', true)
147                                         .text('%d - %d »'.format(list.total - (list.total % 100) + 1, list.total));
148
149                         if (interactive)
150                                 L.ui.loading(false);
151                 }).then(self.updateDiskSpace);
152         },
153
154         execute: function()
155         {
156                 var self = this;
157
158                 $('textarea, input.cbi-button-save').attr('disabled', !this.options.acls.software);
159                 $('#package_update, #package_url, #package_install').attr('disabled', !this.options.acls.software);
160
161                 return $.when(
162                         L.opkg.getConfig().then(function(config) {
163                                 $('#config textarea')
164                                         .attr('rows', (config.match(/\n/g) || [ ]).length + 1)
165                                         .val(config);
166
167                                 $('#config button')
168                                         .click(function() {
169                                                 var data = ($('#config textarea').val() || '').replace(/\r/g, '').replace(/\n?$/, '\n');
170                                                 L.ui.loading(true);
171                                                 L.opkg.setConfig(data).then(function() {
172                                                         $('#config textarea')
173                                                                 .attr('rows', (data.match(/\n/g) || [ ]).length + 1)
174                                                                 .val(data);
175
176                                                         L.ui.loading(false);
177                                                 });
178                                         });
179                         }),
180                         self.fetchInstalledList(),
181                         self.updateDiskSpace()
182                 ).then(function() {
183                         $('#package_prev, #package_next').click(function(ev) {
184                                 if (!this.getAttribute('disabled'))
185                                 {
186                                         self.fetchPackageList(parseInt(this.getAttribute('offset')), true);
187                                         this.blur();
188                                 }
189                         });
190
191                         $('#package_filter').next().click(function(ev) {
192                                 $('#package_filter').val('');
193                                 self.fetchPackageList(0, true);
194                         });
195
196                         $('#package_filter').keyup(function(ev) {
197                                 if (ev.which != 13)
198                                         return true;
199
200                                 ev.preventDefault();
201                                 self.fetchPackageList(0, true);
202                                 return false;
203                         });
204
205                         $('#package_which').click(function(ev) {
206                                 this.blur();
207                                 self.fetchPackageList(0, true);
208                         });
209
210                         $('#package_url').keyup(function(ev) {
211                                 if (ev.which != 13)
212                                         return true;
213
214                                 ev.preventDefault();
215
216                                 if (this.value)
217                                         self.installRemovePackage(this.value, false);
218                         });
219
220                         $('#package_install').click(function(ev) {
221                                 var name = $('#package_url').val();
222                                 if (name)
223                                         self.installRemovePackage(name, false);
224                         });
225
226                         $('#package_update').click(function(ev) {
227                                 L.ui.dialog(L.tr('Updating package lists'), L.tr('Waiting for package manager …'), { style: 'wait' });
228                                 L.opkg.updateLists().then(function(res) {
229                                         var output = [ ];
230
231                                         if (res.stdout)
232                                                 output.push($('<pre />').text(res.stdout));
233
234                                         if (res.stderr)
235                                                 output.push($('<pre />').addClass('alert-message').text(res.stderr));
236
237                                         output.push(res.code ? L.tr('Package manager failed with status %d.').format(res.code) : L.tr('Package manager finished successfully.'));
238
239                                         L.ui.dialog(L.tr('Updating package lists'), output, { style: 'close' });
240                                 });
241                         });
242
243                         return self.fetchPackageList(0);
244                 });
245         }
246 });