]>
git.proxmox.com Git - proxmox-widget-toolkit.git/blob - src/window/FileBrowser.js
1 Ext
.define('proxmox-file-tree', {
2 extend
: 'Ext.data.Model',
4 fields
: ['filepath', 'text', 'type', 'size',
8 dateFormat
: 'timestamp',
12 calculate: function(data
) {
15 case 'b': // block device
18 case 'c': // char device
22 icon
= data
.expanded
? 'folder-open-o' : 'folder-o';
24 case 'f': //regular file
33 case 'p': // pipe/fifo
47 return `fa fa-${icon}`;
51 idProperty
: 'filepath',
54 Ext
.define("Proxmox.window.FileBrowser", {
55 extend
: "Ext.window.Window",
63 // the base-URL to get the list of files. required.
66 // the base download URL, e.g., something like '/api2/...'
69 // extra parameters set as proxy paramns and for an actual download request
72 // the file types for which the download button should be enabled
73 downloadableFileTypes
: {
74 'h': true, // hardlinks
75 'f': true, // "normal" files
76 'd': true, // directories
79 // set to true to show the tar download button
84 xclass
: 'Ext.app.ViewController',
86 buildUrl: function(baseurl
, params
) {
87 let url
= new URL(baseurl
, window
.location
.origin
);
88 for (const [key
, value
] of Object
.entries(params
)) {
89 url
.searchParams
.append(key
, value
);
95 downloadTar: function() {
96 this.downloadFile(true);
99 downloadZip: function() {
100 this.downloadFile(false);
103 downloadFile: function(tar
) {
105 let view
= me
.getView();
106 let tree
= me
.lookup('tree');
107 let selection
= tree
.getSelection();
108 if (!selection
|| selection
.length
< 1) return;
110 let data
= selection
[0].data
;
112 let atag
= document
.createElement('a');
114 atag
.download
= data
.text
;
115 let params
= { ...view
.extraParams
};
116 params
.filepath
= data
.filepath
;
117 atag
.download
= data
.text
;
118 if (data
.type
=== 'd') {
121 atag
.download
+= ".tar.zst";
123 atag
.download
+= ".zip";
126 atag
.href
= me
.buildUrl(view
.downloadURL
, params
);
130 fileChanged: function() {
132 let view
= me
.getView();
133 let tree
= me
.lookup('tree');
134 let selection
= tree
.getSelection();
135 if (!selection
|| selection
.length
< 1) return;
137 let data
= selection
[0].data
;
138 let canDownload
= view
.downloadURL
&& view
.downloadableFileTypes
[data
.type
];
139 let zipBtn
= me
.lookup('downloadBtn');
140 let tarBtn
= me
.lookup('downloadTar');
141 zipBtn
.setDisabled(!canDownload
);
142 tarBtn
.setDisabled(!canDownload
);
143 zipBtn
.setText(data
.type
=== 'd' ? gettext('Download .zip') : gettext('Download'));
144 tarBtn
.setVisible(data
.type
=== 'd' && view
.enableTar
);
147 errorHandler: function(error
, msg
) {
149 if (error
?.status
=== 503) {
152 me
.lookup('downloadBtn').setDisabled(true);
153 me
.lookup('downloadTar').setDisabled(true);
154 if (me
.initialLoadDone
) {
155 Ext
.Msg
.alert(gettext('Error'), msg
);
161 init: function(view
) {
163 let tree
= me
.lookup('tree');
166 throw "no list URL given";
169 let store
= tree
.getStore();
170 let proxy
= store
.getProxy();
172 let errorCallback
= (error
, msg
) => me
.errorHandler(error
, msg
);
173 proxy
.setUrl(view
.listURL
);
174 proxy
.setTimeout(60*1000);
175 proxy
.setExtraParams(view
.extraParams
);
177 tree
.mon(store
, 'beforeload', () => {
178 Proxmox
.Utils
.setErrorMask(tree
, true);
180 tree
.mon(store
, 'load', (treestore
, rec
, success
, operation
, node
) => {
182 Proxmox
.Utils
.setErrorMask(tree
, false);
185 if (!node
.loadCount
) {
186 node
.loadCount
= 0; // ensure its numeric
188 // trigger a reload if we got a 503 answer from the proxy
189 if (operation
?.error
?.status
=== 503 && node
.loadCount
< 10) {
196 let error
= operation
.getError();
197 let msg
= Proxmox
.Utils
.getResponseErrorMessage(error
);
198 if (!errorCallback(error
, msg
)) {
199 Proxmox
.Utils
.setErrorMask(tree
, msg
);
201 Proxmox
.Utils
.setErrorMask(tree
, false);
204 store
.load((rec
, op
, success
) => {
205 let root
= store
.getRoot();
206 root
.expand(); // always expand invisible root node
207 if (view
.archive
=== 'all') {
208 root
.expandChildren(false);
209 } else if (view
.archive
) {
210 let child
= root
.findChild('text', view
.archive
);
213 setTimeout(function() {
214 tree
.setSelection(child
);
215 tree
.getView().focusRow(child
);
218 } else if (root
.childNodes
.length
=== 1) {
219 root
.firstChild
.expand();
221 me
.initialLoadDone
= success
;
227 selectionchange
: 'fileChanged',
241 model
: 'proxmox-file-tree',
243 nodeParam
: 'filepath',
257 text
: gettext('Name'),
261 renderer
: Ext
.String
.htmlEncode
,
264 text
: gettext('Size'),
266 renderer
: value
=> value
=== undefined ? '' : Proxmox
.Utils
.format_size(value
),
268 sorterFn: function(a
, b
) {
269 let asize
= a
.data
.size
|| 0;
270 let bsize
= b
.data
.size
|| 0;
272 return asize
- bsize
;
277 text
: gettext('Modified'),
282 text
: gettext('Type'),
284 renderer: function(value
) {
286 case 'b': return gettext('Block Device');
287 case 'c': return gettext('Character Device');
288 case 'd': return gettext('Directory');
289 case 'f': return gettext('File');
290 case 'h': return gettext('Hardlink');
291 case 'l': return gettext('Softlink');
292 case 'p': return gettext('Pipe/Fifo');
293 case 's': return gettext('Socket');
294 case 'v': return gettext('Virtual');
295 default: return Proxmox
.Utils
.unknownText
;
305 text
: gettext('Download .tar.zst'),
306 handler
: 'downloadTar',
307 reference
: 'downloadTar',
312 text
: gettext('Download .zip'),
313 handler
: 'downloadZip',
314 reference
: 'downloadBtn',