lyrics

lyrics
git clone git://brookjeynes.dev/bjeynes/lyrics.git
Log | Files | Refs

edit-release.templ (6727B)


      1 package editrelease
      2 
      3 import (
      4 	"fmt"
      5 	"lyrics/internal/domain"
      6 	"lyrics/internal/server/routes"
      7 	"lyrics/internal/server/ui/layouts/base"
      8 	"time"
      9 )
     10 
     11 templ EditRelease(params EditReleaseParams) {
     12 	@base.Base(base.BaseParams{Title: "edit " + params.Release.Title, PageStylesheets: []string{"new-release.css"}}) {
     13 		<h1>Edit release</h1>
     14 		<form
     15 			class="release-form"
     16 			hx-post={ routes.ReleaseEdit(params.Release) }
     17 			hx-swap="none"
     18 			hx-disable-elt="#save-release-btn"
     19 		>
     20 			<fieldset>
     21 				<legend>Type</legend>
     22 				<label for="type">type:</label>
     23 				<select name="type" required>
     24 					<option
     25 						if params.Release.Type == "album" {
     26 							selected
     27 						}
     28 						value="album"
     29 					>album</option>
     30 					<option
     31 						if params.Release.Type == "single" {
     32 							selected
     33 						}
     34 						value="single"
     35 					>single</option>
     36 					<option
     37 						if params.Release.Type == "ep" {
     38 							selected
     39 						}
     40 						value="ep"
     41 					>ep</option>
     42 					<option
     43 						if params.Release.Type == "other" {
     44 							selected
     45 						}
     46 						value="other"
     47 					>other</option>
     48 				</select>
     49 			</fieldset>
     50 			<fieldset
     51 				x-data="{ showLatinTitle: false }"
     52 				x-init="showLatinTitle = isNonAscii($refs.releaseTitle.value)"
     53 			>
     54 				<legend>Title</legend>
     55 				<label>
     56 					title:
     57 					<input
     58 						x-ref="releaseTitle"
     59 						hx-get="/release/search?format=similar"
     60 						hx-trigger="input changed delay:500ms"
     61 						hx-target="#similar-releases"
     62 						hx-swap="innerHTML"
     63 						name="release-title"
     64 						type="text"
     65 						value={ params.Release.Title }
     66 						pattern={ domain.NoTrailingOrLeadingSpaceRegex.String() }
     67 						required
     68 						@input="showLatinTitle = isNonAscii($event.target.value)"
     69 					/>
     70 				</label>
     71 				<label x-show="showLatinTitle">
     72 					latin title:
     73 					<input
     74 						name="latin-title"
     75 						type="text"
     76 						if params.Release.LatinTitle != nil {
     77 							value={ *params.Release.LatinTitle }
     78 						}
     79 						:required="showLatinTitle"
     80 						pattern={ domain.IsValidSortNamePattern }
     81 					/>
     82 				</label>
     83 			</fieldset>
     84 			<section id="similar-releases" class="similar-releases" aria-label="Similar releases"></section>
     85 			<fieldset
     86 				x-data={ fmt.Sprintf("{ items: %s, uid: %d }", editReleaseArtistsJSON(params.Release.Artists), len(params.Release.Artists)) }
     87 			>
     88 				<legend>Artists</legend>
     89 				<ol class="picker-list">
     90 					<template x-for="(item, i) in items" :key="item.uid">
     91 						<li
     92 							x-data="item"
     93 							x-init="htmx.process($el); initLucideIcons()"
     94 						>
     95 							<div class="picker-row">
     96 								<div class="picker-main">
     97 									<label x-show="!item.selected">
     98 										<span>artist:</span>
     99 										<input
    100 											type="search"
    101 											hx-get="/artist/search?format=suggest"
    102 											hx-trigger="input changed delay:500ms"
    103 											hx-target="next .picker-options"
    104 											hx-swap="outerHTML"
    105 											name="artist"
    106 											autocomplete="off"
    107 											:required="!item.selected"
    108 										/>
    109 									</label>
    110 									<div class="picker-selected-item" x-show="item.selected">
    111 										<strong x-text="item.artistName"></strong>
    112 										<button
    113 											type="button"
    114 											class="-secondary"
    115 											@click="item.selected = false; item.artistId = ''; item.artistName = ''"
    116 										>
    117 											change
    118 										</button>
    119 									</div>
    120 								</div>
    121 								<div class="picker-actions">
    122 									<button
    123 										type="button"
    124 										aria-label="Remove"
    125 										x-show="items.length > 1"
    126 										@click="items.splice(i, 1)"
    127 									>
    128 										<i data-lucide="x"></i>
    129 									</button>
    130 									<button
    131 										type="button"
    132 										aria-label="Move up"
    133 										x-show="item.selected && items.length > 1 && i >= 1"
    134 										@click="[items[i - 1], items[i]] = [items[i], items[i - 1]]"
    135 									>
    136 										<i data-lucide="chevron-up"></i>
    137 									</button>
    138 									<button
    139 										type="button"
    140 										aria-label="Move down"
    141 										x-show="item.selected && items.length > 1 && i + 1 < items.length"
    142 										@click="[items[i + 1], items[i]] = [items[i], items[i + 1]]"
    143 									>
    144 										<i data-lucide="chevron-down"></i>
    145 									</button>
    146 								</div>
    147 							</div>
    148 							<div x-show="!item.selected">
    149 								<fieldset class="picker-options" role="radiogroup" x-show="false"></fieldset>
    150 							</div>
    151 							<input type="hidden" name="artist-id" :value="item.artistId"/>
    152 						</li>
    153 					</template>
    154 				</ol>
    155 				<button
    156 					class="-secondary"
    157 					type="button"
    158 					@click="items.push({ uid: uid++, selected: false, artistId: '', artistName: '' })"
    159 				>
    160 					add additional artist
    161 				</button>
    162 			</fieldset>
    163 			<fieldset>
    164 				<legend>Release</legend>
    165 				<label>
    166 					release date:
    167 					<input
    168 						name="release-date"
    169 						type="date"
    170 						value={ params.Release.ReleaseDate.Format(time.DateOnly) }
    171 						min="1000-01-01"
    172 						max={ fmt.Sprintf("%s", time.Now().AddDate(3, 0, 0).Format("2006-01-02")) }
    173 						required
    174 					/>
    175 				</label>
    176 			</fieldset>
    177 			<fieldset
    178 				x-data={ fmt.Sprintf("{ items: %s }", editReleaseSongsJSON(params.Release.Songs)) }
    179 			>
    180 				<legend>Songs</legend>
    181 				if len(params.Release.Songs) == 0 {
    182 					<p class="section-label -muted">No songs yet.</p>
    183 				} else {
    184 					<ol class="picker-list">
    185 						<template x-for="(item, i) in items" :key="item.id">
    186 							<li :value="item.trackNumber" x-init="htmx.process($el); initLucideIcons()">
    187 								<div class="picker-row">
    188 									<input
    189 										type="number"
    190 										:value="item.trackNumber"
    191 										min="1"
    192 										@change="changeTrackOrder($event, items, i, $event.target.value)"
    193 										required
    194 									/>
    195 									<div class="picker-main">
    196 										<strong x-text="item.title"></strong>
    197 									</div>
    198 								</div>
    199 								<input type="hidden" name="song-id" :value="item.id"/>
    200 								<input type="hidden" name="track-number" :value="item.trackNumber"/>
    201 							</li>
    202 						</template>
    203 					</ol>
    204 				}
    205 			</fieldset>
    206 			<fieldset>
    207 				<legend>MusicBrainz</legend>
    208 				<label title="External identifier used for metadata lookups such as cover art.">
    209 					Release ID (optional):
    210 					<input
    211 						name="musicbrainz-release-id"
    212 						type="text"
    213 						if params.Release.MusicBrainzReleaseID != nil {
    214 							value={ *params.Release.MusicBrainzReleaseID }
    215 						}
    216 						pattern={ domain.IsValidMusicBrainzIDPattern }
    217 						placeholder="e32a4ae3-67d1-4541-84d8-de6ab2d7dec1"
    218 					/>
    219 					<i data-lucide="info"></i>
    220 				</label>
    221 			</fieldset>
    222 			<footer aria-label="Form actions">
    223 				<button class="-primary" id="save-release-btn" type="submit">save changes</button>
    224 				<a href={ routes.Release(params.Release) }>cancel</a>
    225 			</footer>
    226 		</form>
    227 		<script src="/static/js/edit-release.js" defer></script>
    228 	}
    229 }