3939 <div class =" box-header with-border" >
4040 <h3 class =" box-title" >Existing Allocations</h3 >
4141 </div >
42- <div class =" box-body table-responsive no-padding" >
42+ <div class =" box-body table-responsive no-padding" style = " overflow-x : visible " >
4343 <table class =" table table-hover" style =" margin-bottom :0 ;" >
4444 <tr >
45+ <th >
46+ <input type =" checkbox" class =" select-all-files hidden-xs" data-action =" selectAll" >
47+ </th >
4548 <th >IP Address <i class =" fa fa-fw fa-minus-square" style =" font-weight :normal ;color :#d9534f ;cursor :pointer ;" data-toggle =" modal" data-target =" #allocationModal" ></i ></th >
4649 <th >IP Alias</th >
4750 <th >Port</th >
4851 <th >Assigned To</th >
49- <th ></th >
52+ <th >
53+ <div class =" btn-group hidden-xs" >
54+ <button type =" button" id =" mass_actions" class =" btn btn-sm btn-default dropdown-toggle disabled"
55+ data-toggle =" dropdown" aria-haspopup =" true" aria-expanded =" false" >@lang (' server.allocations.mass_actions' ) <span class =" caret" ></span >
56+ </button >
57+ <ul class =" dropdown-menu dropdown-massactions" >
58+ <li ><a href =" #" id =" selective-deletion" data-action =" selective-deletion" >@lang (' server.allocations.delete' ) <i class =" fa fa-fw fa-trash-o" ></i ></a ></li >
59+ </ul >
60+ </div >
61+ </th >
5062 </tr >
5163 @foreach ($node -> allocations as $allocation )
5264 <tr >
53- <td class =" col-sm-3 middle" >{{ $allocation -> ip } } </td >
65+ <td class =" middle min-size" data-identifier =" type" >
66+ @if (is_null ($allocation -> server_id ) )
67+ <input type =" checkbox" class =" select-file hidden-xs" data-action =" addSelection" >
68+ @else
69+ <input disabled =" disabled" type =" checkbox" class =" select-file hidden-xs" data-action =" addSelection" >
70+ @endif
71+ </td >
72+ <td class =" col-sm-3 middle" data-identifier =" ip" >{{ $allocation -> ip } } </td >
5473 <td class =" col-sm-3 middle" >
5574 <input class =" form-control input-sm" type =" text" value =" {{ $allocation -> ip_alias } }" data-action =" set-alias" data-id =" {{ $allocation -> id } }" placeholder =" none" />
5675 <span class =" input-loader" ><i class =" fa fa-refresh fa-spin fa-fw" ></i ></span >
5776 </td >
58- <td class =" col-sm-2 middle" >{{ $allocation -> port } } </td >
77+ <td class =" col-sm-2 middle" data-identifier = " port " >{{ $allocation -> port } } </td >
5978 <td class =" col-sm-3 middle" >
6079 @if (! is_null ($allocation -> server ) )
6180 <a href =" {{ route (' admin.servers.view' , $allocation -> server_id ) } }" >{{ $allocation -> server -> name } } </a >
153172@section (' footer-scripts' )
154173 @parent
155174 <script >
175+ $ (' [data-action="addSelection"]' ).on (' click' , function () {
176+ updateMassActions ();
177+ });
178+
179+ $ (' [data-action="selectAll"]' ).on (' click' , function () {
180+ $ (' input.select-file' ).not (' :disabled' ).prop (' checked' , function (i , val ) {
181+ return ! val;
182+ });
183+
184+ updateMassActions ();
185+ });
186+
187+ $ (' [data-action="selective-deletion"]' ).on (' mousedown' , function () {
188+ deleteSelected ();
189+ });
190+
156191 $ (' #pAllocationIP' ).select2 ({
157192 tags: true ,
158193 maximumSelectionLength: 1 ,
159194 selectOnClose: true ,
160195 tokenSeparators: [' ,' , ' ' ],
161196 });
197+
162198 $ (' #pAllocationPorts' ).select2 ({
163199 tags: true ,
164200 selectOnClose: true ,
165201 tokenSeparators: [' ,' , ' ' ],
166202 });
203+
167204 $ (' button[data-action="deallocate"]' ).click (function (event ) {
168205 event .preventDefault ();
169206 var element = $ (this );
@@ -216,7 +253,7 @@ function sendAlias(element) {
216253 alias: element .val (),
217254 allocation_id: element .data (' id' ),
218255 }
219- }).done (function (data ) {
256+ }).done (function () {
220257 element .parent ().addClass (' has-success' );
221258 }).fail (function (jqXHR ) {
222259 console .error (jqXHR);
@@ -230,5 +267,99 @@ function sendAlias(element) {
230267 function clearHighlight (element ) {
231268 element .parent ().removeClass (' has-error has-success' );
232269 }
270+
271+ function updateMassActions () {
272+ if ($ (' input.select-file:checked' ).length > 0 ) {
273+ $ (' #mass_actions' ).removeClass (' disabled' );
274+ } else {
275+ $ (' #mass_actions' ).addClass (' disabled' );
276+ }
277+ }
278+
279+ function deleteSelected () {
280+ var selectedIds = [];
281+ var selectedItems = [];
282+ var selectedItemsElements = [];
283+
284+ $ (' input.select-file:checked' ).each (function () {
285+ var $parent = $ ($ (this ).closest (' tr' ));
286+ var id = $parent .find (' [data-action="deallocate"]' ).data (' id' );
287+ var $ip = $parent .find (' td[data-identifier="ip"]' );
288+ var $port = $parent .find (' td[data-identifier="port"]' );
289+ var block = ` ${ $ip .text ()} :${ $port .text ()} ` ;
290+
291+ selectedIds .push ({
292+ id: id
293+ });
294+ selectedItems .push (block);
295+ selectedItemsElements .push ($parent);
296+ });
297+
298+ if (selectedItems .length !== 0 ) {
299+ var formattedItems = " " ;
300+ var i = 0 ;
301+ $ .each (selectedItems, function (key , value ) {
302+ formattedItems += (" <code>" + value + " </code>, " );
303+ i++ ;
304+ return i < 5 ;
305+ });
306+
307+ formattedItems = formattedItems .slice (0 , - 2 );
308+ if (selectedItems .length > 5 ) {
309+ formattedItems += ' , and ' + (selectedItems .length - 5 ) + ' other(s)' ;
310+ }
311+
312+ swal ({
313+ type: ' warning' ,
314+ title: ' ' ,
315+ text: ' Are you sure you want to delete the following allocations: ' + formattedItems + ' ?' ,
316+ html: true ,
317+ showCancelButton: true ,
318+ showConfirmButton: true ,
319+ closeOnConfirm: false ,
320+ showLoaderOnConfirm: true
321+ }, function () {
322+ $ .ajax ({
323+ method: ' DELETE' ,
324+ url: Router .route (' admin.nodes.view.allocation.removeMultiple' , {
325+ node: Pterodactyl .node .id
326+ }),
327+ headers: {' X-CSRF-TOKEN' : $ (' meta[name="_token"]' ).attr (' content' )},
328+ data: JSON .stringify ({
329+ allocations: selectedIds
330+ }),
331+ contentType: ' application/json' ,
332+ processData: false
333+ }).done (function () {
334+ $ (' #file_listing input:checked' ).each (function () {
335+ $ (this ).prop (' checked' , false );
336+ });
337+
338+ $ .each (selectedItemsElements, function () {
339+ $ (this ).addClass (' warning' ).delay (200 ).fadeOut ();
340+ });
341+
342+ swal ({
343+ type: ' success' ,
344+ title: ' Allocations Deleted'
345+ });
346+ }).fail (function (jqXHR ) {
347+ console .error (jqXHR);
348+ swal ({
349+ type: ' error' ,
350+ title: ' Whoops!' ,
351+ html: true ,
352+ text: ' An error occurred while attempting to delete these allocations. Please try again.' ,
353+ });
354+ });
355+ });
356+ } else {
357+ swal ({
358+ type: ' warning' ,
359+ title: ' ' ,
360+ text: ' Please select allocation(s) to delete.' ,
361+ });
362+ }
363+ }
233364 </script >
234365@endsection
0 commit comments