const BASE_URL = "/api";
const { fetch: originalFetch } = window;
window.fetch = async (...args) => {
try {
const response = await originalFetch(...args);
// Check for HTTP errors (e.g., 4xx or 5xx status codes)
// if (!response.ok) {
// const errorDetails = {
// url: response.url,
// status: response.status,
// statusText: response.statusText,
// // You might also want to parse the response body for more details
// // const errorData = await response.json();
// // errorData: errorData
// };
// console.error('Global Fetch Error (HTTP):', errorDetails);
// // Re-throw the error to be caught by individual catch blocks if needed
// throw new Error(`HTTP error! Status: ${response.status}`);
// }
if( response.status == 401){
removeToken();
}
return response;
} catch (error) {
// Handle network errors or other errors thrown before the response is received
console.error('Global Fetch Error (Network/Other):', error);
// Re-throw the error to be caught by individual catch blocks if needed
throw error;
}
};
function getToken(silently = false){
let token = localStorage.getItem("token");
if(!silently && !token){
window.location.href = "/login";
};
return token;
}
function removeToken(){
localStorage.removeItem("token");
getToken();
}
function setToken(token){
localStorage.setItem("token", token);
}
function login(username, password) {
const formdata = new FormData();
formdata.append("username", username);
formdata.append("password", password);
fetch(BASE_URL + "/auth/login", {
method: "POST",
body: formdata,
redirect: "follow"
})
.then(res => res.json())
.then(data => {
if (data.access_token) {
setToken(data.access_token);
window.location.href = "policies";
} else {
alert("Login failed!");
}
});
}
function refreshToken() {
fetch(BASE_URL + "/auth/refresh", {
method: "POST",
headers: {"Authorization": "Bearer " + getToken()},
redirect: "follow"
})
.then(res => res.json())
.then(data => {
if (data.access_token) {
document.getElementById("token").innerHTML = data.access_token;
} else {
alert("Refesh Token failed!");
}
});
}
function register(email, password) {
fetch(BASE_URL + "/auth/register", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, password })
})
.then(res => res.json())
.then(data => {
if (data.success) {
alert("Registered successfully!");
window.location.href = "login";
} else {
alert("Registration failed!");
}
});
}
function snakeCaseToTitleCase(snakeCaseString) {
if (!snakeCaseString) {
return "";
}
// Split the string by underscore
const words = snakeCaseString.split('_');
// Capitalize the first letter of each word and convert the rest to lowercase
const titleCaseWords = words.map(word => {
if (word.length === 0) {
return "";
}
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
});
// Join the words with a space
return titleCaseWords.join(' ');
}
async function loadPolicies() {
let response = await fetch(BASE_URL + "/policies", {
headers: { "Authorization": "Bearer " + getToken() }
})
let data = await response.json();
let mapping = {};
const modules = ['regex', 'bert_similarity', 'openai_compliance', 'prompt'];
data = data.map((row, i) =>{
modules.forEach(m => {
row[m] = 'No';
});
mapping[row.slug] = i;
return row;
});
for(let i = 0; i < modules.length; i++){
let response = await fetch(`${BASE_URL}/${modules[i]}/available-policies`, {
headers: { "Authorization": "Bearer " + getToken() }
});
response = await response.json();
response.forEach(slug => {
data[mapping[slug]][modules[i]] = "Yes";
});
}
let columns = [
{ data: 'slug', title: 'Slug', columnControl: ['order', ['orderAsc', 'orderDesc', 'orderRemove', 'orderClear', 'orderAddAsc', 'orderAddDesc']] },
{ data: 'name', title: 'Name' },
{ data: 'description', title: 'Description'},
{ data: 'priority_score', title: 'Score' },
{ data: 'priority', title: 'Priority' },
{ data: 'is_active', title: 'Active', render: function(data, type, row, meta){
if(type != 'display') return data;
return data ? `Yes` : `No`
}
},
];
modules.forEach(m => {
columns.push({
data: m,
title: snakeCaseToTitleCase(m),
visible: true,
className: 'dt-body-center',
render: function(data, type, row, meta){
if(type != 'display') return data;
return data == "Yes" ? `Yes` : `No`
}
});
})
columns.push({
data: 'slug',
title: 'Action',
searchable: false,
orderable: false,
className: 'dt-body-center',
render: function(data, type, row, meta){
return `Edit`
},
columnControl: [{target: 0, content: []}, {target: 1, content: []}]
});
let table = $("#table").DataTable({
data,
columns: columns,
fixedHeader: {
headerOffset: $('nav').outerHeight()
},
fixedColumns: {
start: 1,
end: 1
},
scrollX: true,
colReorder: {
columns: ':not(:first-child, :last-child)'
},
columnControl: [
{
target: 0,
content: ['order', ['orderAsc', 'orderDesc', 'orderRemove', 'orderClear', 'orderAddAsc', 'orderAddDesc'], 'reorder']
},
{
target: 1,
content: ['search']
}
],
ordering: {
indicators: false,
handler: false
},
layout: {
// top1Start: 'search',
top1Start: {
buttons: [
{
extend: 'searchPanes',
className: 'btn btn-sm bg-secondary text-white my-auto border-0 rounded',
config: {
cascadePanes: true
}
},
{
extend: 'colvis',
className: 'btn btn-sm bg-secondary text-white my-auto border-0 rounded',
}
]
},
top1End: {
buttons: [
{
text: 'New',
className: 'btn btn-sm bg-primary text-white my-auto border-0 rounded',
action: function ( e, dt, node, config ) {
window.location.href = "/create-policy";
}
}
]
}
// top2: 'searchBuilder'
}
});
}
function loadPolicyDetail() {
const params = new URLSearchParams(window.location.search);
const id = params.get("id");
fetch(BASE_URL + "/policies/" + id, {
headers: { "Authorization": "Bearer " + getToken() }
})
.then(res => res.json())
.then(data => {
document.getElementById("slug").value = data.slug ?? "";
document.getElementById("name").value = data.name ?? "";
document.getElementById("priority_score").value = data.priority_score ?? "";
document.getElementById("priority").value = data.priority ?? "";
document.getElementById("description").value = data.description ?? "";
document.getElementById("is_active").value = data.is_active ? "true" : "false";
});
}
function createPolicyDetail() {
fetch(BASE_URL + "/policies/", {
method: "POST",
headers: { "Authorization": "Bearer " + getToken(), "Content-Type": "application/json" },
body: JSON.stringify({
slug: document.getElementById("slug").value,
name: document.getElementById("name").value,
description: document.getElementById("description").value
})
})
.then(res => res.json())
.then(data => {
if(data.slug){
alert("Details Saved Successfully");
window.location.href = "/policy-detail?id=" + data.slug
} else{
alert(data.detail?.length && data.detail[0]?.msg ? `${data.detail[0].input} : ${data.detail[0].msg}` : "Something went wrong");
}
});
}
function deletePolicyDetail() {
fetch(BASE_URL + "/policies/" + document.getElementById("slug").value, {
method: "DELETE",
headers: { "Authorization": "Bearer " + getToken(), "Content-Type": "application/json" },
})
.then(data => {
alert("Policy Deleted Successfully");
window.location.href = "/policies"
}).catch(err => {
alert("Something went wrong")
});
}
function savePolicyDetail() {
const params = new URLSearchParams(window.location.search);
const id = params.get("id");
fetch(BASE_URL + "/policies/" + id, {
method: "PATCH",
headers: { "Authorization": "Bearer " + getToken(), "Content-Type": "application/json" },
body: JSON.stringify({
slug: document.getElementById("slug").value,
name: document.getElementById("name").value,
is_active: document.getElementById("is_active").value == "true",
priority_score: document.getElementById("priority_score").value,
priority: document.getElementById("priority").value,
description: document.getElementById("description").value
})
})
.then(res => res.json())
.then(data => {
alert("Details Saved Successfully");
});
}
function loadPolicyDetailFor(key) {
const params = new URLSearchParams(window.location.search);
const id = params.get("id");
fetch(`${BASE_URL}/${key}/${id}`, {
headers: { "Authorization": "Bearer " + getToken() }
})
.then(res => res.json())
.then(data => {
document.getElementById(key).value = data && data.length ? data.join("\n") : "";
});
}
function savePolicyDetailFor(key) {
const params = new URLSearchParams(window.location.search);
const id = params.get("id");
fetch(`${BASE_URL}/${key}/${id}`, {
method: "POST",
headers: { "Authorization": "Bearer " + getToken(), "Content-Type": "application/json" },
body: JSON.stringify(document.getElementById(key).value.split("\n").map(l => l.trim()).filter(l => l != ""))
})
.then(res => res.json())
.then(data => {
alert(`${key} Saved Successfully`);
});
}
function validateAd() {
document.getElementById("result").textContent = "Validating...";
fetch(BASE_URL + "/ads/validate", {
method: "POST",
headers: { "Content-Type": "application/json", "Authorization": "Bearer " + localStorage.getItem("token") },
body: JSON.stringify({
url: document.getElementById("url").value,
headlines: document.getElementById("headlines").value.split("\n").map((l) => l.trim()).filter((l) => l != ""),
descriptions: document.getElementById("descriptions").value.split("\n").map((l) => l.trim()).filter((l) => l != ""),
module: document.getElementById("module").value,
config:{
article: "separator:none",
open_ai_key: document.getElementById("open_ai_key").value.trim() != "" ? document.getElementById("open_ai_key").value.trim() : undefined
}
})
})
.then(res => res.json())
.then(data => {
document.getElementById("result").textContent = JSON.stringify(data, null, 2);
});
}
function validateContent() {
document.getElementById("result").textContent = "Validating...";
fetch(BASE_URL + "/ads/validate-content", {
method: "POST",
headers: { "Content-Type": "application/json", "Authorization": "Bearer " + localStorage.getItem("token") },
body: JSON.stringify({
content: document.getElementById("content").value,
module: document.getElementById("module").value,
config: {
content: "separator:none",
open_ai_key: document.getElementById("open_ai_key").value.trim() != "" ? document.getElementById("open_ai_key").value.trim() : undefined
}
})
})
.then(res => res.json())
.then(data => {
document.getElementById("result").textContent = JSON.stringify(data, null, 2);
});
}
function articleExtract() {
document.getElementById("result").textContent = "Extracting...";
fetch(BASE_URL + "/article-extractor", {
method: "POST",
headers: { "Content-Type": "application/json", "Authorization": "Bearer " + localStorage.getItem("token") },
body: JSON.stringify({
url: document.getElementById("url").value,
open_ai_key: document.getElementById("open_ai_key").value.trim() != "" ? document.getElementById("open_ai_key").value.trim() : undefined
})
})
.then(res => res.json())
.then(data => {
document.getElementById("result").textContent = JSON.stringify(data, null, 2);
document.getElementById("article").innerHTML = data.html ?? "";
});
}
function validateData(data) {
document.getElementById("result").textContent = "Validating...";
fetch(BASE_URL + "/ads/validate", {
method: "POST",
headers: { "Content-Type": "application/json", "Authorization": "Bearer " + localStorage.getItem("token") },
body: JSON.stringify(data)
})
.then(res => res.json())
.then(data => {
document.getElementById("result").textContent = JSON.stringify(data, null, 2);
});
}