mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
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:
@ -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;
|
||||||
|
}
|
||||||
|
@ -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>
|
||||||
|
@ -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()) {
|
const filterData = structuredClone(entitiesFilter.getFilterData(FILTER_TYPES.TAG));
|
||||||
// Get tags of entities within the bogus folder
|
|
||||||
const filterData = structuredClone(entitiesFilter.getFilterData(FILTER_TYPES.TAG));
|
entities = entities.filter(entity => {
|
||||||
entities = entities.filter(x => x.type !== 'tag');
|
if (entity.type === 'tag') {
|
||||||
const otherTags = tags.filter(x => x.is_folder && !filterData.selected.includes(x.id)).sort(compareTagsForSort);
|
// Remove filtered tags/bogus folders
|
||||||
const bogusTags = [];
|
if (filterData.selected.includes(entity.id) || filterData.excluded.includes(entity.id)) {
|
||||||
for (const entity of entities) {
|
return false;
|
||||||
for (const tag of otherTags) {
|
|
||||||
if (!bogusTags.includes(tag) && entitiesFilter.isElementTagged(entity, tag.id)) {
|
|
||||||
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));
|
||||||
}
|
}
|
||||||
entities.push(...bogusTags.map(item => tagToEntity(item)));
|
return true;
|
||||||
}
|
});
|
||||||
|
|
||||||
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 () {
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user