Commit 847d61cc authored by Thidaporn Laisan's avatar Thidaporn Laisan
Browse files

Merge branch 'sprint1' of...

Merge branch 'sprint1' of https://idemo.netbay.co.th/gitlab/sarun.netbay/spnpatch-laravel into sprint1

# Conflicts:
#	resources/views/livewire/main-container.blade.php
#	resources/views/livewire/navbar.blade.php
parents 570d9c08 2de5e46a
......@@ -6,10 +6,11 @@ use Livewire\Component;
class MainContainer extends Component
{
public $currentContent = 'Patch';
public $currentContent = 'SendMultiPatch';
public $loading = false;
public $pagePaginate = 1;
protected $listeners = ['menuChanged' => 'loadContent'];
protected $listeners = ['menuChanged' => 'loadContent' , 'updatePagePaginate'];
public function loadContent($menu)
{
......@@ -19,10 +20,11 @@ class MainContainer extends Component
// sleep(1);
$this->currentContent = $menu;
$this->emitTo('pages.patch.patch-index', 'showpatchListForm');
// $this->emitTo('PatchIndex', 'showpatchListForm');
$this->loading = false;
}
public function updatePagePaginate($page) {
$this->pagePaginate = $page;
}
public function render()
{
......
......@@ -58,6 +58,11 @@ class PatchIndex extends Component
// $this->emit('showpatchEditForm');
}
public function showDeleteModal($patchFileId)
{
$this->emit('showDeleteModal' ,$patchFileId);
}
public function deleteItem($pid) {
$pathFile = TabPatchFile::where("ptid", $pid)->delete();
......
<?php
namespace App\Http\Livewire\Pages\SendPatch;
use App\Models\ConfServerLicense;
use App\Models\ConfServerPendding;
use App\Models\ConfSmartupdate;
use Livewire\Component;
class SendMultiPatchBox extends Component
{
protected $listeners = ['updateSelectedPatches'];
public $selectedPatches = [];
public $selectedPatchName = [];
public $serverkey = '', $showSearch = false, $searchInProgress, $reponseMessages = [];
public $showProgressModal = false;
public $results = [];
public function updatedServerkey()
{
$this->showSearch = true;
if ($this->searchInProgress) {
$this->reset('results');
}
$this->searchInProgress = true;
$this->results = ConfServerLicense::where('SNKEY', 'LIKE', '%' . $this->serverkey . '%')->take(50)->get();
$this->searchInProgress = false;
}
public function selectResult($key)
{
$this->serverkey = $key;
$this->results = [];
$this->showSearch = false;
}
public function mount($selectedPatches)
{
$this->selectedPatches = $selectedPatches;
}
public function updateSelectedPatches($patchId, $allSelectPatchName)
{
if (is_array($patchId)) {
$this->selectedPatches = $patchId;
$this->selectedPatchName = $allSelectPatchName;
} else {
if (in_array($patchId, $this->selectedPatches)) {
$key = array_search($patchId, $this->selectedPatches);
if ($key !== false) {
unset($this->selectedPatches[$key]);
unset($this->allSelectPatchName[$key]);
}
} else {
$this->selectedPatches[] = $patchId;
$this->selectedPatchName[] = $allSelectPatchName;
}
}
}
public function sendSelectedPatches()
{
$this->reponseMessages = [];
if (count($this->selectedPatches) > 0 && !empty($this->serverkey)) {
foreach ($this->selectedPatches as $pId) {
$serverLicense = ConfServerLicense::where('SNKEY', $this->serverkey)->first();
if (isset($serverLicense)) {
$serverPhpVersion = $serverLicense->PHP_VERSION_ID;
$patch = ConfSmartupdate::where('PID', $pId)->first();
$patchPhpVersion = $patch->PHP_VERSION_ID;
if ($serverPhpVersion != 0 && $patchPhpVersion != 0 && $serverPhpVersion != $patchPhpVersion) {
$this->reponseMessages[] = '<span class="text-error">Serverkey : ' . $this->serverkey . " and Patch : " . $pId . " PHP version conflict</span>";
continue;
}
$checkPendding = ConfServerPendding::where("PatchID", $pId)->where("ServerID", $serverLicense->ID)->first();
if (isset($checkPendding)) {
$checkPendding = ConfServerPendding::where("PatchID", $pId)->where("ServerID", $serverLicense->ID)->update([
"TaskStatus" => "0",
"TaskFinish" => '0000_00_00 00:00:00'
]);
SendPatchEdit::logSendPatch($patch, $serverLicense->ID, "Reload Patch");
$this->reponseMessages[] = "[Reload Patch] Send Success Serverkey : " . $this->serverkey . " and Patch : " . $pId ;
} else {
$serverPedding = new ConfServerPendding;
$serverPedding->ServerID = $serverLicense->ID;
$serverPedding->PatchID = $pId;
$serverPedding->TaskDate = date("Y-m-d H:i:s");
$serverPedding->TaskType = "";
$serverPedding->TaskStatus = "0";
$serverPedding->TaskRunner = auth()->user()->USERNAME;
$serverPedding->save();
SendPatchEdit::logSendPatch($patch, $serverLicense->ID, "Add Patch");
$this->reponseMessages[] = "[Add Patch] Send Success Serverkey : " . $this->serverkey . " and Patch : " . $pId ;
}
} else {
$this->reponseMessages[] = '<span class="text-error">Serverkey : ' . $this->serverkey . ' not found</span>';
}
}
}
$this->showProgressModal = true;
}
public function render()
{
// dd($this->selectedPatches);
return view('livewire.pages.send-patch.send-multi-patch-box');
}
}
<?php
namespace App\Http\Livewire\Pages\SendPatch;
use Livewire\Component;
use Livewire\WithPagination;
use App\Models\ConfSmartUpdate;
class SendMultiPatchList extends Component
{
use WithPagination;
public $action = 'list';
public $searchBy, $editPid, $message, $keyword, $perPage = 10, $searchSelected = 'PID';
public $selectedPatches = [];
public $insertedIds = [];
protected $listeners = ['deleteItem', 'deleteSelected', 'showMultiPatchList'];
public function mount()
{
$this->searchBy = [
'PID' => 'PID',
'PATCHNAME' => 'Patch Name',
'PDESC' => 'Description',
'MAJOR_VERSION' => 'Major Vaersion',
'Remark' => 'Remark'
];
$this->selectedPatches = [];
$this->dispatchBrowserEvent('grandchild-component-loaded');
}
public function search()
{
$this->resetPage();
}
public function showMultiPatchList() {
$this->render();
}
public function loadPage($page)
{
$this->emit('menuChanged', $page);
}
public function render()
{
// dd("dd");
$query = ConfSmartUpdate::select('PID', 'PATCHNAME', 'PDESC', 'PDATE', 'PLEVEL', 'Remark', 'MAJOR_VERSION');
if ($this->searchSelected && $this->keyword) {
$query->where($this->searchSelected, 'LIKE', '%' . $this->keyword . '%');
}
$query->orderBy('PID', 'DESC');
$results = $query->paginate($this->perPage);
return view('livewire.pages.send-patch.send-multi-patch-list', [
'results' => $results,
'selectedPatches' => ConfSmartUpdate::whereIn('PID', $this->selectedPatches)->get()
]);
}
}
......@@ -51,7 +51,7 @@ class SendPatch extends Component
$query->orderBy('p1.PID', 'DESC');
$results = $query->paginate($this->perPage);
return view('livewire.pages.sendpatch.send-patch', compact('results'));
return view('livewire.pages.send-patch.send-patch', compact('results'));
}
public function search()
......
......@@ -78,7 +78,7 @@ class SendPatchEdit extends Component
->where('PatchID', $this->PID)
->paginate($this->perPage);
return view('livewire.pages.sendpatch.send-patch-edit', compact('ownerType', 'results'));
return view('livewire.pages.send-patch.send-patch-edit', compact('ownerType', 'results'));
}
......
......@@ -14,6 +14,8 @@
'pages.patch.patch-edit' => 'App\\Http\\Livewire\\Pages\\Patch\\PatchEdit',
'pages.patch.patch-index' => 'App\\Http\\Livewire\\Pages\\Patch\\PatchIndex',
'pages.role.role-index' => 'App\\Http\\Livewire\\Pages\\Role\\RoleIndex',
'pages.send-patch.send-multi-patch-box' => 'App\\Http\\Livewire\\Pages\\SendPatch\\SendMultiPatchBox',
'pages.send-patch.send-multi-patch-list' => 'App\\Http\\Livewire\\Pages\\SendPatch\\SendMultiPatchList',
'pages.send-patch.send-patch' => 'App\\Http\\Livewire\\Pages\\SendPatch\\SendPatch',
'pages.send-patch.send-patch-edit' => 'App\\Http\\Livewire\\Pages\\SendPatch\\SendPatchEdit',
'pages.user.user-index' => 'App\\Http\\Livewire\\Pages\\User\\UserIndex',
......
<div class="card mx-4 my-4 z-0 ">
<link href="{{ asset('css/pages/patch.css') }}" rel="stylesheet">
<div wire:loading.class="flex" wire:loading.class.remove="hidden"
<div wire:loading.class="" wire:loading.class.remove="hidden"
class="absolute inset-0 items-center justify-center z-50 bg-slate-50 dark:bg-navy-900 hidden">
<div class="flex justify-center items-center ">
<div class="items-center h-100vh" style="align-content: center;">
<div class="animate-spin rounded-full h-32 w-32 border-t-2 border-b-2 border-blue-500"></div>
</div>
</div>
</div>
{{-- end loading --}}
......@@ -15,13 +18,14 @@
<livewire:pages.user.user-index />
@elseif ($currentContent === 'SendPatch')
<livewire:pages.send-patch.send-patch />
@elseif ($currentContent === 'SendMultiPatch')
<livewire:pages.send-patch.send-multi-patch-list />
@elseif ($currentContent === 'Patch')
<livewire:pages.patch.patch-index />
@elseif ($currentContent === 'Parameter')
<livewire:pages.parameter.parameter-index />
@elseif ($currentContent === 'ExchangeRate')
@elseif ($currentContent === 'Exchangerate')
<livewire:pages.exchangerate.exchangerate-index />
@else
@livewire('code-comparer')
@endif
......
......@@ -2,30 +2,47 @@
<div class="container mx-auto flex justify-between items-center">
<div class="text-xl font-bold text-stone-700"><a href="/">SPN Patch</a></div>
<ul class="flex space-x-4 z-50">
<li x-data="{ open: false }" @click.away="open = false" @mouseenter="open = true" class="relative">
<a href="#" class="text-gray-700 hover:text-stone-700">Server License Management</a>
<ul x-show="open" @click="open = false" @mouseleave="open = false"
<li x-data="{ open: false, timer: null }" @click.away="open = false" @mouseenter="open = true; clearTimeout(timer)"
@mouseleave="timer = setTimeout(() => open = false, 100)"
class="relative px-2 py-1 rounded text-gray-700 hover:bg-primary-focus hover:text-white">
<a href="#">Server License Management</a>
<ul x-show="open" @click="open = false" @mouseenter="clearTimeout(timer)"
@mouseleave="timer = setTimeout(() => open = false, 100)"
class="absolute left-0 mt-2 w-48 bg-white shadow-lg">
<li><a href="#" class="block px-4 py-2 text-gray-700 hover:bg-stone-100">Submenu 1</a></li>
<li><a href="#" class="block px-4 py-2 text-gray-700 hover:bg-stone-100">Submenu 2</a></li>
<li><a href="#" class="block px-4 py-2 text-gray-700 hover:bg-stone-100">Submenu 3</a></li>
</ul>
</li>
<li x-data="{ open: false }" wire:click.prevent="loadContent('Patch')" class="relative">
<a href="#" class="text-gray-700 hover:text-stone-700">Patch</a>
<li x-data="{ open: false }" wire:click.prevent="loadContent('Patch')"
class="relative px-2 py-1 rounded text-gray-700 hover:bg-primary-focus hover:text-white">
<a href="#">Patch</a>
</li>
<li x-data="{ open: false }" wire:click.prevent="loadContent('SendPatch')" class="relative">
<a href="#" class="text-gray-700 hover:text-stone-700">Send Patch</a>
<li x-data="{ open: false, timer: null }" @click.away="open = false" @mouseenter="open = true; clearTimeout(timer)"
@mouseleave="timer = setTimeout(() => open = false, 100)"
class="relative px-2 py-1 rounded text-gray-700 hover:bg-primary-focus hover:text-white">
<span class="cursor-pointer" @click.stop wire:click.prevent="loadContent('SendPatch')">Send Patch</span>
<ul x-show="open" @click.stop="open = false" @mouseleave="open = false"
class="absolute left-0 mt-2 w-48 bg-white shadow-lg">
<li><a href="#" wire:click.prevent="loadContent('SendPatch')"
class="block px-4 py-2 text-gray-700 hover:bg-stone-100">Send Patch</a></li>
<li><a href="#" wire:click.prevent="loadContent('SendMultiPatch')"
class="block px-4 py-2 text-gray-700 hover:bg-stone-100">Send Multi Patch</a></li>
</ul>
</li>
<li x-data="{ open: false }" wire:click.prevent="loadContent('Parameter')" class="relative">
<a href="#" class="text-gray-700 hover:text-stone-700">Parameter</a>
<li x-data="{ open: false }" wire:click.prevent="loadContent('Parameter')"
class="relative px-2 py-1 rounded text-gray-700 hover:bg-primary-focus hover:text-white">
<a href="#">Parameter</a>
</li>
<li x-data="{ open: false }" wire:click.prevent="loadContent('ExchangeRate')" class="relative">
<a href="#" class="text-gray-700 hover:text-stone-700">Create Patch Exchange Rate</a>
<li x-data="{ open: false }" wire:click.prevent="loadContent('Exchangerate')"
class="relative px-2 py-1 rounded text-gray-700 hover:bg-primary-focus hover:text-white">
<a href="#">Create Patch Exchangerate</a>
</li>
<li x-data="{ open: false }" @click.away="open = false" @mouseenter="open = true" class="relative">
<a href="#" class="text-gray-700 hover:text-stone-700">Configuration</a>
<li x-data="{ open: false, timer: null }" @click.away="open = false" @mouseenter="open = true; clearTimeout(timer)"
@mouseleave="timer = setTimeout(() => open = false, 100)"
class="relative px-2 py-1 rounded text-gray-700 hover:bg-primary-focus hover:text-white">
<a href="#">Configuration</a>
<ul x-show="open" @click="open = false" @mouseleave="open = false"
class="absolute left-0 mt-2 w-48 bg-white shadow-lg">
<li><a href="#" wire:click.prevent="loadContent('Role')"
......@@ -37,7 +54,7 @@
</li>
</ul>
</li>
<li><a href="#" class="bg-stone-700 text-white px-4 py-2 rounded">Logout</a></li>
<li><a href="#" class="bg-primary text-white px-4 py-2 rounded">Logout</a></li>
<span>Hello , {{ auth()->user()->USERNAME ?? '' }}</span>
</ul>
</div>
......
......@@ -161,6 +161,7 @@
@endif
</main>
@vite(['resources/js/app.js', 'resources/js/sweetalert.js'])
</div>
<!-- <script src="//cdn.jsdelivr.net/npm/sweetalert2@11"></script> -->
......
<div wire:loading.remove>
<main class="m-2">
<div>
<div wire:loading.class="" wire:loading.class.remove="hidden"
class="absolute inset-0 items-center justify-center z-50 bg-slate-50 dark:bg-navy-900 hidden">
<div class="flex justify-center items-center ">
<div class="items-center h-100vh" style="align-content: center;">
<div class="animate-spin rounded-full h-32 w-32 border-t-2 border-b-2 border-blue-500"></div>
</div>
</div>
</div>
<main class="m-2" wire:loading.remove>
{{-- <div wire:loading.class="flex" wire:loading.class.remove="hidden"
class="absolute inset-0 items-center justify-center z-50 bg-slate-50 dark:bg-navy-900 hidden">
<div class="flex justify-center items-center ">
......@@ -28,7 +37,8 @@
</div>
<div class="flex justify-between">
<div class="px-2 ml-4">
<button type="button" class="py-2 px-3 bg-stone-700 rounded-lg text-white" wire:click="showpatchAddForm">Add</button>
<button type="button" class="py-2 px-3 bg-stone-700 rounded-lg text-white"
wire:click="showpatchAddForm">Add</button>
</div>
<div class="inline-flex flex-initial">
<div x-data="{ isInputActive: true }">
......@@ -152,9 +162,14 @@
</div>
</div>
@elseif($action === 'add')
<livewire:pages.patch.patch-create >
<livewire:pages.patch.patch-create>
@elseif($action === 'edit')
<livewire:pages.patch.patch-edit :editPid="$editPid">
@endif
@push('script')
<script>
console.log("ddd")
</script>
@endpush
</main>
</div>
<div class="w-full md:w-1/3 px-3 mb-6" x-data="{ showProgressModal: @entangle('showProgressModal') }">
<div class="p-6 bg-white shadow-md rounded-lg">
<h2 class="text-2xl font-bold mb-4">Selected Patches</h2>
<div class="bg-gray m-3">
@foreach ($selectedPatchName as $key => $patch)
<button class="bg-blue-500 text-white px-4 py-2 rounded m-1">{{ $selectedPatches[$key]." : ".$patch }}</button>
@endforeach
</div>
<div class="flex flex-col items-center">
{{-- <input type="text"
class="form-input h-9 peer w-full rounded-lg border border-slate-300 bg-transparent px-3 py-2 placeholder:text-slate-400/70 hover:border-slate-400 focus:border-primary dark:border-navy-450 dark:hover:border-navy-400 dark:focus:border-accent"
name="serverkey" id="serverkey"> --}}
<div>
<input type="text"
class="form-input h-9 peer w-full rounded-lg border border-slate-300 bg-transparent px-3 py-2 placeholder:text-slate-400/70 hover:border-slate-400 focus:border-primary dark:border-navy-450 dark:hover:border-navy-400 dark:focus:border-accent"
wire:model.debounce.500ms="serverkey" placeholder="Search for a server key">
@if (!empty($serverkey) && $showSearch)
<ul class="mt-2 border border-gray-200 rounded-md max-h-64 overflow-auto">
@forelse($results as $result)
<li class="p-2 hover:bg-gray-100 cursor-pointer"
wire:click="selectResult('{{ $result->SNKEY }}')">
{{ $result->SNKEY }}
</li>
@empty
<li class="p-2 text-gray-500">No results found</li>
@endforelse
</ul>
@endif
</div>
<button type="button" class="bg-stone-700 text-white px-4 py-2 rounded max-w-xs mt-4"
wire:click="sendSelectedPatches" @click="showProgressModal = true" wire:loading.attr="disabled"
type="button" class="bg-stone-700 text-white px-4 py-2 rounded relative">
<span wire:loading.remove>Send Patch</span>
<span wire:loading>
<svg class="animate-spin h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor"
stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.964 7.964 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z">
</path>
</svg>
</span>
</button>
</div>
</div>
<div x-show="showProgressModal" x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 scale-90" x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-300" x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-90" class="fixed z-10 inset-0 overflow-y-auto">
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<div x-show="showProgressModal" class="fixed inset-0 transition-opacity" aria-hidden="true">
<div class="absolute inset-0 bg-gray-500 opacity-75"></div>
</div>
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
<div x-show="showProgressModal"
class="inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:p-6">
<div>
<div class="mt-3 text-center sm:mt-5">
<h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">
Inserted Patch IDs
</h3>
<div class="mt-2">
<ul>
@if (count($reponseMessages) > 0)
@foreach ($reponseMessages as $message)
<li>{!! $message !!}</li>
@endforeach
@endif
</ul>
</div>
</div>
</div>
<div class="mt-5 sm:mt-6">
<button @click="showProgressModal = false" type="button"
class="inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 bg-green-600 text-base font-medium text-white hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 sm:text-sm">
Close
</button>
</div>
</div>
</div>
</div>
</div>
<div x-data=" {
selectedPatch: [],
selectedPatchByPage: {},
allSelectPatches: [],
allSelectPatchName: [],
currentPage: @entangle('page'), // Bind currentPage to Livewire 'page' variable
init() {
this.$watch('currentPage', (value) => {
this.loadSelectedPatch();
this.resetCheckAllCheckbox();
});
// this.$watch('selectedPatch.length', () => {
// this.resetCheckAllCheckbox();
// });
this.loadSelectedPatch();
},
toggleAllCheckboxes(event) {
const checkboxes = document.querySelectorAll('.individual-checkbox');
const isChecked = event.target.checked;
checkboxes.forEach(checkbox => {
checkbox.checked = isChecked;
// Livewire.emit('updateSelectedPatches', checkbox.value);
const patchName = checkbox.getAttribute('data-patchname');
this.updatePatchSelection(checkbox.value, patchName, isChecked);
});
this.updateSelectedPatchList();
},
updateSelectedPatch(event) {
const patchName = event.target.getAttribute('data-patchname');
this.updatePatchSelection(event.target.value, patchName, event.target.checked);
this.updateSelectedPatchList();
},
updatePatchSelection(patch, patchName, isSelected) {
const pagePatches = this.selectedPatchByPage[this.currentPage] || [];
console.log(this.allSelectPatches)
console.log(this.allSelectPatchName)
if (isSelected) {
if (!pagePatches.includes(patch)) {
pagePatches.push(patch);
this.allSelectPatches.push(patch);
this.allSelectPatchName.push(patchName);
}
} else {
const indexPage = pagePatches.indexOf(patch);
const indexAll = this.allSelectPatches.indexOf(patch);
if (indexPage !== -1) {
pagePatches.splice(indexPage, 1);
}
if (indexAll !== -1) {
this.allSelectPatches.splice(indexAll, 1);
this.allSelectPatchName.splice(indexAll, 1);
}
}
Livewire.emit('updateSelectedPatches', this.allSelectPatches, this.allSelectPatchName);
this.selectedPatchByPage[this.currentPage] = pagePatches;
},
updateSelectedPatchList() {
this.selectedPatch = Object.values(this.selectedPatchByPage).flat();
},
loadSelectedPatch() {
const pagePatches = this.selectedPatchByPage[this.currentPage] || [];
const checkboxes = document.querySelectorAll('.individual-checkbox');
checkboxes.forEach(checkbox => {
checkbox.checked = pagePatches.includes(checkbox.value);
});
this.updateSelectedPatchList();
},
resetCheckAllCheckbox() {
const checkAllCheckbox = document.getElementById('check-all');
const pagePatches = this.selectedPatchByPage[this.currentPage] || [];
const checkboxes = document.querySelectorAll('.individual-checkbox');
checkAllCheckbox.checked = checkboxes.length > 0 && pagePatches.length === checkboxes
.length;
}
}" x-init="$watch('selectedPatch', () => resetCheckAllCheckbox())">
<style>
.animate-spin {
animation: spin 1s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
<div class="max-w-full mx-auto p-6 bg-gray-100">
@if (session()->has('message'))
<div class="alert alert-success">
{{ session('message') }}
</div>
@endif
<div class="flex flex-wrap -mx-3">
<div class="w-full md:w-2/3 px-3 mb-6">
<div class="p-6 bg-white shadow-md rounded-lg">
<div x-show="true" class="">
<div class="flex justify-between mb-5">
<h2
class="font-medium tracking-wide text-slate-700 line-clamp-1 dark:text-navy-100 lg:text-base">
Send Multi Patch
</h2>
<div class="inline-flex flex-initial">
<div x-data="{ isInputActive: true }">
<div class="flex gap-4 px-5 items-center">
<button @click="isInputActive = !isInputActive"
class="btn h-8 w-14 rounded-full p-0 hover:bg-slate-300/20 focus:bg-slate-300/20 active:bg-slate-300/25 dark:hover:bg-navy-300/20 dark:focus:bg-navy-300/20 dark:active:bg-navy-300/25">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4.5 w-4.5" fill="none"
viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
</button>
<span class="w-64" x-show="isInputActive === true">
<input
class="form-input h-9 peer w-full rounded-lg border border-slate-300 bg-transparent px-3 py-2 placeholder:text-slate-400/70 hover:border-slate-400 focus:border-primary dark:border-navy-450 dark:hover:border-navy-400 dark:focus:border-accent"
placeholder="Search Keyword" type="text"
wire:model.defer="keyword" />
</span>
<span class="w-52" x-show="isInputActive === true">
<select wire:model.defer="searchSelected"
class="form-select h-9 w-full rounded-lg border border-slate-300 bg-white px-3 py-2 hover:border-slate-400 focus:border-primary dark:border-navy-450 dark:bg-navy-700 dark:hover:border-navy-400 dark:focus:border-accent">
@foreach ($searchBy as $key => $by)
<option value="{{ $key }}">{{ $by }}</option>
@endforeach
</select>
</span>
<button type="button" class="bg-stone-700 text-white px-4 py-2 rounded"
wire:click="search">Search</button>
</div>
</div>
</div>
</div>
<div class="mx-3 mt-3 px-4">
<div class="is-scrollbar-hidden min-w-full table-responsive">
<table class="is-hoverable table w-full text-left">
<thead>
<tr>
<th
class="whitespace-nowrap rounded-tl-lg bg-slate-200 px-4 py-3 font-semibold uppercase text-slate-800 dark:bg-navy-800 dark:text-navy-100 lg:px-5">
<input
class="form-checkbox is-basic h-4 w-4 rounded border-slate-400/70 checked:bg-primary checked:border-primary hover:border-primary focus:border-primary dark:bg-navy-900 dark:border-navy-500 dark:checked:bg-accent dark:checked:border-accent dark:hover:border-accent dark:focus:border-accent"
type="checkbox" id="check-all" @click="toggleAllCheckboxes" />
</th>
<th
class="whitespace-nowrap bg-slate-200 px-2 py-3 font-semibold uppercase text-slate-800 dark:bg-navy-800 dark:text-navy-100 lg:px-2">
Patch ID
</th>
<th
class="whitespace-nowrap bg-slate-200 px-2 py-3 font-semibold uppercase text-slate-800 dark:bg-navy-800 dark:text-navy-100 lg:px-2">
Patch Name
</th>
<th
class="whitespace-nowrap bg-slate-200 px-2 py-3 font-semibold uppercase text-slate-800 dark:bg-navy-800 dark:text-navy-100 lg:px-2">
Description
</th>
<th
class="whitespace-nowrap bg-slate-200 px-2 py-3 font-semibold uppercase text-slate-800 dark:bg-navy-800 dark:text-navy-100 lg:px-2">
Server
</th>
<th
class="whitespace-nowrap bg-slate-200 px-2 py-3 font-semibold uppercase text-slate-800 dark:bg-navy-800 dark:text-navy-100 lg:px-2">
Date
</th>
<th
class="whitespace-nowrap rounded-tr-lg bg-slate-200 px-2 py-3 font-semibold uppercase text-slate-800 dark:bg-navy-800 dark:text-navy-100 lg:px-2">
Remark
</th>
</tr>
</thead>
<tbody>
@foreach ($results as $patch)
<tr
class="border-y border-transparent border-b-slate-200 dark:border-b-navy-500">
<td class="whitespace-nowrap px-4 py-3 sm:px-5">
<label class="inline-flex items-center space-x-2">
<input
class="form-checkbox individual-checkbox is-basic h-4 w-4 rounded border-slate-400/70 checked:bg-primary checked:border-primary hover:border-primary focus:border-primary dark:bg-navy-900 dark:border-navy-500 dark:checked:bg-accent dark:checked:border-accent dark:hover:border-accent dark:focus:border-accent"
type="checkbox" @click="updateSelectedPatch"
value="{{ $patch->PID }}"
data-patchname = "{{ $patch->PATCHNAME }}" />
</label>
</td>
<td class="whitespace-nowrap px-1 py-3 sm:px-2">{{ $patch->PID }}</td>
<td class="whitespace-nowrap px-1 py-3 sm:px-2"
data-id="{{ $patch->PID }}">
{{ \Illuminate\Support\Str::limit($patch->PATCHNAME, 40) }}
</td>
<td class="whitespace-nowrap px-1 py-3 sm:px-2">
{{ \Illuminate\Support\Str::limit($patch->PDESC, 40) }}</td>
<td class="whitespace-nowrap px-1 py-3 sm:px-2">{{ $patch->server }}
</td>
<td class="whitespace-nowrap px-1 py-3 sm:px-2">{{ $patch->PDATE }}
</td>
<td class="whitespace-nowrap px-1 py-3 sm:px-2">{{ $patch->Remark }}
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<livewire:delete-modal />
{{ $results->links('livewire.paginate-custom') }}
</div>
</div>
</div>
</div>
<livewire:pages.send-patch.send-multi-patch-box :selectedPatches="$selectedPatches">
</div>
</div>
</div>
<!-- example-component.blade.php -->
<div x-data="patchManager()" x-init="$watch('selectedPatch', () => resetCheckAllCheckbox())">
<style>
.animate-spin {
animation: spin 1s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
<div class="max-w-full mx-auto p-6 bg-gray-100">
@if (session()->has('message'))
<div class="alert alert-success">
{{ session('message') }}
</div>
@endif
<div class="flex flex-wrap -mx-3">
<div class="w-full md:w-2/3 px-3 mb-6">
<div class="p-6 bg-white shadow-md rounded-lg">
<div x-show="true" class="">
<div class="flex justify-between mb-5">
<h2
class="font-medium tracking-wide text-slate-700 line-clamp-1 dark:text-navy-100 lg:text-base">
Send Multi Patch
</h2>
<div class="inline-flex flex-initial">
<div x-data="{ isInputActive: true }">
<div class="flex gap-4 px-5 items-center">
<button @click="isInputActive = !isInputActive"
class="btn h-8 w-14 rounded-full p-0 hover:bg-slate-300/20 focus:bg-slate-300/20 active:bg-slate-300/25 dark:hover:bg-navy-300/20 dark:focus:bg-navy-300/20 dark:active:bg-navy-300/25">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4.5 w-4.5" fill="none"
viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
</button>
<span class="w-64" x-show="isInputActive === true">
<input
class="form-input h-9 peer w-full rounded-lg border border-slate-300 bg-transparent px-3 py-2 placeholder:text-slate-400/70 hover:border-slate-400 focus:border-primary dark:border-navy-450 dark:hover:border-navy-400 dark:focus:border-accent"
placeholder="Search Keyword" type="text"
wire:model.defer="keyword" />
</span>
<span class="w-52" x-show="isInputActive === true">
<select wire:model.defer="searchSelected"
class="form-select h-9 w-full rounded-lg border border-slate-300 bg-white px-3 py-2 hover:border-slate-400 focus:border-primary dark:border-navy-450 dark:bg-navy-700 dark:hover:border-navy-400 dark:focus:border-accent">
@foreach ($searchBy as $key => $by)
<option value="{{ $key }}">{{ $by }}</option>
@endforeach
</select>
</span>
<button type="button" class="bg-stone-700 text-white px-4 py-2 rounded"
wire:click="search">Search</button>
</div>
</div>
</div>
</div>
<div class="mx-3 mt-3 px-4">
<div class="is-scrollbar-hidden min-w-full table-responsive">
<table class="is-hoverable table w-full text-left">
<thead>
<tr>
<th
class="whitespace-nowrap rounded-tl-lg bg-slate-200 px-4 py-3 font-semibold uppercase text-slate-800 dark:bg-navy-800 dark:text-navy-100 lg:px-5">
<input
class="form-checkbox is-basic h-4 w-4 rounded border-slate-400/70 checked:bg-primary checked:border-primary hover:border-primary focus:border-primary dark:bg-navy-900 dark:border-navy-500 dark:checked:bg-accent dark:checked:border-accent dark:hover:border-accent dark:focus:border-accent"
type="checkbox" id="check-all" @click="toggleAllCheckboxes" />
</th>
<th
class="whitespace-nowrap bg-slate-200 px-2 py-3 font-semibold uppercase text-slate-800 dark:bg-navy-800 dark:text-navy-100 lg:px-2">
Patch ID
</th>
<th
class="whitespace-nowrap bg-slate-200 px-2 py-3 font-semibold uppercase text-slate-800 dark:bg-navy-800 dark:text-navy-100 lg:px-2">
Patch Name
</th>
<th
class="whitespace-nowrap bg-slate-200 px-2 py-3 font-semibold uppercase text-slate-800 dark:bg-navy-800 dark:text-navy-100 lg:px-2">
Description
</th>
<th
class="whitespace-nowrap bg-slate-200 px-2 py-3 font-semibold uppercase text-slate-800 dark:bg-navy-800 dark:text-navy-100 lg:px-2">
Server
</th>
<th
class="whitespace-nowrap bg-slate-200 px-2 py-3 font-semibold uppercase text-slate-800 dark:bg-navy-800 dark:text-navy-100 lg:px-2">
Date
</th>
<th
class="whitespace-nowrap rounded-tr-lg bg-slate-200 px-2 py-3 font-semibold uppercase text-slate-800 dark:bg-navy-800 dark:text-navy-100 lg:px-2">
Remark
</th>
</tr>
</thead>
<tbody>
@foreach ($results as $patch)
<tr
class="border-y border-transparent border-b-slate-200 dark:border-b-navy-500">
<td class="whitespace-nowrap px-4 py-3 sm:px-5">
<label class="inline-flex items-center space-x-2">
<input
class="form-checkbox individual-checkbox is-basic h-4 w-4 rounded border-slate-400/70 checked:bg-primary checked:border-primary hover:border-primary focus:border-primary dark:bg-navy-900 dark:border-navy-500 dark:checked:bg-accent dark:checked:border-accent dark:hover:border-accent dark:focus:border-accent"
type="checkbox" x-model="selectedPatch"
value="{{ $patch->PID }}"
wire:click="updateSelectedPatch" />
</label>
</td>
<td class="whitespace-nowrap px-1 py-3 sm:px-2">{{ $patch->PID }}</td>
<td class="whitespace-nowrap px-1 py-3 sm:px-2"
data-id="{{ $patch->PID }}">
{{ \Illuminate\Support\Str::limit($patch->PATCHNAME, 40) }}
</td>
<td class="whitespace-nowrap px-1 py-3 sm:px-2">
{{ \Illuminate\Support\Str::limit($patch->PDESC, 40) }}</td>
<td class="whitespace-nowrap px-1 py-3 sm:px-2">{{ $patch->server }}
</td>
<td class="whitespace-nowrap px-1 py-3 sm:px-2">{{ $patch->PDATE }}
</td>
<td class="whitespace-nowrap px-1 py-3 sm:px-2">{{ $patch->Remark }}
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<livewire:delete-modal />
{{ $results->links('livewire.paginate-custom') }}
</div>
</div>
</div>
</div>
<livewire:pages.send-patch.send-multi-patch-box>
</div>
</div>
{{-- <div x-show="showModal" x-data="{ showModal: false }" @patchInserted.window="showModal = true"
x-transition:enter="transition ease-out duration-300" x-transition:enter-start="opacity-0 scale-90"
x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-300"
x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-90"
class="fixed z-10 inset-0 overflow-y-auto">
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<div x-show="showModal" class="fixed inset-0 transition-opacity" aria-hidden="true">
<div class="absolute inset-0 bg-gray-500 opacity-75"></div>
</div>
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
<div x-show="showModal"
class="inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:p-6">
<div>
<div class="mt-3 text-center sm:mt-5">
<h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">
Inserted Patch IDs
</h3>
<div class="mt-2">
<ul>
@foreach ($insertedIds as $id)
<li>{{ $id }}</li>
@endforeach
</ul>
</div>
</div>
</div>
<div class="mt-5 sm:mt-6">
<button @click="showModal = false" type="button"
class="inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 bg-green-600 text-base font-medium text-white hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 sm:text-sm">
Close
</button>
</div>
</div>
</div>
</div> --}}
<script>
function patchManager() {
return {
selectedPatch: [],
selectedPatchByPage: {},
currentPage: @entangle('page'), // Bind currentPage to Livewire 'page' variable
// init() {
// this.$watch('currentPage', (value) => {
// this.loadSelectedPatch();
// this.resetCheckAllCheckbox();
// });
// this.$watch('selectedPatch.length', () => {
// this.resetCheckAllCheckbox();
// });
// this.loadSelectedPatch();
// },
toggleAllCheckboxes(event) {
const checkboxes = document.querySelectorAll('.individual-checkbox');
const isChecked = event.target.checked;
checkboxes.forEach(checkbox => {
checkbox.checked = isChecked;
@this.call('updateSelectedPatch', checkbox.value);
// this.updatePatchSelection(checkbox.value, isChecked);
});
this.updateSelectedPatchList();
},
// updateSelectedPatch(event) {
// this.updatePatchSelection(event.target.value, event.target.checked);
// this.updateSelectedPatchList();
// },
// updatePatchSelection(patch, isSelected) {
// const pagePatches = this.selectedPatchByPage[this.currentPage] || [];
// if (isSelected) {
// if (!pagePatches.includes(patch)) {
// pagePatches.push(patch);
// }
// } else {
// const index = pagePatches.indexOf(patch);
// if (index !== -1) {
// pagePatches.splice(index, 1);
// }
// }
// this.selectedPatchByPage[this.currentPage] = pagePatches;
// },
// updateSelectedPatchList() {
// this.selectedPatch = Object.values(this.selectedPatchByPage).flat();
// },
// loadSelectedPatch() {
// const pagePatches = this.selectedPatchByPage[this.currentPage] || [];
// const checkboxes = document.querySelectorAll('.individual-checkbox');
// checkboxes.forEach(checkbox => {
// checkbox.checked = pagePatches.includes(checkbox.value);
// });
// this.updateSelectedPatchList();
// },
// resetCheckAllCheckbox() {
// const checkAllCheckbox = document.getElementById('check-all');
// const pagePatches = this.selectedPatchByPage[this.currentPage] || [];
// const checkboxes = document.querySelectorAll('.individual-checkbox');
// checkAllCheckbox.checked = checkboxes.length > 0 && pagePatches.length === checkboxes.length;
// },
// sendSelectedPatches() {
// @this.call('setPagePatches', this.selectedPatch);
// @this.call('sendPatch');
// }
}
}
</script>
</div>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment