ADMIN: added pending review
Build and Publish / Build and Publish Docker Image (push) Successful in 5m5s
Build and Publish / Build and Publish Docker Image (push) Successful in 5m5s
This commit is contained in:
@@ -25,28 +25,76 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if review.status_str() == "pending" %}
|
||||
<h2>{{ t.reviews_result }}</h2>
|
||||
<form method="post" action="/admin/reviews/{{ review.id_val() }}/approve" style="margin: 1rem 0;">
|
||||
<table>
|
||||
<tr>
|
||||
<td><label for="artist">Artist</label></td>
|
||||
<td><input name="artist" id="artist" value="{{ edit.artist }}" style="width:100%"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="album">Album</label></td>
|
||||
<td><input name="album" id="album" value="{{ edit.album }}" style="width:100%"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="title">Title</label></td>
|
||||
<td><input name="title" id="title" value="{{ edit.title }}" style="width:100%"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="year">Year</label></td>
|
||||
<td><input name="year" id="year" type="number" min="0" max="3000" value="{{ edit.year }}" style="width:100%"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="track_number">Track</label></td>
|
||||
<td><input name="track_number" id="track_number" type="number" min="0" value="{{ edit.track_number }}" style="width:100%"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="genre">Genre</label></td>
|
||||
<td><input name="genre" id="genre" value="{{ edit.genre }}" style="width:100%"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="featured_artists">Featured artists</label></td>
|
||||
<td><input name="featured_artists" id="featured_artists" value="{{ edit.featured_artists }}" style="width:100%"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="release_type">{{ t.releases_type }}</label></td>
|
||||
<td>
|
||||
<select name="release_type" id="release_type" style="width:100%; padding:.4rem;">
|
||||
{% for rt in release_types %}
|
||||
<option value="{{ rt.0 }}"{% if edit.release_type == rt.0 %} selected{% endif %}>{% if lang_code == "ru" %}{{ rt.2 }}{% else %}{{ rt.1 }}{% endif %} ({{ rt.0 }})</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="notes">Notes</label></td>
|
||||
<td><textarea name="notes" id="notes" style="width:100%; min-height:4rem;">{{ edit.notes }}</textarea></td>
|
||||
</tr>
|
||||
</table>
|
||||
<button type="submit" style="margin-top:1rem; padding:.4rem 1rem; background:#28a745; color:#fff; border:none; border-radius:4px; cursor:pointer;">{{ t.reviews_approve }}</button>
|
||||
</form>
|
||||
<div style="margin: 1rem 0; display: flex; gap: .5rem;">
|
||||
{% if review.status_str() == "pending" %}
|
||||
<form method="post" action="/admin/reviews/{{ review.id_val() }}/approve" style="display:inline;">
|
||||
<button type="submit" style="padding:.4rem 1rem; background:#28a745; color:#fff; border:none; border-radius:4px; cursor:pointer;">{{ t.reviews_approve }}</button>
|
||||
</form>
|
||||
<form method="post" action="/admin/reviews/{{ review.id_val() }}/reject" style="display:inline;">
|
||||
<button type="submit" style="padding:.4rem 1rem; background:#dc3545; color:#fff; border:none; border-radius:4px; cursor:pointer;">{{ t.reviews_reject }}</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div style="margin: 1rem 0; display: flex; gap: .5rem;">
|
||||
{% if review.status_str() == "failed" || review.status_str() == "processing" %}
|
||||
<form method="post" action="/admin/reviews/{{ review.id_val() }}/requeue" style="display:inline;" onsubmit="return confirm('{{ t.reviews_requeue_confirm }}');">
|
||||
<button type="submit" style="padding:.4rem 1rem; background:#17a2b8; color:#fff; border:none; border-radius:4px; cursor:pointer;">{{ t.reviews_requeue }}</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if !context_pretty.is_empty() %}
|
||||
<h2>{{ t.reviews_context }}</h2>
|
||||
<pre style="background:#f4f4f4; padding:1rem; border-radius:6px; overflow-x:auto; font-size:.85rem;">{{ context_pretty }}</pre>
|
||||
{% endif %}
|
||||
|
||||
{% if !result_pretty.is_empty() %}
|
||||
{% if !result_pretty.is_empty() && review.status_str() != "pending" %}
|
||||
<h2>{{ t.reviews_result }}</h2>
|
||||
<pre style="background:#f4f4f4; padding:1rem; border-radius:6px; overflow-x:auto; font-size:.85rem;">{{ result_pretty }}</pre>
|
||||
{% endif %}
|
||||
|
||||
+94
-1
@@ -851,7 +851,8 @@ tbody tr:hover {
|
||||
}
|
||||
|
||||
.field input,
|
||||
.field textarea {
|
||||
.field textarea,
|
||||
.field select {
|
||||
width: 100%;
|
||||
min-height: 34px;
|
||||
padding: 8px 10px;
|
||||
@@ -1673,7 +1674,60 @@ tbody tr:hover {
|
||||
<label>Error</label>
|
||||
<textarea readonly x-text="activeReview?.error_message || ''"></textarea>
|
||||
</div>
|
||||
<div x-show="activeReview?.status === 'pending'">
|
||||
<div class="field">
|
||||
<label>Artist</label>
|
||||
<input x-model="reviewDraft.artist" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Album</label>
|
||||
<input x-model="reviewDraft.album" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Title</label>
|
||||
<input x-model="reviewDraft.title" />
|
||||
</div>
|
||||
<div style="display:grid; grid-template-columns: 1fr 1fr; gap: 12px;">
|
||||
<div class="field">
|
||||
<label>Year</label>
|
||||
<input type="number" min="0" max="3000" x-model="reviewDraft.year" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Track</label>
|
||||
<input type="number" min="0" x-model="reviewDraft.track_number" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Genre</label>
|
||||
<input x-model="reviewDraft.genre" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Featured artists</label>
|
||||
<input x-model="reviewDraft.featured_artists" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Release type</label>
|
||||
<select x-model="reviewDraft.release_type">
|
||||
<option value="album">Album</option>
|
||||
<option value="single">Single</option>
|
||||
<option value="ep">EP</option>
|
||||
<option value="compilation">Compilation</option>
|
||||
<option value="soundtrack">Soundtrack</option>
|
||||
<option value="live">Live</option>
|
||||
<option value="remix">Remix</option>
|
||||
<option value="unknown">Unknown</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Notes</label>
|
||||
<textarea x-model="reviewDraft.notes"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="toolbar">
|
||||
<button class="btn primary" x-show="activeReview?.status === 'pending'" @click="approveActiveReview()">
|
||||
<i data-lucide="check"></i>
|
||||
Approve
|
||||
</button>
|
||||
<button class="btn warn" @click="bulkOneReview('requeue', activeReview)">
|
||||
<i data-lucide="rotate-ccw"></i>
|
||||
Requeue
|
||||
@@ -1751,6 +1805,17 @@ function adminV2() {
|
||||
selectedReviewIds: {},
|
||||
reviewSelectionScope: 'ids',
|
||||
activeReview: null,
|
||||
reviewDraft: {
|
||||
title: '',
|
||||
artist: '',
|
||||
album: '',
|
||||
year: '',
|
||||
track_number: '',
|
||||
genre: '',
|
||||
featured_artists: '',
|
||||
release_type: 'album',
|
||||
notes: ''
|
||||
},
|
||||
reviewModalOpen: false,
|
||||
reviewStatuses: [
|
||||
{ value: null, label: 'All' },
|
||||
@@ -2072,6 +2137,17 @@ function adminV2() {
|
||||
|
||||
openReview(row) {
|
||||
this.activeReview = row;
|
||||
this.reviewDraft = Object.assign({
|
||||
title: '',
|
||||
artist: '',
|
||||
album: '',
|
||||
year: '',
|
||||
track_number: '',
|
||||
genre: '',
|
||||
featured_artists: '',
|
||||
release_type: 'album',
|
||||
notes: ''
|
||||
}, row.normalized || {});
|
||||
this.activeRunDetail = null;
|
||||
this.reviewModalOpen = true;
|
||||
},
|
||||
@@ -2165,6 +2241,23 @@ function adminV2() {
|
||||
this.reviewModalOpen = false;
|
||||
},
|
||||
|
||||
async approveActiveReview() {
|
||||
if (!this.activeReview) return;
|
||||
try {
|
||||
await this.request(`${this.apiBase}/reviews/${this.activeReview.id}/approve`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(this.reviewDraft)
|
||||
});
|
||||
this.showToast('Review approved');
|
||||
this.reviewModalOpen = false;
|
||||
this.activeReview = null;
|
||||
await this.loadReviews(false);
|
||||
await this.loadLibrary(false);
|
||||
} catch (error) {
|
||||
this.showToast(error.message);
|
||||
}
|
||||
},
|
||||
|
||||
async runJob(job) {
|
||||
job.launching = true;
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user