diff --git a/ui/v2.5/src/components/Tags/TagCard.tsx b/ui/v2.5/src/components/Tags/TagCard.tsx index e03efb309..2b03624f5 100644 --- a/ui/v2.5/src/components/Tags/TagCard.tsx +++ b/ui/v2.5/src/components/Tags/TagCard.tsx @@ -3,6 +3,7 @@ import React from "react"; import { Link } from "react-router-dom"; import * as GQL from "src/core/generated-graphql"; import { NavUtils } from "src/utils"; +import { FormattedMessage } from "react-intl"; import { Icon } from "../Shared"; import { GridCard } from "../Shared/GridCard"; import { PopoverCountButton } from "../Shared/PopoverCountButton"; @@ -22,6 +23,53 @@ export const TagCard: React.FC = ({ selected, onSelectedChanged, }) => { + function maybeRenderParents() { + if (tag.parents.length === 1) { + const parent = tag.parents[0]; + return ( +
+ +   + {parent.name} +
+ ); + } + + if (tag.parents.length > 1) { + return ( +
+ +   + + {tag.parents.length}  + + +
+ ); + } + } + + function maybeRenderChildren() { + if (tag.children.length > 1) { + return ( +
+ +   + + {tag.children.length}  + + +
+ ); + } + } + function maybeRenderScenesPopoverButton() { if (!tag.scene_count) return; @@ -114,7 +162,13 @@ export const TagCard: React.FC = ({ src={tag.image_path ?? ""} /> } - popovers={maybeRenderPopoverButtonGroup()} + details={ + <> + {maybeRenderParents()} + {maybeRenderChildren()} + {maybeRenderPopoverButtonGroup()} + + } selected={selected} selecting={selecting} onSelectedChanged={onSelectedChanged} diff --git a/ui/v2.5/src/locales/en-GB.json b/ui/v2.5/src/locales/en-GB.json index 98480e1f8..9919b1630 100644 --- a/ui/v2.5/src/locales/en-GB.json +++ b/ui/v2.5/src/locales/en-GB.json @@ -614,6 +614,7 @@ "next": "Next", "previous": "Previous" }, + "parent_of": "Parent of", "parent_studios": "Parent Studios", "parent_tags": "Parent Tags", "parent_tag_count": "Parent Tag Count", @@ -643,6 +644,7 @@ }, "seconds": "Seconds", "settings": "Settings", + "sub_tag_of": "Sub-tag of", "stash_id": "Stash ID", "status": "Status: {statusText}", "studio": "Studio", diff --git a/ui/v2.5/src/utils/navigation.ts b/ui/v2.5/src/utils/navigation.ts index 9584f6af8..7c11a6cb1 100644 --- a/ui/v2.5/src/utils/navigation.ts +++ b/ui/v2.5/src/utils/navigation.ts @@ -6,6 +6,8 @@ import { ParentStudiosCriterion, } from "src/models/list-filter/criteria/studios"; import { + ChildTagsCriterionOption, + ParentTagsCriterionOption, TagsCriterion, TagsCriterionOption, } from "src/models/list-filter/criteria/tags"; @@ -167,6 +169,40 @@ const makeMovieScenesUrl = (movie: Partial) => { return `/scenes?${filter.makeQueryParameters()}`; }; +const makeParentTagsUrl = (tag: Partial) => { + if (!tag.id) return "#"; + const filter = new ListFilterModel(GQL.FilterMode.Tags); + const criterion = new TagsCriterion(ChildTagsCriterionOption); + criterion.value = { + items: [ + { + id: tag.id, + label: tag.name || `Tag ${tag.id}`, + }, + ], + depth: 0, + }; + filter.criteria.push(criterion); + return `/tags?${filter.makeQueryParameters()}`; +}; + +const makeChildTagsUrl = (tag: Partial) => { + if (!tag.id) return "#"; + const filter = new ListFilterModel(GQL.FilterMode.Tags); + const criterion = new TagsCriterion(ParentTagsCriterionOption); + criterion.value = { + items: [ + { + id: tag.id, + label: tag.name || `Tag ${tag.id}`, + }, + ], + depth: 0, + }; + filter.criteria.push(criterion); + return `/tags?${filter.makeQueryParameters()}`; +}; + const makeTagScenesUrl = (tag: Partial) => { if (!tag.id) return "#"; const filter = new ListFilterModel(GQL.FilterMode.Scenes); @@ -259,6 +295,8 @@ export default { makeStudioImagesUrl, makeStudioGalleriesUrl, makeStudioMoviesUrl, + makeParentTagsUrl, + makeChildTagsUrl, makeTagSceneMarkersUrl, makeTagScenesUrl, makeTagPerformersUrl,