Tag Folders: Drilldown for select and improved filter

- drilldown visible for bogus folder selections
- drilldown can be changed and refreshed
- enhanced filters (remove empty folders/tags from list by default)
This commit is contained in:
Wolfsblvt
2024-02-19 05:30:42 +01:00
parent 25a0ea0cb6
commit 3e44dddfda
4 changed files with 79 additions and 31 deletions

View File

@ -124,6 +124,7 @@
display: flex; display: flex;
column-gap: 10px; column-gap: 10px;
flex-direction: row; flex-direction: row;
flex-wrap: wrap;
align-items: flex-start; align-items: flex-start;
margin: 5px; margin: 5px;
} }
@ -232,3 +233,24 @@
1px -1px 0px black; 1px -1px 0px black;
opacity: 1; opacity: 1;
} }
.rm_tag_bogus_drilldown .tag:not(:first-child) {
position: relative;
margin-left: calc(var(--mainFontSize) * 2);
}
.rm_tag_bogus_drilldown .tag:not(:first-child):before {
position: absolute;
left: calc(var(--mainFontSize) * -2);
top: -1px;
content: "\21E8";
font-size: calc(var(--mainFontSize) * 2);
color: var(--SmartThemeBodyColor);
line-height: calc(var(--mainFontSize) * 1.3);
text-align: center;
text-shadow: 1px 1px 0px black,
-1px -1px 0px black,
-1px 1px 0px black,
1px -1px 0px black;
opacity: 1;
}

View File

@ -4210,6 +4210,7 @@
</form> </form>
<div class="rm_tag_controls"> <div class="rm_tag_controls">
<div class="tags rm_tag_filter"></div> <div class="tags rm_tag_filter"></div>
<div class="tags rm_tag_bogus_drilldown"></div>
</div> </div>
<hr> <hr>
</div> </div>

View File

@ -272,6 +272,7 @@ export {
printCharacters, printCharacters,
isOdd, isOdd,
countOccurrences, countOccurrences,
chooseBogusFolder,
}; };
showLoader(); showLoader();
@ -1334,21 +1335,20 @@ export function getEntitiesList({ doFilter } = {}) {
entities = entitiesFilter.applyFilters(entities); entities = entitiesFilter.applyFilters(entities);
} }
if (isBogusFolderOpen()) {
// Get tags of entities within the bogus folder
const filterData = structuredClone(entitiesFilter.getFilterData(FILTER_TYPES.TAG)); const filterData = structuredClone(entitiesFilter.getFilterData(FILTER_TYPES.TAG));
entities = entities.filter(x => x.type !== 'tag');
const otherTags = tags.filter(x => x.is_folder && !filterData.selected.includes(x.id)).sort(compareTagsForSort); entities = entities.filter(entity => {
const bogusTags = []; if (entity.type === 'tag') {
for (const entity of entities) { // Remove filtered tags/bogus folders
for (const tag of otherTags) { if (filterData.selected.includes(entity.id) || filterData.excluded.includes(entity.id)) {
if (!bogusTags.includes(tag) && entitiesFilter.isElementTagged(entity, tag.id)) { return false;
bogusTags.push(tag);
} }
// Check if tag is used in any other entities, removing 0 count folders
return entities.some(e => e.type !== 'tag' && entitiesFilter.isElementTagged(e, entity.id));
} }
} return true;
entities.push(...bogusTags.map(item => tagToEntity(item))); });
}
sortEntitiesList(entities); sortEntitiesList(entities);
return entities; return entities;
@ -8054,6 +8054,40 @@ function doTogglePanels() {
$('#option_settings').trigger('click'); $('#option_settings').trigger('click');
} }
function chooseBogusFolder(tagId, remove = false) {
// Update bogus filter
const filterData = structuredClone(entitiesFilter.getFilterData(FILTER_TYPES.TAG));
if (!Array.isArray(filterData.selected)) {
filterData.selected = [];
filterData.excluded = [];
filterData.bogus = false;
}
if (tagId === 'back') {
filterData.selected.pop();
filterData.bogus = filterData.selected.length > 0;
} else if (remove) {
const index = filterData.selected.indexOf(tagId);
if (index > -1) filterData.selected.splice(index, 1);
} else {
filterData.selected.push(tagId);
filterData.bogus = true;
}
entitiesFilter.setFilterData(FILTER_TYPES.TAG, filterData);
// Update bogus drilldown
if (tagId === 'back') {
$('.rm_tag_controls .rm_tag_bogus_drilldown .tag').last().remove();
} else if (remove) {
$(`.rm_tag_controls .rm_tag_bogus_drilldown .tag[id=${tagId}]`).remove();
} else {
const tag = tags.find(x => x.id === tagId);
appendTagToList('.rm_tag_controls .rm_tag_bogus_drilldown', tag, { removable: true, selectable: false, isGeneralList: false });
}
}
function addDebugFunctions() { function addDebugFunctions() {
const doBackfill = async () => { const doBackfill = async () => {
for (const message of chat) { for (const message of chat) {
@ -8229,24 +8263,7 @@ jQuery(async function () {
$(document).on('click', '.bogus_folder_select', function () { $(document).on('click', '.bogus_folder_select', function () {
const tagId = $(this).attr('tagid'); const tagId = $(this).attr('tagid');
console.log('Bogus folder clicked', tagId); console.log('Bogus folder clicked', tagId);
chooseBogusFolder(tagId);
const filterData = structuredClone(entitiesFilter.getFilterData(FILTER_TYPES.TAG));
if (!Array.isArray(filterData.selected)) {
filterData.selected = [];
filterData.excluded = [];
filterData.bogus = false;
}
if (tagId === 'back') {
filterData.selected.pop();
filterData.bogus = filterData.selected.length > 0;
} else {
filterData.selected.push(tagId);
filterData.bogus = true;
}
entitiesFilter.setFilterData(FILTER_TYPES.TAG, filterData);
}); });
$(document).on('input', '.edit_textarea', function () { $(document).on('input', '.edit_textarea', function () {

View File

@ -7,6 +7,7 @@ import {
getCharacters, getCharacters,
entitiesFilter, entitiesFilter,
printCharacters, printCharacters,
chooseBogusFolder,
} from '../script.js'; } from '../script.js';
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
import { FILTER_TYPES, FilterHelper } from './filters.js'; import { FILTER_TYPES, FilterHelper } from './filters.js';
@ -430,6 +431,13 @@ function onTagRemoveClick(event) {
const tag = $(this).closest('.tag'); const tag = $(this).closest('.tag');
const tagId = tag.attr('id'); const tagId = tag.attr('id');
// Check if we are inside the drilldown. If so, we call remove on the bogus folder
if ($(this).closest('.rm_tag_bogus_drilldown').length > 0) {
console.debug('Bogus drilldown remove', tagId);
chooseBogusFolder(tagId, true);
return;
}
// Optional, check for multiple character ids being present. // Optional, check for multiple character ids being present.
const characterData = event.target.closest('#bulk_tags_div')?.dataset.characters; const characterData = event.target.closest('#bulk_tags_div')?.dataset.characters;
const characterIds = characterData ? JSON.parse(characterData).characterIds : null; const characterIds = characterData ? JSON.parse(characterData).characterIds : null;