2024-08-31 00:30:30 +00:00
|
|
|
<dialog id="editlinks">
|
|
|
|
<header>
|
|
|
|
<h2>Editing: Links</h2>
|
|
|
|
<button id="add-link" class="button new">Add</button>
|
|
|
|
</header>
|
|
|
|
|
|
|
|
<form action="/api/v1/music/{{.ID}}/links">
|
|
|
|
<table>
|
|
|
|
<tr>
|
|
|
|
<th class="grabber"></th>
|
|
|
|
<th class="link-name">Name</th>
|
|
|
|
<th class="link-url">URL</th>
|
|
|
|
<th></th>
|
|
|
|
</tr>
|
|
|
|
{{range .Links}}
|
|
|
|
<tr class="link">
|
|
|
|
<td class="grabber"><img src="/img/list-grabber.svg"/></td>
|
|
|
|
<td class="link-name">
|
|
|
|
<input type="text" name="name" value="{{.Name}}">
|
|
|
|
</td>
|
|
|
|
<td class="link-url">
|
|
|
|
<input type="text" name="url" value="{{.URL}}">
|
|
|
|
</td>
|
|
|
|
<td>
|
|
|
|
<a class="delete">Delete</a>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
{{end}}
|
|
|
|
</table>
|
|
|
|
|
|
|
|
<div class="dialog-actions">
|
|
|
|
<button id="discard" type="button">Discard</button>
|
|
|
|
<button id="save" type="submit" class="save">Save</button>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
|
|
|
|
<script type="module">
|
|
|
|
import { makeMagicList } from "/admin/static/admin.js";
|
|
|
|
(() => {
|
|
|
|
const container = document.getElementById("editlinks");
|
|
|
|
const form = document.querySelector("#editlinks form");
|
|
|
|
const linkTable = form.querySelector("table tbody");
|
|
|
|
const addLinkBtn = document.getElementById("add-link");
|
|
|
|
const discardBtn = form.querySelector("button#discard");
|
|
|
|
|
|
|
|
makeMagicList(linkTable, "tr.link");
|
|
|
|
|
|
|
|
function rigLinkItem(el) {
|
|
|
|
const nameInput = el.querySelector(`input[name="name"]`)
|
|
|
|
const deleteBtn = el.querySelector("a.delete");
|
|
|
|
|
|
|
|
deleteBtn.addEventListener("click", e => {
|
|
|
|
e.preventDefault();
|
|
|
|
if (nameInput.value != "" &&
|
|
|
|
!confirm("Are you sure you want to delete \"" + nameInput.value + "\"?"))
|
|
|
|
return;
|
|
|
|
el.remove();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
[...linkTable.querySelectorAll("tr.link")].map(rigLinkItem);
|
|
|
|
|
|
|
|
addLinkBtn.addEventListener("click", e => {
|
|
|
|
e.preventDefault();
|
|
|
|
const row = document.createElement("tr");
|
|
|
|
row.className = "link";
|
|
|
|
|
|
|
|
const grabberCell = document.createElement("td");
|
|
|
|
grabberCell.className = "grabber";
|
|
|
|
const grabberImg = document.createElement("img");
|
|
|
|
grabberImg.src = "/img/list-grabber.svg";
|
|
|
|
grabberCell.appendChild(grabberImg);
|
|
|
|
row.appendChild(grabberCell);
|
|
|
|
|
|
|
|
const nameCell = document.createElement("td");
|
|
|
|
nameCell.className = "link-name";
|
|
|
|
const nameInput = document.createElement("input");
|
|
|
|
nameInput.type = "text";
|
|
|
|
nameInput.name = "name";
|
|
|
|
nameCell.appendChild(nameInput);
|
|
|
|
row.appendChild(nameCell);
|
|
|
|
|
|
|
|
const urlCell = document.createElement("td");
|
|
|
|
urlCell.className = "link-url";
|
|
|
|
const urlInput = document.createElement("input");
|
|
|
|
urlInput.type = "text";
|
|
|
|
urlInput.name = "url";
|
|
|
|
urlCell.appendChild(urlInput);
|
|
|
|
row.appendChild(urlCell);
|
|
|
|
|
|
|
|
const deleteCell = document.createElement("td");
|
|
|
|
const deleteBtn = document.createElement("a");
|
|
|
|
deleteBtn.className = "delete";
|
|
|
|
deleteBtn.innerText = "Delete";
|
|
|
|
deleteCell.appendChild(deleteBtn);
|
|
|
|
row.appendChild(deleteCell);
|
|
|
|
|
|
|
|
linkTable.appendChild(row);
|
|
|
|
|
|
|
|
row.draggable = true;
|
|
|
|
row.addEventListener("dragstart", () => { row.classList.add("moving") });
|
|
|
|
row.addEventListener("dragend", () => { row.classList.remove("moving") });
|
|
|
|
row.querySelectorAll("input").forEach(el => {
|
|
|
|
el.addEventListener("mousedown", () => { row.draggable = false });
|
|
|
|
el.addEventListener("mouseup", () => { row.draggable = true });
|
|
|
|
el.addEventListener("dragstart", e => { e.stopPropagation() });
|
|
|
|
});
|
|
|
|
|
|
|
|
deleteBtn.addEventListener("click", e => {
|
|
|
|
e.preventDefault();
|
|
|
|
if (nameInput.value != "" && !confirm("Are you sure you want to delete \"" + nameInput.value + "\"?")) return;
|
|
|
|
row.remove();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
container.showModal();
|
|
|
|
|
|
|
|
container.addEventListener("close", () => {
|
|
|
|
container.remove();
|
|
|
|
});
|
|
|
|
|
|
|
|
form.addEventListener("submit", e => {
|
|
|
|
var links = [];
|
|
|
|
[...linkTable.querySelectorAll("tr.link")].map(el => {
|
|
|
|
const name = el.querySelector(`input[name="name"]`).value;
|
|
|
|
const url = el.querySelector(`input[name="url"]`).value;
|
|
|
|
if (name == "" || url == "") return;
|
|
|
|
links.push({
|
|
|
|
"name": name,
|
|
|
|
"url": url,
|
|
|
|
});
|
|
|
|
})
|
|
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
fetch(form.action, {
|
|
|
|
method: "PUT",
|
|
|
|
headers: { "Content-Type": "application/json" },
|
|
|
|
body: JSON.stringify(links)
|
|
|
|
}).then(res => {
|
|
|
|
if (res.ok) location = location;
|
|
|
|
else {
|
|
|
|
res.text().then(err => {
|
|
|
|
alert(err);
|
|
|
|
console.error(err);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}).catch(err => {
|
|
|
|
alert("Failed to update links. Check the console for details.");
|
|
|
|
console.error(err);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
discardBtn.addEventListener("click", e => {
|
|
|
|
e.preventDefault();
|
|
|
|
container.close();
|
|
|
|
});
|
|
|
|
})();
|
|
|
|
</script>
|
|
|
|
</dialog>
|