]> git.proxmox.com Git - proxmox-backup.git/blob - www/window/FileBrowser.js
src/api2/admin/datastore.rs: avoid slash in UPID strings
[proxmox-backup.git] / www / window / FileBrowser.js
1 Ext.define('pbs-file-tree', {
2 extend: 'Ext.data.Model',
3
4 fields: [ 'filepath', 'text', 'type', 'size',
5 {
6 name: 'mtime',
7 type: 'date',
8 dateFormat: 'timestamp',
9 },
10 {
11 name: 'iconCls',
12 calculate: function(data) {
13 let icon = 'file-o';
14 switch (data.type) {
15 case 'b': // block device
16 icon = 'cube';
17 break;
18 case 'c': // char device
19 icon = 'tty';
20 break;
21 case 'd':
22 icon = data.expanded ? 'folder-open-o' : 'folder-o';
23 break;
24 case 'f': //regular file
25 icon = 'file-text-o';
26 break;
27 case 'h': // hardlink
28 icon = 'file-o';
29 break;
30 case 'l': // softlink
31 icon = 'link';
32 break;
33 case 'p': // pipe/fifo
34 icon = 'exchange';
35 break;
36 case 's': // socket
37 icon = 'plug';
38 break;
39 default:
40 icon = 'file-o';
41 break;
42 }
43
44 return `fa fa-${icon}`;
45 },
46 }
47 ],
48 idProperty: 'filepath',
49 });
50
51 Ext.define("PBS.window.FileBrowser", {
52 extend: "Ext.window.Window",
53
54 width: 800,
55 height: 600,
56
57 modal: true,
58
59 controller: {
60 xclass: 'Ext.app.ViewController',
61
62 buildUrl: function(baseurl, params) {
63 let url = new URL(baseurl, window.location.origin);
64 for (const [key, value] of Object.entries(params)) {
65 url.searchParams.append(key, value);
66 }
67
68 return url.href;
69 },
70
71 downloadFile: function() {
72 let me = this;
73 let view = me.getView();
74 let tree = me.lookup('tree');
75 let selection = tree.getSelection();
76 if (!selection || selection.length < 1) return;
77
78 let data = selection[0].data;
79
80 let atag = document.createElement('a');
81
82 atag.download = data.text;
83 let params = {
84 'backup-id': view['backup-id'],
85 'backup-type': view['backup-type'],
86 'backup-time': view['backup-time'],
87 };
88 params['filepath'] = data.filepath;
89 atag.download = data.text;
90 atag.href = me.buildUrl(`/api2/json/admin/datastore/${view.datastore}/pxar-file-download`, params);
91 atag.click();
92 },
93
94 fileChanged: function() {
95 let me = this;
96 let view = me.getView();
97 let tree = me.lookup('tree');
98 let selection = tree.getSelection();
99 if (!selection || selection.length < 1) return;
100
101 let data = selection[0].data;
102
103 let canDownload = false;
104 switch (data.type) {
105 case 'h':
106 case 'f':
107 canDownload = true;
108 break;
109 default: break;
110 }
111
112 me.lookup('downloadBtn').setDisabled(!canDownload);
113 },
114
115 init: function(view) {
116 let me = this;
117 let tree = me.lookup('tree');
118
119 if (!view['backup-id']) {
120 throw "no backup-id given";
121 }
122
123 if (!view['backup-type']) {
124 throw "no backup-id given";
125 }
126
127 if (!view['backup-time']) {
128 throw "no backup-id given";
129 }
130
131 if (!view.datastore) {
132 throw "no datastore given";
133 }
134
135 let store = tree.getStore();
136 let proxy = store.getProxy();
137
138 Proxmox.Utils.monStoreErrors(tree, store, true);
139 proxy.setUrl(`/api2/json/admin/datastore/${view.datastore}/catalog`);
140 proxy.setExtraParams({
141 'backup-id': view['backup-id'],
142 'backup-type': view['backup-type'],
143 'backup-time': view['backup-time'],
144 });
145 store.load(() => {
146 let root = store.getRoot();
147 root.expand(); // always expand invisible root node
148 if (root.childNodes.length === 1) {
149 root.firstChild.expand();
150 }
151 });
152 },
153
154 control: {
155 'treepanel': {
156 selectionchange: 'fileChanged',
157 },
158 },
159 },
160
161 layout: 'fit',
162 items: [
163 {
164 xtype: 'treepanel',
165 scrollable: true,
166 rootVisible: false,
167 reference: 'tree',
168 store: {
169 autoLoad: false,
170 model: 'pbs-file-tree',
171 nodeParam: 'filepath',
172 sorters: 'text',
173 proxy: {
174 appendId: false,
175 type: 'proxmox',
176 },
177 },
178
179 columns: [
180 {
181 text: gettext('Name'),
182 xtype: 'treecolumn',
183 flex: 1,
184 dataIndex: 'text',
185 renderer: Ext.String.htmlEncode,
186 },
187 {
188 text: gettext('Size'),
189 dataIndex: 'size',
190 renderer: value => value === undefined ? '' : Proxmox.Utils.format_size(value),
191 sorter: {
192 sorterFn: function(a, b) {
193 let asize = a.data.size || 0;
194 let bsize = b.data.size || 0;
195
196 return asize - bsize;
197 },
198 }
199 },
200 {
201 text: gettext('Modified'),
202 dataIndex: 'mtime',
203 minWidth: 200,
204 },
205 {
206 text: gettext('Type'),
207 dataIndex: 'type',
208 renderer: function(value) {
209 switch (value) {
210 case 'b': return gettext('Block Device');
211 case 'c': return gettext('Character Device');
212 case 'd': return gettext('Directory');
213 case 'f': return gettext('File');
214 case 'h': return gettext('Hardlink');
215 case 'l': return gettext('Softlink');
216 case 'p': return gettext('Pipe/Fifo');
217 case 's': return gettext('Socket');
218 default: return Proxmox.Utils.unknownText;
219 }
220 }
221 },
222 ]
223 }
224 ],
225
226 buttons: [
227 {
228 text: gettext('Download'),
229 handler: 'downloadFile',
230 reference: 'downloadBtn',
231 disabled: true,
232 }
233 ],
234 });