Added quick associate functionality to web UI

This commit is contained in:
krateng 2023-10-17 12:55:25 +02:00
parent 15c16014e0
commit 25ba050d30
6 changed files with 120 additions and 19 deletions

View File

@ -941,7 +941,7 @@ def count_scrobbles_by_artist(since,to,resolve_ids=True,dbconn=None):
if resolve_ids:
artists = get_artists_map([row.artist_id for row in result],dbconn=dbconn)
result = [{'scrobbles':row.count,'artist':artists[row.artist_id]} for row in result]
result = [{'scrobbles':row.count,'artist':artists[row.artist_id],'artist_id':row.artist_id} for row in result]
else:
result = [{'scrobbles':row.count,'artist_id':row.artist_id} for row in result]
result = rank(result,key='scrobbles')
@ -963,7 +963,7 @@ def count_scrobbles_by_track(since,to,resolve_ids=True,dbconn=None):
if resolve_ids:
tracks = get_tracks_map([row.track_id for row in result],dbconn=dbconn)
result = [{'scrobbles':row.count,'track':tracks[row.track_id]} for row in result]
result = [{'scrobbles':row.count,'track':tracks[row.track_id],'track_id':row.track_id} for row in result]
else:
result = [{'scrobbles':row.count,'track_id':row.track_id} for row in result]
result = rank(result,key='scrobbles')
@ -991,7 +991,7 @@ def count_scrobbles_by_album(since,to,resolve_ids=True,dbconn=None):
if resolve_ids:
albums = get_albums_map([row.album_id for row in result],dbconn=dbconn)
result = [{'scrobbles':row.count,'album':albums[row.album_id]} for row in result]
result = [{'scrobbles':row.count,'album':albums[row.album_id],'album_id':row.album_id} for row in result]
else:
result = [{'scrobbles':row.count,'album_id':row.album_id} for row in result]
result = rank(result,key='scrobbles')
@ -1028,7 +1028,7 @@ def count_scrobbles_by_album_of_artist(since,to,artist,resolve_ids=True,dbconn=N
if resolve_ids:
albums = get_albums_map([row.album_id for row in result],dbconn=dbconn)
result = [{'scrobbles':row.count,'album':albums[row.album_id]} for row in result]
result = [{'scrobbles':row.count,'album':albums[row.album_id],'album_id':row.album_id} for row in result]
else:
result = [{'scrobbles':row.count,'album_id':row.album_id} for row in result]
result = rank(result,key='scrobbles')
@ -1065,7 +1065,7 @@ def count_scrobbles_of_artist_by_album(since,to,artist,resolve_ids=True,dbconn=N
if resolve_ids:
albums = get_albums_map([row.album_id for row in result],dbconn=dbconn)
result = [{'scrobbles':row.count,'album':albums[row.album_id]} for row in result]
result = [{'scrobbles':row.count,'album':albums[row.album_id],'album_id':row.album_id} for row in result]
else:
result = [{'scrobbles':row.count,'album_id':row.album_id} for row in result]
result = rank(result,key='scrobbles')
@ -1097,7 +1097,7 @@ def count_scrobbles_by_track_of_artist(since,to,artist,resolve_ids=True,dbconn=N
if resolve_ids:
tracks = get_tracks_map([row.track_id for row in result],dbconn=dbconn)
result = [{'scrobbles':row.count,'track':tracks[row.track_id]} for row in result]
result = [{'scrobbles':row.count,'track':tracks[row.track_id],'track_id':row.track_id} for row in result]
else:
result = [{'scrobbles':row.count,'track_id':row.track_id} for row in result]
result = rank(result,key='scrobbles')
@ -1129,7 +1129,7 @@ def count_scrobbles_by_track_of_album(since,to,album,resolve_ids=True,dbconn=Non
if resolve_ids:
tracks = get_tracks_map([row.track_id for row in result],dbconn=dbconn)
result = [{'scrobbles':row.count,'track':tracks[row.track_id]} for row in result]
result = [{'scrobbles':row.count,'track':tracks[row.track_id],'track_id':row.track_id} for row in result]
else:
result = [{'scrobbles':row.count,'track_id':row.track_id} for row in result]
result = rank(result,key='scrobbles')

View File

@ -1,5 +1,5 @@
<div title="Cancel Track Association" id="associationcancelicon" class="clickable_icon" onclick="cancelAssociate()">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<div title="Cancel Track Association" id="associationcancelicon" class="clickable_icon" onclick="umarkForAssociate(this)">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M2.345 20.595 8.47 14.47q.219-.22.53-.22.311 0 .53.22.22.219.22.53 0 .311-.22.53l-6.125 6.125q-.219.22-.53.22-.311 0-.53-.22-.22-.219-.22-.53 0-.311.22-.53Z"></path>
<path d="m16.72 11.97.358-.358a6.738 6.738 0 0 1 2.326-1.518l1.896-.738a.25.25 0 0 0 .086-.409l-6.333-6.333a.25.25 0 0 0-.409.086l-.521 1.34a8.663 8.663 0 0 1-2.243 3.265.75.75 0 0 1-1.01-1.11 7.132 7.132 0 0 0 1.854-2.699l.521-1.34a1.75 1.75 0 0 1 2.869-.603l6.333 6.333a1.75 1.75 0 0 1-.603 2.869l-1.896.737a5.26 5.26 0 0 0-1.81 1.18l-.358.358a.749.749 0 1 1-1.06-1.06Zm-12.549-.738a1.75 1.75 0 0 1 .757-2.92l3.366-.962.412 1.443-3.366.961a.25.25 0 0 0-.108.417l8.597 8.597a.25.25 0 0 0 .417-.108l.961-3.366 1.443.412-.962 3.366a1.75 1.75 0 0 1-2.92.757Z"></path>
<path d="m3.405 2.095 18.75 18.75q.22.219.22.53 0 .311-.22.53-.219.22-.53.22-.311 0-.53-.22L2.345 3.155q-.22-.219-.22-.53 0-.311.22-.53.219-.22.53-.22.311 0 .53.22Z"></path>

View File

@ -1,5 +1,5 @@
<div title="Mark to associate artists or album" id="associationmarkicon" class="clickable_icon" onclick="markForAssociate()">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<div title="Mark to associate artists or album" id="associationmarkicon" class="clickable_icon" onclick="markForAssociate(this)">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="m16.114 1.553 6.333 6.333a1.75 1.75 0 0 1-.603 2.869l-1.63.633a5.67 5.67 0 0 0-3.395 3.725l-1.131 3.959a1.75 1.75 0 0 1-2.92.757L9 16.061l-5.595 5.594a.749.749 0 1 1-1.06-1.06L7.939 15l-3.768-3.768a1.75 1.75 0 0 1 .757-2.92l3.959-1.131a5.666 5.666 0 0 0 3.725-3.395l.633-1.63a1.75 1.75 0 0 1 2.869-.603ZM5.232 10.171l8.597 8.597a.25.25 0 0 0 .417-.108l1.131-3.959A7.17 7.17 0 0 1 19.67 9.99l1.63-.634a.25.25 0 0 0 .086-.409l-6.333-6.333a.25.25 0 0 0-.409.086l-.634 1.63a7.17 7.17 0 0 1-4.711 4.293L5.34 9.754a.25.25 0 0 0-.108.417Z"></path>
</svg>
</div>

View File

@ -6,16 +6,33 @@
{% set firstindex = amountkeys.page * amountkeys.perpage %}
{% set lastindex = firstindex + amountkeys.perpage %}
<script src="/edit.js"></script>
<table class='list'>
{% for e in list %}
{% if loop.index0 >= firstindex and loop.index0 < lastindex %}
<tr>
<tr class="listrow unmarked" data-entity_id="{{ e['track_id'] }}" data-entity_type="track" data-entity_name="{{ e['track'].title }}">
<!-- artist -->
{{ entityrow.row(e['track']) }}
{% with inlineicons = True %}
<td>
{% include 'icons/association_mark.jinja' %}
{% include 'icons/association_cancel.jinja' %}
</td>
{% endwith %}
</tr>
{% endif %}
{% endfor %}
</table>
<script>
var listrows = document.getElementsByClassName('listrow');
for (var row of listrows) {
toggleAssociationIcons(row);
}
</script>

View File

@ -83,7 +83,26 @@ div.clickable_icon.danger:hover svg {
fill: red;
}
#icon_bar svg {
width:24px;
height:24px;
}
.list svg {
height:16px;
}
.list div.clickable_icon {
display: inline-block;
}
.list tr.marked {
background-color: rgba(50,20,0,0.5);
}
.list tr.marked #associationmarkicon {
display:none;
}
.list tr:not(.marked) #associationcancelicon {
display:none;
}
/**
Footer

View File

@ -310,17 +310,82 @@ function markForMerge() {
showValidMergeIcons();
}
function markForAssociate() {
function markForAssociate(element) {
console.log(element);
const parentElement = element.closest('[data-entity_id]');
console.log(parentElement);
// use local element for entity data, otherwise use from global scope (on entity info page)
var l_entity_type = parentElement ? parentElement.dataset.entity_type : entity_type;
var l_entity_id = parentElement ? parentElement.dataset.entity_id : entity_id;
var l_entity_name = parentElement ? parentElement.dataset.entity_name : entity_name;
l_entity_id = parseInt(l_entity_id);
const lcst = window.sessionStorage;
var key = "marked_for_associate_" + l_entity_type;
var current_stored = (lcst.getItem(key) || '').split(",");
current_stored = current_stored.filter((x)=>x).map((x)=>parseInt(x));
current_stored.push(l_entity_id);
current_stored = [...new Set(current_stored)];
lcst.setItem(key,current_stored); //this already formats it correctly
var whattoadd = ((l_entity_type == 'track') ? "Artists or Album" : "Artists")
notify("Marked " + l_entity_name + " to add " + whattoadd,"Currently " + current_stored.length + " marked!")
if (!parentElement) {
showValidMergeIcons();
}
else {
toggleAssociationIcons(parentElement);
}
}
function umarkForAssociate(element) {
const parentElement = element.closest('[data-entity_id]');
// use local element for entity data, otherwise use from global scope (on entity info page)
var l_entity_type = parentElement ? parentElement.dataset.entity_type : entity_type;
var l_entity_id = parentElement ? parentElement.dataset.entity_id : entity_id;
var l_entity_name = parentElement ? parentElement.dataset.entity_name : entity_name;
l_entity_id = parseInt(l_entity_id);
const lcst = window.sessionStorage;
var key = "marked_for_associate_" + l_entity_type;
var current_stored = (lcst.getItem(key) || '').split(",");
current_stored = current_stored.filter((x)=>x).map((x)=>parseInt(x));
if (current_stored.indexOf(l_entity_id) > -1) {
current_stored.splice(current_stored.indexOf(l_entity_id),1);
current_stored = [...new Set(current_stored)];
lcst.setItem(key,current_stored); //this already formats it correctly
var whattoadd = ((l_entity_type == 'track') ? "Artists or Album" : "Artists")
notify("Unmarked " + l_entity_name + " to add " + whattoadd,"Currently " + current_stored.length + " marked!")
if (!parentElement) {
showValidMergeIcons();
}
else {
toggleAssociationIcons(parentElement);
}
}
else {
notify(entity_name + " was not marked!","")
}
}
function toggleAssociationIcons(element) {
var entity_type = element.dataset.entity_type;
var entity_id = element.dataset.entity_id;
entity_id = parseInt(entity_id);
const lcst = window.sessionStorage;
var key = "marked_for_associate_" + entity_type;
var current_stored = (lcst.getItem(key) || '').split(",");
current_stored = current_stored.filter((x)=>x).map((x)=>parseInt(x));
current_stored.push(entity_id);
current_stored = [...new Set(current_stored)];
lcst.setItem(key,current_stored); //this already formats it correctly
var whattoadd = ((entity_type == 'track') ? "Artists or Album" : "Artists")
notify("Marked " + entity_name + " to add " + whattoadd,"Currently " + current_stored.length + " marked!")
showValidMergeIcons();
if (current_stored.indexOf(entity_id) > -1) {
element.classList.add('marked');
} else {
element.classList.remove('marked');
}
}
function merge() {