Commit 755b18d3 authored by Sarun Mungthanya's avatar Sarun Mungthanya
Browse files

add edit patch

parent f0a4d521
...@@ -7,7 +7,12 @@ use Livewire\Component; ...@@ -7,7 +7,12 @@ use Livewire\Component;
class Navbar extends Component class Navbar extends Component
{ {
public $currentMenu = 'DeleteMultiPatch'; public $currentMenu = 'DeleteMultiPatch';
public $navLoaded = false;
public function loadNav()
{
$this->navLoaded = true;
}
public function loadContent($menu) public function loadContent($menu)
{ {
$this->currentMenu = $menu; $this->currentMenu = $menu;
......
<?php
namespace App\Http\Livewire\Pages\Patch;
use App\Models\TabPatchFile;
use Livewire\Component;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use Jfcherng\Diff\Differ;
use Jfcherng\Diff\DiffHelper;
use Jfcherng\Diff\Factory\RendererFactory;
class ModalFormPatchFile extends Component
{
public $openModalFormPatchFile = false;
public $patchFileId, $patchId, $patchFile, $dbCode, $fileName, $commit, $comparisonResult, $diffResult, $message;
public $preImpHeader;
public $isOpenFormPatchFile = false;
protected $listeners = ['openModalFormPatchFile', 'deleteSubItem'];
public function openModalFormPatchFile($patchFileId = null, $patchId = null)
{
$this->patchFileId = $patchFileId;
$this->patchId = $patchId;
if (isset($patchFileId) && $patchFileId !== '') {
$patchFile = TabPatchFile::where('fid', $this->patchFileId)->first();
$this->patchFile = $patchFile->file_name;
$this->dbCode = base64_decode($patchFile->file_data);
$this->dbCode = (iconv('TIS-620', 'UTF-8', $this->dbCode));
}else{
$this->patchFile = '';
$this->dbCode = '';
}
$this->isOpenFormPatchFile = true;
}
public function closeModal()
{
$this->isOpenFormPatchFile = false;
}
public function updateCode()
{
}
private function getFileContentFromGit($filePath, $commit)
{
$token = env('GITLAB_API_TOKEN');
$client = new Client([
'base_uri' => 'https://idemo.netbay.co.th/gitlab/api/v4/',
'headers' => [
'Authorization' => "Bearer $token",
'Accept' => 'application/json',
],
'verify' => false,
]);
if (strpos($filePath, "../SPN/") !== false) {
$filePath = str_replace("../SPN/", "SPN/", $filePath);
} else if (strpos($filePath, "../spn/") !== false) {
$filePath = str_replace("../spn/", "spn/", $filePath);
} else {
$filePath = str_replace("./", "IE5DEV.shippingnet/", $filePath);
}
try {
$response = $client->get("projects/{$this->selectedProject}/repository/files/" . urlencode($filePath) . "/raw", [
'query' => ['ref' => $commit]
]);
$statusCode = $response->getStatusCode();
$content = $response->getBody()->getContents();
if ($statusCode == 200) {
return $content;
} else {
throw new \Exception("Failed to fetch file. Status code: $statusCode");
}
} catch (RequestException $e) {
throw $e;
} catch (\Exception $e) {
throw $e;
}
}
public function getDiff($code1, $code2)
{
$diffOptions = [
'context' => 0,
'ignoreCase' => false,
'ignoreWhitespace' => true,
];
$rendererOptions = [
'detailLevel' => 'char',
'language' => 'eng',
'lineNumbers' => true,
'separateBlock' => true,
'showHeader' => true,
'spacesToNbsp' => false,
'outputFormat' => 'inline',
'mergeThreshold' => 0.8,
'originalFileName' => 'Original',
'newFileName' => 'New',
'cliColorization' => 'none',
];
$differ = new Differ(explode("\n", $code1), explode("\n", $code2), $diffOptions);
$renderer = RendererFactory::make('Inline', $rendererOptions);
$result = $renderer->render($differ);
$result = $this->convertDiffToPrismFormat($result);
return $result;
}
public function compare()
{
try {
// $this->comparisonResult = 'GitLab connection successful.';
$this->diffResult = $this->getDiff($this->gitCode, $this->dbCode);
// dd($this->diffResult);
$this->emit('diffResultUpdated');
} catch (RequestException $e) {
$this->comparisonResult = 'Error connecting to GitLab: ' . $e->getMessage();
// $this->gitCode = '';
// $this->gitCodeRaw = '';
}
}
private function convertDiffToPrismFormat($diffHtml)
{
$diffHtml = str_replace('<tr data-type="-"', '<tr class="token deleted"', $diffHtml);
$diffHtml = str_replace('<tr data-type="+"', '<tr class="token inserted"', $diffHtml);
$diffHtml = str_replace('<td class="old">', '<td class="token deleted">', $diffHtml);
$diffHtml = str_replace('<td class="new">', '<td class="token inserted">', $diffHtml);
$diffHtml = str_replace('<th class="sign del">-</th>', '', $diffHtml);
$diffHtml = str_replace('<th class="sign ins">+</th>', '', $diffHtml);
return $diffHtml;
}
public function showDeleteItemModal($patchFileId)
{
$this->emit('showDeleteItemModal', $patchFileId);
}
public function deleteSubItem($patchFileId)
{
$pathFile = TabPatchFile::where("fid", $patchFileId)->first();
$patchId = $pathFile->ptid;
$pathFile = TabPatchFile::where("fid", $patchFileId)->delete();
$message = "Deleted File ID : " . json_encode($patchFileId) . " Successfully";
$this->message = $message;
$this->emit('reloadComponent', $patchId);
$this->isOpenFormPatchFile = false;
}
public function render()
{
return view('livewire.pages.patch.modal-form-patch-file');
}
public function saveCode($dbCode, $fileName)
{
$dbCode = (iconv('UTF-8', 'TIS-620', $dbCode));
if (isset($this->patchFileId) && $this->patchFileId !== '') {
$pathFile = TabPatchFile::where("fid", $this->patchFileId)->first();
$pathFile->file_name = $fileName;
$pathFile->file_data = base64_encode($dbCode);
$pathFile->save();
} else {
$filepath = new TabPatchFile;
$filepath->ptid = $this->patchId;
$filepath->file_name = $fileName;
$filepath->file_data = base64_encode($dbCode);
$filepath->save();
}
$this->isOpenFormPatchFile = false;
$this->emit('reloadComponent',$this->patchId );
}
}
<?php <?php
namespace App\Http\Livewire\Pages\Patch; namespace App\Http\Livewire\Pages\Patch;
use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Exception\RequestException;
use App\Models\ConfSmartupdate; use App\Models\ConfSmartupdate;
use App\Models\MasterPhpVer; use App\Models\MasterPhpVer;
...@@ -10,6 +11,7 @@ use GuzzleHttp\Client; ...@@ -10,6 +11,7 @@ use GuzzleHttp\Client;
use ZipArchive; use ZipArchive;
use Symfony\Component\Process\Exception\ProcessFailedException; use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
class PatchCreate extends Component class PatchCreate extends Component
{ {
public $projects = []; public $projects = [];
...@@ -99,6 +101,7 @@ class PatchCreate extends Component ...@@ -99,6 +101,7 @@ class PatchCreate extends Component
'verify' => false, 'verify' => false,
]); ]);
try {
$response = $client->get(env('GITLAB_API_URL') . "/projects/{$this->selectedProject}/repository/compare", [ $response = $client->get(env('GITLAB_API_URL') . "/projects/{$this->selectedProject}/repository/compare", [
'query' => [ 'query' => [
'from' => $this->startCommit, 'from' => $this->startCommit,
...@@ -107,12 +110,14 @@ class PatchCreate extends Component ...@@ -107,12 +110,14 @@ class PatchCreate extends Component
]); ]);
$data = json_decode($response->getBody(), true); $data = json_decode($response->getBody(), true);
foreach ($data['diffs'] as $file) { foreach ($data['diffs'] as $file) {
$this->filePathChanges[] = $file['new_path']; $this->filePathChanges[] = $file['new_path'];
} }
$this->fileChanges = $this->buildTree($data['diffs']); $this->fileChanges = $this->buildTree($data['diffs']);
} catch (\Throwable $th) {
$data = '';
}
$this->dispatchBrowserEvent('files-fetched', ['fileChanges' => $this->fileChanges]); $this->dispatchBrowserEvent('files-fetched', ['fileChanges' => $this->fileChanges]);
} }
...@@ -190,7 +195,7 @@ class PatchCreate extends Component ...@@ -190,7 +195,7 @@ class PatchCreate extends Component
$confSmartUpdate->POWNER = $this->POWNER; $confSmartUpdate->POWNER = $this->POWNER;
$confSmartUpdate->PAPPROVEDATE = $this->PAPPROVEDATE; $confSmartUpdate->PAPPROVEDATE = $this->PAPPROVEDATE;
$confSmartUpdate->PTYPE = $this->PTYPE; $confSmartUpdate->PTYPE = $this->PTYPE;
$confSmartUpdate->PATCHCODE = ($codePhpVersion->check_code ?? ''). " " .$this->PATCHCODE; $confSmartUpdate->PATCHCODE = ($codePhpVersion->check_code ?? '') . " " . $this->PATCHCODE;
$confSmartUpdate->UNINSTALL = $this->UNINSTALL; $confSmartUpdate->UNINSTALL = $this->UNINSTALL;
$confSmartUpdate->PATCHCODE_SERVER = $this->PATCHCODE_SERVER; $confSmartUpdate->PATCHCODE_SERVER = $this->PATCHCODE_SERVER;
$confSmartUpdate->save(); $confSmartUpdate->save();
...@@ -200,24 +205,31 @@ class PatchCreate extends Component ...@@ -200,24 +205,31 @@ class PatchCreate extends Component
$filedata = $this->getFileContentFromGit($file, $this->endCommit); $filedata = $this->getFileContentFromGit($file, $this->endCommit);
if(strpos( $file, 'SPN/') !== false ) { $filePath = $this->formatFilePath($file);
$real_file = str_replace("SPN/", "../SPN/", $file);
}else if(strpos( $file, 'spn/') !== false) {
$real_file = str_replace("spn/", "../spn/", $file);
}else{
$real_file = str_replace("IE5DEV.shippingnet", ".", $file);
}
$filepath = new TabPatchFile; $filepath = new TabPatchFile;
$filepath->ptid = $confSmartUpdate->PID; $filepath->ptid = $confSmartUpdate->PID;
$filepath->file_name = $real_file; $filepath->file_name = $filePath;
$filepath->file_data = base64_encode($filedata); $filepath->file_data = base64_encode($filedata);
$filepath->save(); $filepath->save();
} }
} }
session()->flash('message', 'Patch details saved successfully.'); // session()->flash('message', 'Patch details saved successfully.');
return redirect()->route('patch.index')->with('message', 'Patch details saved successfully.');
} }
private function formatFilePath($file)
{
if (strpos($file, 'SPN/') !== false) {
return str_replace("SPN/", "../SPN/", $file);
} else if (strpos($file, 'spn/') !== false) {
return str_replace("spn/", "../spn/", $file);
} else {
return str_replace("IE5DEV.shippingnet", ".", $file);
}
}
private function getFileContentFromGit($filePath, $commit) private function getFileContentFromGit($filePath, $commit)
{ {
$token = env('GITLAB_API_TOKEN'); $token = env('GITLAB_API_TOKEN');
...@@ -244,13 +256,16 @@ class PatchCreate extends Component ...@@ -244,13 +256,16 @@ class PatchCreate extends Component
throw new \Exception("Failed to fetch file. Status code: $statusCode"); throw new \Exception("Failed to fetch file. Status code: $statusCode");
} }
} catch (RequestException $e) { } catch (RequestException $e) {
throw $e; return '';
// throw $e;
} catch (\Exception $e) { } catch (\Exception $e) {
throw $e; return '';
// throw $e;
} }
} }
public function loadPage($page) { public function loadPage($page)
{
$this->emit('menuChanged', $page); $this->emit('menuChanged', $page);
} }
public function render() public function render()
......
...@@ -7,16 +7,20 @@ use App\Models\ConfSmartUpdate; ...@@ -7,16 +7,20 @@ use App\Models\ConfSmartUpdate;
use App\Models\TabPatchFile; use App\Models\TabPatchFile;
use GuzzleHttp\Client; use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Exception\RequestException;
use Illuminate\Support\Facades\Cache;
class PatchEdit extends Component class PatchEdit extends Component
{ {
public $patchId; public $patchId;
public $progressSave = 0 ,$isProcessing = false;
public $searchProject = ''; public $searchProject = '';
public $selectedBranch , $selectedPatch; public $selectedBranch, $selectedPatch, $showModal;
public $selectedProject; public $selectedProject;
public $projects = []; public $projects = [];
public $branches = []; public $branches = [];
public $fileGitChanges = [];
public $filePatchChanges = [];
public $filePatch = [];
public $fileChangesTemp = [];
public $fileChanges = []; public $fileChanges = [];
public $startCommit; public $startCommit;
public $endCommit; public $endCommit;
...@@ -35,12 +39,72 @@ class PatchEdit extends Component ...@@ -35,12 +39,72 @@ class PatchEdit extends Component
public $UNINSTALL; public $UNINSTALL;
public $PATCHCODE_SERVER; public $PATCHCODE_SERVER;
public $filePathChanges = []; public $filePathChanges = [];
protected $listeners = [ 'gotoModal', 'reloadComponent']; protected $listeners = ['gotoModal', 'reloadComponent', 'deletePatchFile'];
public $modalLoaded = false;
public function loadModal()
{
$this->modalLoaded = true;
}
public function mount($editPid) public function mount($editPid)
{ {
$editPid = '15689'; // remove this when real
$this->patchId = $editPid; $this->patchId = $editPid;
$this->loadPatchData(); $this->loadPatchData();
} }
public function getChangedFiles()
{
$this->fileChangesTemp = [];
$client = new Client([
'headers' => [
'Authorization' => 'Bearer ' . env('GITLAB_API_TOKEN'),
'Accept' => 'application/json',
],
'verify' => false,
]);
try {
$response = $client->get(env('GITLAB_API_URL') . "/projects/{$this->selectedProject}/repository/compare", [
'query' => [
'from' => $this->startCommit,
'to' => $this->endCommit,
],
]);
$data = json_decode($response->getBody(), true);
foreach ($data['diffs'] as $file) {
$this->fileChangesTemp[] = $file['new_path'];
}
$this->fileGitChanges = $this->buildTreeEdit($data['diffs']);
} catch (\Throwable $th) {
$data = '';
}
}
private function buildTreeEdit($files)
{
$tree = [];
foreach ($files as $file) {
$path = explode('/', $file['new_path']);
$current = &$tree;
foreach ($path as $part) {
if (!isset($current[$part])) {
$current[$part] = [];
}
$current = &$current[$part];
}
// $current['id'] = $file['fid'];
}
return $tree;
}
public function reloadComponent($id) public function reloadComponent($id)
{ {
$this->patchId = $id; $this->patchId = $id;
...@@ -66,35 +130,35 @@ class PatchEdit extends Component ...@@ -66,35 +130,35 @@ class PatchEdit extends Component
$this->PATCHCODE_SERVER = $patch->PATCHCODE_SERVER; $this->PATCHCODE_SERVER = $patch->PATCHCODE_SERVER;
$filePath = TabPatchFile::where("ptid", $this->patchId)->get()->toArray(); $filePath = TabPatchFile::where("ptid", $this->patchId)->get()->toArray();
$filePath = $this->buildTree($filePath);
$this->fileChanges = $filePath ; $this->filePatch = $filePath;
$this->filePatchChanges = $this->buildTree($filePath);
} }
public function save() public function save()
{ {
$this->isProcessing = true;
$this->validate([ // $this->validate([
'PATCHNAME' => 'required|string|max:255', // 'PATCHNAME' => 'required|string|max:255',
'PDATE' => 'required|date', // 'PDATE' => 'required|date',
'PHP_VERSION' => 'required|integer', // 'PHP_VERSION' => 'required|integer',
'PLEVEL' => 'required|string|max:255', // 'PLEVEL' => 'required|string|max:255',
'PCODE' => 'required|string|max:255', // 'PCODE' => 'required|string|max:255',
'MAJOR_VERSION' => 'required|string|max:255', // 'MAJOR_VERSION' => 'required|string|max:255',
'PDESC' => 'required|string|max:255', // 'PDESC' => 'required|string|max:255',
'Remark' => 'required|string|max:255', // 'Remark' => 'required|string|max:255',
'POWNER' => 'required|string|max:255', // 'POWNER' => 'required|string|max:255',
'PAPPROVEDATE' => 'required|date', // 'PAPPROVEDATE' => 'required|date',
'PTYPE' => 'required|string|max:255', // 'PTYPE' => 'required|string|max:255',
'PATCHCODE' => 'required|string', // 'PATCHCODE' => 'required|string',
'UNINSTALL' => 'required|string|max:255', // 'UNINSTALL' => 'required|string|max:255',
'PATCHCODE_SERVER' => 'required|string', // 'PATCHCODE_SERVER' => 'required|string',
]); // ]);
$confSmartUpdate = ConfSmartUpdate::findOrFail($this->patchId); $confSmartUpdate = ConfSmartUpdate::findOrFail($this->patchId);
$confSmartUpdate->PATCHNAME = $this->PATCHNAME; $confSmartUpdate->PATCHNAME = $this->PATCHNAME;
$confSmartUpdate->PDATE = $this->PDATE; $confSmartUpdate->PDATE = $this->PDATE;
$confSmartUpdate->PHP_VERSION = $this->PHP_VERSION; $confSmartUpdate->PHP_VERSION_ID = $this->PHP_VERSION;
$confSmartUpdate->PLEVEL = $this->PLEVEL; $confSmartUpdate->PLEVEL = $this->PLEVEL;
$confSmartUpdate->PCODE = $this->PCODE; $confSmartUpdate->PCODE = $this->PCODE;
$confSmartUpdate->MAJOR_VERSION = $this->MAJOR_VERSION; $confSmartUpdate->MAJOR_VERSION = $this->MAJOR_VERSION;
...@@ -108,31 +172,59 @@ class PatchEdit extends Component ...@@ -108,31 +172,59 @@ class PatchEdit extends Component
$confSmartUpdate->PATCHCODE_SERVER = $this->PATCHCODE_SERVER; $confSmartUpdate->PATCHCODE_SERVER = $this->PATCHCODE_SERVER;
$confSmartUpdate->save(); $confSmartUpdate->save();
if (count($this->filePathChanges) > 0) { $totalFiles = count($this->fileChangesTemp);
foreach ($this->filePathChanges as $file) { $successCount = 0;
// $this->fileChangesTemp = 1000000;
if(strpos($file, 'SPN/') !== false ) { if (count($this->fileChangesTemp) > 0) {
$filePath = str_replace("SPN/", "../SPN/", $file); for ($i=0; $i < $this->fileChangesTemp; $i++) {
}else if(strpos($file, 'spn/' ) !== false) { $progress = (($i + 1) / $this->fileChangesTemp) * 100;
$filePath = str_replace("spn/", "../spn/", $file); $this->progressSave = $i;
}else{
$filePath = str_replace("IE5DEV.shippingnet", ".", $file);
}
// Emit an event to update progress on the frontend
// $this->emit('progressUpdated', $progress);
$filedata = $this->getFileContentFromGit($filePath, $this->endCommit); // Use dispatch browser event to trigger frontend update
// $this->dispatchBrowserEvent('progressUpdated', ['progress' => $progress]);
}
foreach ($this->fileChangesTemp as $index => $file) {
$filedata = $this->getFileContentFromGit($file, $this->endCommit);
$filePath = $this->formatFilePath($file);
$filepath = new TabPatchFile; $filepath = new TabPatchFile;
$filepath->ptid = $confSmartUpdate->PID; $filepath->ptid = $confSmartUpdate->PID;
$filepath->file_name = $filePath; $filepath->file_name = $filePath;
$filepath->file_data = base64_encode($filedata); $filepath->file_data = base64_encode($filedata);
$filepath->save(); if ($filepath->save()) {
$successCount++;
}
$progress = (($index + 1) / $totalFiles) * 100;
$this->progressSave = $progress;
// Emit an event to update progress on the frontend
$this->emit('progressUpdated', $progress);
// Use dispatch browser event to trigger frontend update
$this->dispatchBrowserEvent('progressUpdated', ['progress' => $progress]);
} }
} }
session()->flash('message', 'Patch details and file changes updated successfully.'); // session()->flash('message', 'Patch details and file changes updated successfully.');
// $this->reset(['fileChangesTemp', 'fileGitChanges']);
// $this->emit('reloadComponent', $this->patchId);
} }
private function formatFilePath($file)
{
if (strpos($file, 'SPN/') !== false) {
return str_replace("SPN/", "../SPN/", $file);
} else if (strpos($file, 'spn/') !== false) {
return str_replace("spn/", "../spn/", $file);
} else {
return str_replace("IE5DEV.shippingnet", ".", $file);
}
}
private function getFileContentFromGit($filePath, $commit) private function getFileContentFromGit($filePath, $commit)
{ {
$token = env('GITLAB_API_TOKEN'); $token = env('GITLAB_API_TOKEN');
...@@ -170,11 +262,11 @@ class PatchEdit extends Component ...@@ -170,11 +262,11 @@ class PatchEdit extends Component
$tree = []; $tree = [];
foreach ($files as $file) { foreach ($files as $file) {
if(strpos($file['file_name'], "../SPN/" ) !== false ) { if (strpos($file['file_name'], "../SPN/") !== false) {
$filePath = str_replace("../SPN/", "SPN/", $file['file_name']); $filePath = str_replace("../SPN/", "SPN/", $file['file_name']);
}else if(strpos($file['file_name'], "../spn/" ) !== false) { } else if (strpos($file['file_name'], "../spn/") !== false) {
$filePath = str_replace("../spn/", "spn/", $file['file_name']); $filePath = str_replace("../spn/", "spn/", $file['file_name']);
}else{ } else {
$filePath = "IE5DEV.shippingnet" . substr($file['file_name'], 1); $filePath = "IE5DEV.shippingnet" . substr($file['file_name'], 1);
} }
...@@ -188,22 +280,32 @@ class PatchEdit extends Component ...@@ -188,22 +280,32 @@ class PatchEdit extends Component
$current = &$current[$part]; $current = &$current[$part];
} }
$current['id'] = $file['fid']; $current['id'] = $file['fid'] ?? 0;
} }
return $tree; return $tree;
} }
public function loadPage($page) { public function loadPage($page)
{
$this->emit('menuChanged', $page); $this->emit('menuChanged', $page);
} }
public function deletePatchFile($patchFileId)
{
$pathFile = TabPatchFile::where("fid", $patchFileId)->first();
$patchId = $pathFile->ptid;
$pathFile = TabPatchFile::where("fid", $patchFileId)->delete();
$message = "Deleted File ID : " . json_encode($patchFileId) . " Successfully";
// $this->message = $message;
$this->emit('reloadComponent', $patchId);
}
public function render() public function render()
{ {
return view('livewire.pages.patch.patch-edit'); return view('livewire.pages.patch.patch-edit');
} }
} }
...@@ -10,7 +10,7 @@ use App\Models\TabPatchFile; ...@@ -10,7 +10,7 @@ use App\Models\TabPatchFile;
class PatchIndex extends Component class PatchIndex extends Component
{ {
use WithPagination; use WithPagination;
public $action = 'list'; public $action = 'edit';
public $searchBy, $editPid, $message, $keyword, $perPage = 10, $searchSelected = 'PID' ; public $searchBy, $editPid, $message, $keyword, $perPage = 10, $searchSelected = 'PID' ;
protected $listeners = [ 'deleteItem', 'deleteSelected' ,'showpatchListForm']; protected $listeners = [ 'deleteItem', 'deleteSelected' ,'showpatchListForm'];
public function mount() public function mount()
......
...@@ -7,6 +7,8 @@ use Illuminate\Database\Eloquent\Model; ...@@ -7,6 +7,8 @@ use Illuminate\Database\Eloquent\Model;
class TabPatchFile extends Model class TabPatchFile extends Model
{ {
protected $table = 'tab_patch_file'; protected $table = 'tab_patch_file';
protected $primaryKey = 'fid';
public $timestamps = false; public $timestamps = false;
protected $fillable = [ protected $fillable = [
'fid', 'fid',
......
...@@ -6,24 +6,51 @@ window.confirmDelete = function(pid) { ...@@ -6,24 +6,51 @@ window.confirmDelete = function(pid) {
text: "You won't be able to revert this!", text: "You won't be able to revert this!",
icon: 'warning', icon: 'warning',
showCancelButton: true, showCancelButton: true,
confirmButtonColor: '#3085d6', confirmButtonColor: '#2D6A4F',
cancelButtonColor: '#d33', cancelButtonColor: '#d32424',
confirmButtonText: 'Yes, delete it!' confirmButtonText: 'Yes, delete it!'
}).then((result) => { }).then((result) => {
if (result.isConfirmed) { if (result.isConfirmed) {
Livewire.emit('deleteItem', pid); Livewire.emit('deleteItem', pid);
Swal.fire(
'Deleted!',
'Your item has been deleted.',
'success'
);
} }
}); });
} }
window.confirmDeletePatchFile = function(pid) {
Swal.fire({
title: 'Are you sure?',
text: "You won't be able to revert this!",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#2D6A4F',
cancelButtonColor: '#d32424',
confirmButtonText: 'Yes, delete it!'
}).then((result) => {
if (result.isConfirmed) {
Livewire.emit('deletePatchFile', pid);
Swal.fire(
'Deleted!',
'Your patch file has been deleted.',
'success'
);
}
});
}
window.confirmDelete2 = function(currency, exdate) { window.confirmDelete2 = function(currency, exdate) {
Swal.fire({ Swal.fire({
title: 'Are you sure?', title: 'Are you sure?',
text: "You won't be able to revert this!", text: "You won't be able to revert this!",
icon: 'warning', icon: 'warning',
showCancelButton: true, showCancelButton: true,
confirmButtonColor: '#3085d6', confirmButtonColor: '#2D6A4F',
cancelButtonColor: '#d33', cancelButtonColor: '#d32424',
confirmButtonText: 'Yes, delete it!' confirmButtonText: 'Yes, delete it!'
}).then((result) => { }).then((result) => {
if (result.isConfirmed) { if (result.isConfirmed) {
...@@ -38,8 +65,8 @@ window.confirmDeleteSelected = function() { ...@@ -38,8 +65,8 @@ window.confirmDeleteSelected = function() {
text: "You won't be able to revert this!", text: "You won't be able to revert this!",
icon: 'warning', icon: 'warning',
showCancelButton: true, showCancelButton: true,
confirmButtonColor: '#3085d6', confirmButtonColor: '#2D6A4F',
cancelButtonColor: '#d33', cancelButtonColor: '#d32424',
confirmButtonText: 'Yes, delete them!' confirmButtonText: 'Yes, delete them!'
}).then((result) => { }).then((result) => {
if (result.isConfirmed) { if (result.isConfirmed) {
......
...@@ -16,9 +16,8 @@ ...@@ -16,9 +16,8 @@
</title> </title>
<!-- CSS & JS Assets --> <!-- CSS & JS Assets -->
@vite(['resources/css/app.css', 'resources/js/app.js']) @vite(['resources/css/app.css', 'resources/js/app.js', 'resources/js/sweetalert.js'])
<!-- Fonts --> <!-- Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link <link
......
<div class="card mx-4 my-4 z-0 bg-slate-150"> <div class="bg-main-container mt-1 z-0 ">
<link href="{{ asset('css/pages/patch.css') }}" rel="stylesheet"> <link href="{{ asset('css/pages/patch.css') }}" rel="stylesheet">
<div wire:loading.class="" 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"> class="absolute inset-0 items-center justify-center z-50 bg-slate-50 dark:bg-navy-900 hidden">
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
</div> </div>
{{-- end loading --}} {{-- end loading --}}
<div wire:loading.remove class="bg-slate-150"> <div wire:loading.remove class="bg-main-container mx-4">
@if ($currentContent === 'Role') @if ($currentContent === 'Role')
<livewire:pages.role.role-index /> <livewire:pages.role.role-index />
@elseif ($currentContent === 'User') @elseif ($currentContent === 'User')
......
<nav class="shadow p-4 z-100 bg-secondary "> <nav class="shadow p-4 z-100 bg-secondary " wire:init="loadNav">
{{-- @if ($navLoaded) --}}
<div class="container mx-auto flex justify-between items-center"> <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> <div class="text-xl font-bold text-stone-700"><a href="/">SPN Patch</a></div>
<ul class="flex space-x-4 z-50"> <ul class="flex space-x-4 z-50">
...@@ -9,9 +10,12 @@ ...@@ -9,9 +10,12 @@
<ul x-show="open" @click="open = false" @mouseenter="clearTimeout(timer)" <ul x-show="open" @click="open = false" @mouseenter="clearTimeout(timer)"
@mouseleave="timer = setTimeout(() => open = false, 100)" @mouseleave="timer = setTimeout(() => open = false, 100)"
class="absolute left-0 mt-2 w-48 bg-white shadow-lg"> 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 1</a>
<li><a href="#" class="block px-4 py-2 text-gray-700 hover:bg-stone-100">Submenu 2</a></li> </li>
<li><a href="#" class="block px-4 py-2 text-gray-700 hover:bg-stone-100">Submenu 3</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> </ul>
</li> </li>
<li x-data="{ open: false }" <li x-data="{ open: false }"
...@@ -21,13 +25,13 @@ ...@@ -21,13 +25,13 @@
<li x-data="{ open: false, timer: null }" @click.away="open = false" @mouseenter="open = true; clearTimeout(timer)" <li x-data="{ open: false, timer: null }" @click.away="open = false" @mouseenter="open = true; clearTimeout(timer)"
@mouseleave="timer = setTimeout(() => open = false, 100)" @mouseleave="timer = setTimeout(() => open = false, 100)"
class="relative px-2 py-1 rounded text-gray-700 hover:bg-primary-focus hover:text-white"> class="relative px-2 py-1 rounded text-gray-700 hover:bg-primary-focus hover:text-white">
<span class="cursor-pointer" @click.stop >Send Patch</span> <span class="cursor-pointer" @click.stop>Send Patch</span>
<ul x-show="open" @click.stop="open = false" @mouseleave="open = false" <ul x-show="open" @click.stop="open = false" @mouseleave="open = false"
class="absolute left-0 mt-2 w-48 bg-white shadow-lg"> class="absolute left-0 mt-2 w-48 bg-white shadow-lg">
<li><a href="/send-patch" <li><a href="/send-patch" class="block px-4 py-2 text-gray-700 hover:bg-stone-100">Send
class="block px-4 py-2 text-gray-700 hover:bg-stone-100">Send Patch</a></li> Patch</a></li>
<li><a href="/send-multi-patch" <li><a href="/send-multi-patch" class="block px-4 py-2 text-gray-700 hover:bg-stone-100">Send
class="block px-4 py-2 text-gray-700 hover:bg-stone-100">Send Multi Patch</a></li> Multi Patch</a></li>
<li><a href="/delete-multi-patch" <li><a href="/delete-multi-patch"
class="block px-4 py-2 text-gray-700 hover:bg-stone-100">Delete Multi Patch</a></li> class="block px-4 py-2 text-gray-700 hover:bg-stone-100">Delete Multi Patch</a></li>
</ul> </ul>
...@@ -51,12 +55,11 @@ ...@@ -51,12 +55,11 @@
<a href="#">Configuration</a> <a href="#">Configuration</a>
<ul x-show="open" @click="open = false" @mouseleave="open = false" <ul x-show="open" @click="open = false" @mouseleave="open = false"
class="absolute left-0 mt-2 w-48 bg-white shadow-lg"> class="absolute left-0 mt-2 w-48 bg-white shadow-lg">
<li><a href="/role" <li><a href="/role" class="block px-4 py-2 text-gray-700 hover:bg-stone-100">Role</a></li>
class="block px-4 py-2 text-gray-700 hover:bg-stone-100">Role</a></li> <li><a href="/user" class="block px-4 py-2 text-gray-700 hover:bg-stone-100">User</a>
<li><a href="/user"
class="block px-4 py-2 text-gray-700 hover:bg-stone-100">User</a>
</li> </li>
<li><a href="#" class="block px-4 py-2 text-gray-700 hover:bg-stone-100">Submenu Item 3</a> <li><a href="#" class="block px-4 py-2 text-gray-700 hover:bg-stone-100">Submenu Item
3</a>
</li> </li>
</ul> </ul>
</li> </li>
...@@ -64,6 +67,5 @@ ...@@ -64,6 +67,5 @@
<span>Hello , {{ auth()->user()->USERNAME ?? '' }}</span> <span>Hello , {{ auth()->user()->USERNAME ?? '' }}</span>
</ul> </ul>
</div> </div>
{{-- @endif --}}
</nav> </nav>
...@@ -160,7 +160,7 @@ ...@@ -160,7 +160,7 @@
@livewire('pages.parameter.parameter-edit', ['editPid' => $editPid]) @livewire('pages.parameter.parameter-edit', ['editPid' => $editPid])
@endif @endif
</main> </main>
@vite(['resources/js/app.js', 'resources/js/sweetalert.js'])
</div> </div>
<!-- <script src="//cdn.jsdelivr.net/npm/sweetalert2@11"></script> --> <!-- <script src="//cdn.jsdelivr.net/npm/sweetalert2@11"></script> -->
......
<div x-data="{ isOpenFormPatchFile: @entangle('isOpenFormPatchFile') }">
<div wire:loading.class="flex" wire:loading.class.remove="hidden" wire:target="search, openModalMergeVessel, closeModal, mergeFlight" class="fixed inset-0 items-center justify-center z-50 bg-gray-800 bg-opacity-75 hidden">
<div class="bg-white p-4 rounded-lg flex items-center justify-center">
<svg class="animate-spin h-5 w-5 text-gray-600" 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-8v8H4z"></path>
</svg>
<span class="ml-2 text-gray-600">Loading...</span>
</div>
</div>
<div x-show="isOpenFormPatchFile" class="fixed inset-0 z-50 bg-gray-800/40 overflow-auto">
<div class="bg-white rounded-lg w-4/5 mx-auto mt-10 mb-10 pb-4">
<style>
code[class*="language-"],
pre[class*="language-"] {
background: white !important;
color: black;
}
.token.deleted {
background-color: #f8d7da;
color: #721c24;
}
.token.inserted {
background-color: #d4edda;
color: #155724;
}
</style>
<div class="flex w-full justify-between rounded-t-lg bg-primary px-4 py-3 dark:bg-navy-800 sm:px-5">
<h3 class="text-lg text-white font-semibold mr-4">File Name:</h3>
<button type="button" @click="isOpenFormPatchFile = false" class="btn -mr-1.5 h-7 w-7 text-white 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="white" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
</div>
<div class="flex" x-data="{ dbCode: @entangle('dbCode').defer , patchFile: @entangle('patchFile').defer }" style=" overflow-y: auto;">
<div class="w-full p-4">
<div class="flex">
<h3 class="text-md font-semibold mr-4">File Name:</h3>
<input type="text" x-model.defer="patchFile"
class="placeholder:text-sm text-md w-3/5 form-input rounded-md border border-slate-300 px-2">
</div>
<h3 class="text-md font-semibold">Code:</h3>
<div class="relative">
<div class="overflow-auto p-2 bg-gray-100 rounded" >
<textarea x-model.defer="dbCode" class="w-full h-full p-2 bg-white rounded border border-gray-300" rows="30"
style="font-family: monospace; white-space: pre; overflow-wrap: normal; overflow-x: auto;"></textarea>
</div>
</div>
<div class="flex justify-center">
<button type="button" @click="$wire.saveCode(dbCode , patchFile)" class="bg-primary hover:bg-primary-focus text-main-container font-bold py-2 px-4 rounded mx-2 my-2">Save</button>
</div>
<!-- <div class="mt-4">
<button @click="$wire.set('dbCode', dbCode)" class="btn text-white bg-blue-600 px-4 py-2 rounded">Save</button>
</div> -->
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
<div class="bg-secondary"> <div class="bg-main-container">
<link href="{{ asset('css/pages/patch.css') }}" rel="stylesheet"> <link href="{{ asset('css/pages/patch.css') }}" rel="stylesheet">
<div class="max-w-full mx-auto p-6 "> <div class="max-w-full mx-auto px-5 ">
<a type="button" href="/patch" <h2 class="text-2xl text-black ">
class="btn mx-auto m-3 text-white bg-primary px-3 py-2">Back</a> Patch Management
</h2>
<a type="button" href="/patch" class="btn mx-auto m-3 text-white bg-primary px-3 py-2">Back</a>
@if (session()->has('message')) @if (session()->has('message'))
<div class="alert alert-success"> <div class="alert alert-success">
{{ session('message') }} {{ session('message') }}
</div> </div>
@endif @endif
<div class="flex flex-wrap -mx-3"> <div class="flex flex-wrap -mx-3 ">
<div class="w-full md:w-1/2 px-3 mb-6"> <div class="w-full md:w-1/2 px-3 mb-6 ">
<div x-data="{ <div x-data="{
searchQuery: 'SPN64Bits', searchQuery: 'SPN64Bits',
selectedBranch: @entangle('selectedBranch'), selectedBranch: @entangle('selectedBranch'),
...@@ -33,7 +34,7 @@ ...@@ -33,7 +34,7 @@
} }
}" @projects-fetched.window="isLoading = false" }" @projects-fetched.window="isLoading = false"
@files-fetched.window="isLoading = false" x-init="fetchProjects" @files-fetched.window="isLoading = false" x-init="fetchProjects"
class="p-6 bg-white shadow-md rounded-lg"> class="p-6 bg-white shadow-lg rounded-lg ">
...@@ -87,7 +88,7 @@ ...@@ -87,7 +88,7 @@
class="placeholder:text-sm text-lg mb-2 form-input rounded-lg border border-slate-300 px-2"> class="placeholder:text-sm text-lg mb-2 form-input rounded-lg border border-slate-300 px-2">
<div class="text-center"> <div class="text-center">
<button type="button" wire:click="getChangedFiles" <button type="button" wire:click="getChangedFiles"
class="btn mx-auto mt-3 text-white bg-stone-700 px-3 py-2">Get class="btn mx-auto mt-3 text-white bg-primary px-3 py-2">Get
Changed Changed
Files</button> Files</button>
</div> </div>
...@@ -122,8 +123,8 @@ ...@@ -122,8 +123,8 @@
</div> </div>
</div> </div>
<div class="w-full md:w-1/2 px-3 mb-6"> <div class="w-full md:w-1/2 px-3 mb-6">
<div class="p-6 bg-white shadow-md rounded-lg"> <div class="p-6 bg-white shadow-md rounded-lg rounded-lg ">
<h2 class="text-2xl font-bold mb-4">Create Patch</h2> <h2 class="text-2xl text-black font-bold mb-4">Create Patch</h2>
<div class="mb-4"> <div class="mb-4">
<label for="patch_name" class="block text-gray-700">Patch name</label> <label for="patch_name" class="block text-gray-700">Patch name</label>
<input type="text" id="patch_name" class="w-full mt-1 p-2 border border-gray-300 rounded-md" <input type="text" id="patch_name" class="w-full mt-1 p-2 border border-gray-300 rounded-md"
......
<div> <button type="button" wire:click="loadPage('Patch')" <div class="bg-main-container">
class="btn mx-auto m-3 text-white bg-primary px-3 py-2">Back</button> <link href="{{ asset('css/pages/patch.css') }}" rel="stylesheet">
<div class="max-w-full mx-auto p-6 bg-gray-100"> <div class="max-w-full mx-auto px-5">
<h2 class="text-2xl text-black ">
Patch Management
</h2>
<a href="/patch" type="button" class="btn mx-auto m-3 text-white bg-primary px-3 py-2">Back</a>
<div class="flex flex-wrap -mx-3"> <div class="flex flex-wrap -mx-3">
<div class="w-full md:w-1/2 px-3 mb-6"> <div class="w-full md:w-1/2 px-3 mb-6">
<div x-data="{ <div x-data="{
activeTab: 'tab1',
searchQuery: 'SPN64Bits', searchQuery: 'SPN64Bits',
selectedBranch: @entangle('selectedBranch'), selectedBranch: @entangle('selectedBranch'),
selectedProject: @entangle('selectedProject'), selectedProject: @entangle('selectedProject'),
...@@ -24,8 +29,19 @@ ...@@ -24,8 +29,19 @@
} }
}" @projects-fetched.window="isLoading = false" }" @projects-fetched.window="isLoading = false"
@files-fetched.window="isLoading = false" x-init="fetchProjects" @files-fetched.window="isLoading = false" x-init="fetchProjects"
class="p-6 bg-white shadow-md rounded-lg"> class="p-6 bg-white shadow-lg rounded-lg ">
<div class="mb-4">
<button @click="activeTab = 'tab1'"
:class="{ 'border-b-2 border-blue-500': activeTab === 'tab1' }"
class="px-4 py-2">Git</button>
<button @click="activeTab = 'tab2'"
:class="{ 'border-b-2 border-blue-500': activeTab === 'tab2' }"
class="px-4 py-2">Manual</button>
</div>
<div x-show="activeTab === 'tab1'" class="">
<!-- Content for Tab 1 -->
<div class=""> <div class="">
<div class="flex mb-3"> <div class="flex mb-3">
<label for="searchProject" class="form-label text-lg mr-2">Search Project:</label> <label for="searchProject" class="form-label text-lg mr-2">Search Project:</label>
...@@ -41,8 +57,8 @@ ...@@ -41,8 +57,8 @@
<div x-show="isLoading" class="mx-auto mt-2"> <div x-show="isLoading" class="mx-auto mt-2">
<span>Loading...</span> <span>Loading...</span>
</div> </div>
<select x-model="selectedProject" x-show="!isLoading" @change="fetchBranches" id="project" <select x-model="selectedProject" x-show="!isLoading" @change="fetchBranches"
class="ml-2 w-64 h-8 mt-1 border border-gray-300 rounded-md"> id="project" class="ml-2 w-64 h-8 mt-1 border border-gray-300 rounded-md">
<option value="">Choose Project</option> <option value="">Choose Project</option>
<template x-for="project in projects" :key="project.id"> <template x-for="project in projects" :key="project.id">
<option :value="project.id" x-text="project.name"></option> <option :value="project.id" x-text="project.name"></option>
...@@ -50,7 +66,6 @@ ...@@ -50,7 +66,6 @@
</select> </select>
</div> </div>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<input type="text" wire:model.defer="startCommit" placeholder="Start Commit" <input type="text" wire:model.defer="startCommit" placeholder="Start Commit"
class="placeholder:text-sm text-lg mb-2 form-input rounded-lg border border-slate-300 px-2"> class="placeholder:text-sm text-lg mb-2 form-input rounded-lg border border-slate-300 px-2">
...@@ -58,39 +73,140 @@ ...@@ -58,39 +73,140 @@
class="placeholder:text-sm text-lg mb-2 form-input rounded-lg border border-slate-300 px-2"> class="placeholder:text-sm text-lg mb-2 form-input rounded-lg border border-slate-300 px-2">
<div class="text-center"> <div class="text-center">
<button type="button" wire:click="getChangedFiles" <button type="button" wire:click="getChangedFiles"
class="btn mx-auto mt-3 text-white bg-stone-700 px-3 py-2">Get Changed Files</button> class="btn mx-auto mt-3 text-white bg-stone-700 px-3 py-2">Get Changed
Files</button>
</div>
</div>
<div class="flex justify-center">
<button type="button" wire:click="save"
class="bg-stone-700 text-white px-4 py-2 rounded-md hover:bg-blue-600">Save</button>
</div>
<div class="relative pt-1" >
<div class="flex mb-2 items-center justify-between">
<div
class="text-xs font-semibold inline-block py-1 px-2 rounded text-teal-600 bg-teal-200">
Progress
</div>
</div> </div>
<div class="flex">
<div >
<div class="mt-2">
{{-- <div class="progress-bar bg-blue-500 h-4" x-bind:style="`width: ${progress}%`"></div>
<span class="block mt-2" x-text="progress + '%'"></span> --}}
</div> </div>
</div>
</div>
</div>
<div class="mt-5 bg-gray-100 p-4 rounded-lg shadow">
<h3 class="text-lg mb-3">Git Changed Files</h3>
<div wire:loading.class="flex" wire:loading.class.remove="hidden" <div wire:loading.class="flex" wire:loading.class.remove="hidden"
class="flex inset-0 items-center justify-center z-50 bg-slate-50 dark:bg-navy-900 hidden"> class="flex inset-0 items-center justify-center z-50 bg-slate-50 dark:bg-navy-900 hidden">
<div class="app-preloader grid h-full w-full place-content-center"> <div class="app-preloader grid h-full w-full place-content-center">
<div class="app-preloader-inner relative inline-block h-48 w-48"></div> <div class="app-preloader-inner relative inline-block h-48 w-48"></div>
</div> </div>
</div> </div>
<div class="file-tree">
<ul class='pl-4 mt-1'>
@foreach ($fileGitChanges as $name => $item)
@include('livewire.pages.patch.tree-item', [
'name' => $name,
'item' => $item,
])
@endforeach
</ul>
</div>
</div>
<div class="mt-5 bg-gray-100 p-4 rounded-lg shadow"> <div class="mt-5 bg-gray-100 p-4 rounded-lg shadow">
<h3 class="text-lg mb-3">Changed Files</h3> <h3 class="text-lg mb-3">Patch Files</h3>
<div class="file-tree"> <div class="file-tree">
<ul class='pl-4 mt-1'> <ul class='pl-4 mt-1'>
@foreach ($fileChanges as $name => $item) @foreach ($filePatchChanges as $name => $item)
@include('livewire.pages.patch.tree-item', [ @include('livewire.pages.patch.tree-item', [
'name' => $name, 'name' => $name,
'item' => $item, 'item' => $item,
'patchId' => $patchId,
]) ])
@endforeach @endforeach
</ul> </ul>
</div> </div>
</div> </div>
</div>
<div x-show="activeTab === 'tab2'" class="">
<div class="py-2 ">
<button type="button"
class="py-2 px-3 bg-main-container border border-primary text-primary rounded-md hover:text-main-container hover:bg-primary-focus"
wire:click="$emit('openModalFormPatchFile', '', '{{ $patchId }}')">Add</button>
<button type="button"
class="py-2 px-3 bg-main-container border-error border rounded-md text-error hover:text-main-container hover:bg-error-focus"
wire:click="showModalDeletePatchFile">Delete</button>
</div>
<div class="is-scrollbar-hidden min-w-full table-responsive" x-data="pages.tables.initExample1">
<table class="is-hoverable table w-full text-left border-b">
<thead>
<tr>
<th
class="whitespace-nowrap rounded-tl-md bg-slate-300 px-4 py-1 font-semibold uppercase text-black dark:bg-navy-800 dark:text-navy-100 lg:px-5">
#
</th>
<th
class="whitespace-nowrap bg-slate-300 px-2 py-1 font-semibold uppercase text-black dark:bg-navy-800 dark:text-navy-100 lg:px-2">
File Name
</th>
<th
class="whitespace-nowrap rounded-tr-md bg-slate-300 px-2 py-1 font-semibold uppercase text-black dark:bg-navy-800 dark:text-navy-100 lg:px-2">
Action
</th>
</tr>
</thead>
<tbody>
@foreach ($filePatch as $patchFile)
<tr
class="border-y border-transparent border-b-slate-200 dark:border-b-navy-500">
<td class="whitespace-nowrap px-4 py-1 sm:px-5">
<label class="inline-flex items-center space-x-2">
<input
class="form-checkbox is-basic h-4 w-4 rounded border-slate-400/70 checked:bg-primary checked: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" wire:model.defer="selectedPatchFile"
value="{{ $patchFile['fid'] }}" />
</label>
</td>
<td class="whitespace-nowrap px-1 py-1 sm:px-2">
{{ $patchFile['file_name'] }}</td>
<td class="whitespace-nowrap px-1 py-1 sm:px-2">
<div class="flex justify-center space-x-2">
<a wire:click="$emit('openModalFormPatchFile', '{{ $patchFile['fid'] }}' , '{{ $patchId }}')"
class="btn h-8 w-8 p-0 hover:text-main-container active:text-main-container hover:primary-focus focus:primary-focus active:bg-info/25">
<i class="fa fa-edit"></i>
</a>
<a onclick="confirmDeletePatchFile({{ $patchFile['fid'] }})"
class="btn h-8 w-8 p-0 hover:text-main-container active:text-main-container hover:primary-focus focus:primary-focus active:bg-info/25">
<i class="fa fa-trash"></i>
</a>
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div> </div>
</div> </div>
</div>
<div class="w-full md:w-1/2 px-3 mb-6"> <div class="w-full md:w-1/2 px-3 mb-6">
<div class="p-6 bg-white shadow-md rounded-lg"> <div class="p-6 bg-white shadow-lg rounded-lg ">
<h2 class="text-2xl font-bold mb-4">Edit Patch</h2> <h2 class="text-2xl font-bold mb-4">Edit Patch</h2>
<div class="mb-4"> <div class="mb-4">
<label for="patch_name" class="block text-gray-700">Patch name</label> <label for="patch_name" class="block text-gray-700">Patch name</label>
<input type="text" id="patch_name" class="w-full mt-1 p-2 border border-gray-300 rounded-md" <input type="text" id="patch_name"
wire:model.defer="PATCHNAME"> class="w-full mt-1 p-2 border border-gray-300 rounded-md" wire:model.defer="PATCHNAME">
</div> </div>
<div class="mb-4"> <div class="mb-4">
<label for="patch_date" class="block text-gray-700">Patch date</label> <label for="patch_date" class="block text-gray-700">Patch date</label>
...@@ -109,8 +225,8 @@ ...@@ -109,8 +225,8 @@
</div> </div>
<div class="mb-4"> <div class="mb-4">
<label for="patch_level" class="block text-gray-700">Patch level</label> <label for="patch_level" class="block text-gray-700">Patch level</label>
<input type="text" id="patch_level" class="w-full mt-1 p-2 border border-gray-300 rounded-md" <input type="text" id="patch_level"
wire:model.defer="PLEVEL"> class="w-full mt-1 p-2 border border-gray-300 rounded-md" wire:model.defer="PLEVEL">
</div> </div>
<div class="mb-4"> <div class="mb-4">
<label for="code" class="block text-gray-700">Patch Code</label> <label for="code" class="block text-gray-700">Patch Code</label>
...@@ -168,14 +284,22 @@ ...@@ -168,14 +284,22 @@
<textarea id="patchcode_server" wire:model.defer="PATCHCODE_SERVER" <textarea id="patchcode_server" wire:model.defer="PATCHCODE_SERVER"
class="w-full mt-1 p-2 border border-gray-300 rounded-md" rows="5"></textarea> class="w-full mt-1 p-2 border border-gray-300 rounded-md" rows="5"></textarea>
</div> </div>
<div class="flex justify-center"> {{-- <div class="flex justify-center">
<button type="button" wire:click="save" <button type="button" wire:click="save"
class="bg-stone-700 text-white px-4 py-2 rounded-md hover:bg-blue-600">Save</button> class="bg-stone-700 text-white px-4 py-2 rounded-md hover:bg-blue-600">Save</button>
</div> --}}
</div> </div>
</div> </div>
</div> </div>
</div> <div wire:init="loadModal">
<livewire:pages.patch.modal-edit-code> @if ($modalLoaded)
<livewire:pages.patch.modal-edit-code />
<livewire:pages.patch.modal-form-patch-file />
<livewire:delete-item-modal /> <livewire:delete-item-modal />
@endif
</div>
</div> </div>
</div> </div>
<div class="bg-secondary"> <div class="border-0 shadow-none">
<style> ` <div wire:loading.class="" wire:loading.class.remove="hidden" wire:target="save"
</style>
` <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"> 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="flex justify-center items-center ">
<div class="items-center h-100vh" style="align-content: center;"> <div class="items-center h-100vh" style="align-content: center;">
...@@ -11,7 +8,7 @@ ...@@ -11,7 +8,7 @@
</div> </div>
</div> </div>
<main class="m-2" wire:loading.remove> <div class="m-2" >
{{-- <div wire:loading.class="flex" wire:loading.class.remove="hidden" {{-- <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"> 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="flex justify-center items-center ">
...@@ -28,26 +25,24 @@ ...@@ -28,26 +25,24 @@
</div> </div>
</div> </div>
@endif @endif
<div class="grid grid-cols-1 gap-4 sm:gap-5 lg:gap-6 bg-secondary"> <div class="grid grid-cols-1 gap-4 sm:gap-5 lg:gap-6 bg-main-container rounded-md">
<div class="pb-4"> <div class="pb-4">
<div class="my-3 flex h-8 items-center justify-between px-4 sm:px-5"> <div class="my-3 flex h-8 items-center justify-between px-4 sm:px-5">
<h2 <h2 class="text-2xl text-black ">
class="font-medium tracking-wide text-slate-700 line-clamp-1 dark:text-navy-100 lg:text-base">
Patch Management Patch Management
</h2> </h2>
</div> </div>
<div class="flex justify-between"> <div class="flex justify-between">
<div class="px-2 ml-4"> <div class="px-2 ml-4">
<button type="button" class="py-2 px-3 bg-primary rounded-lg text-white" <button type="button" class="py-2 px-3 bg-primary rounded-md text-white hover:bg-primary-focus"
wire:click="showpatchAddForm">Add</button> wire:click="showpatchAddForm">Add</button>
</div> </div>
<div class="inline-flex flex-initial"> <div class="inline-flex flex-initial">
<div x-data="{ isInputActive: true }"> <div x-data="{ isInputActive: true }">
<div class="flex gap-4 px-5 items-center"> <div class="flex gap-4 px-5 items-center">
<button @click="isInputActive = !isInputActive" <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"> class="btn h-8 w-10 rounded-full p-0 hover:bg-primary-focus hover:text-main-container active:text-main-container focus:text-main-container focus:bg-primary-focus active:bg-primary-focus 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" <svg xmlns="http://www.w3.org/2000/svg" class="h-4.5 w-4.5" fill="none"
viewBox="0 0 24 24" stroke="currentColor"> viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
...@@ -61,13 +56,13 @@ ...@@ -61,13 +56,13 @@
</span> </span>
<span class="w-52" x-show="isInputActive === true"> <span class="w-52" x-show="isInputActive === true">
<select wire:model.defer="searchSelected" <select wire:model.defer="searchSelected"
class="form-select h-9 w-full rounded-lg border border-slate-300 bg-slate-300 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"> class="form-select h-9 w-full rounded-lg border border-slate-300 bg-main-container 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) @foreach ($searchBy as $key => $by)
<option value="{{ $key }}">{{ $by }}</option> <option value="{{ $key }}">{{ $by }}</option>
@endforeach @endforeach
</select> </select>
</span> </span>
<button type="button" class="bg-primary text-white px-4 py-2 rounded" <button type="button" class="bg-primary text-white px-4 py-2 rounded hover:bg-primary-focus"
wire:click="search">Search</button> wire:click="search">Search</button>
</div> </div>
</div> </div>
...@@ -143,11 +138,11 @@ ...@@ -143,11 +138,11 @@
<td class="whitespace-nowrap px-1 py-3 sm:px-2"> <td class="whitespace-nowrap px-1 py-3 sm:px-2">
<div class="flex justify-center space-x-2"> <div class="flex justify-center space-x-2">
<a wire:click="showpatchEditForm({{ $patch->PID }})" <a wire:click="showpatchEditForm({{ $patch->PID }})"
class="btn h-8 w-8 p-0 text-info hover:primary-focus focus:primary-focus active:bg-info/25"> class="btn h-8 w-8 p-0 hover:text-main-container active:text-main-container hover:primary-focus focus:primary-focus active:bg-info/25">
<i class="fa fa-edit"></i> <i class="fa fa-edit"></i>
</a> </a>
<a wire:click="showDeleteModal({{ $patch->PID }})" <a wire:click="showDeleteModal({{ $patch->PID }})"
class="btn h-8 w-8 p-0 text-info hover:primary-focus focus:primary-focus active:bg-info/25"> class="btn h-8 w-8 p-0 hover:text-main-container active:text-main-container hover:primary-focus focus:primary-focus active:bg-info/25">
<i class="fa fa-trash"></i> <i class="fa fa-trash"></i>
</a> </a>
</div> </div>
...@@ -174,5 +169,5 @@ ...@@ -174,5 +169,5 @@
console.log("ddd") console.log("ddd")
</script> </script>
@endpush @endpush
</main> </div>
</div> </div>
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<li class="{{ $isFile ? 'file' : 'folder' }} tree"> <li class="{{ $isFile ? 'file' : 'folder' }} tree">
@if($isFile) @if($isFile)
<a href="#" class="text-bold" wire:click.prevent="$emit('openModalEditCode', '{{ $item['id'] }}' , '{{ $selectedProject }}')"><i class='fa fa-file text-base mr-2'></i>{{ $name }}</a> <a href="#" class="text-bold" wire:click="$emit('openModalFormPatchFile', '{{ $item['id'] }}' , '{{ $patchId??'' }}')"><i class='fa fa-file text-base mr-2'></i>{{ $name }}</a>
@else @else
<span>{{ $name }}</span> <span>{{ $name }}</span>
<ul class='pl-4 mt-1'> <ul class='pl-4 mt-1'>
......
...@@ -51,7 +51,7 @@ Route::middleware('auth')->group(function () { ...@@ -51,7 +51,7 @@ Route::middleware('auth')->group(function () {
Route::get('/', [HomeController::class, 'index'])->name('index'); Route::get('/', [HomeController::class, 'index'])->name('index');
Route::get('/get-serverlicense', [ServerLicenseController::class, 'getAllServerKey']); Route::get('/get-serverlicense', [ServerLicenseController::class, 'getAllServerKey']);
Route::get('/patch', [PatchController::class, 'index']); Route::get('/patch', [PatchController::class, 'index'])->name('patch.index');
Route::get('/send-patch', [SendPatchController::class, 'index']); Route::get('/send-patch', [SendPatchController::class, 'index']);
Route::get('/send-multi-patch', [SendPatchController::class, 'indexMulti']); Route::get('/send-multi-patch', [SendPatchController::class, 'indexMulti']);
Route::get('/delete-multi-patch', [DeletePatchController::class, 'indexMulti']); Route::get('/delete-multi-patch', [DeletePatchController::class, 'indexMulti']);
......
...@@ -39,6 +39,7 @@ const customColors = { ...@@ -39,6 +39,7 @@ const customColors = {
error: "#DC3545", error: "#DC3545",
"error-focus": "#C82333", "error-focus": "#C82333",
"slate-100": "#2D6A4F", "slate-100": "#2D6A4F",
"main-container": "#ffffff", // background
}; };
module.exports = { module.exports = {
content: [ content: [
......
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