fix queue execute scraping syncronize simbg add new column to resume

This commit is contained in:
arifal
2025-03-03 22:55:57 +07:00
parent 9ea7e96af1
commit 3bfcaddba4
16 changed files with 503 additions and 150 deletions

View File

@@ -34,18 +34,18 @@ class BigdataResume {
this.table = new Grid({
columns: [
{ name: "ID" },
{ name: "Potention Count" },
{ name: "Potention Sum" },
{ name: "Non Verified Count" },
{ name: "Non Verified Sum" },
{ name: "Verified Count" },
{ name: "Verified Sum" },
{ name: "Business Count" },
{ name: "Business Sum" },
{ name: "Non Business Count" },
{ name: "Non Business Sum" },
{ name: "Spatial Sum" },
{ name: "Spatial Count" },
{ name: "Jumlah Potensi" },
{ name: "Total Potensi" },
{ name: "Jumlah Berkas Belum Terverifikasi" },
{ name: "Total Berkas Belum Terverifikasi" },
{ name: "Jumlah Berkas Terverifikasi" },
{ name: "Total Berkas Terverifikasi" },
{ name: "Jumlah Usaha" },
{ name: "Total Usaha" },
{ name: "Jumlah Non Usaha" },
{ name: "Total Non Usaha" },
{ name: "Jumlah Tata Ruang" },
{ name: "Total Tata Ruang" },
{
name: "Created",
attributes: { style: "width: 200px; white-space: nowrap;" }, // Set width dynamically

View File

@@ -16,6 +16,19 @@ class LackOfPotential {
this.pdamCount = this.allCountData.total_pdam ?? 0;
this.tataRuangCount = this.allCountData.total_tata_ruang ?? 0;
let dataReportTourism = this.allCountData.data_report;
this.totalVilla = dataReportTourism
.filter((item) => item.kbli_title.toLowerCase() === "vila")
.reduce((sum, item) => sum + item.total_records, 0);
this.totalRestoran = dataReportTourism
.filter((item) => item.kbli_title.toLowerCase() === "restoran")
.reduce((sum, item) => sum + item.total_records, 0);
this.totalPariwisata = dataReportTourism.reduce(
(sum, item) => sum + item.total_records,
0
);
this.bigTargetPAD = new Big(this.totalTargetPAD ?? 0);
this.bigTotalPotensi = new Big(this.totalPotensi.total ?? 0);
this.bigTotalLackPotential = this.bigTargetPAD.minus(
@@ -140,6 +153,15 @@ class LackOfPotential {
document.getElementById("pdam-count").innerText = this.pdamCount;
document.getElementById("pbb-bangunan-count").innerText =
this.tataRuangCount;
document.getElementById("tata-ruang-count").innerText =
this.tataRuangCount;
document.getElementById("tata-ruang-usaha-count").innerText =
this.tataRuangCount;
document.getElementById("restoran-count").innerText =
this.totalRestoran;
document.getElementById("villa-count").innerText = this.totalVilla;
document.getElementById("pariwisata-count").innerText =
this.totalPariwisata;
}
}
document.addEventListener("DOMContentLoaded", async function (e) {

View File

@@ -4,13 +4,21 @@ import "gridjs/dist/gridjs.umd.js";
import GlobalConfig from "../../global-config.js";
class SyncronizeTask {
constructor() {
this.toastElement = document.getElementById("toastNotification");
this.toastMessage = document.getElementById("toast-message");
this.toast = new bootstrap.Toast(this.toastElement);
this.table = null;
}
init() {
this.initTableImportDatasources();
this.handleSubmitSync();
this.handleSubmitSnycGoogleSheet();
}
initTableImportDatasources() {
new Grid({
let tableContainer = document.getElementById(
"table-import-datasources"
);
this.table = new gridjs.Grid({
columns: ["ID", "Message", "Response", "Status", "Created"],
search: {
server: {
@@ -45,20 +53,24 @@ class SyncronizeTask {
]),
total: (data) => data.meta.total,
},
}).render(document.getElementById("table-import-datasources"));
}).render(tableContainer);
}
handleSubmitSync() {
const button = document.getElementById("btn-sync-submit");
const spinner = document.getElementById("spinner");
const apiToken = document
.querySelector('meta[name="api-token"]')
.getAttribute("content");
// Show the spinner while checking
spinner.classList.remove("d-none");
// Check if the button should be enabled or disabled based on the status
fetch(
`${GlobalConfig.apiHost}/api/import-datasource/check-datasource`,
{
method: "GET",
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
Authorization: `Bearer ${apiToken}`,
"Content-Type": "application/json",
},
}
@@ -70,49 +82,21 @@ class SyncronizeTask {
return response.json();
})
.then((data) => {
console.log("data check button sync", data.can_execute);
button.disabled = !data.can_execute;
// If the button is enabled, add click event to trigger sync
if (!button.disabled) {
button.addEventListener("click", function (e) {
button.disabled = true; // Disable button to prevent multiple clicks
button.textContent = "Syncing..."; // Change button text to show syncing
if (!data.can_execute) {
// Keep spinner visible if cannot execute
spinner.classList.remove("d-none");
} else {
// Hide spinner when execution is allowed
spinner.classList.add("d-none");
// Trigger the scraping API call
fetch(`${GlobalConfig.apiHost}/api/scraping`, {
method: "GET",
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
"Content-Type": "application/json",
},
})
.then((response) => {
if (!response.ok) {
throw new Error(
"Network response was not ok"
);
}
return response.json();
})
.then((data) => {
console.log("data sync button", data);
alert("Synchronization executed successfully");
window.location.reload();
})
.catch((err) => {
console.error("Fetch error:", err);
alert(
"An error occurred during synchronization"
);
})
.finally(() => {
button.disabled = false; // Re-enable the button after the request is complete
button.textContent = "Sync Data"; // Reset button text
});
});
// Remove previous event listener before adding a new one
button.removeEventListener("click", this.handleSyncClick);
button.addEventListener(
"click",
this.handleSyncClick.bind(this)
);
}
})
.catch((err) => {
@@ -120,42 +104,53 @@ class SyncronizeTask {
alert("An error occurred while checking the datasource");
});
}
handleSubmitSnycGoogleSheet() {
const button = document.getElementById("btn-sync-submit-google-sheet");
button.addEventListener("click", function (e) {
button.disabled = true; // Disable button to prevent multiple clicks
button.textContent = "Syncing..."; // Change button text to show syncing
// Trigger the scraping API call
fetch(`${GlobalConfig.apiHost}/api/sync-pbg-task-google-sheet`, {
method: "GET",
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
"Content-Type": "application/json",
},
handleSyncClick() {
const button = document.getElementById("btn-sync-submit");
const spinner = document.getElementById("spinner");
const apiToken = document
.querySelector('meta[name="api-token"]')
.getAttribute("content");
button.disabled = true; // Prevent multiple clicks
spinner.classList.remove("d-none"); // Show spinner during sync
fetch(`${GlobalConfig.apiHost}/api/scraping`, {
method: "GET",
headers: {
Authorization: `Bearer ${apiToken}`,
"Content-Type": "application/json",
},
})
.then(async (response) => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
let data;
try {
data = await response.json();
} catch (jsonError) {
throw new Error("Failed to parse JSON response");
}
return data;
})
.then((response) => {
if (!response.ok) {
throw new Error("Network response was not ok");
}
return response.json();
})
.then((data) => {
console.log("data sync button", data);
alert("Synchronization executed successfully");
window.location.reload();
})
.catch((err) => {
console.error("Fetch error:", err);
alert("An error occurred during synchronization");
})
.finally(() => {
button.disabled = false; // Re-enable the button after the request is complete
button.textContent = "Sync Google Sheet"; // Reset button text
});
});
.then((data) => {
this.toastMessage.innerText =
data.data.message || "Synchronize successfully!";
this.toast.show();
// Update the table if it exists
if (this.table) {
this.table.updateConfig({}).forceRender();
}
})
.catch((err) => {
console.error("Fetch error:", err);
alert("An error occurred during synchronization" + err.message);
button.disabled = false;
});
}
}
document.addEventListener("DOMContentLoaded", function (e) {

View File

@@ -21,7 +21,7 @@
<div class="wrapper">
<div id="lack-of-potential-fixed-container" class="" style="width:1400px;height:770px;position:relative;margin:auto;z-index:1;">
<div style="position: absolute; top: 200px; left: 50px;">
<x-custom-circle title="Restoran" size="small" style="background-color: #0e4753;" />
<x-custom-circle title="Restoran" size="small" style="background-color: #0e4753;" visible_data="true" data_id="restoran-count" data_count="0" />
<div class="square dia-top-left-bottom-right" style="top:30px;left:50px;width:150px;height:120px;"></div>
<x-custom-circle title="PBB Bangunan" visible_data="true" data_id="pbb-bangunan-count" data_count="0" size="small" style="background-color: #0e4753;" />
<div class="square" style="width:150px;height:2px;background-color:black;left:50px;top:150px;"></div>
@@ -52,11 +52,11 @@
<div class="square dia-top-right-bottom-left" style="top:-110px;left:90px;width:150px;height:170px;"></div>
<div class="square dia-top-left-bottom-right" style="top:-110px;left:230px;width:150px;height:170px;"></div>
<div class="square dia-top-left-bottom-right" style="top:-110px;left:260px;width:200px;height:180px;"></div>
<x-custom-circle title="Villa" size="small" style="float:left;background-color: #234f6c;" />
<x-custom-circle title="Villa" size="small" style="float:left;background-color: #234f6c;" visible_data="true" data_id="villa-count" data_count="0" />
<x-custom-circle title="Pabrik" size="small" style="float:left;background-color: #234f6c;" />
<x-custom-circle title="Jalan Protocol" size="small" style="float:left;background-color: #234f6c;" />
<x-custom-circle title="Ruko" size="small" style="float:left;background-color: #234f6c;" />
<x-custom-circle title="Pariwisata" size="small" style="float:left;background-color: #234f6c; margin-right: 20px;" />
<x-custom-circle title="Pariwisata" size="small" style="float:left;background-color: #234f6c; margin-right: 20px;" visible_data="true" data_id="pariwisata-count" data_count="0" />
<div class="square" style="width:150px;height:2px;background-color:black;left:350px;top:50px;"></div>
<x-custom-circle title="DISBUDPAR" size="small" style="background-color: #3a968b;" />
</div>
@@ -74,23 +74,20 @@
'visible_small_circle' => false,
'style' => 'margin-left:180px;top:-20px;'
])
@endcomponent
<x-custom-circle title="Tata Ruang" size="large" style="background-color: #da6635;float:left;margin-left:250px;" />
</div>
@endcomponent
<x-custom-circle title="Tata Ruang" size="large" style="background-color: #da6635;float:left;margin-left:250px;" visible_data="true" data_id="tata-ruang-count" data_count="0" />
</div>
<div style="position: absolute; top: 310px; left: 1150px;">
<div class="square dia-top-left-bottom-right" style="top:90px;left:-100px;width:100px;height:100px;"></div>
<div class="square dia-top-right-bottom-left" style="top:-110px;left:-100px;width:100px;height:100px;"></div>
<x-custom-circle title="Peta" visible_data_type="true" data_type="1:5000" size="small" style="background-color: #224f6d;float:left;" />
<x-custom-circle title="Tapak Bangunan" size="small" style="background-color: #2390af;float:left;margin-left:20px;" />
</div>
<div style="position: absolute; top: 310px; left: 1150px;">
<div class="square dia-top-left-bottom-right" style="top:90px;left:-100px;width:100px;height:100px;"></div>
<div class="square dia-top-right-bottom-left" style="top:-110px;left:-100px;width:100px;height:100px;"></div>
<x-custom-circle title="Peta" visible_data_type="true" data_type="1:5000" size="small" style="background-color: #224f6d;float:left;" />
<x-custom-circle title="Tapak Bangunan" size="small" style="background-color: #2390af;float:left;margin-left:20px;" />
</div>
<x-custom-circle title="BPN" size="small" style="background-color: #2390af;position:absolute;left:1270px;top:440px;" />
<x-custom-circle title="BPN" size="small" style="background-color: #2390af;position:absolute;left:1270px;top:440px;" />
<div style="position: absolute; top: 470px; left: 430px;">
<div style="position: absolute; top: 470px; left: 430px;">
<div class="square dia-top-right-bottom-left" style="top:-80px;left:20px;width:150px;height:120px;"></div>
<div class="square dia-top-right-bottom-left" style="top:-50px;left:100px;width:100px;height:100px;"></div>
<div class="square dia-top-left-bottom-right" style="top:-50px;left:180px;width:100px;height:100px;"></div>
@@ -105,7 +102,7 @@
<div style="position: absolute; top: 50px; left: 1100px;">
<x-custom-circle title="Non Usaha" size="large" style="background-color: #3a968b;margin-top:20px;" />
<x-custom-circle title="USAHA" size="large" style="background-color: #627c8b;margin-top:260px;" />
<x-custom-circle title="USAHA" size="large" style="background-color: #627c8b;margin-top:260px;" visible_data="true" data_id="tata-ruang-usaha-count" data_count="0" />
</div>
</div>
</div>

View File

@@ -3,32 +3,57 @@
<style>
/* .floating-icon {
position: fixed;
right: 30px;
bottom: 70px;
background: white;
padding: 10px;
border-radius: 50%;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
cursor: pointer;
z-index: 1000;
} */
.floating-icon {
position: fixed;
right: 40px;
bottom: 100px;
width: 70px; /* Sesuaikan ukuran */
height: 70px; /* Sesuaikan ukuran */
width: 70px;
height: 70px;
background: white;
border-radius: 50%;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
cursor: pointer;
z-index: 1000;
background-image: url('/images/iconchatbot.jpeg'); /* Path ke gambar */
background-size: cover; /* Agar gambar menyesuaikan */
background-position: center; /* Memusatkan gambar */
background-image: url('/images/iconchatbot.jpeg');
background-size: cover;
background-position: center;
} */
.floating-icon {
position: fixed;
right: 20px;
bottom: 20px;
width: 60px;
height: 60px;
background: white;
border-radius: 50%;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
cursor: pointer;
z-index: 1000;
background-image: url('/images/iconchatbot.jpeg');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
transition: transform 0.3s ease-in-out, box-shadow 0.3s ease-in-out;
}
.floating-icon:hover {
transform: scale(1.1);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3);
}
@keyframes bounce {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-10px);
}
}
.floating-icon.animate {
animation: bounce 1s infinite;
}
</style>
<head>

View File

@@ -7,14 +7,16 @@
@section('content')
@include('layouts.partials/page-title', ['title' => 'Settings', 'subtitle' => 'Syncronize'])
<x-toast-notification />
<div class="row">
<div class="col-12">
<div class="card w-100">
<div class="card-body">
<div class="d-flex flex-wrap justify-content-end gap-2">
<button type="button" class="btn btn-success btn-sm d-block d-sm-inline w-auto" id="btn-sync-submit-google-sheet">Sync Google Sheet</button>
<button type="button" class="btn btn-success btn-sm d-block d-sm-inline w-auto" id="btn-sync-submit">Sync SIMBG</button>
<button type="button" class="btn btn-success btn-sm d-block d-sm-inline w-auto" id="btn-sync-submit">
<span id="spinner" class="spinner-border spinner-border-sm me-1 d-none" role="status" aria-hidden="true"></span>
Sync SIMBG
</button>
</div>
<div>
<div id="table-import-datasources"></div>