Added toggle to select actor tags or all tags in filters.
This commit is contained in:
27
assets/img/icons/user-tags.svg
Normal file
27
assets/img/icons/user-tags.svg
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Generated by IcoMoon.io -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
version="1.1"
|
||||||
|
width="16"
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
id="svg2"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<path
|
||||||
|
id="path2"
|
||||||
|
d="M 7 0 C 4 0 4 2.015 4 4.5 C 4 6.048 4.898 7.5957969 6 8.2167969 L 6 9.0410156 C 2.608 9.3180156 0 10.985 0 13 L 4.9726562 13 C 4.6689986 12.449922 4.7486357 11.731833 5.2109375 11.269531 L 8 8.4804688 L 8 8.2167969 C 9.102 7.5957969 10 6.048 10 4.5 C 10 2.015 10 0 7 0 z M 9 11.509766 L 8.2167969 12.292969 L 8.9238281 13 L 9 13 L 9 11.509766 z " />
|
||||||
|
<g
|
||||||
|
id="g2"
|
||||||
|
transform="matrix(0.51568847,0,0,0.51568847,5.8471254,8.4255678)">
|
||||||
|
<path
|
||||||
|
d="m 18.938,-1 h -6 c -0.412,0 -0.989,0.239 -1.28,0.53 L 4.219,6.969 c -0.292,0.292 -0.292,0.769 0,1.061 l 6.439,6.439 c 0.292,0.292 0.769,0.292 1.061,0 L 19.158,7.03 c 0.292,-0.292 0.53,-0.868 0.53,-1.28 v -6 c 0,-0.412 -0.337,-0.75 -0.75,-0.75 z m -3.75,6 c -0.828,0 -1.5,-0.672 -1.5,-1.5 0,-0.828 0.672,-1.5 1.5,-1.5 0.828,0 1.5,0.672 1.5,1.5 0,0.828 -0.672,1.5 -1.5,1.5 z"
|
||||||
|
id="path1-5" />
|
||||||
|
<path
|
||||||
|
d="m 1.688,7.5 8.5,-8.5 h -1.25 c -0.412,0 -0.989,0.239 -1.28,0.53 L 0.219,6.969 c -0.292,0.292 -0.292,0.769 0,1.061 l 6.439,6.439 c 0.292,0.292 0.769,0.292 1.061,0 l 0.47,-0.47 -6.5,-6.5 z"
|
||||||
|
id="path2-3" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -12,14 +12,30 @@
|
|||||||
<Icon icon="search" />
|
<Icon icon="search" />
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-show="showActorTags"
|
||||||
|
v-tooltip="'Tags relevant to the selected actors'"
|
||||||
|
class="filter-sort order noselect"
|
||||||
|
@click="showActorTags = false"
|
||||||
|
>
|
||||||
|
<Icon icon="user-tags" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-show="!showActorTags"
|
||||||
|
v-tooltip="'All tags'"
|
||||||
|
class="filter-sort order noselect"
|
||||||
|
@click="showActorTags = true"
|
||||||
|
>
|
||||||
|
<Icon icon="price-tags" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-show="order === 'priority'"
|
v-show="order === 'priority'"
|
||||||
class="filter-sort order noselect"
|
class="filter-sort order noselect"
|
||||||
@click="order = 'count'"
|
@click="order = 'count'"
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon icon="star" />
|
||||||
icon="star"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -115,16 +131,21 @@ const props = defineProps({
|
|||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
|
actorTags: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['update']);
|
const emit = defineEmits(['update']);
|
||||||
|
|
||||||
|
const { pageProps } = inject('pageContext');
|
||||||
|
const { tag: pageTag, actor: pageActor } = pageProps;
|
||||||
|
|
||||||
const search = ref('');
|
const search = ref('');
|
||||||
const searchRegexp = computed(() => new RegExp(search.value, 'i'));
|
const searchRegexp = computed(() => new RegExp(search.value, 'i'));
|
||||||
const order = ref('priority');
|
const order = ref('priority');
|
||||||
|
const showActorTags = ref(true);
|
||||||
const { pageProps } = inject('pageContext');
|
|
||||||
const { tag: pageTag } = pageProps;
|
|
||||||
|
|
||||||
const priorityTags = [
|
const priorityTags = [
|
||||||
'anal',
|
'anal',
|
||||||
@@ -148,8 +169,12 @@ const priorityTags = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const groupedTags = computed(() => {
|
const groupedTags = computed(() => {
|
||||||
const selected = props.tags.filter((tag) => props.filters.tags.includes(tag.slug));
|
const tags = showActorTags.value && props.actorTags && (props.filters.actors.length > 0 || pageActor)
|
||||||
const filtered = props.tags.filter((tag) => !props.filters.tags.includes(tag.slug)
|
? props.actorTags
|
||||||
|
: props.tags;
|
||||||
|
|
||||||
|
const selected = tags.filter((tag) => props.filters.tags.includes(tag.slug));
|
||||||
|
const filtered = tags.filter((tag) => !props.filters.tags.includes(tag.slug)
|
||||||
&& tag.id !== pageTag?.id
|
&& tag.id !== pageTag?.id
|
||||||
&& searchRegexp.value.test(tag.name));
|
&& searchRegexp.value.test(tag.name));
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
<TagsFilter
|
<TagsFilter
|
||||||
:filters="filters"
|
:filters="filters"
|
||||||
:tags="aggTags"
|
:tags="aggTags"
|
||||||
|
:actor-tags="aggActorTags"
|
||||||
@update="updateFilter"
|
@update="updateFilter"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -263,6 +264,7 @@ const scenes = ref(pageProps.scenes);
|
|||||||
const aggYears = ref(pageProps.aggYears || []);
|
const aggYears = ref(pageProps.aggYears || []);
|
||||||
const aggActors = ref(pageProps.aggActors || []);
|
const aggActors = ref(pageProps.aggActors || []);
|
||||||
const aggTags = ref(pageProps.aggTags || []);
|
const aggTags = ref(pageProps.aggTags || []);
|
||||||
|
const aggActorTags = ref(pageProps.aggActorTags || []);
|
||||||
const aggChannels = ref(pageProps.aggChannels || []);
|
const aggChannels = ref(pageProps.aggChannels || []);
|
||||||
|
|
||||||
const currentPage = ref(Number(routeParams.page));
|
const currentPage = ref(Number(routeParams.page));
|
||||||
@@ -363,6 +365,7 @@ async function search(options = {}) {
|
|||||||
aggYears.value = res.aggYears;
|
aggYears.value = res.aggYears;
|
||||||
aggActors.value = res.aggActors;
|
aggActors.value = res.aggActors;
|
||||||
aggTags.value = res.aggTags;
|
aggTags.value = res.aggTags;
|
||||||
|
aggActorTags.value = res.aggActorTags;
|
||||||
aggChannels.value = res.aggChannels;
|
aggChannels.value = res.aggChannels;
|
||||||
|
|
||||||
total.value = res.total;
|
total.value = res.total;
|
||||||
|
|||||||
@@ -424,6 +424,7 @@ async function queryManticoreSql(filters, options, _reqUser) {
|
|||||||
:yearsFacet:
|
:yearsFacet:
|
||||||
:actorsFacet:
|
:actorsFacet:
|
||||||
:tagsFacet:
|
:tagsFacet:
|
||||||
|
:actorTagsFacet:
|
||||||
:channelsFacet:
|
:channelsFacet:
|
||||||
:studiosFacet:;
|
:studiosFacet:;
|
||||||
show meta;
|
show meta;
|
||||||
@@ -566,10 +567,9 @@ async function queryManticoreSql(filters, options, _reqUser) {
|
|||||||
yearsFacet: options.aggregateYears ? knex.raw('facet effective_year as years_facet order by effective_year desc limit ?', [aggSize]) : null,
|
yearsFacet: options.aggregateYears ? knex.raw('facet effective_year as years_facet order by effective_year desc limit ?', [aggSize]) : null,
|
||||||
actorsFacet: options.aggregateActors ? knex.raw('facet scenes.actor_ids as actors_facet distinct id order by count(distinct id) desc limit ?', [aggSize]) : null,
|
actorsFacet: options.aggregateActors ? knex.raw('facet scenes.actor_ids as actors_facet distinct id order by count(distinct id) desc limit ?', [aggSize]) : null,
|
||||||
// don't facet tags associated to other actors, actor ID 0 means global
|
// don't facet tags associated to other actors, actor ID 0 means global
|
||||||
tagsFacet: options.aggregateTags // eslint-disable-line no-nested-ternary
|
tagsFacet: options.aggregateTags ? knex.raw('facet scenes.tag_ids as tags_facet order by count(distinct id) desc limit ?', [aggSize]) : null,
|
||||||
? (filters.stashId || !filters?.actorIds || filters.actorIds.length === 0 // we can't join the tags table as well as the stashes table
|
actorTagsFacet: options.aggregateTags && !filters.stashId // eslint-disable-line no-nested-ternary
|
||||||
? knex.raw('facet scenes.tag_ids as tags_facet order by count(distinct id) desc limit ?', [aggSize])
|
? knex.raw(`facet IF(IN(scenes_tags.actor_id, ${[0, ...filters?.actorIds || []]}), scenes_tags.tag_id, 0) actor_tags_facet distinct id order by count(distinct id) desc limit ?`, [aggSize])
|
||||||
: knex.raw(`facet IF(IN(scenes_tags.actor_id, ${[0, ...filters?.actorIds || []]}), scenes_tags.tag_id, 0) tags_facet distinct id order by count(distinct id) desc limit ?`, [aggSize]))
|
|
||||||
: null,
|
: null,
|
||||||
channelsFacet: options.aggregateChannels ? knex.raw('facet scenes.channel_id as channels_facet distinct id order by count(distinct id) desc limit ?', [aggSize]) : null,
|
channelsFacet: options.aggregateChannels ? knex.raw('facet scenes.channel_id as channels_facet distinct id order by count(distinct id) desc limit ?', [aggSize]) : null,
|
||||||
studiosFacet: options.aggregateChannels ? knex.raw('facet scenes.studio_id as studios_facet distinct id order by count(distinct id) desc limit ?', [aggSize]) : null,
|
studiosFacet: options.aggregateChannels ? knex.raw('facet scenes.studio_id as studios_facet distinct id order by count(distinct id) desc limit ?', [aggSize]) : null,
|
||||||
@@ -607,6 +607,11 @@ async function queryManticoreSql(filters, options, _reqUser) {
|
|||||||
?.data.map((row) => ({ key: row.tags_facet, doc_count: row['count(distinct id)'] || row['count(*)'] }))
|
?.data.map((row) => ({ key: row.tags_facet, doc_count: row['count(distinct id)'] || row['count(*)'] }))
|
||||||
|| [];
|
|| [];
|
||||||
|
|
||||||
|
const actorTagIds = results
|
||||||
|
.find((result) => result.columns[0].actor_tags_facet && result.columns[1]['count(distinct id)'])
|
||||||
|
?.data.map((row) => ({ key: row.actor_tags_facet, doc_count: row['count(distinct id)'] || row['count(*)'] }))
|
||||||
|
|| [];
|
||||||
|
|
||||||
const channelIds = results
|
const channelIds = results
|
||||||
.find((result) => result.columns[0].channels_facet && result.columns[1]['count(distinct id)'])
|
.find((result) => result.columns[0].channels_facet && result.columns[1]['count(distinct id)'])
|
||||||
?.data.map((row) => ({ key: row.channels_facet || row['scenes.channel_id'], doc_count: row['count(distinct id)'] }))
|
?.data.map((row) => ({ key: row.channels_facet || row['scenes.channel_id'], doc_count: row['count(distinct id)'] }))
|
||||||
@@ -626,6 +631,7 @@ async function queryManticoreSql(filters, options, _reqUser) {
|
|||||||
years,
|
years,
|
||||||
actorIds,
|
actorIds,
|
||||||
tagIds,
|
tagIds,
|
||||||
|
actorTagIds,
|
||||||
channelIds,
|
channelIds,
|
||||||
studioIds,
|
studioIds,
|
||||||
},
|
},
|
||||||
@@ -663,9 +669,10 @@ export async function fetchScenes(filters, rawOptions, reqUser, context) {
|
|||||||
|
|
||||||
console.time('fetch aggregations');
|
console.time('fetch aggregations');
|
||||||
|
|
||||||
const [aggActors, aggTags, aggChannels] = await Promise.all([
|
const [aggActors, aggTags, aggActorTags, aggChannels] = await Promise.all([
|
||||||
options.aggregateActors ? fetchActorsById(result.aggregations.actorIds.map((bucket) => bucket.key), { shallow: true, order: ['slug', 'asc'], append: actorCounts }, reqUser) : [],
|
options.aggregateActors ? fetchActorsById(result.aggregations.actorIds.map((bucket) => bucket.key), { shallow: true, order: ['slug', 'asc'], append: actorCounts }, reqUser) : [],
|
||||||
options.aggregateTags ? fetchTagsById(result.aggregations.tagIds.map((bucket) => bucket.key), { order: [knex.raw('lower(name)'), 'asc'], append: tagCounts }, reqUser, context) : [],
|
options.aggregateTags ? fetchTagsById(result.aggregations.tagIds.map((bucket) => bucket.key), { order: [knex.raw('lower(name)'), 'asc'], append: tagCounts }, reqUser, context) : [],
|
||||||
|
options.aggregateTags ? fetchTagsById(result.aggregations.actorTagIds.map((bucket) => bucket.key), { order: [knex.raw('lower(name)'), 'asc'], append: tagCounts }, reqUser, context) : [],
|
||||||
options.aggregateChannels ? fetchEntitiesById(entityIds.map((bucket) => bucket.key), { order: ['slug', 'asc'], append: channelCounts }, reqUser, context) : [],
|
options.aggregateChannels ? fetchEntitiesById(entityIds.map((bucket) => bucket.key), { order: ['slug', 'asc'], append: channelCounts }, reqUser, context) : [],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -681,6 +688,7 @@ export async function fetchScenes(filters, rawOptions, reqUser, context) {
|
|||||||
aggYears,
|
aggYears,
|
||||||
aggActors,
|
aggActors,
|
||||||
aggTags,
|
aggTags,
|
||||||
|
aggActorTags,
|
||||||
aggChannels,
|
aggChannels,
|
||||||
total: result.total,
|
total: result.total,
|
||||||
limit: options.limit,
|
limit: options.limit,
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ async function fetchScenesApi(req, res) {
|
|||||||
aggYears,
|
aggYears,
|
||||||
aggActors,
|
aggActors,
|
||||||
aggTags,
|
aggTags,
|
||||||
|
aggActorTags,
|
||||||
aggChannels,
|
aggChannels,
|
||||||
limit,
|
limit,
|
||||||
total,
|
total,
|
||||||
@@ -77,6 +78,7 @@ async function fetchScenesApi(req, res) {
|
|||||||
aggYears,
|
aggYears,
|
||||||
aggActors,
|
aggActors,
|
||||||
aggTags,
|
aggTags,
|
||||||
|
aggActorTags,
|
||||||
aggChannels,
|
aggChannels,
|
||||||
limit,
|
limit,
|
||||||
total,
|
total,
|
||||||
|
|||||||
Reference in New Issue
Block a user