101 lines
2.8 KiB
JavaScript
101 lines
2.8 KiB
JavaScript
// FILE: backend/src/routes/view.js
|
|
// Saved Views: อ่านด้วย reports.view (GLOBAL); เขียนด้วย settings.manage
|
|
import { Router } from "express";
|
|
import sql from "../db/index.js";
|
|
import { requirePerm } from "../middleware/requirePerm.js";
|
|
|
|
const r = Router();
|
|
|
|
// LIST (ทุกคนที่มี reports.view)
|
|
r.get("/", requirePerm("reports.view"), async (req, res) => {
|
|
const { project_id, shared = "1", q, limit = 50, offset = 0 } = req.query;
|
|
const p = req.principal;
|
|
const cond = [];
|
|
const params = [];
|
|
// ให้เห็นของตัวเองเสมอ + shared
|
|
cond.push("(v.is_shared=1 OR v.owner_user_id=?)");
|
|
params.push(p.user_id);
|
|
if (project_id) {
|
|
cond.push("v.project_id=?");
|
|
params.push(Number(project_id));
|
|
}
|
|
if (q) {
|
|
cond.push("v.name LIKE ?");
|
|
params.push(`%${q}%`);
|
|
}
|
|
if (shared === "0") {
|
|
cond.push("v.is_shared=0");
|
|
}
|
|
|
|
const where = `WHERE ${cond.join(" AND ")}`;
|
|
const [rows] = await sql.query(
|
|
`SELECT v.* FROM saved_views v ${where} ORDER BY v.id DESC LIMIT ? OFFSET ?`,
|
|
[...params, Number(limit), Number(offset)]
|
|
);
|
|
res.json(rows);
|
|
});
|
|
|
|
// GET
|
|
r.get("/:id", requirePerm("reports.view"), async (req, res) => {
|
|
const id = Number(req.params.id);
|
|
const [[row]] = await sql.query("SELECT * FROM saved_views WHERE id=?", [id]);
|
|
if (!row) return res.status(404).json({ error: "Not found" });
|
|
if (
|
|
!(
|
|
row.is_shared ||
|
|
row.owner_user_id === req.principal.user_id ||
|
|
req.principal.is_superadmin
|
|
)
|
|
) {
|
|
return res.status(403).json({ error: "FORBIDDEN" });
|
|
}
|
|
res.json(row);
|
|
});
|
|
|
|
// CREATE / UPDATE / DELETE (ต้องมี settings.manage)
|
|
r.post("/", requirePerm("settings.manage"), async (req, res) => {
|
|
const {
|
|
org_id,
|
|
project_id,
|
|
name,
|
|
payload_json,
|
|
is_shared = 0,
|
|
} = req.body || {};
|
|
const [rs] = await sql.query(
|
|
`INSERT INTO saved_views (org_id, project_id, name, payload_json, is_shared, owner_user_id)
|
|
VALUES (?,?,?,?,?,?)`,
|
|
[
|
|
org_id ?? null,
|
|
project_id ?? null,
|
|
name ?? "",
|
|
JSON.stringify(payload_json ?? {}),
|
|
Number(is_shared) ? 1 : 0,
|
|
req.principal.user_id,
|
|
]
|
|
);
|
|
res.status(201).json({ id: rs.insertId });
|
|
});
|
|
|
|
r.put("/:id", requirePerm("settings.manage"), async (req, res) => {
|
|
const id = Number(req.params.id);
|
|
const { name, payload_json, is_shared } = req.body || {};
|
|
await sql.query(
|
|
"UPDATE saved_views SET name=?, payload_json=?, is_shared=? WHERE id=?",
|
|
[
|
|
name ?? null,
|
|
JSON.stringify(payload_json ?? {}),
|
|
Number(is_shared) ? 1 : 0,
|
|
id,
|
|
]
|
|
);
|
|
res.json({ ok: 1 });
|
|
});
|
|
|
|
r.delete("/:id", requirePerm("settings.manage"), async (req, res) => {
|
|
const id = Number(req.params.id);
|
|
await sql.query("DELETE FROM saved_views WHERE id=?", [id]);
|
|
res.json({ ok: 1 });
|
|
});
|
|
|
|
export default r;
|