|
19 | 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
20 | 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
21 | 21 | // SOFTWARE. |
22 | | -class ContextMenuActions { |
23 | | - constructor(element, menu) { |
24 | | - this.element = element; |
25 | | - this.menu = menu; |
| 22 | +class ContextMenuClass { |
| 23 | + constructor() { |
| 24 | + this.activeLine = null; |
26 | 25 | } |
27 | 26 |
|
28 | | - destroy() { |
29 | | - this.element = undefined; |
| 27 | + run() { |
| 28 | + this.directoryClick(); |
| 29 | + this.rightClick(); |
30 | 30 | } |
31 | 31 |
|
32 | | - move() { |
33 | | - alert($(this.element).data('path')); |
| 32 | + makeMenu() { |
| 33 | + $(document).find('#fileOptionMenu').remove(); |
| 34 | + if (!_.isNull(this.activeLine)) this.activeLine.removeClass('active'); |
| 35 | + return '<ul id="fileOptionMenu" class="dropdown-menu" role="menu" style="display:none" > \ |
| 36 | + <li data-action="move"><a tabindex="-1" href="#"><i class="fa fa-arrow-right"></i> Move</a></li> \ |
| 37 | + <li data-action="rename"><a tabindex="-1" href="#"><i class="fa fa-pencil-square-o"></i> Rename</a></li> \ |
| 38 | + <li data-action="compress" class="hidden"><a tabindex="-1" href="#"><i class="fa fa-file-archive-o"></i> Compress</a></li> \ |
| 39 | + <li data-action="decompress" class="hidden"><a tabindex="-1" href="#"><i class="fa fa-expand"></i> Decompress</a></li> \ |
| 40 | + <li class="divider"></li> \ |
| 41 | + <li data-action="download" class="hidden"><a tabindex="-1" href="/server/{{ $server->uuidShort }}/files/download/"><i class="fa fa-download"></i> Download</a></li> \ |
| 42 | + <li data-action="delete" class="bg-danger"><a tabindex="-1" href="#"><i class="fa fa-trash-o"></i> Delete</a></li> \ |
| 43 | + </ul>'; |
34 | 44 | } |
35 | 45 |
|
36 | | - download() { |
37 | | - var baseURL = $(this.menu).find('li[data-action="download"] a').attr('href'); |
38 | | - var toURL = baseURL + $(this.element).find('td[data-identifier="name"]').data('name'); |
| 46 | + rightClick() { |
| 47 | + $('#file_listing > tbody td').on('contextmenu', event => { |
39 | 48 |
|
40 | | - window.location = toURL; |
41 | | - } |
| 49 | + const parent = $(event.target).parent(); |
| 50 | + const menu = $(this.makeMenu()); |
| 51 | + |
| 52 | + if (parent.data('type') === 'disabled') return; |
| 53 | + event.preventDefault(); |
| 54 | + |
| 55 | + $(menu).appendTo('body'); |
| 56 | + $(menu).data('invokedOn', $(event.target)).show().css({ |
| 57 | + position: 'absolute', |
| 58 | + left: event.pageX, |
| 59 | + top: event.pageY, |
| 60 | + }); |
| 61 | + |
| 62 | + this.activeLine = parent; |
| 63 | + this.activeLine.addClass('active'); |
42 | 64 |
|
43 | | - rename() { |
44 | | - const nameBlock = $(this.element).find('td[data-identifier="name"]'); |
45 | | - const currentLink = nameBlock.find('a'); |
46 | | - const currentName = decodeURIComponent(nameBlock.attr('data-name')); |
47 | | - const attachEditor = ` |
48 | | - <input class="form-control input-sm" type="text" value="${currentName}" /> |
49 | | - <span class="input-loader"><i class="fa fa-refresh fa-spin fa-fw"></i></span> |
50 | | - `; |
51 | | - |
52 | | - nameBlock.html(attachEditor); |
53 | | - const inputField = nameBlock.find('input'); |
54 | | - const inputLoader = nameBlock.find('.input-loader'); |
55 | | - |
56 | | - inputField.focus(); |
57 | | - inputField.on('blur keypress', e => { |
58 | | - // Save Field |
59 | | - if (e.type === 'blur' || (e.type === 'keypress' && e.which !== 13)) { |
60 | | - // Escape Key Pressed, don't save. |
61 | | - if (e.which === 27 || e.type === 'blur') { |
62 | | - if (!_.isEmpty(currentLink)) { |
63 | | - nameBlock.html(currentLink); |
64 | | - } else { |
65 | | - nameBlock.html(currentName); |
66 | | - } |
67 | | - inputField.remove(); |
68 | | - Actions.run(); |
69 | | - } |
70 | | - return; |
| 65 | + if (parent.data('type') === 'file') { |
| 66 | + $(menu).find('li[data-action="download"]').removeClass('hidden'); |
71 | 67 | } |
72 | 68 |
|
73 | | - inputLoader.show(); |
74 | | - const currentPath = decodeURIComponent(nameBlock.data('path')); |
75 | | - |
76 | | - $.ajax({ |
77 | | - type: 'POST', |
78 | | - headers: { |
79 | | - 'X-Access-Token': '{{ $server->daemonSecret }}', |
80 | | - 'X-Access-Server': '{{ $server->uuid }}' |
81 | | - }, |
82 | | - contentType: 'application/json; charset=utf-8', |
83 | | - url: '{{ $node->scheme }}://{{ $node->fqdn }}:{{ $node->daemonListen }}/server/files/rename', |
84 | | - timeout: 10000, |
85 | | - data: JSON.stringify({ |
86 | | - from: `${currentPath}${currentName}`, |
87 | | - to: `${currentPath}${inputField.val()}`, |
88 | | - }), |
89 | | - }).done(data => { |
90 | | - nameBlock.attr('data-name', inputField.val()); |
91 | | - if (!_.isEmpty(currentLink)) { |
92 | | - const newLink = currentLink.attr('href').substr(0, currentLink.attr('href').lastIndexOf('/')) + '/' + inputField.val(); |
93 | | - currentLink.attr('href', newLink); |
94 | | - nameBlock.html( |
95 | | - currentLink.html(inputField.val()) |
96 | | - ); |
97 | | - } else { |
98 | | - nameBlock.html(inputField.val()); |
99 | | - } |
100 | | - inputField.remove(); |
101 | | - }).fail(jqXHR => { |
102 | | - nameBlock.addClass('has-error'); |
103 | | - inputLoader.remove(); |
104 | | - console.error(jqXHR); |
105 | | - var error = 'An error occured while trying to process this request.'; |
106 | | - if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') { |
107 | | - error = jqXHR.responseJSON.error; |
108 | | - } |
109 | | - swal({ |
110 | | - type: 'error', |
111 | | - title: '', |
112 | | - text: error, |
113 | | - }); |
114 | | - }).always(() => { |
115 | | - inputLoader.remove(); |
| 69 | + if (parent.data('type') === 'folder') { |
| 70 | + $(menu).find('li[data-action="compress"]').removeClass('hidden'); |
| 71 | + } |
| 72 | + |
| 73 | + if (_.without(['application/zip', 'application/gzip', 'application/x-gzip'], parent.data('mime')).length < 3) { |
| 74 | + $(menu).find('li[data-action="decompress"]').removeClass('hidden'); |
| 75 | + } |
| 76 | + |
| 77 | + // Handle Events |
| 78 | + const Actions = new ActionsClass(parent, menu); |
| 79 | + $(menu).find('li[data-action="move"]').unbind().on('click', e => { |
| 80 | + Actions.move(); |
| 81 | + }); |
| 82 | + |
| 83 | + $(menu).find('li[data-action="rename"]').unbind().on('click', e => { |
| 84 | + Actions.rename(); |
116 | 85 | }); |
| 86 | + |
| 87 | + $(menu).find('li[data-action="download"]').unbind().on('click', e => { |
| 88 | + e.preventDefault(); |
| 89 | + Actions.download(); |
| 90 | + }); |
| 91 | + |
| 92 | + $(window).on('click', () => { |
| 93 | + $(menu).remove(); |
| 94 | + if(!_.isNull(this.activeLine)) this.activeLine.removeClass('active'); |
| 95 | + }); |
| 96 | + }); |
| 97 | + } |
| 98 | + |
| 99 | + directoryClick() { |
| 100 | + $('a[data-action="directory-view"]').on('click', function (event) { |
| 101 | + event.preventDefault(); |
| 102 | + |
| 103 | + const path = $(this).parent().data('path') || ''; |
| 104 | + const name = $(this).parent().data('name') || ''; |
| 105 | + |
| 106 | + console.log('changing hash'); |
| 107 | + window.location.hash = encodeURIComponent(path + name); |
| 108 | + Files.list(); |
117 | 109 | }); |
118 | 110 | } |
119 | 111 | } |
| 112 | + |
| 113 | +window.ContextMenu = new ContextMenuClass; |
0 commit comments