|
307 | 307 | <div class="tab-pane" id="tab_allocation"> |
308 | 308 | <div class="panel panel-default"> |
309 | 309 | <div class="panel-heading"></div> |
310 | | - <div class="panel-body"> |
311 | | - <table class="table table-striped table-bordered table-hover" style="margin-bottom:0;"> |
312 | | - <thead> |
313 | | - <td>IP Address</td> |
314 | | - <td>Ports</td> |
315 | | - <td></td> |
316 | | - </thead> |
317 | | - <tbody> |
318 | | - @foreach($allocations as $ip => $ports) |
319 | | - <tr> |
320 | | - <td><span style="cursor:pointer" data-action="delete" data-ip="{{ $ip }}" data-total="{{ count($ports) }}" class="is-ipblock"><i class="fa fa-fw fa-square-o"></i></span> {{ $ip }}</td> |
321 | | - <td> |
322 | | - @foreach($ports as $id => $allocation) |
323 | | - @if (($id % 2) === 0) |
324 | | - @if($allocation->assigned_to === null) |
325 | | - <span style="cursor:pointer" data-action="delete" data-ip="{{ $ip }}" data-port="{{ $allocation->port }}"><i class="fa fa-fw fa-square-o"></i> {{ $allocation->port }} <br /></span> |
326 | | - @else |
327 | | - <i class="fa fa-fw fa-check-square-o"></i> {{ $allocation->port }} <br /> |
328 | | - @endif |
329 | | - @endif |
330 | | - @endforeach |
331 | | - </td> |
332 | | - <td> |
333 | | - @foreach($ports as $id => $allocation) |
334 | | - @if (($id % 2) === 1) |
335 | | - @if($allocation->assigned_to === null) |
336 | | - <span style="cursor:pointer" data-action="delete" data-ip="{{ $ip }}" data-port="{{ $allocation->port }}"><i class="fa fa-fw fa-square-o"></i> {{ $allocation->port }} <br /></span> |
337 | | - @else |
338 | | - <i class="fa fa-fw fa-check-square-o"></i> {{ $allocation->port }} <br /> |
339 | | - @endif |
340 | | - @endif |
341 | | - @endforeach |
342 | | - </td> |
343 | | - </tr> |
344 | | - @endforeach |
345 | | - </tbody> |
346 | | - </table> |
347 | | - </div> |
348 | | - <div class="panel-heading" style="border-top: 1px solid #ddd;"></div> |
349 | 310 | <div class="panel-body"> |
350 | 311 | <h4 style="margin-top:0;">Allocate Additional Ports</h4> |
351 | 312 | <form action="{{ route('admin.nodes.post.allocations', $node->id) }}" method="POST"> |
|
391 | 352 | </div> |
392 | 353 | </form> |
393 | 354 | </div> |
| 355 | + <div class="panel-heading" style="border-top: 1px solid #ddd;"></div> |
| 356 | + <div class="panel-body"> |
| 357 | + <div class="row"> |
| 358 | + <table class="table table-hover" style="margin-bottom:0;"> |
| 359 | + <thead style="font-weight:bold;"> |
| 360 | + <td>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></td> |
| 361 | + <td>IP Alias</td> |
| 362 | + <td>Port</td> |
| 363 | + <td>Assigned To</td> |
| 364 | + <td></td> |
| 365 | + </thead> |
| 366 | + <tbody> |
| 367 | + @foreach($allocations as $allocation) |
| 368 | + <tr> |
| 369 | + <td class="col-sm-3 align-middle">{{ $allocation->ip }}</td> |
| 370 | + <td class="col-sm-3 align-middle"> |
| 371 | + <input class="form-control input-sm" type="text" value="{{ $allocation->ip_alias }}" data-action="set-alias" data-id="{{ $allocation->id }}" placeholder="none" /> |
| 372 | + <span class="input-loader"><i class="fa fa-refresh fa-spin fa-fw"></i></span> |
| 373 | + </td> |
| 374 | + <td class="col-sm-2 align-middle">{{ $allocation->port }}</td> |
| 375 | + <td class="col-sm-3 align-middle">@if(!is_null($allocation->assigned_to))<a href="{{ route('admin.servers.view', $allocation->assigned_to) }}">{{ $allocation->assigned_to_name }}</a>@endif</td> |
| 376 | + <td class="col-sm-1 align-middle"> |
| 377 | + @if(is_null($allocation->assigned_to)) |
| 378 | + <a href="#" data-action="deallocate" data-id="{{ $allocation->id }}"><span class="badge label-danger"><i class="fa fa-trash-o"></i></span></a> |
| 379 | + @else |
| 380 | + <span class="badge label-default"><i class="fa fa-trash-o"></i></span> |
| 381 | + @endif |
| 382 | + </td> |
| 383 | + </tr> |
| 384 | + @endforeach |
| 385 | + </tbody> |
| 386 | + </table> |
| 387 | + <div class="col-md-12 text-center"> |
| 388 | + {{ $allocations->appends(['tab' => 'tab_allocation'])->links() }} |
| 389 | + </div> |
| 390 | + </div> |
| 391 | + </div> |
394 | 392 | </div> |
395 | 393 | </div> |
396 | 394 | <div class="tab-pane" id="tab_servers"> |
|
458 | 456 | <div class="col-xs-11" id="col11_setter"></div> |
459 | 457 | </div> |
460 | 458 | </div> |
| 459 | +<div class="modal fade" id="allocationModal" tabindex="-1" role="dialog"> |
| 460 | + <div class="modal-dialog" role="document"> |
| 461 | + <div class="modal-content"> |
| 462 | + <div class="modal-header"> |
| 463 | + <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> |
| 464 | + <h4 class="modal-title">Delete Allocations for IP Block</h4> |
| 465 | + </div> |
| 466 | + <form action="{{ route('admin.nodes.view', $node->id) }}/deallocate/block" method="POST"> |
| 467 | + <div class="modal-body"> |
| 468 | + <div class="row"> |
| 469 | + <div class="col-md-12"> |
| 470 | + <select class="form-control" name="ip"> |
| 471 | + <?php $displayed = []; ?> |
| 472 | + @foreach($allocations as $allocation) |
| 473 | + @if(!array_key_exists($allocation->ip, $displayed)) |
| 474 | + <option value="{{ $allocation->ip }}">{{ $allocation->ip }}</option> |
| 475 | + <?php $displayed[$allocation->ip] = true; ?> |
| 476 | + @endif |
| 477 | + @endforeach |
| 478 | + </select> |
| 479 | + </div> |
| 480 | + </div> |
| 481 | + </div> |
| 482 | + <div class="modal-footer"> |
| 483 | + {{{ csrf_field() }}} |
| 484 | + <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> |
| 485 | + <button type="submit" class="btn btn-danger">Delete Allocations</button> |
| 486 | + </div> |
| 487 | + </form> |
| 488 | + </div> |
| 489 | + </div> |
| 490 | +</div> |
461 | 491 | <script> |
462 | 492 | $(document).ready(function () { |
463 | 493 | $('#sidebar_links').find("a[href='/admin/nodes']").addClass('active'); |
|
655 | 685 | $(this).find('i').css('color', 'inherit').addClass('fa-square-o').removeClass('fa-minus-square'); |
656 | 686 | }); |
657 | 687 |
|
658 | | - $('span[data-action="delete"]').click(function (event) { |
| 688 | + $('a[data-action="deallocate"]').click(function (event) { |
659 | 689 | event.preventDefault(); |
660 | 690 | var element = $(this); |
661 | | - var deleteIp = $(this).data('ip'); |
662 | | - var deletePort = $(this).data('port'); |
| 691 | + var allocation = $(this).data('id'); |
663 | 692 | swal({ |
664 | 693 | title: '', |
665 | | - text: 'Are you sure you want to delete this port?', |
| 694 | + text: 'Are you sure you want to delete this allocation?', |
666 | 695 | type: 'warning', |
667 | 696 | showCancelButton: true, |
668 | 697 | allowOutsideClick: true, |
|
673 | 702 | }, function () { |
674 | 703 | $.ajax({ |
675 | 704 | method: 'DELETE', |
676 | | - url: '{{ route('admin.nodes.view', $node->id) }}/allocation/' + deleteIp + '/' + deletePort, |
| 705 | + url: '{{ route('admin.nodes.view', $node->id) }}/deallocate/single/' + allocation, |
677 | 706 | headers: { |
678 | 707 | 'X-CSRF-TOKEN': '{{ csrf_token() }}' |
679 | 708 | } |
680 | 709 | }).done(function (data) { |
681 | | - if (element.hasClass('is-ipblock')) { |
682 | | - var tMatched = 0; |
683 | | - element.parent().parent().find('*').each(function () { |
684 | | - if ($(this).attr('data-port') && $(this).attr('data-ip')) { |
685 | | - $(this).fadeOut(); |
686 | | - tMatched++; |
687 | | - } |
688 | | - }); |
689 | | - if (tMatched === element.data('total')) { |
690 | | - element.fadeOut(); |
691 | | - $('li[data-action="alloc_dropdown_val"][data-value="' + deleteIp + '"]').remove(); |
692 | | - element.parent().parent().slideUp().remove(); |
693 | | - } |
694 | | - } else { |
695 | | - element.fadeOut(); |
696 | | - } |
| 710 | + element.parent().parent().addClass('warning').delay(100).fadeOut(); |
697 | 711 | swal({ |
698 | 712 | type: 'success', |
699 | 713 | title: 'Port Deleted!', |
|
709 | 723 | }); |
710 | 724 | }); |
711 | 725 |
|
| 726 | + var typingTimer; |
| 727 | + $('input[data-action="set-alias"]').keyup(function () { |
| 728 | + clearTimeout(typingTimer); |
| 729 | + $(this).parent().removeClass('has-error has-success'); |
| 730 | + typingTimer = setTimeout(sendAlias, 700, $(this)); |
| 731 | + }); |
| 732 | +
|
| 733 | + var fadeTimers = []; |
| 734 | + function sendAlias(element) { |
| 735 | + element.parent().find('.input-loader').show(); |
| 736 | + clearTimeout(fadeTimers[element.data('id')]); |
| 737 | + $.ajax({ |
| 738 | + method: 'POST', |
| 739 | + url: '{{ route('admin.nodes.alias', $node->id) }}', |
| 740 | + headers: { |
| 741 | + 'X-CSRF-TOKEN': '{{ csrf_token() }}' |
| 742 | + }, |
| 743 | + data: { |
| 744 | + alias: element.val(), |
| 745 | + allocation: element.data('id') |
| 746 | + } |
| 747 | + }).done(function (data) { |
| 748 | + element.parent().addClass('has-success'); |
| 749 | + }).fail(function (jqXHR) { |
| 750 | + console.error(jqXHR); |
| 751 | + element.parent().addClass('has-error'); |
| 752 | + }).always(function () { |
| 753 | + element.parent().find('.input-loader').hide(); |
| 754 | + fadeTimers[element.data('id')] = setTimeout(clearHighlight, 2500, element); |
| 755 | + }); |
| 756 | + } |
| 757 | +
|
| 758 | + function clearHighlight(element) { |
| 759 | + element.parent().removeClass('has-error has-success'); |
| 760 | + } |
| 761 | +
|
712 | 762 | }); |
713 | 763 | </script> |
714 | 764 | @endsection |
0 commit comments