1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
'use strict';
'require baseclass';
'require fs';
'require uci';
const SLOTS = [ 'cards', 'charts', 'tabs' ];
return baseclass.extend({
slots: SLOTS,
load() {
return L.resolveDefault(fs.list('/www' + L.resource('view/dashboard/include')), []).then(entries => {
return Promise.all(entries.filter(e => {
return (e.type == 'file' && e.name.match(/\.js$/));
}).map(e => {
return 'view.dashboard.include.' + e.name.replace(/\.js$/, '');
}).sort().map(n => {
return L.require(n);
}));
}).then(includes => {
return Promise.all(includes.map(include => new Promise(resolve => {
resolve((typeof(include.available) == 'function') ? include.available() : true);
}).catch(e => {
console.error(e);
return false;
}))).then(flags => includes.filter((include, i) => flags[i]));
});
},
list(includes, slot) {
return includes.reduce((list, include) => list.concat(include.widgets || []), [])
.filter(widget => widget.slot == slot)
.sort((a, b) => (a.order || 0) - (b.order || 0));
},
defaults(includes, slot) {
return this.list(includes, slot).filter(widget => !widget.hidden).map(widget => widget.id);
},
// The ids to show in each slot, in display order. A slot that is not
// configured shows its defaults: UCI cannot store an empty list, so
// emptying one brings them back. Ids this device does not know, from
// a restored config or typed by hand, are ignored.
layout(includes) {
const layout = {};
return L.resolveDefault(uci.load('dashboard')).then(() => {
SLOTS.forEach(slot => {
const known = this.list(includes, slot).map(widget => widget.id);
const ids = L.toArray(uci.get('dashboard', 'layout', slot)).filter((id, i, list) => {
return known.includes(id) && list.indexOf(id) == i;
});
layout[slot] = ids.length ? ids : this.defaults(includes, slot);
});
return layout;
});
}
});
|