]> git.proxmox.com Git - proxmox-widget-toolkit.git/blob - src/window/FileBrowser.js
file browser: add config and comments for params, uper case URL
[proxmox-widget-toolkit.git] / src / window / FileBrowser.js
1 Ext.define('proxmox-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("Proxmox.window.FileBrowser", {
52 extend: "Ext.window.Window",
53
54 width: 800,
55 height: 600,
56
57 modal: true,
58
59 config: {
60 // the base-URL to get the list of files. required.
61 listURL: '',
62
63 // the base download URL, e.g., something like '/api2/...'
64 downloadURL: '',
65
66 // extra parameters set as proxy paramns and for an actual download request
67 extraParams: {},
68
69 // the file types for which the download button should be enabled
70 downloadableFileTypes: {
71 'h': true, // hardlinks
72 'f': true, // "normal" files
73 'd': true, // directories
74 },
75 },
76
77 controller: {
78 xclass: 'Ext.app.ViewController',
79
80 buildUrl: function(baseurl, params) {
81 let url = new URL(baseurl, window.location.origin);
82 for (const [key, value] of Object.entries(params)) {
83 url.searchParams.append(key, value);
84 }
85
86 return url.href;
87 },
88
89 downloadFile: function() {
90 let me = this;
91 let view = me.getView();
92 let tree = me.lookup('tree');
93 let selection = tree.getSelection();
94 if (!selection || selection.length < 1) return;
95
96 let data = selection[0].data;
97
98 let atag = document.createElement('a');
99
100 atag.download = data.text;
101 let params = { ...view.extraParams };
102 params.filepath = data.filepath;
103 atag.download = data.text;
104 if (data.type === 'd') {
105 atag.download += ".zip";
106 }
107 atag.href = me.buildUrl(view.downloadURL, params);
108 atag.click();
109 },
110
111 fileChanged: function() {
112 let me = this;
113 let view = me.getView();
114 let tree = me.lookup('tree');
115 let selection = tree.getSelection();
116 if (!selection || selection.length < 1) return;
117
118 let data = selection[0].data;
119 let canDownload = view.downloadURL && view.downloadableFileTypes[data.type];
120 me.lookup('downloadBtn').setDisabled(!canDownload);
121 },
122
123 init: function(view) {
124 let me = this;
125 let tree = me.lookup('tree');
126
127 if (!view.listURL) {
128 throw "no list URL given";
129 }
130
131 let store = tree.getStore();
132 let proxy = store.getProxy();
133
134 Proxmox.Utils.monStoreErrors(tree, store, true);
135 proxy.setUrl(view.listURL);
136 proxy.setExtraParams(view.extraParams);
137 store.load(() => {
138 let root = store.getRoot();
139 root.expand(); // always expand invisible root node
140 if (view.archive) {
141 let child = root.findChild('text', view.archive);
142 if (child) {
143 child.expand();
144 setTimeout(function() {
145 tree.setSelection(child);
146 tree.getView().focusRow(child);
147 }, 10);
148 }
149 } else if (root.childNodes.length === 1) {
150 root.firstChild.expand();
151 }
152 });
153 },
154
155 control: {
156 'treepanel': {
157 selectionchange: 'fileChanged',
158 },
159 },
160 },
161
162 layout: 'fit',
163 items: [
164 {
165 xtype: 'treepanel',
166 scrollable: true,
167 rootVisible: false,
168 reference: 'tree',
169 store: {
170 autoLoad: false,
171 model: 'proxmox-file-tree',
172 defaultRootId: '/',
173 nodeParam: 'filepath',
174 sorters: 'text',
175 proxy: {
176 appendId: false,
177 type: 'proxmox',
178 },
179 },
180
181 columns: [
182 {
183 text: gettext('Name'),
184 xtype: 'treecolumn',
185 flex: 1,
186 dataIndex: 'text',
187 renderer: Ext.String.htmlEncode,
188 },
189 {
190 text: gettext('Size'),
191 dataIndex: 'size',
192 renderer: value => value === undefined ? '' : Proxmox.Utils.format_size(value),
193 sorter: {
194 sorterFn: function(a, b) {
195 let asize = a.data.size || 0;
196 let bsize = b.data.size || 0;
197
198 return asize - bsize;
199 },
200 },
201 },
202 {
203 text: gettext('Modified'),
204 dataIndex: 'mtime',
205 minWidth: 200,
206 },
207 {
208 text: gettext('Type'),
209 dataIndex: 'type',
210 renderer: function(value) {
211 switch (value) {
212 case 'b': return gettext('Block Device');
213 case 'c': return gettext('Character Device');
214 case 'd': return gettext('Directory');
215 case 'f': return gettext('File');
216 case 'h': return gettext('Hardlink');
217 case 'l': return gettext('Softlink');
218 case 'p': return gettext('Pipe/Fifo');
219 case 's': return gettext('Socket');
220 default: return Proxmox.Utils.unknownText;
221 }
222 },
223 },
224 ],
225 },
226 ],
227
228 buttons: [
229 {
230 text: gettext('Download'),
231 handler: 'downloadFile',
232 reference: 'downloadBtn',
233 disabled: true,
234 },
235 ],
236 });