]>
git.proxmox.com Git - proxmox-backup.git/blob - www/DataStoreContent.js
1 Ext
.define('pbs-data-store-snapshots', {
2 extend
: 'Ext.data.Model',
9 dateFormat
: 'timestamp'
13 { name
: 'size', type
: 'int' },
17 calculate: function(data
) {
20 data
.files
.forEach(file
=> {
21 if (file
.filename
=== 'index.json.blob') return; // is never encrypted
28 if (encrypted
=== 0) {
30 } else if (encrypted
< files
) {
40 Ext
.define('PBS.DataStoreContent', {
41 extend
: 'Ext.tree.Panel',
42 alias
: 'widget.pbsDataStoreContent',
46 title
: gettext('Content'),
49 xclass
: 'Ext.app.ViewController',
51 init: function(view
) {
52 if (!view
.datastore
) {
53 throw "no datastore specified";
56 this.store
= Ext
.create('Ext.data.Store', {
57 model
: 'pbs-data-store-snapshots',
58 groupField
: 'backup-group',
60 this.store
.on('load', this.onLoad
, this);
62 view
.getStore().setSorters([
67 Proxmox
.Utils
.monStoreErrors(view
, this.store
);
68 this.reload(); // initial load
72 let view
= this.getView();
74 if (!view
.store
|| !this.store
) {
75 console
.warn('cannot reload, no store(s)');
79 let url
= `/api2/json/admin/datastore/${view.datastore}/snapshots`;
88 getRecordGroups: function(records
) {
91 for (const item
of records
) {
92 var btype
= item
.data
["backup-type"];
93 let group
= btype
+ "/" + item
.data
["backup-id"];
95 if (groups
[group
] !== undefined) {
100 if (btype
=== 'vm') {
102 } else if (btype
=== 'ct') {
104 } else if (btype
=== 'host') {
107 console
.warn(`got unknown backup-type '${btype}'`);
108 continue; // FIXME: auto render? what do?
114 iconCls
: "fa " + cls
,
116 backup_type
: item
.data
["backup-type"],
117 backup_id
: item
.data
["backup-id"],
125 onLoad: function(store
, records
, success
, operation
) {
126 let view
= this.getView();
129 Proxmox
.Utils
.setErrorMask(view
, Proxmox
.Utils
.getResponseErrorMessage(operation
.getError()));
133 let groups
= this.getRecordGroups(records
);
135 for (const item
of records
) {
136 let group
= item
.data
["backup-type"] + "/" + item
.data
["backup-id"];
137 let children
= groups
[group
].children
;
139 let data
= item
.data
;
141 data
.text
= group
+ '/' + PBS
.Utils
.render_datetime_utc(data
["backup-time"]);
143 data
.cls
= 'no-leaf-icons';
149 for (const [_key
, group
] of Object
.entries(groups
)) {
152 for (const item
of group
.children
) {
153 if (item
.encrypted
> 0) {
156 if (item
["backup-time"] > last_backup
) {
157 last_backup
= item
["backup-time"];
158 group
["backup-time"] = last_backup
;
159 group
.files
= item
.files
;
160 group
.size
= item
.size
;
161 group
.owner
= item
.owner
;
165 if (encrypted
=== 0) {
167 } else if (encrypted
< group
.children
.length
) {
172 group
.count
= group
.children
.length
;
173 children
.push(group
);
180 Proxmox
.Utils
.setErrorMask(view
, false);
183 onPrune: function() {
184 var view
= this.getView();
186 let rec
= view
.selModel
.getSelection()[0];
187 if (!(rec
&& rec
.data
)) return;
189 if (data
.leaf
) return;
191 if (!view
.datastore
) return;
193 let win
= Ext
.create('PBS.DataStorePrune', {
194 datastore
: view
.datastore
,
195 backup_type
: data
.backup_type
,
196 backup_id
: data
.backup_id
,
198 win
.on('destroy', this.reload
, this);
202 openBackupFileDownloader: function() {
204 let view
= me
.getView();
206 let rec
= view
.selModel
.getSelection()[0];
207 if (!(rec
&& rec
.data
)) return;
210 Ext
.create('PBS.window.BackupFileDownloader', {
211 baseurl
: `/api2/json/admin/datastore/${view.datastore}`,
213 'backup-id': data
['backup-id'],
214 'backup-type': data
['backup-type'],
215 'backup-time': (data
['backup-time'].getTime()/1000).toFixed(0),
221 openPxarBrowser: function() {
223 let view
= me
.getView();
225 let rec
= view
.selModel
.getSelection()[0];
226 if (!(rec
&& rec
.data
)) return;
229 let encrypted
= false;
230 data
.files
.forEach(file
=> {
231 if (file
.filename
=== 'catalog.pcat1.didx' && file
.encrypted
) {
238 gettext('Cannot open Catalog'),
239 gettext('Only unencrypted Backups can be opened on the server. Please use the client with the decryption key instead.'),
244 let id
= data
['backup-id'];
245 let time
= data
['backup-time'];
246 let type
= data
['backup-type'];
247 let timetext
= PBS
.Utils
.render_datetime_utc(data
["backup-time"]);
249 Ext
.create('PBS.window.FileBrowser', {
250 title
: `${type}/${id}/${timetext}`,
251 datastore
: view
.datastore
,
253 'backup-time': (time
.getTime()/1000).toFixed(0),
262 header
: gettext("Backup Group"),
268 header
: gettext('Backup Time'),
270 dataIndex
: 'backup-time',
271 format
: 'Y-m-d H:i:s',
275 header
: gettext("Size"),
278 renderer
: Proxmox
.Utils
.format_size
,
281 xtype
: 'numbercolumn',
283 header
: gettext("Count"),
288 header
: gettext("Owner"),
293 header
: gettext('Encrypted'),
294 dataIndex
: 'encrypted',
295 renderer: function(value
) {
297 case 0: return Proxmox
.Utils
.noText
;
298 case 1: return gettext('Mixed');
299 case 2: return Proxmox
.Utils
.yesText
;
300 default: Proxmox
.Utils
.unknownText
;
305 header
: gettext("Files"),
308 renderer: function(files
) {
309 return files
.map((file
) => {
312 if (file
.encrypted
) {
313 icon
= '<i class="fa fa-lock"></i> ';
316 size
= ` (${Proxmox.Utils.format_size(file.size)})`;
318 return `${icon}${file.filename}${size}`;
327 text
: gettext('Reload'),
328 iconCls
: 'fa fa-refresh',
332 xtype
: 'proxmoxButton',
333 text
: gettext('Prune'),
335 parentXType
: 'pbsDataStoreContent',
336 enableFn: function(record
) { return !record
.data
.leaf
; },
340 xtype
: 'proxmoxButton',
341 text
: gettext('Download Files'),
343 parentXType
: 'pbsDataStoreContent',
344 handler
: 'openBackupFileDownloader',
345 enableFn: function(record
) {
346 return !!record
.data
.leaf
;
350 xtype
: "proxmoxButton",
351 text
: gettext('PXAR File Browser'),
353 handler
: 'openPxarBrowser',
354 parentXType
: 'pbsDataStoreContent',
355 enableFn: function(record
) {
356 return !!record
.data
.leaf
&& record
.data
.files
.some(el
=> el
.filename
.endsWith('pxar.didx'));