]>
Commit | Line | Data |
---|---|---|
33839735 | 1 | Ext.define('pbs-data-store-snapshots', { |
ca23a97f | 2 | extend: 'Ext.data.Model', |
d9c38ddc | 3 | fields: [ |
d9c38ddc | 4 | 'backup-type', |
507c39c5 DM |
5 | 'backup-id', |
6 | { | |
e8f0ad19 | 7 | name: 'backup-time', |
507c39c5 DM |
8 | type: 'date', |
9 | dateFormat: 'timestamp' | |
10 | }, | |
d9c38ddc | 11 | 'files', |
04b0ca8b | 12 | 'owner', |
e8f0ad19 | 13 | { name: 'size', type: 'int' }, |
33839735 | 14 | ] |
ca23a97f DM |
15 | }); |
16 | ||
17 | Ext.define('PBS.DataStoreContent', { | |
e8f0ad19 | 18 | extend: 'Ext.tree.Panel', |
ca23a97f DM |
19 | alias: 'widget.pbsDataStoreContent', |
20 | ||
e8f0ad19 | 21 | rootVisible: false, |
507c39c5 | 22 | |
c0ac2074 DC |
23 | title: gettext('Content'), |
24 | ||
f1baa7f4 TL |
25 | controller: { |
26 | xclass: 'Ext.app.ViewController', | |
27 | ||
28 | init: function(view) { | |
29 | if (!view.datastore) { | |
30 | throw "no datastore specified"; | |
31 | } | |
32 | ||
3f98b347 | 33 | this.store = Ext.create('Ext.data.Store', { |
33839735 | 34 | model: 'pbs-data-store-snapshots', |
e8f0ad19 DM |
35 | sorters: 'backup-group', |
36 | groupField: 'backup-group', | |
37 | }); | |
3f98b347 | 38 | this.store.on('load', this.onLoad, this); |
e8f0ad19 | 39 | |
f1baa7f4 TL |
40 | Proxmox.Utils.monStoreErrors(view, view.store, true); |
41 | this.reload(); // initial load | |
42 | }, | |
43 | ||
44 | reload: function() { | |
3f98b347 TL |
45 | let view = this.getView(); |
46 | ||
47 | if (!view.store || !this.store) { | |
48 | console.warn('cannot reload, no store(s)'); | |
49 | return; | |
50 | } | |
f1baa7f4 | 51 | |
e8f0ad19 | 52 | let url = `/api2/json/admin/datastore/${view.datastore}/snapshots`; |
3f98b347 | 53 | this.store.setProxy({ |
f1baa7f4 TL |
54 | type: 'proxmox', |
55 | url: url | |
56 | }); | |
e8f0ad19 | 57 | |
3f98b347 TL |
58 | this.store.load(); |
59 | }, | |
e8f0ad19 | 60 | |
3f98b347 TL |
61 | getRecordGroups: function(records) { |
62 | let groups = {}; | |
63 | ||
64 | for (const item of records) { | |
65 | var btype = item.data["backup-type"]; | |
66 | let group = btype + "/" + item.data["backup-id"]; | |
67 | ||
68 | if (groups[group] !== undefined) { | |
69 | continue; | |
70 | } | |
71 | ||
72 | var cls = ''; | |
73 | if (btype === 'vm') { | |
74 | cls = 'fa-desktop'; | |
75 | } else if (btype === 'ct') { | |
76 | cls = 'fa-cube'; | |
77 | } else if (btype === 'host') { | |
78 | cls = 'fa-building'; | |
79 | } else { | |
80 | console.warn(`got unkown backup-type '${btype}'`); | |
81 | continue; // FIXME: auto render? what do? | |
82 | } | |
83 | ||
84 | groups[group] = { | |
85 | text: group, | |
86 | leaf: false, | |
87 | iconCls: "fa " + cls, | |
88 | expanded: false, | |
89 | backup_type: item.data["backup-type"], | |
90 | backup_id: item.data["backup-id"], | |
91 | children: [] | |
aeee4329 | 92 | }; |
3f98b347 | 93 | } |
aeee4329 | 94 | |
3f98b347 TL |
95 | return groups; |
96 | }, | |
e8f0ad19 | 97 | |
3f98b347 TL |
98 | onLoad: function(store, records, success) { |
99 | let view = this.getView(); | |
100 | ||
101 | if (!success) { | |
102 | return; | |
103 | } | |
104 | ||
105 | let groups = this.getRecordGroups(records); | |
e8f0ad19 | 106 | |
3f98b347 TL |
107 | for (const item of records) { |
108 | let group = item.data["backup-type"] + "/" + item.data["backup-id"]; | |
109 | let children = groups[group].children; | |
110 | ||
111 | let data = item.data; | |
112 | ||
f68ae22c | 113 | data.text = group + '/' + PBS.Utils.render_datetime_utc(data["backup-time"]); |
3f98b347 TL |
114 | data.leaf = true; |
115 | data.cls = 'no-leaf-icons'; | |
116 | ||
117 | children.push(data); | |
118 | } | |
119 | ||
120 | let children = []; | |
121 | for (const [_key, group] of Object.entries(groups)) { | |
122 | let last_backup = 0; | |
123 | for (const item of group.children) { | |
124 | if (item["backup-time"] > last_backup) { | |
125 | last_backup = item["backup-time"]; | |
126 | group["backup-time"] = last_backup; | |
127 | group.files = item.files; | |
128 | group.size = item.size; | |
04b0ca8b | 129 | group.owner = item.owner; |
3f98b347 TL |
130 | } |
131 | } | |
132 | group.count = group.children.length; | |
133 | children.push(group); | |
134 | } | |
135 | ||
136 | view.setRootNode({ | |
137 | expanded: true, | |
138 | children: children | |
139 | }); | |
f1baa7f4 | 140 | }, |
5f448992 DM |
141 | |
142 | onPrune: function() { | |
143 | var view = this.getView(); | |
144 | ||
145 | let rec = view.selModel.getSelection()[0]; | |
146 | if (!(rec && rec.data)) return; | |
147 | let data = rec.data; | |
148 | if (data.leaf) return; | |
149 | ||
150 | if (!view.datastore) return; | |
151 | ||
152 | let win = Ext.create('PBS.DataStorePrune', { | |
153 | datastore: view.datastore, | |
154 | backup_type: data.backup_type, | |
155 | backup_id: data.backup_id, | |
156 | }); | |
157 | win.on('destroy', this.reload, this); | |
158 | win.show(); | |
159 | } | |
f1baa7f4 TL |
160 | }, |
161 | ||
04b0ca8b DC |
162 | columns: [ |
163 | { | |
164 | xtype: 'treecolumn', | |
165 | header: gettext("Backup Group"), | |
166 | dataIndex: 'text', | |
167 | flex: 1 | |
168 | }, | |
169 | { | |
170 | xtype: 'datecolumn', | |
171 | header: gettext('Backup Time'), | |
172 | sortable: true, | |
173 | dataIndex: 'backup-time', | |
174 | format: 'Y-m-d H:i:s', | |
175 | width: 150 | |
176 | }, | |
177 | { | |
178 | header: gettext("Size"), | |
179 | sortable: true, | |
180 | dataIndex: 'size', | |
181 | renderer: Proxmox.Utils.format_size, | |
182 | }, | |
183 | { | |
184 | xtype: 'numbercolumn', | |
185 | format: '0', | |
186 | header: gettext("Count"), | |
187 | sortable: true, | |
188 | dataIndex: 'count', | |
189 | }, | |
190 | { | |
191 | header: gettext("Owner"), | |
192 | sortable: true, | |
193 | dataIndex: 'owner', | |
194 | }, | |
195 | { | |
196 | header: gettext("Files"), | |
197 | sortable: false, | |
198 | dataIndex: 'files', | |
199 | flex: 2 | |
200 | }, | |
201 | ], | |
b1127fd0 | 202 | |
04b0ca8b DC |
203 | tbar: [ |
204 | { | |
205 | text: gettext('Reload'), | |
206 | iconCls: 'fa fa-refresh', | |
207 | handler: 'reload', | |
208 | }, | |
209 | { | |
210 | xtype: 'proxmoxButton', | |
b1127fd0 DM |
211 | text: gettext('Prune'), |
212 | disabled: true, | |
5f448992 DM |
213 | enableFn: function(record) { return !record.data.leaf; }, |
214 | handler: 'onPrune', | |
04b0ca8b DC |
215 | } |
216 | ], | |
ca23a97f | 217 | }); |