fix delete log
This commit is contained in:
parent
e8694be0e2
commit
5c12dcf950
|
|
@ -108,6 +108,10 @@ input[type="text"]:focus {
|
|||
margin-top: 32px;
|
||||
}
|
||||
|
||||
.command-section .log-block.soft-deleted {
|
||||
background-color: #ffd2d2;
|
||||
}
|
||||
|
||||
.command-section h3 {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
|
@ -370,6 +374,15 @@ mark {
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.cancel-trash-btn {
|
||||
font-size: 16px;
|
||||
position: absolute;
|
||||
right: 2px;
|
||||
top: 2px;
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.remove-item-btn {
|
||||
font-size: 20px;
|
||||
right: 2px;
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@
|
|||
<button id="deviceCancelBtn" class="secondary-btn">
|
||||
Cancel
|
||||
</button>
|
||||
<button id="submitDeviceConfirmBtn" class="danger-btn">
|
||||
<button id="submitDeviceConfirmBtn" class="primary-btn">
|
||||
Confirm
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -332,6 +332,9 @@
|
|||
async function loadLogs(pid, version) {
|
||||
logSections.innerHTML = "";
|
||||
logsCache[`${pid}_${version}`] = {};
|
||||
const currentVerUser = versionsUser.find(
|
||||
(verItem) => verItem.version === version,
|
||||
);
|
||||
|
||||
for (const cmd of commands) {
|
||||
const res = await fetch(
|
||||
|
|
@ -359,8 +362,16 @@
|
|||
<button class="next-btn" id="btn-next-${cmd}">Next</button>
|
||||
</div>
|
||||
</h3>
|
||||
<div class="log-block" id="log-${cmd}">
|
||||
<button type="button" class="danger-btn trash-btn" title="Add to delete list">🗑</button>
|
||||
<div class="log-block ${
|
||||
data[0].is_deleted ? "soft-deleted" : ""
|
||||
}" id="log-${cmd}">
|
||||
${
|
||||
currentVerUser
|
||||
? ""
|
||||
: data[0].is_deleted
|
||||
? `<button type="button" class="secondary-btn cancel-trash-btn" title="Cancel soft delete">✖️</button>`
|
||||
: `<button type="button" class="danger-btn trash-btn" title="Soft delete">🗑</button>`
|
||||
}
|
||||
<b>${data[0].filename}</b>\n${data[0].output}
|
||||
</div>
|
||||
`;
|
||||
|
|
@ -373,10 +384,27 @@
|
|||
const curr = info.logs[info.index];
|
||||
|
||||
const logBlock = document.getElementById(`log-${cmd}`);
|
||||
logBlock.innerHTML = `
|
||||
<button type="button" class="danger-btn trash-btn" title="Add to delete list">🗑</button>
|
||||
<b>${curr.filename}</b>\n${curr.output}
|
||||
`;
|
||||
logBlock.className = `log-block ${
|
||||
curr.is_deleted ? "soft-deleted" : ""
|
||||
}`;
|
||||
|
||||
const currentVerUser = versionsUser.find(
|
||||
(verItem) => verItem.version === version,
|
||||
);
|
||||
|
||||
if (!currentVerUser) {
|
||||
if (curr.is_deleted) {
|
||||
logBlock.innerHTML = `
|
||||
<button type="button" class="secondary-btn cancel-trash-btn" title="Cancel soft delete">✖️</button>
|
||||
<b>${curr.filename}</b>\n${curr.output}
|
||||
`;
|
||||
} else {
|
||||
logBlock.innerHTML = `
|
||||
<button type="button" class="danger-btn trash-btn" title="Soft delete">🗑</button>
|
||||
<b>${curr.filename}</b>\n${curr.output}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById(
|
||||
`page-info-${cmd}`,
|
||||
|
|
@ -494,10 +522,15 @@ ${license}`.trim();
|
|||
}
|
||||
</script>
|
||||
|
||||
<!-- Handle delete log -->
|
||||
<!-- Handle soft delete log -->
|
||||
<script>
|
||||
let pendingDeleteLog = null;
|
||||
|
||||
const logDeleteModal = document.getElementById("logDeleteModal");
|
||||
const logCancelDeleteBtn =
|
||||
document.getElementById("logCancelDeleteBtn");
|
||||
const logDeleteBtn = document.getElementById("logDeleteBtn");
|
||||
|
||||
document.addEventListener("click", async (e) => {
|
||||
if (e.target.classList.contains("trash-btn")) {
|
||||
const section = e.target.closest(".command-section");
|
||||
|
|
@ -508,19 +541,45 @@ ${license}`.trim();
|
|||
const log =
|
||||
logsCache[`${pid}_${version}`][command].logs[index];
|
||||
|
||||
pendingDeleteLog = { id: log.id, command, pid, version };
|
||||
pendingDeleteLog = {
|
||||
id: log.id,
|
||||
command,
|
||||
pid,
|
||||
version,
|
||||
is_deleted: true,
|
||||
};
|
||||
|
||||
const text = `Are you sure you want to delete this log? <br /><code>${pid} - ${version} - ${command}</code> <br /> <div style="font-size: 12px; font-weight: 700" >${log.filename}</div>`;
|
||||
const text = `Are you sure you want to <strong>soft delete</strong> this log? <br /><code>${pid} - ${version} - ${command}</code> <br /> <div style="font-size: 12px; font-weight: 700" >${log.filename}</div>`;
|
||||
document.getElementById("deleteLogText").innerHTML = text;
|
||||
logDeleteBtn.innerHTML = "Delete";
|
||||
showDeleteModal();
|
||||
}
|
||||
|
||||
if (e.target.classList.contains("cancel-trash-btn")) {
|
||||
const section = e.target.closest(".command-section");
|
||||
const pid = pidList.value;
|
||||
const version = versionList.value;
|
||||
const command = section.id.replace("section-", "");
|
||||
const index = logsCache[`${pid}_${version}`][command].index;
|
||||
const log =
|
||||
logsCache[`${pid}_${version}`][command].logs[index];
|
||||
|
||||
pendingDeleteLog = {
|
||||
id: log.id,
|
||||
command,
|
||||
pid,
|
||||
version,
|
||||
is_deleted: false,
|
||||
};
|
||||
|
||||
const text = `Are you sure you want to <strong>cancel soft delete</strong> this log? <br /><code>${pid} - ${version} - ${command}</code> <br /> <div style="font-size: 12px; font-weight: 700" >${log.filename}</div>`;
|
||||
document.getElementById("deleteLogText").innerHTML = text;
|
||||
|
||||
logDeleteBtn.innerHTML = "Cancel Delete";
|
||||
showDeleteModal();
|
||||
}
|
||||
});
|
||||
|
||||
const logDeleteModal = document.getElementById("logDeleteModal");
|
||||
const logCancelDeleteBtn =
|
||||
document.getElementById("logCancelDeleteBtn");
|
||||
const logDeleteBtn = document.getElementById("logDeleteBtn");
|
||||
|
||||
function showDeleteModal() {
|
||||
logDeleteModal.classList.remove("hidden");
|
||||
}
|
||||
|
|
@ -536,7 +595,7 @@ ${license}`.trim();
|
|||
|
||||
const token = localStorage.getItem("token");
|
||||
try {
|
||||
const res = await fetch("/api/delete-log", {
|
||||
const res = await fetch("/api/soft-delete-log", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
|
|
@ -546,10 +605,10 @@ ${license}`.trim();
|
|||
});
|
||||
const data = await res.json();
|
||||
if (data.success) {
|
||||
alert("Deleted successfully!");
|
||||
alert(data.message || "Soft deleted successfully!");
|
||||
location.reload();
|
||||
} else {
|
||||
alert("Delete failed.");
|
||||
alert(data.message || "Delete failed.");
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
|
@ -600,7 +659,7 @@ ${license}`.trim();
|
|||
pendingDevice = { pid, version };
|
||||
|
||||
deviceConfirmText.innerHTML = `
|
||||
Are you sure you want to confirm this device?<br />
|
||||
Are you sure you want to <strong>save</strong> these changes?<br />
|
||||
<strong>${pid} - ${version}</strong>
|
||||
`;
|
||||
|
||||
|
|
|
|||
53
server.js
53
server.js
|
|
@ -120,6 +120,12 @@ const checkAndInsertAdminUser = async () => {
|
|||
FOREIGN KEY (device_id) REFERENCES devices(id) ON DELETE CASCADE
|
||||
)
|
||||
`);
|
||||
|
||||
if (!(await columnExists(`${command}_outputs`, "is_deleted"))) {
|
||||
await db.query(
|
||||
`ALTER TABLE ${command}_outputs ADD COLUMN is_deleted BOOLEAN DEFAULT FALSE`,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
await createOutputTable("inventory");
|
||||
|
|
@ -213,22 +219,23 @@ app.get("/api/device/:pid/:version/:command", async (req, res) => {
|
|||
if (!device) return res.status(404).json({ message: "Not found" });
|
||||
|
||||
const [logs] = await db.query(
|
||||
`SELECT id, filename, output, created_at FROM ${command}_outputs WHERE device_id = ? ORDER BY created_at DESC`,
|
||||
`SELECT id, filename, output, created_at, is_deleted FROM ${command}_outputs WHERE device_id = ? ORDER BY created_at DESC`,
|
||||
[device.id],
|
||||
);
|
||||
|
||||
res.json(logs);
|
||||
});
|
||||
|
||||
app.post("/api/delete-log", authenticateToken, async (req, res) => {
|
||||
app.post("/api/soft-delete-log", authenticateToken, async (req, res) => {
|
||||
const logId = req.body.id;
|
||||
const logCommand = req.body.command;
|
||||
const isDeleted = req.body.is_deleted;
|
||||
|
||||
try {
|
||||
if (!logCommand || typeof logId !== "number") {
|
||||
return res
|
||||
.status(400)
|
||||
.json({ success: false, message: "Invalid input" });
|
||||
.json({ success: false, message: "Invalid input." });
|
||||
}
|
||||
|
||||
const [rows] = await db.query(
|
||||
|
|
@ -239,18 +246,29 @@ app.post("/api/delete-log", authenticateToken, async (req, res) => {
|
|||
if (rows.length === 0) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: "Log not found",
|
||||
message: "Log not found.",
|
||||
});
|
||||
}
|
||||
|
||||
await db.query(`DELETE FROM \`${logCommand}_outputs\` WHERE id = ?`, [
|
||||
logId,
|
||||
]);
|
||||
await db.query(
|
||||
`UPDATE \`${logCommand}_outputs\` SET is_deleted = ? WHERE id = ?`,
|
||||
[isDeleted, logId],
|
||||
);
|
||||
|
||||
res.json({ success: true });
|
||||
if (isDeleted) {
|
||||
res.json({ success: true, message: "Soft deleted successfully!" });
|
||||
} else {
|
||||
res.json({
|
||||
success: true,
|
||||
message: "Cancel soft deleted successfully!",
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Delete error:", error);
|
||||
res.status(500).json({ success: false, message: "Server error" });
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: "Server error, please try again!",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -268,7 +286,7 @@ app.post("/api/confirm-device", authenticateToken, async (req, res) => {
|
|||
try {
|
||||
// Check if device exists
|
||||
const [rows] = await db.query(
|
||||
`SELECT * FROM devices WHERE pid = ? AND version = ?`,
|
||||
`SELECT id FROM devices WHERE pid = ? AND version = ?`,
|
||||
[pid, version],
|
||||
);
|
||||
|
||||
|
|
@ -279,6 +297,7 @@ app.post("/api/confirm-device", authenticateToken, async (req, res) => {
|
|||
});
|
||||
}
|
||||
|
||||
const deviceId = rows[0].id;
|
||||
if (rows[0].is_confirmed) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
|
|
@ -296,6 +315,20 @@ app.post("/api/confirm-device", authenticateToken, async (req, res) => {
|
|||
[updatedBy, pid, version],
|
||||
);
|
||||
|
||||
// Delete Log
|
||||
const tables = [
|
||||
"inventory_outputs",
|
||||
"version_outputs",
|
||||
"license_outputs",
|
||||
"logging_outputs",
|
||||
];
|
||||
for (const table of tables) {
|
||||
await db.query(
|
||||
`DELETE FROM ${table} WHERE device_id = ? AND is_deleted = TRUE`,
|
||||
[deviceId],
|
||||
);
|
||||
}
|
||||
|
||||
await db.query(
|
||||
"UPDATE users SET confirm_count = confirm_count + 1 WHERE id = ?",
|
||||
[updatedBy],
|
||||
|
|
|
|||
Loading…
Reference in New Issue