remove ajax and md5

This commit is contained in:
Evgenii Alekseev 2024-09-04 18:38:24 +03:00
parent bd926de740
commit 8e8be8a622
7 changed files with 201 additions and 143 deletions

View File

@ -2,7 +2,7 @@
const alertPlaceholder = document.getElementById("alert-placeholder");
function createAlert(title, message, clz, action, id) {
if (!id) id = $.md5(title + message); // MD5 id from the content
id ??= md5(title + message); // MD5 id from the content
if (alertPlaceholder.querySelector(`#alert-${id}`)) return; // check if there are duplicates
const wrapper = document.createElement("div");
@ -32,12 +32,12 @@
toast.show();
}
function showFailure(title, description, jqXHR, errorThrown) {
function showFailure(title, description, error) {
let details;
try {
details = JSON.parse(jqXHR.responseText).error; // execution handler json error response
details = JSON.parse(error.text).error; // execution handler json error response
} catch (_) {
details = errorThrown;
details = error.text ?? error;
}
createAlert(title, description(details), "text-bg-danger");
}

View File

@ -55,13 +55,17 @@
const server = keyImportServerInput.value;
if (key && server) {
$.ajax({
url: "/api/v1/service/pgp",
data: {"key": key, "server": server},
type: "GET",
dataType: "json",
success: response => { keyImportBodyInput.textContent = response.key; },
});
makeRequest(
"/api/v1/service/pgp",
{
query: {
key: key,
server: server,
},
convert: response => response.json(),
},
data => { keyImportBodyInput.textContent = data.key; },
);
}
}
@ -70,20 +74,24 @@
const server = keyImportServerInput.value;
if (key && server) {
$.ajax({
url: "/api/v1/service/pgp",
data: JSON.stringify({key: key, server: server}),
type: "POST",
contentType: "application/json",
success: _ => {
makeRequest(
"/api/v1/service/pgp",
{
method: "POST",
json: {
key: key,
server: server,
},
},
_ => {
bootstrap.Modal.getOrCreateInstance(keyImportModal).hide();
showSuccess("Success", `Key ${key} has been imported`);
},
error: (jqXHR, _, errorThrown) => {
error => {
const message = _ => `Could not import key ${key} from ${server}`;
showFailure("Action failed", message, jqXHR, errorThrown);
showFailure("Action failed", message, error);
},
});
);
}
}

View File

@ -46,23 +46,27 @@
const username = loginUsernameInput.value;
if (username && password) {
$.ajax({
url: "/api/v1/login",
data: JSON.stringify({username: username, password: password}),
type: "POST",
contentType: "application/json",
success: _ => {
makeRequest(
"/api/v1/login",
{
method: "POST",
json: {
username: username,
password: password,
},
},
_ => {
bootstrap.Modal.getOrCreateInstance(loginModal).hide();
showSuccess("Logged in", `Successfully logged in as ${username}`, _ => location.href = "/");
},
error: (jqXHR, _, errorThrown) => {
error => {
const message = _ =>
username === "admin" && password === "admin"
? "You've entered a password for user \"root\", did you make a typo in username?"
: `Could not login as ${username}`;
showFailure("Login error", message, jqXHR, errorThrown);
showFailure("Login error", message, error);
},
});
);
}
}

View File

@ -141,10 +141,15 @@
const value = packageAddInput.value;
if (value.length >= 3) {
const query = new URLSearchParams({for: value});
fetch(`/api/v1/service/search?${query.toString()}`)
.then(response => response.json())
.then(data => {
makeRequest(
"/api/v1/service/search",
{
query: {
for: value,
},
convert: response => response.json(),
},
data => {
const options = data.map(pkg => {
const option = document.createElement("option");
option.value = pkg.package;
@ -152,8 +157,8 @@
return option;
});
packageAddKnownPackagesList.replaceChildren(...options);
})
.catch(_ => {});
},
);
}
}, 500);
});

View File

@ -163,12 +163,13 @@
variableButtonRemove.classList.add("btn-outline-danger");
variableButtonRemove.innerHTML = "<i class=\"bi bi-trash\"></i>";
variableButtonRemove.onclick = _ => {
$.ajax({
url: `/api/v1/packages/${packageBase}/patches/${variable.key}`,
type: "DELETE",
dataType: "json",
success: _ => variableInput.remove(),
});
makeRequest(
`/api/v1/packages/${packageBase}/patches/${variable.key}`,
{
method: "DELETE",
},
_ => variableInput.remove(),
);
};
// bring them together
@ -181,39 +182,41 @@
}
function loadChanges(packageBase, onFailure) {
$.ajax({
url: `/api/v1/packages/${packageBase}/changes`,
data: {
architecture: repository.architecture,
repository: repository.repository,
makeRequest(
`/api/v1/packages/${packageBase}/changes`,
{
query: {
architecture: repository.architecture,
repository: repository.repository,
},
convert: response => response.json(),
},
type: "GET",
dataType: "json",
success: response => {
const changes = response.changes;
data => {
const changes = data.changes;
packageInfoChangesInput.textContent = changes ?? "";
highlight(packageInfoChangesInput);
},
error: onFailure,
});
onFailure,
);
}
function loadEvents(packageBase, onFailure) {
packageInfoEventsTable.bootstrapTable("showLoading");
clearChart();
$.ajax({
url: `/api/v1/events`,
data: {
architecture: repository.architecture,
repository: repository.repository,
object_id: packageBase,
limit: 30,
makeRequest(
"/api/v1/events",
{
query: {
architecture: repository.architecture,
repository: repository.repository,
object_id: packageBase,
limit: 30,
},
convert: response => response.json(),
},
type: "GET",
dataType: "json",
success: response => {
const events = response.map(event => {
data => {
const events = data.map(event => {
return {
timestamp: new Date(1000 * event.created).toISOStringShort(),
event: event.event,
@ -225,7 +228,7 @@
packageInfoEventsTable.bootstrapTable("hideLoading");
if (packageInfoEventsUpdateChart) {
const chart = response.filter(event => event.event === "package-updated");
const chart = data.filter(event => event.event === "package-updated");
packageInfoEventsUpdateChart.config.data = {
labels: chart.map(event => new Date(1000 * event.created).toISOStringShort()),
datasets: [{
@ -237,30 +240,31 @@
};
packageInfoEventsUpdateChart.update();
}
packageInfoEventsUpdateChart.hidden = !events.length;
packageInfoEventsUpdateChartCanvas.hidden = !events.length;
},
error: onFailure,
});
onFailure,
);
}
function loadLogs(packageBase, onFailure) {
$.ajax({
url: `/api/v2/packages/${packageBase}/logs`,
data: {
architecture: repository.architecture,
repository: repository.repository,
makeRequest(
`/api/v2/packages/${packageBase}/logs`,
{
query: {
architecture: repository.architecture,
repository: repository.repository,
},
convert: response => response.json(),
},
type: "GET",
dataType: "json",
success: response => {
const logs = response.map(log_record => {
data => {
const logs = data.map(log_record => {
return `[${new Date(1000 * log_record.created).toISOString()}] ${log_record.message}`;
});
packageInfoLogsInput.textContent = logs.join("\n");
highlight(packageInfoLogsInput);
},
error: onFailure,
});
onFailure,
);
}
function loadPackage(packageBase, onFailure) {
@ -272,16 +276,17 @@
return ["bg-secondary", "text-white"];
};
$.ajax({
url: `/api/v1/packages/${packageBase}`,
data: {
architecture: repository.architecture,
repository: repository.repository,
makeRequest(
`/api/v1/packages/${packageBase}`,
{
query: {
architecture: repository.architecture,
repository: repository.repository,
},
convert: response => response.json(),
},
type: "GET",
dataType: "json",
success: response => {
const description = response.find(Boolean);
data => {
const description = data.find(Boolean);
const packages = Object.keys(description.package.packages);
const aurUrl = description.package.remote.web_url;
const upstreamUrls = Array.from(
@ -313,22 +318,23 @@
packageInfoUpstreamUrl.innerHTML = upstreamUrls.map(url => safeLink(url, url, "upstream link").outerHTML).join("<br>");
packageInfoVersion.textContent = description.package.version;
},
error: onFailure,
});
onFailure,
);
}
function loadPatches(packageBase, onFailure) {
$.ajax({
url: `/api/v1/packages/${packageBase}/patches`,
type: "GET",
dataType: "json",
success: response => {
packageInfoVariablesDiv.replaceChildren();
response.map(patch => insertVariable(packageBase, patch));
packageInfoVariablesBlock.hidden = !response.length;
makeRequest(
`/api/v1/packages/${packageBase}/patches`,
{
convert: response => response.json(),
},
error: onFailure,
});
data => {
packageInfoVariablesDiv.replaceChildren();
data.map(patch => insertVariable(packageBase, patch));
packageInfoVariablesBlock.hidden = !data.length;
},
onFailure,
);
}
function packageInfoRemove() {
@ -348,10 +354,10 @@
else
packageBase = packageInfoModal.package; // read package base from the current window attribute
const onFailure = (jqXHR, _, errorThrown) => {
const onFailure = error => {
if (isPackageBaseSet) {
const message = error => `Could not load package ${packageBase} info: ${error}`;
showFailure("Load failure", message, jqXHR, errorThrown);
const message = details => `Could not load package ${packageBase} info: ${details}`;
showFailure("Load failure", message, error);
}
};

View File

@ -11,24 +11,24 @@
const versionBadge = document.getElementById("badge-version");
function doPackageAction(uri, packages, repository, successText, failureText, data) {
const queryParams = $.param({
architecture: repository.architecture,
repository: repository.repository,
}); // it will never be empty btw
$.ajax({
url: `${uri}?${queryParams}`,
data: JSON.stringify(Object.assign({}, {packages: packages}, data || {})),
type: "POST",
contentType: "application/json",
success: _ => {
makeRequest(
uri,
{
method: "POST",
query: {
architecture: repository.architecture,
repository: repository.repository,
},
json: Object.assign({}, {packages: packages}, data || {}),
},
_ => {
const message = successText(packages.join(", "));
showSuccess("Success", message);
},
error: (jqXHR, _, errorThrown) => {
showFailure("Action failed", failureText, jqXHR, errorThrown);
error => {
showFailure("Action failed", failureText, error);
},
});
);
}
function filterListGroups() {
@ -84,16 +84,17 @@
return "btn-outline-secondary";
};
$.ajax({
url: "/api/v1/packages",
data: {
architecture: repository.architecture,
repository: repository.repository,
makeRequest(
"/api/v1/packages",
{
query: {
architecture: repository.architecture,
repository: repository.repository,
},
convert: response => response.json(),
},
type: "GET",
dataType: "json",
success: response => {
const payload = response.map(description => {
data => {
const payload = data.map(description => {
const package_base = description.package.base;
const web_url = description.package.remote.web_url;
return {
@ -113,8 +114,8 @@
table.bootstrapTable("uncheckAll");
table.bootstrapTable("hideLoading");
},
error: (jqXHR, _, errorThrown) => {
if ((jqXHR.status === 401) || (jqXHR.status === 403)) {
error => {
if ((error.status === 401) || (error.status === 403)) {
// authorization error
const text = "In order to see statuses you must login first.";
table.find("tr.unauthorized").remove();
@ -122,33 +123,34 @@
table.bootstrapTable("hideLoading");
} else {
// other errors
const message = error => `Could not load list of packages: ${error}`;
showFailure("Load failure", message, jqXHR, errorThrown);
const message = details => `Could not load list of packages: ${details}`;
showFailure("Load failure", message, error);
}
},
});
);
$.ajax({
url: "/api/v1/status",
data: {
architecture: repository.architecture,
repository: repository.repository,
makeRequest(
"/api/v1/status",
{
query: {
architecture: repository.architecture,
repository: repository.repository,
},
convert: response => response.json(),
},
type: "GET",
dataType: "json",
success: response => {
versionBadge.innerHTML = `<i class="bi bi-github"></i> ahriman ${safe(response.version)}`;
data => {
versionBadge.innerHTML = `<i class="bi bi-github"></i> ahriman ${safe(data.version)}`;
statusBadge.classList.remove(...statusBadge.classList);
statusBadge.classList.add("btn");
statusBadge.classList.add(badgeClass(response.status.status));
statusBadge.classList.add(badgeClass(data.status.status));
const popover = bootstrap.Popover.getOrCreateInstance(statusBadge);
popover.dispose();
statusBadge.dataset.bsContent = `${response.status.status} at ${new Date(1000 * response.status.timestamp).toISOStringShort()}`;
statusBadge.dataset.bsContent = `${data.status.status} at ${new Date(1000 * data.status.timestamp).toISOStringShort()}`;
bootstrap.Popover.getOrCreateInstance(statusBadge);
},
});
);
}
function selectRepository() {

View File

@ -1,5 +1,5 @@
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js" crossorigin="anonymous" type="application/javascript"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery.md5@1.0.2/index.min.js" crossorigin="anonymous" type="application/javascript"></script>
<script src="https://cdn.jsdelivr.net/npm/js-md5@0.8.3/src/md5.min.js" crossorigin="anonymous" type="application/javascript"></script>
<script src="https://cdn.jsdelivr.net/npm/moment@2.29.4/moment.min.js" crossorigin="anonymous" type="application/javascript"></script>
<script src="https://cdn.jsdelivr.net/npm/daterangepicker@3.1.0/daterangepicker.min.js" crossorigin="anonymous" type="application/javascript"></script>
@ -66,6 +66,39 @@
.join("<br>");
}
function makeRequest(url, params, onSuccess, onFailure) {
const requestParams = {
method: params.method,
body: params.json ? JSON.stringify(params.json) : params.json,
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
};
if (params.query) {
const query = new URLSearchParams(params.query);
url += `?${query.toString()}`;
}
convert = params.convert ?? (response => response.text());
return fetch(url, requestParams)
.then(response => {
if (response.ok) {
return convert(response);
} else {
const error = new Error("Network request error");
error.status = response.status;
error.statusText = response.statusText;
return response.text().then(text => {
error.text = text;
throw error;
});
}
})
.then(data => onSuccess && onSuccess(data))
.catch(error => onFailure && onFailure(error));
}
function safe(string) {
return String(string)
.replace(/&/g, "&amp;")