review remains

This commit is contained in:
Evgenii Alekseev 2024-09-03 18:31:05 +03:00
parent b67e246ea9
commit bd926de740
10 changed files with 159 additions and 193 deletions

View File

@ -44,28 +44,28 @@
</button>
<ul class="dropdown-menu">
<li>
<button id="package-add-button" class="btn dropdown-item" data-bs-toggle="modal" data-bs-target="#package-add-modal" hidden>
<button id="package-add-button" class="btn dropdown-item" data-bs-toggle="modal" data-bs-target="#package-add-modal">
<i class="bi bi-plus"></i> add
</button>
</li>
<li>
<button id="package-update-button" class="btn dropdown-item" onclick="packagesUpdate()" hidden>
<button id="package-update-button" class="btn dropdown-item" onclick="packagesUpdate()">
<i class="bi bi-play"></i> update
</button>
</li>
<li>
<button id="package-rebuild-button" class="btn dropdown-item" data-bs-toggle="modal" data-bs-target="#package-rebuild-modal" hidden>
<button id="package-rebuild-button" class="btn dropdown-item" data-bs-toggle="modal" data-bs-target="#package-rebuild-modal">
<i class="bi bi-arrow-clockwise"></i> rebuild
</button>
</li>
<li>
<button id="package-remove-button" class="btn dropdown-item" onclick="packagesRemove()" disabled hidden>
<button id="package-remove-button" class="btn dropdown-item" onclick="packagesRemove()" disabled>
<i class="bi bi-trash"></i> remove
</button>
</li>
</ul>
<button id="key-import-button" type="button" class="btn btn-info" data-bs-toggle="modal" data-bs-target="#key-import-modal" hidden>
<button id="key-import-button" type="button" class="btn btn-info" data-bs-toggle="modal" data-bs-target="#key-import-modal">
<i class="bi bi-key"></i><span class="d-none d-sm-inline"> import key</span>
</button>
{% endif %}

View File

@ -35,7 +35,7 @@
function showFailure(title, description, jqXHR, errorThrown) {
let details;
try {
details = $.parseJSON(jqXHR.responseText).error; // execution handler json error response
details = JSON.parse(jqXHR.responseText).error; // execution handler json error response
} catch (_) {
details = errorThrown;
}

View File

@ -76,7 +76,7 @@
type: "POST",
contentType: "application/json",
success: _ => {
bootstrap.Modal.getInstance(keyImportModal).hide();
bootstrap.Modal.getOrCreateInstance(keyImportModal).hide();
showSuccess("Success", `Key ${key} has been imported`);
},
error: (jqXHR, _, errorThrown) => {
@ -87,7 +87,7 @@
}
}
$(_ => {
document.addEventListener("DOMContentLoaded", _ => {
keyImportModal.addEventListener("hidden.bs.modal", _ => {
keyImportBodyInput.textContent = "";
keyImportForm.reset();

View File

@ -52,7 +52,7 @@
type: "POST",
contentType: "application/json",
success: _ => {
bootstrap.Modal.getInstance(loginModal).hide();
bootstrap.Modal.getOrCreateInstance(loginModal).hide();
showSuccess("Logged in", `Successfully logged in as ${username}`, _ => location.href = "/");
},
error: (jqXHR, _, errorThrown) => {
@ -78,7 +78,7 @@
}
}
$(_ => {
document.addEventListener("DOMContentLoaded", _ => {
loginModal.addEventListener("hidden.bs.modal", _ => {
loginForm.reset();
});

View File

@ -41,14 +41,14 @@
</div>
<script>
const packageAddModal = $("#package-add-modal");
const packageAddForm = $("#package-add-form");
const packageAddModal = document.getElementById("package-add-modal");
const packageAddForm = document.getElementById("package-add-form");
const packageAddInput = $("#package-add-input");
const packageAddRepositoryInput = $("#package-add-repository-input");
const packageAddKnownPackagesList = $("#package-add-known-packages-dlist");
const packageAddInput = document.getElementById("package-add-input");
const packageAddRepositoryInput = document.getElementById("package-add-repository-input");
const packageAddKnownPackagesList = document.getElementById("package-add-known-packages-dlist");
const packageAddVariablesDiv = $("#package-add-variables-div");
const packageAddVariablesDiv = document.getElementById("package-add-variables-div");
function packageAddVariableInputCreate() {
const variableInput = document.createElement("div");
@ -78,7 +78,7 @@
variableButtonRemove.classList.add("btn");
variableButtonRemove.classList.add("btn-outline-danger");
variableButtonRemove.innerHTML = "<i class=\"bi bi-trash\"></i>";
variableButtonRemove.onclick = _ => { return variableInput.remove(); };
variableButtonRemove.onclick = _ => { variableInput.remove(); };
// bring them together
variableInput.appendChild(variableNameInput);
@ -86,27 +86,26 @@
variableInput.appendChild(variableValueInput);
variableInput.appendChild(variableButtonRemove);
packageAddVariablesDiv.append(variableInput);
packageAddVariablesDiv.appendChild(variableInput);
}
function patchesParse() {
const patches = packageAddVariablesDiv.find(".package-add-variable").map((_, element) => {
const richElement = $(element);
const patches = Array.from(packageAddVariablesDiv.getElementsByClassName("package-add-variable")).map(element => {
return {
key: richElement.find(".package-add-variable-name").val(),
value: richElement.find(".package-add-variable-value").val(),
key: element.querySelector(".package-add-variable-name").value,
value: element.querySelector(".package-add-variable-value").value,
};
}).filter((_, patch) => patch.key).get();
}).filter(patch => patch.key);
return {patches: patches};
}
function packagesAdd(packages, patches, repository) {
packages = packages ?? packageAddInput.val();
packages = packages ?? packageAddInput.value;
patches = patches ?? patchesParse();
repository = repository ?? getRepositorySelector(packageAddRepositoryInput);
if (packages) {
packageAddModal.modal("hide");
bootstrap.Modal.getOrCreateInstance(packageAddModal).hide();
const onSuccess = update => `Packages ${update} have been added`;
const onFailure = error => `Package addition failed: ${error}`;
doPackageAction("/api/v1/service/add", [packages], repository, onSuccess, onFailure, patches);
@ -114,50 +113,49 @@
}
function packagesRequest(packages, patches) {
packages = packages ?? packageAddInput.val();
packages = packages ?? packageAddInput.value;
patches = patches ?? patchesParse();
const repository = getRepositorySelector(packageAddRepositoryInput);
if (packages) {
packageAddModal.modal("hide");
bootstrap.Modal.getOrCreateInstance(packageAddModal).hide();
const onSuccess = update => `Packages ${update} have been requested`;
const onFailure = error => `Package request failed: ${error}`;
doPackageAction("/api/v1/service/request", [packages], repository, onSuccess, onFailure, patches);
}
}
$(_ => {
packageAddModal.on("shown.bs.modal", _ => {
$(`#package-add-repository-input option[value="${repository.architecture}-${repository.repository}"]`).prop("selected", true);
document.addEventListener("DOMContentLoaded", _ => {
packageAddModal.addEventListener("shown.bs.modal", _ => {
const option = packageAddRepositoryInput.querySelector(`option[value="${repository.architecture}-${repository.repository}"]`);
if (option) option.selected = "selected";
});
packageAddModal.on("hidden.bs.modal", _ => {
packageAddVariablesDiv.empty();
packageAddForm.trigger("reset");
packageAddModal.addEventListener("hidden.bs.modal", _ => {
packageAddVariablesDiv.replaceChildren();
packageAddForm.reset();
});
packageAddInput.keyup(_ => {
clearTimeout(packageAddInput.data("timeout"));
packageAddInput.data("timeout", setTimeout($.proxy(_ => {
const value = packageAddInput.val();
packageAddInput.addEventListener("keyup", _ => {
clearTimeout(packageAddInput.requestTimeout);
packageAddInput.requestTimeout = setTimeout(_ => {
const value = packageAddInput.value;
if (value.length >= 3) {
$.ajax({
url: "/api/v1/service/search",
data: {"for": value},
type: "GET",
dataType: "json",
success: response => {
const options = response.map(pkg => {
const query = new URLSearchParams({for: value});
fetch(`/api/v1/service/search?${query.toString()}`)
.then(response => response.json())
.then(data => {
const options = data.map(pkg => {
const option = document.createElement("option");
option.value = pkg.package;
option.innerText = `${pkg.package} (${pkg.description})`;
return option;
});
packageAddKnownPackagesList.empty().append(options);
},
});
packageAddKnownPackagesList.replaceChildren(...options);
})
.catch(_ => {});
}
}, this), 500));
}, 500);
});
});
</script>

View File

@ -58,7 +58,7 @@
<pre class="language-diff"><code id="package-info-changes-input" class="pre-scrollable language-diff"></code><button id="package-info-changes-copy-button" type="button" class="btn language-diff" onclick="copyChanges()"><i class="bi bi-clipboard"></i> copy</button></pre>
</div>
<div id="package-info-events" class="tab-pane fade" role="tabpanel" aria-labelledby="package-info-events-button" tabindex="0">
<canvas id="package-info-events-update-chart"></canvas>
<canvas id="package-info-events-update-chart" hidden></canvas>
<table id="package-info-events-table"
data-classes="table table-hover"
data-sortable="true"
@ -77,8 +77,10 @@
</div>
</div>
<div class="modal-footer">
<button id="package-info-update-button" type="submit" class="btn btn-success" onclick="packageInfoUpdate()" data-bs-dismiss="modal" hidden><i class="bi bi-play"></i><span class="d-none d-sm-inline"> update</span></button>
<button id="package-info-remove-button" type="submit" class="btn btn-danger" onclick="packageInfoRemove()" data-bs-dismiss="modal" hidden><i class="bi bi-trash"></i><span class="d-none d-sm-inline"> remove</span></button>
{% if not auth.enabled or auth.username is not none %}
<button id="package-info-update-button" type="submit" class="btn btn-success" onclick="packageInfoUpdate()" data-bs-dismiss="modal"><i class="bi bi-play"></i><span class="d-none d-sm-inline"> update</span></button>
<button id="package-info-remove-button" type="submit" class="btn btn-danger" onclick="packageInfoRemove()" data-bs-dismiss="modal"><i class="bi bi-trash"></i><span class="d-none d-sm-inline"> remove</span></button>
{% endif %}
<button type="button" class="btn btn-secondary" onclick="showPackageInfo()"><i class="bi bi-arrow-clockwise"></i><span class="d-none d-sm-inline"> reload</span></button>
<button type="button" class="btn btn-primary" data-bs-dismiss="modal"><i class="bi bi-x"></i><span class="d-none d-sm-inline"> close</span></button>
</div>
@ -87,33 +89,35 @@
</div>
<script>
const packageInfoModal = $("#package-info-modal");
const packageInfoModalHeader = $("#package-info-modal-header");
const packageInfo = $("#package-info");
const packageInfoModal = document.getElementById("package-info-modal");
const packageInfoModalHeader = document.getElementById("package-info-modal-header");
const packageInfo = document.getElementById("package-info");
const packageInfoLogsInput = $("#package-info-logs-input");
const packageInfoLogsCopyButton = $("#package-info-logs-copy-button");
const packageInfoLogsInput = document.getElementById("package-info-logs-input");
const packageInfoLogsCopyButton = document.getElementById("package-info-logs-copy-button");
const packageInfoChangesInput = $("#package-info-changes-input");
const packageInfoChangesCopyButton = $("#package-info-changes-copy-button");
const packageInfoChangesInput = document.getElementById("package-info-changes-input");
const packageInfoChangesCopyButton = document.getElementById("package-info-changes-copy-button");
const packageInfoEventsTable = $("#package-info-events-table");
// so far bootstrap-table only operates with jquery elements
const packageInfoEventsTable = $(document.getElementById("package-info-events-table"));
const packageInfoEventsUpdateChartCanvas = document.getElementById("package-info-events-update-chart");
let packageInfoEventsUpdateChart = null;
const packageInfoAurUrl = $("#package-info-aur-url");
const packageInfoDepends = $("#package-info-depends");
const packageInfoGroups = $("#package-info-groups");
const packageInfoLicenses = $("#package-info-licenses");
const packageInfoPackager = $("#package-info-packager");
const packageInfoPackages = $("#package-info-packages");
const packageInfoUpstreamUrl = $("#package-info-upstream-url");
const packageInfoVersion = $("#package-info-version");
const packageInfoAurUrl = document.getElementById("package-info-aur-url");
const packageInfoDepends = document.getElementById("package-info-depends");
const packageInfoGroups = document.getElementById("package-info-groups");
const packageInfoLicenses = document.getElementById("package-info-licenses");
const packageInfoPackager = document.getElementById("package-info-packager");
const packageInfoPackages = document.getElementById("package-info-packages");
const packageInfoUpstreamUrl = document.getElementById("package-info-upstream-url");
const packageInfoVersion = document.getElementById("package-info-version");
const packageInfoVariablesBlock = $("#package-info-variables-block");
const packageInfoVariablesDiv = $("#package-info-variables-div");
const packageInfoVariablesBlock = document.getElementById("package-info-variables-block");
const packageInfoVariablesDiv = document.getElementById("package-info-variables-div");
function clearChart() {
packageInfoEventsUpdateChartCanvas.hidden = true;
if (packageInfoEventsUpdateChart) {
packageInfoEventsUpdateChart.data = {};
packageInfoEventsUpdateChart.update();
@ -121,20 +125,15 @@
}
async function copyChanges() {
const changes = packageInfoChangesInput.text();
const changes = packageInfoChangesInput.textContent;
await copyToClipboard(changes, packageInfoChangesCopyButton);
}
async function copyLogs() {
const logs = packageInfoLogsInput.text();
const logs = packageInfoLogsInput.textContent;
await copyToClipboard(logs, packageInfoLogsCopyButton);
}
function hideInfoControls(hidden) {
packageInfoRemoveButton.attr("hidden", hidden);
packageInfoUpdateButton.attr("hidden", hidden);
}
function highlight(element) {
delete element.dataset.highlighted;
hljs.highlightElement(element);
@ -178,7 +177,7 @@
variableInput.appendChild(variableValueInput);
variableInput.appendChild(variableButtonRemove);
packageInfoVariablesDiv.append(variableInput);
packageInfoVariablesDiv.appendChild(variableInput);
}
function loadChanges(packageBase, onFailure) {
@ -192,8 +191,8 @@
dataType: "json",
success: response => {
const changes = response.changes;
packageInfoChangesInput.text(changes || "");
packageInfoChangesInput.map((_, el) => highlight(el));
packageInfoChangesInput.textContent = changes ?? "";
highlight(packageInfoChangesInput);
},
error: onFailure,
});
@ -222,6 +221,9 @@
};
});
packageInfoEventsTable.bootstrapTable("load", events);
packageInfoEventsTable.bootstrapTable("hideLoading");
if (packageInfoEventsUpdateChart) {
const chart = response.filter(event => event.event === "package-updated");
packageInfoEventsUpdateChart.config.data = {
@ -235,9 +237,7 @@
};
packageInfoEventsUpdateChart.update();
}
packageInfoEventsTable.bootstrapTable("load", events);
packageInfoEventsTable.bootstrapTable("hideLoading");
packageInfoEventsUpdateChart.hidden = !events.length;
},
error: onFailure,
});
@ -256,8 +256,8 @@
const logs = response.map(log_record => {
return `[${new Date(1000 * log_record.created).toISOString()}] ${log_record.message}`;
});
packageInfoLogsInput.text(logs.join("\n"));
packageInfoLogsInput.map((_, el) => highlight(el));
packageInfoLogsInput.textContent = logs.join("\n");
highlight(packageInfoLogsInput);
},
error: onFailure,
});
@ -291,34 +291,29 @@
)
).sort();
packageInfo.text(`${description.package.base} ${description.status.status} at ${new Date(1000 * description.status.timestamp).toISOStringShort()}`);
packageInfo.textContent = `${description.package.base} ${description.status.status} at ${new Date(1000 * description.status.timestamp).toISOStringShort()}`;
packageInfoModalHeader.removeClass();
packageInfoModalHeader.addClass("modal-header");
headerClass(description.status.status).forEach(clz => packageInfoModalHeader.addClass(clz));
packageInfoModalHeader.classList.remove(...packageInfoModalHeader.classList);
packageInfoModalHeader.classList.add("modal-header");
headerClass(description.status.status).forEach(clz => packageInfoModalHeader.classList.add(clz));
packageInfoAurUrl.html(aurUrl ? safeLink(aurUrl, aurUrl, "AUR link").outerHTML : "");
packageInfoDepends.html(listToTable(
packageInfoAurUrl.innerHTML = aurUrl ? safeLink(aurUrl, aurUrl, "AUR link").outerHTML : "";
packageInfoDepends.innerHTML = listToTable(
Object.values(description.package.packages)
.reduce((accumulator, currentValue) => {
return accumulator.concat(currentValue.depends.filter(v => packages.indexOf(v) === -1))
.concat(currentValue.make_depends.filter(v => packages.indexOf(v) === -1).map(v => `${v} (make)`))
.concat(currentValue.opt_depends.filter(v => packages.indexOf(v) === -1).map(v => `${v} (optional)`));
}, [])
));
packageInfoGroups.html(listToTable(extractListProperties(description.package, "groups")));
packageInfoLicenses.html(listToTable(extractListProperties(description.package, "licenses")));
packageInfoPackager.text(description.package.packager);
packageInfoPackages.html(listToTable(packages));
packageInfoUpstreamUrl.html(upstreamUrls.map(url => safeLink(url, url, "upstream link").outerHTML).join("<br>"));
packageInfoVersion.text(description.package.version);
hideInfoControls(false);
},
error: (jqXHR, _, errorThrown) => {
hideInfoControls(true);
onFailure(jqXHR, null, errorThrown);
);
packageInfoGroups.innerHTML = listToTable(extractListProperties(description.package, "groups"));
packageInfoLicenses.innerHTML = listToTable(extractListProperties(description.package, "licenses"));
packageInfoPackager.textContent = description.package.packager;
packageInfoPackages.innerHTML = listToTable(packages);
packageInfoUpstreamUrl.innerHTML = upstreamUrls.map(url => safeLink(url, url, "upstream link").outerHTML).join("<br>");
packageInfoVersion.textContent = description.package.version;
},
error: onFailure,
});
}
@ -328,30 +323,30 @@
type: "GET",
dataType: "json",
success: response => {
packageInfoVariablesDiv.empty();
packageInfoVariablesDiv.replaceChildren();
response.map(patch => insertVariable(packageBase, patch));
packageInfoVariablesBlock.attr("hidden", response.length === 0);
packageInfoVariablesBlock.hidden = !response.length;
},
error: onFailure,
});
}
function packageInfoRemove() {
const packageBase = packageInfoModal.data("package");
const packageBase = packageInfoModal.package;
if (packageBase) return packagesRemove([packageBase]);
}
function packageInfoUpdate() {
const packageBase = packageInfoModal.data("package");
const packageBase = packageInfoModal.package;
if (packageBase) return packagesAdd(packageBase, [], repository);
}
function showPackageInfo(packageBase) {
const isPackageBaseSet = packageBase !== undefined;
if (isPackageBaseSet)
packageInfoModal.data("package", packageBase); // set package base as currently used
packageInfoModal.package = packageBase; // set package base as currently used
else
packageBase = packageInfoModal.data("package"); // read package base from the current window attribute
packageBase = packageInfoModal.package; // read package base from the current window attribute
const onFailure = (jqXHR, _, errorThrown) => {
if (isPackageBaseSet) {
@ -366,10 +361,11 @@
loadChanges(packageBase, onFailure);
loadEvents(packageBase, onFailure);
if (isPackageBaseSet) packageInfoModal.modal("show");
if (isPackageBaseSet)
bootstrap.Modal.getOrCreateInstance(packageInfoModal).show();
}
$(_ => {
document.addEventListener("DOMContentLoaded", _ => {
packageInfoEventsUpdateChart = new Chart(packageInfoEventsUpdateChartCanvas, {
type: "line",
data: {},
@ -378,27 +374,23 @@
},
});
packageInfoModal.on("hidden.bs.modal", _ => {
packageInfoAurUrl.empty();
packageInfoDepends.empty();
packageInfoGroups.empty();
packageInfoLicenses.empty();
packageInfoPackager.empty();
packageInfoPackages.empty();
packageInfoUpstreamUrl.empty();
packageInfoVersion.empty();
packageInfoModal.addEventListener("hidden.bs.modal", _ => {
packageInfoAurUrl.textContent = "";
packageInfoDepends.textContent = "";
packageInfoGroups.textContent = "";
packageInfoLicenses.textContent = "";
packageInfoPackager.textContent = "";
packageInfoPackages.textContent = "";
packageInfoUpstreamUrl.textContent = "";
packageInfoVersion.textContent = "";
packageInfoVariablesBlock.attr("hidden", true);
packageInfoVariablesDiv.empty();
packageInfoVariablesBlock.hidden = true;
packageInfoVariablesDiv.replaceChildren();
packageInfoLogsInput.empty();
packageInfoChangesInput.empty();
packageInfoLogsInput.textContent = "";
packageInfoChangesInput.textContent = "";
packageInfoEventsTable.bootstrapTable("load", []);
clearChart();
packageInfoModal.trigger("reset");
hideInfoControls(true);
});
});
</script>

View File

@ -43,14 +43,14 @@
const packages = packageRebuildDependencyInput.value;
const repository = getRepositorySelector(packageRebuildRepositoryInput);
if (packages) {
bootstrap.Modal.getInstance(packageRebuildModal).hide();
bootstrap.Modal.getOrCreateInstance(packageRebuildModal).hide();
const onSuccess = update => `Repository rebuild has been run for packages which depend on ${update}`;
const onFailure = error => `Repository rebuild failed: ${error}`;
doPackageAction("/api/v1/service/rebuild", [packages], repository, onSuccess, onFailure);
}
}
$(_ => {
document.addEventListener("DOMContentLoaded", _ => {
packageRebuildModal.addEventListener("shown.bs.modal", _ => {
const option = packageRebuildRepositoryInput.querySelector(`option[value="${repository.architecture}-${repository.repository}"]`);
if (option) option.selected = "selected";

View File

@ -1,19 +1,14 @@
<script>
const keyImportButton = $("#key-import-button");
const packageAddButton = $("#package-add-button");
const packageRebuildButton = $("#package-rebuild-button");
const packageRemoveButton = $("#package-remove-button");
const packageUpdateButton = $("#package-update-button");
const packageInfoRemoveButton = $("#package-info-remove-button");
const packageInfoUpdateButton = $("#package-info-update-button");
const packageRemoveButton = document.getElementById("package-remove-button");
const packageUpdateButton = document.getElementById("package-update-button");
let repository = null;
const table = $("#packages");
// so far bootstrap-table only operates with jquery elements
const table = $(document.getElementById("packages"));
const statusBadge = $("#badge-status");
const versionBadge = $("#badge-version");
const statusBadge = document.getElementById("badge-status");
const versionBadge = document.getElementById("badge-version");
function doPackageAction(uri, packages, repository, successText, failureText, data) {
const queryParams = $.param({
@ -49,10 +44,10 @@
}
function getRepositorySelector(selector) {
const selected = selector.find(":selected");
const selected = selector.options[selector.selectedIndex];
return {
architecture: selected.data("architecture"),
repository: selected.data("repository"),
architecture: selected.getAttribute("data-architecture"),
repository: selected.getAttribute("data-repository"),
};
}
@ -60,14 +55,6 @@
return table.bootstrapTable("getSelections").map(row => row.id);
}
function hideControls(hidden) {
keyImportButton.attr("hidden", hidden);
packageAddButton.attr("hidden", hidden);
packageRebuildButton.attr("hidden", hidden);
packageRemoveButton.attr("hidden", hidden);
packageUpdateButton.attr("hidden", hidden);
}
function packagesRemove(packages) {
packages = packages ?? getSelection();
const onSuccess = update => `Packages ${update} have been removed`;
@ -125,7 +112,6 @@
table.bootstrapTable("load", payload);
table.bootstrapTable("uncheckAll");
table.bootstrapTable("hideLoading");
hideControls(false);
},
error: (jqXHR, _, errorThrown) => {
if ((jqXHR.status === 401) || (jqXHR.status === 403)) {
@ -139,7 +125,6 @@
const message = error => `Could not load list of packages: ${error}`;
showFailure("Load failure", message, jqXHR, errorThrown);
}
hideControls(true);
},
});
@ -152,23 +137,23 @@
type: "GET",
dataType: "json",
success: response => {
versionBadge.html(`<i class="bi bi-github"></i> ahriman ${safe(response.version)}`);
versionBadge.innerHTML = `<i class="bi bi-github"></i> ahriman ${safe(response.version)}`;
statusBadge
.popover("dispose")
.attr("data-bs-content", `${response.status.status} at ${new Date(1000 * response.status.timestamp).toISOStringShort()}`)
.popover();
statusBadge.removeClass();
statusBadge.addClass("btn");
statusBadge.addClass(badgeClass(response.status.status));
statusBadge.classList.remove(...statusBadge.classList);
statusBadge.classList.add("btn");
statusBadge.classList.add(badgeClass(response.status.status));
const popover = bootstrap.Popover.getOrCreateInstance(statusBadge);
popover.dispose();
statusBadge.dataset.bsContent = `${response.status.status} at ${new Date(1000 * response.status.timestamp).toISOStringShort()}`;
bootstrap.Popover.getOrCreateInstance(statusBadge);
},
});
}
function selectRepository() {
const fragment = window.location.hash.replace("#", "") || "{{ repositories[0].id }}";
const element = $(`#${fragment}-link`);
element.click();
document.getElementById(`${fragment}-link`).click();
}
function statusFormat(value) {
@ -182,20 +167,21 @@
return {classes: cellClass(value)};
}
$(_ => {
$("#repositories a").on("click", event => {
const element = event.target;
repository = {
architecture: element.dataset.architecture,
repository: element.dataset.repository,
document.addEventListener("DOMContentLoaded", _ => {
document.querySelectorAll("#repositories a").forEach(element => {
element.onclick = _ => {
repository = {
architecture: element.dataset.architecture,
repository: element.dataset.repository,
};
if (packageUpdateButton) packageUpdateButton.innerHTML = `<i class="bi bi-play"></i> update<span class="d-none d-sm-inline"> ${safe(repository.repository)} (${safe(repository.architecture)})</span>`;
bootstrap.Tab.getOrCreateInstance(document.getElementById(element.id)).show();
reload();
};
packageUpdateButton.html(`<i class="bi bi-play"></i> update<span class="d-none d-sm-inline"> ${safe(repository.repository)} (${safe(repository.architecture)})</span>`);
$(`#${element.id}`).tab("show");
reload();
});
table.on("check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table", _ => {
packageRemoveButton.prop("disabled", !table.bootstrapTable("getSelections").length);
if (packageRemoveButton) packageRemoveButton.disabled = !table.bootstrapTable("getSelections").length;
});
table.on("click-row.bs.table", (self, data, row, cell) => {
if (0 === cell || "base" === cell) {
@ -204,7 +190,7 @@
} else showPackageInfo(data.id);
});
table.on("created-controls.bs.table", _ => {
const pickerInput = $(".bootstrap-table-filter-control-timestamp");
const pickerInput = $(document.querySelector(".bootstrap-table-filter-control-timestamp"));
pickerInput.daterangepicker({
autoUpdateInput: false,
locale: {
@ -223,7 +209,7 @@
});
});
statusBadge.popover();
bootstrap.Popover.getOrCreateInstance(statusBadge);
selectRepository();
});
</script>

View File

@ -105,13 +105,13 @@ SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Pa
</div>
<script>
const table = $("#packages");
const table = $(document.getElementById("packages"));
const pacmanConf = $("#pacman-conf");
const pacmanConfCopyButton = $("#copy-btn");
const pacmanConf = document.getElementById("pacman-conf");
const pacmanConfCopyButton = document.getElementById("copy-btn");
async function copyPacmanConf() {
const conf = pacmanConf.text();
const conf = pacmanConf.textContent;
await copyToClipboard(conf, pacmanConfCopyButton);
}
@ -127,9 +127,9 @@ SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Pa
return extractDataList(table.bootstrapTable("getData"), "licenses");
}
$(_ => {
document.addEventListener("DOMContentLoaded", _ => {
table.on("created-controls.bs.table", _ => {
const pickerInput = $(".bootstrap-table-filter-control-timestamp");
const pickerInput = $(document.querySelector(".bootstrap-table-filter-control-timestamp"));
pickerInput.daterangepicker({
autoUpdateInput: false,
locale: {

View File

@ -22,17 +22,7 @@
<script>
async function copyToClipboard(text, button) {
if (navigator.clipboard === undefined) {
const input = document.createElement("textarea");
input.innerHTML = text;
document.body.appendChild(input);
input.select();
document.execCommand("copy");
document.body.removeChild(input);
} else {
await navigator.clipboard.writeText(text);
}
await navigator.clipboard.writeText(text);
button.innerHTML = "<i class=\"bi bi-clipboard-check\"></i> copied";
setTimeout(()=> {
button.innerHTML = "<i class=\"bi bi-clipboard\"></i> copy";