embed html template and static files
This commit is contained in:
parent
b150fa491c
commit
e5dcc4b884
44 changed files with 316 additions and 255 deletions
47
admin/templates/html/components/credits/addcredit.html
Normal file
47
admin/templates/html/components/credits/addcredit.html
Normal file
|
@ -0,0 +1,47 @@
|
|||
<dialog id="addcredit">
|
||||
<header>
|
||||
<h2>Add Artist Credit</h2>
|
||||
</header>
|
||||
|
||||
<ul>
|
||||
{{range $Artist := .Artists}}
|
||||
<li class="new-artist"
|
||||
data-id="{{$Artist.ID}}"
|
||||
hx-get="/admin/release/{{$.ReleaseID}}/newcredit/{{$Artist.ID}}"
|
||||
hx-target="#editcredits ul"
|
||||
hx-swap="beforeend"
|
||||
>
|
||||
<img src="{{$Artist.GetAvatar}}" alt="" width="16" loading="lazy" class="artist-avatar">
|
||||
<span class="artist-name">{{$Artist.Name}} <span class="artist-id">({{$Artist.ID}})</span></span>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
|
||||
{{if not .Artists}}
|
||||
<p class="empty">There are no more artists to add.</p>
|
||||
{{end}}
|
||||
|
||||
<div class="dialog-actions">
|
||||
<button id="cancel" type="button">Cancel</button>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
(() => {
|
||||
const newCreditModal = document.getElementById("addcredit")
|
||||
const editCreditsModal = document.getElementById("editcredits")
|
||||
const cancelBtn = newCreditModal.querySelector("#cancel");
|
||||
|
||||
editCreditsModal.addEventListener("htmx:afterSwap", () => {
|
||||
newCreditModal.close();
|
||||
newCreditModal.remove();
|
||||
});
|
||||
|
||||
cancelBtn.addEventListener("click", () => {
|
||||
newCreditModal.close();
|
||||
newCreditModal.remove();
|
||||
});
|
||||
|
||||
newCreditModal.showModal();
|
||||
})();
|
||||
</script>
|
||||
</dialog>
|
114
admin/templates/html/components/credits/editcredits.html
Normal file
114
admin/templates/html/components/credits/editcredits.html
Normal file
|
@ -0,0 +1,114 @@
|
|||
<dialog id="editcredits">
|
||||
<header>
|
||||
<h2>Editing: Credits</h2>
|
||||
<a id="add-credit"
|
||||
class="button new"
|
||||
href="/admin/release/{{.ID}}/addcredit"
|
||||
hx-get="/admin/release/{{.ID}}/addcredit"
|
||||
hx-target="body"
|
||||
hx-swap="beforeend"
|
||||
>Add</a>
|
||||
</header>
|
||||
|
||||
<form action="/api/v1/music/{{.ID}}/credits">
|
||||
<ul>
|
||||
{{range .Credits}}
|
||||
<li class="credit" data-artist="{{.Artist.ID}}">
|
||||
<div>
|
||||
<img src="{{.Artist.GetAvatar}}" alt="" width="64" loading="lazy" class="artist-avatar">
|
||||
<div class="credit-info">
|
||||
<p class="artist-name">{{.Artist.Name}}</p>
|
||||
<div class="credit-attribute">
|
||||
<label for="role">Role:</label>
|
||||
<input type="text" name="role" value="{{.Role}}">
|
||||
</div>
|
||||
<div class="credit-attribute">
|
||||
<label for="primary">Primary:</label>
|
||||
<input type="checkbox" name="primary" {{if .Primary}}checked{{end}}>
|
||||
</div>
|
||||
</div>
|
||||
<a class="delete">Delete</a>
|
||||
</div>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
|
||||
<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("editcredits");
|
||||
const form = document.querySelector("#editcredits form");
|
||||
const creditList = form.querySelector("ul");
|
||||
const addCreditBtn = document.getElementById("add-credit");
|
||||
const discardBtn = form.querySelector("button#discard");
|
||||
|
||||
makeMagicList(creditList, ".credit");
|
||||
|
||||
function rigCredit(el) {
|
||||
const artistID = el.dataset.artist;
|
||||
const deleteBtn = el.querySelector("a.delete");
|
||||
|
||||
deleteBtn.addEventListener("click", e => {
|
||||
if (!confirm("Are you sure you want to delete " + artistID + "'s credit?")) return;
|
||||
el.remove();
|
||||
});
|
||||
|
||||
el.draggable = true;
|
||||
el.addEventListener("dragstart", () => { el.classList.add("moving") });
|
||||
el.addEventListener("dragend", () => { el.classList.remove("moving") });
|
||||
}
|
||||
|
||||
[...creditList.querySelectorAll(".credit")].map(rigCredit);
|
||||
|
||||
creditList.addEventListener("htmx:afterSwap", () => {
|
||||
rigCredit(creditList.children[creditList.children.length - 1]);
|
||||
});
|
||||
|
||||
container.showModal();
|
||||
|
||||
container.addEventListener("close", () => {
|
||||
container.remove();
|
||||
});
|
||||
|
||||
form.addEventListener("submit", e => {
|
||||
const credits = [...creditList.querySelectorAll(".credit")].map(el => {
|
||||
return {
|
||||
"artist": el.dataset.artist,
|
||||
"role": el.querySelector(`input[name="role"]`).value,
|
||||
"primary": el.querySelector(`input[name="primary"]`).checked,
|
||||
};
|
||||
});
|
||||
|
||||
e.preventDefault();
|
||||
fetch(form.action, {
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(credits)
|
||||
}).then(res => {
|
||||
if (res.ok) location = location;
|
||||
else {
|
||||
res.text().then(err => {
|
||||
alert(err);
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
}).catch(err => {
|
||||
alert("Failed to update credits. Check the console for details.");
|
||||
console.error(err);
|
||||
});
|
||||
});
|
||||
|
||||
discardBtn.addEventListener("click", e => {
|
||||
e.preventDefault();
|
||||
container.close();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</dialog>
|
17
admin/templates/html/components/credits/newcredit.html
Normal file
17
admin/templates/html/components/credits/newcredit.html
Normal file
|
@ -0,0 +1,17 @@
|
|||
<li class="credit" data-artist="{{.ID}}">
|
||||
<div>
|
||||
<img src="{{.GetAvatar}}" alt="" width="64" loading="lazy" class="artist-avatar">
|
||||
<div class="credit-info">
|
||||
<p class="artist-name">{{.Name}}</p>
|
||||
<div class="credit-attribute">
|
||||
<label for="role">Role:</label>
|
||||
<input type="text" name="role" value="">
|
||||
</div>
|
||||
<div class="credit-attribute">
|
||||
<label for="primary">Primary:</label>
|
||||
<input type="checkbox" name="primary">
|
||||
</div>
|
||||
</div>
|
||||
<a class="delete">Delete</a>
|
||||
</div>
|
||||
</li>
|
Loading…
Add table
Add a link
Reference in a new issue