]> git.proxmox.com Git - proxmox-widget-toolkit.git/blob - src/window/FileBrowser.js
d8e75f458e447a57b23067c7951e316b328bb2b6
[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 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 = { ...view.extraParams };
84 params.filepath = data.filepath;
85 atag.download = data.text;
86 if (data.type === 'd') {
87 atag.download += ".zip";
88 }
89 atag.href = me.buildUrl(view.downloadUrl, params);
90 atag.click();
91 },
92
93 fileChanged: function() {
94 let me = this;
95 let view = me.getView();
96 let tree = me.lookup('tree');
97 let selection = tree.getSelection();
98 if (!selection || selection.length < 1) return;
99
100 let data = selection[0].data;
101
102 let canDownload = false;
103 if (view.downloadUrl) {
104 switch (data.type) {
105 case 'h':
106 case 'f':
107 canDownload = true;
108 break;
109 case 'd':
110 if (data.depth > 1) {
111 canDownload = true;
112 }
113 break;
114 default: break;
115 }
116 }
117
118 me.lookup('downloadBtn').setDisabled(!canDownload);
119 },
120
121 init: function(view) {
122 let me = this;
123 let tree = me.lookup('tree');
124
125 if (!view.listUrl) {
126 throw "no list URL given";
127 }
128
129 let store = tree.getStore();
130 let proxy = store.getProxy();
131
132 Proxmox.Utils.monStoreErrors(tree, store, true);
133 proxy.setUrl(view.listUrl);
134 proxy.setExtraParams(view.extraParams);
135 store.load(() => {
136 let root = store.getRoot();
137 root.expand(); // always expand invisible root node
138 if (view.archive) {
139 let child = root.findChild('text', view.archive);
140 if (child) {
141 child.expand();
142 setTimeout(function() {
143 tree.setSelection(child);
144 tree.getView().focusRow(child);
145 }, 10);
146 }
147 } else if (root.childNodes.length === 1) {
148 root.firstChild.expand();
149 }
150 });
151 },
152
153 control: {
154 'treepanel': {
155 selectionchange: 'fileChanged',
156 },
157 },
158 },
159
160 layout: 'fit',
161 items: [
162 {
163 xtype: 'treepanel',
164 scrollable: true,
165 rootVisible: false,
166 reference: 'tree',
167 store: {
168 autoLoad: false,
169 model: 'proxmox-file-tree',
170 defaultRootId: '/',
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 });