2024-10-05 21:15:26 +02:00
|
|
|
import type { PageServerLoad, Actions } from "./$types";
|
2024-09-25 21:45:01 +02:00
|
|
|
import { API_BASE_PREFIX, apiRequest } from "$lib/server/utils";
|
2024-09-13 17:04:04 +02:00
|
|
|
import type { ChangeLog, User, Collab } from "$lib/db-schema";
|
2024-10-05 21:15:26 +02:00
|
|
|
import DiffMatchPatch from "diff-match-patch";
|
2024-10-19 21:01:45 +02:00
|
|
|
import { PAGINATION_MAX_ITEMS } from "$lib/utils";
|
2024-09-13 17:04:04 +02:00
|
|
|
|
2024-09-25 21:45:01 +02:00
|
|
|
export const load: PageServerLoad = async ({ parent, fetch, params, url }) => {
|
2024-10-19 17:55:02 +02:00
|
|
|
const userFilter = url.searchParams.get("user");
|
|
|
|
|
const resourceFilter = url.searchParams.get("resource");
|
|
|
|
|
const operationFilter = url.searchParams.get("operation");
|
|
|
|
|
const currentPage = Number.parseInt(url.searchParams.get("page") ?? "1");
|
2024-11-19 18:49:40 +01:00
|
|
|
const sinceTime = url.searchParams.get("since");
|
2024-10-19 21:01:45 +02:00
|
|
|
const resultOffset = (currentPage - 1) * PAGINATION_MAX_ITEMS;
|
2024-09-13 17:04:04 +02:00
|
|
|
|
|
|
|
|
const searchParams = new URLSearchParams();
|
|
|
|
|
|
2024-09-14 15:12:08 +02:00
|
|
|
const baseFetchUrl = `${API_BASE_PREFIX}/change_log?website_id=eq.${params.websiteId}&select=id,table_name,operation,tstamp,old_value,new_value,user_id,username&order=tstamp.desc`;
|
2024-09-13 17:04:04 +02:00
|
|
|
|
2024-11-19 18:49:40 +01:00
|
|
|
if (sinceTime) {
|
|
|
|
|
searchParams.append("tstamp", `gt.${sinceTime}`);
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-13 17:04:04 +02:00
|
|
|
if (userFilter && userFilter !== "all") {
|
2024-09-14 15:12:08 +02:00
|
|
|
searchParams.append("username", `eq.${userFilter}`);
|
2024-09-13 17:04:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (resourceFilter && resourceFilter !== "all") {
|
|
|
|
|
searchParams.append("table_name", `eq.${resourceFilter}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (operationFilter && operationFilter !== "all") {
|
|
|
|
|
searchParams.append("operation", `eq.${operationFilter.toUpperCase()}`);
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-19 21:01:45 +02:00
|
|
|
const constructedFetchUrl = `${baseFetchUrl}&${searchParams.toString()}&limit=${PAGINATION_MAX_ITEMS}&offset=${resultOffset}`;
|
2024-09-13 17:04:04 +02:00
|
|
|
|
2024-09-25 21:45:01 +02:00
|
|
|
const changeLog: (ChangeLog & { user: { username: User["username"] } })[] = (
|
2024-10-06 02:01:15 +02:00
|
|
|
await apiRequest(fetch, constructedFetchUrl, "GET", {
|
|
|
|
|
headers: { Accept: "application/vnd.pgrst.array+json;nulls=stripped" },
|
|
|
|
|
returnData: true
|
|
|
|
|
})
|
2024-09-25 21:45:01 +02:00
|
|
|
).data;
|
2024-09-13 17:04:04 +02:00
|
|
|
|
2024-09-25 21:45:01 +02:00
|
|
|
const resultChangeLogData = await apiRequest(fetch, constructedFetchUrl, "HEAD", {
|
2024-09-13 17:04:04 +02:00
|
|
|
headers: {
|
|
|
|
|
Prefer: "count=exact"
|
2024-09-25 21:45:01 +02:00
|
|
|
},
|
|
|
|
|
returnData: true
|
2024-09-13 17:04:04 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const resultChangeLogCount = Number(
|
2024-09-25 21:45:01 +02:00
|
|
|
resultChangeLogData.data.headers.get("content-range")?.split("/").at(-1)
|
2024-09-13 17:04:04 +02:00
|
|
|
);
|
|
|
|
|
|
2024-09-25 21:45:01 +02:00
|
|
|
const collaborators: (Collab & { user: User })[] = (
|
|
|
|
|
await apiRequest(
|
|
|
|
|
fetch,
|
|
|
|
|
`${API_BASE_PREFIX}/collab?website_id=eq.${params.websiteId}&select=*,user!user_id(*)&order=last_modified_at.desc,added_at.desc`,
|
|
|
|
|
"GET",
|
|
|
|
|
{ returnData: true }
|
|
|
|
|
)
|
|
|
|
|
).data;
|
2024-09-13 17:04:04 +02:00
|
|
|
|
|
|
|
|
const { website, home } = await parent();
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
changeLog,
|
|
|
|
|
resultChangeLogCount,
|
|
|
|
|
website,
|
|
|
|
|
home,
|
|
|
|
|
collaborators
|
|
|
|
|
};
|
|
|
|
|
};
|
2024-10-05 21:15:26 +02:00
|
|
|
|
|
|
|
|
export const actions: Actions = {
|
|
|
|
|
computeDiff: async ({ request, fetch }) => {
|
|
|
|
|
const data = await request.formData();
|
|
|
|
|
|
|
|
|
|
const dmp = new DiffMatchPatch();
|
|
|
|
|
|
|
|
|
|
const htmlDiff = (oldValue: string, newValue: string) => {
|
|
|
|
|
const diff = dmp.diff_main(oldValue, newValue);
|
|
|
|
|
dmp.diff_cleanupSemantic(diff);
|
|
|
|
|
|
|
|
|
|
return diff
|
|
|
|
|
.map(([op, text]) => {
|
|
|
|
|
switch (op) {
|
|
|
|
|
case 1:
|
|
|
|
|
return `<ins>${text}</ins>`;
|
|
|
|
|
case -1:
|
|
|
|
|
return `<del>${text}</del>`;
|
|
|
|
|
default:
|
|
|
|
|
return text;
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.join("");
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const log: ChangeLog = (
|
|
|
|
|
await apiRequest(
|
|
|
|
|
fetch,
|
|
|
|
|
`${API_BASE_PREFIX}/change_log?id=eq.${data.get("id")}&select=old_value,new_value`,
|
|
|
|
|
"GET",
|
2024-10-06 02:01:15 +02:00
|
|
|
{
|
|
|
|
|
headers: { Accept: "application/vnd.pgrst.object+json;nulls=stripped" },
|
|
|
|
|
returnData: true
|
|
|
|
|
}
|
2024-10-05 21:15:26 +02:00
|
|
|
)
|
|
|
|
|
).data;
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
logId: data.get("id"),
|
|
|
|
|
currentDiff: htmlDiff(
|
|
|
|
|
JSON.stringify(log.old_value, null, 2),
|
|
|
|
|
JSON.stringify(log.new_value, null, 2)
|
|
|
|
|
)
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
};
|