Tag Folders: Clear all filters button

- Add "clear all filters" button for tag and search filters
- Resize back button to take less space
- Fix char grid display
This commit is contained in:
Wolfsblvt 2024-03-07 04:26:33 +01:00
parent fb97f563b7
commit 9f42cafc39
5 changed files with 83 additions and 22 deletions

View File

@ -68,6 +68,11 @@
align-items: center;
}
.tag.actionable.clearAllFilters {
border: 0;
background: none;
}
.tagListHint {
align-self: center;
display: flex;
@ -217,6 +222,10 @@
opacity: 1;
}
.rm_tag_bogus_drilldown {
height: calc(var(--mainFontSize)* 2 - 2);
}
.rm_tag_bogus_drilldown .tag:not(:first-child) {
position: relative;
margin-left: calc(var(--mainFontSize) * 2);
@ -238,3 +247,12 @@
opacity: 1;
}
.bogus_folder_select_back .avatar {
display: none;
}
.bogus_folder_select_back .bogus_folder_back_placeholder {
min-height: calc(var(--mainFontSize)*2);
width: var(--avatar-base-width);
justify-content: center;
}

View File

@ -96,14 +96,18 @@ body.charListGrid #rm_print_characters_block .group_select .group_name_block {
body.charListGrid #rm_print_characters_block .ch_description,
body.charListGrid #rm_print_characters_block .tags_inline,
body.charListGrid #rm_print_characters_block .character_version,
body.charListGrid #rm_print_characters_block .bogus_folder_unit,
body.charListGrid #rm_print_characters_block .group_select_unit,
body.charListGrid #rm_print_characters_block .group_select_block_list,
body.charListGrid #rm_print_characters_block .ch_avatar_url,
#user_avatar_block.gridView .avatar-container .ch_description {
body.charListGrid #rm_print_characters_block .character_name_block_sub_line,
#user_avatar_block.gridView .avatar-container .ch_description,
body.charListGrid #rm_print_characters_block .bogus_folder_select_back .bogus_folder_back_placeholder {
display: none;
}
body.charListGrid #rm_print_characters_block .bogus_folder_select_back .avatar {
display: flex;
}
/*big avatars mode page-wide changes*/
body.big-avatars .character_select .avatar,

View File

@ -5026,10 +5026,13 @@
</div>
</div>
<div id="bogus_folder_back_template" class="template_element">
<div class="bogus_folder_select flex-container wide100p alignitemsflexstart" id="BogusFolderBack" tagid="back">
<div class="bogus_folder_select bogus_folder_select_back flex-container wide100p alignitemsflexstart" id="BogusFolderBack" tagid="back">
<div class="avatar flex alignitemscenter textAlignCenter">
<i class="bogus_folder_icon fa-solid fa-xl fa-right-from-bracket fa-flip-horizontal"></i>
</div>
<div class="bogus_folder_back_placeholder flex alignitemscenter textAlignCenter">
<i class="bogus_folder_icon fa-solid fa-xl fa-right-from-bracket fa-flip-horizontal"></i>
</div>
<div class="flex-container wide100pLess70px character_select_container height100p alignitemscenter">
<div class="wide100p character_name_block">
<span class="ch_name">Go back</span>

View File

@ -22,7 +22,7 @@ export const FILTER_TYPES = {
export const FILTER_STATES = {
SELECTED: { key: 'SELECTED', class: 'selected' },
EXCLUDED: { key: 'EXCLUDED', class: 'excluded' },
UNDEFINED: { key: 'UNDEFINED', class: undefined },
UNDEFINED: { key: 'UNDEFINED', class: 'undefined' },
};
/**

View File

@ -55,6 +55,7 @@ const ACTIONABLE_TAGS = {
FOLDER: { id: 4, name: 'Always show folders', color: 'rgba(120, 120, 120, 0.5)', action: filterByFolder, icon: 'fa-solid fa-folder-plus', class: 'filterByFolder' },
VIEW: { id: 2, name: 'Manage tags', color: 'rgba(150, 100, 100, 0.5)', action: onViewTagsListClick, icon: 'fa-solid fa-gear', class: 'manageTags' },
HINT: { id: 3, name: 'Show Tag List', color: 'rgba(150, 100, 100, 0.5)', action: onTagListHintClick, icon: 'fa-solid fa-tags', class: 'showTagList' },
UNFILTER: { id: 5, name: 'Clear all filters', action: onClearAllFiltersClick, icon: 'fa-solid fa-filter-circle-xmark', class: 'clearAllFilters' },
};
const InListActionable = {
@ -490,7 +491,7 @@ function appendTagToList(listElement, tag, { removable, selectable, action, isGe
}
if (tag.excluded && isGeneralList) {
toggleTagThreeState(tagElement, FILTER_STATES.EXCLUDED);
toggleTagThreeState(tagElement, { stateOverride: FILTER_STATES.EXCLUDED });
}
if (selectable) {
@ -536,28 +537,44 @@ function onTagFilterClick(listElement) {
updateTagFilterIndicator();
}
function toggleTagThreeState(element, stateOverride = undefined) {
function toggleTagThreeState(element, { stateOverride = undefined, simulateClick = false } = {}) {
const states = Object.keys(FILTER_STATES);
const overrideKey = states.includes(stateOverride) ? stateOverride : states.find(key => FILTER_STATES[key] === stateOverride);
const overrideKey = states.includes(stateOverride) ? stateOverride : Object.keys(FILTER_STATES).find(key => FILTER_STATES[key] === stateOverride);
const currentState = element.attr('data-toggle-state') ?? states[states.length - 1];
const nextState = overrideKey ?? states[(states.indexOf(currentState) + 1) % states.length];
const currentStateIndex = states.indexOf(element.attr('data-toggle-state')) ?? states.length - 1;
const targetStateIndex = overrideKey !== undefined ? states.indexOf(overrideKey) : (currentStateIndex + 1) % states.length;
element.attr('data-toggle-state', nextState);
console.debug('toggle three-way filter on', element, 'from', currentState, 'to', nextState);
// Update css class and remove all others
Object.keys(FILTER_STATES).forEach(x => {
if (!isFilterState(x, FILTER_STATES.UNDEFINED)) {
element.toggleClass(FILTER_STATES[x].class, x === nextState);
if (simulateClick) {
// Calculate how many clicks are needed to go from the current state to the target state
let clickCount = 0;
if (targetStateIndex >= currentStateIndex) {
clickCount = targetStateIndex - currentStateIndex;
} else {
clickCount = (states.length - currentStateIndex) + targetStateIndex;
}
});
return nextState;
for (let i = 0; i < clickCount; i++) {
$(element).trigger('click');
}
console.debug('manually click-toggle three-way filter from', states[currentStateIndex], 'to', states[targetStateIndex], 'on', element);
} else {
element.attr('data-toggle-state', states[targetStateIndex]);
// Update css class and remove all others
states.forEach(state => {
element.toggleClass(FILTER_STATES[state].class, state === states[targetStateIndex]);
});
console.debug('toggle three-way filter from', states[currentStateIndex], 'to', states[targetStateIndex], 'on', element);
}
return states[targetStateIndex];
}
function runTagFilters(listElement) {
const tagIds = [...($(listElement).find('.tag.selected:not(.actionable)').map((_, el) => $(el).attr('id')))];
const excludedTagIds = [...($(listElement).find('.tag.excluded:not(.actionable)').map((_, el) => $(el).attr('id')))];
@ -576,11 +593,13 @@ function printTagFilters(type = tag_filter_types.character) {
.sort(compareTagsForSort);
for (const tag of Object.values(ACTIONABLE_TAGS)) {
if (!power_user.bogus_folders && tag.id == ACTIONABLE_TAGS.FOLDER.id) {
continue;
}
appendTagToList(FILTER_SELECTOR, tag, { removable: false, selectable: false, action: tag.action, isGeneralList: true });
}
$(FILTER_SELECTOR).find('.actionable').last().addClass('margin-right-10px');
for (const tag of Object.values(InListActionable)) {
appendTagToList(FILTER_SELECTOR, tag, { removable: false, selectable: false, action: tag.action, isGeneralList: true });
}
@ -1064,6 +1083,23 @@ function onTagListHintClick() {
console.debug('show_tag_filters', power_user.show_tag_filters);
}
function onClearAllFiltersClick() {
console.debug('clear all filters clicked');
// We have to manually go through the elements and unfilter by clicking...
// Thankfully nearly all filter controls are three-state-toggles
const filterTags = $('.rm_tag_controls .rm_tag_filter').find('.tag');
for(const tag of filterTags) {
const toggleState = $(tag).attr('data-toggle-state');
if (toggleState !== undefined && !isFilterState(toggleState ?? FILTER_STATES.UNDEFINED, FILTER_STATES.UNDEFINED)) {
toggleTagThreeState($(tag), { stateOverride: FILTER_STATES.UNDEFINED, simulateClick: true });
}
}
// Reset search too
$('#character_search_bar').val('').trigger('input');
}
jQuery(() => {
createTagInput('#tagInput', '#tagList');
createTagInput('#groupTagInput', '#groupTagList');