Add parent/sub-tags to tag cards (#1792)

This commit is contained in:
WithoutPants
2021-10-03 11:37:28 +11:00
committed by GitHub
parent 7464454da5
commit 17f5642ebd
3 changed files with 95 additions and 1 deletions

View File

@@ -3,6 +3,7 @@ import React from "react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import * as GQL from "src/core/generated-graphql"; import * as GQL from "src/core/generated-graphql";
import { NavUtils } from "src/utils"; import { NavUtils } from "src/utils";
import { FormattedMessage } from "react-intl";
import { Icon } from "../Shared"; import { Icon } from "../Shared";
import { GridCard } from "../Shared/GridCard"; import { GridCard } from "../Shared/GridCard";
import { PopoverCountButton } from "../Shared/PopoverCountButton"; import { PopoverCountButton } from "../Shared/PopoverCountButton";
@@ -22,6 +23,53 @@ export const TagCard: React.FC<IProps> = ({
selected, selected,
onSelectedChanged, onSelectedChanged,
}) => { }) => {
function maybeRenderParents() {
if (tag.parents.length === 1) {
const parent = tag.parents[0];
return (
<div className="tag-parent-tags">
<FormattedMessage id="sub_tag_of" />
&nbsp;
<Link to={`/tags/${parent.id}`}>{parent.name}</Link>
</div>
);
}
if (tag.parents.length > 1) {
return (
<div className="tag-parent-tags">
<FormattedMessage id="sub_tag_of" />
&nbsp;
<Link to={NavUtils.makeParentTagsUrl(tag)}>
{tag.parents.length}&nbsp;
<FormattedMessage
id="countables.tags"
values={{ count: tag.parents.length }}
/>
</Link>
</div>
);
}
}
function maybeRenderChildren() {
if (tag.children.length > 1) {
return (
<div className="tag-sub-tags">
<FormattedMessage id="parent_of" />
&nbsp;
<Link to={NavUtils.makeChildTagsUrl(tag)}>
{tag.children.length}&nbsp;
<FormattedMessage
id="countables.tags"
values={{ count: tag.children.length }}
/>
</Link>
</div>
);
}
}
function maybeRenderScenesPopoverButton() { function maybeRenderScenesPopoverButton() {
if (!tag.scene_count) return; if (!tag.scene_count) return;
@@ -114,7 +162,13 @@ export const TagCard: React.FC<IProps> = ({
src={tag.image_path ?? ""} src={tag.image_path ?? ""}
/> />
} }
popovers={maybeRenderPopoverButtonGroup()} details={
<>
{maybeRenderParents()}
{maybeRenderChildren()}
{maybeRenderPopoverButtonGroup()}
</>
}
selected={selected} selected={selected}
selecting={selecting} selecting={selecting}
onSelectedChanged={onSelectedChanged} onSelectedChanged={onSelectedChanged}

View File

@@ -614,6 +614,7 @@
"next": "Next", "next": "Next",
"previous": "Previous" "previous": "Previous"
}, },
"parent_of": "Parent of",
"parent_studios": "Parent Studios", "parent_studios": "Parent Studios",
"parent_tags": "Parent Tags", "parent_tags": "Parent Tags",
"parent_tag_count": "Parent Tag Count", "parent_tag_count": "Parent Tag Count",
@@ -643,6 +644,7 @@
}, },
"seconds": "Seconds", "seconds": "Seconds",
"settings": "Settings", "settings": "Settings",
"sub_tag_of": "Sub-tag of",
"stash_id": "Stash ID", "stash_id": "Stash ID",
"status": "Status: {statusText}", "status": "Status: {statusText}",
"studio": "Studio", "studio": "Studio",

View File

@@ -6,6 +6,8 @@ import {
ParentStudiosCriterion, ParentStudiosCriterion,
} from "src/models/list-filter/criteria/studios"; } from "src/models/list-filter/criteria/studios";
import { import {
ChildTagsCriterionOption,
ParentTagsCriterionOption,
TagsCriterion, TagsCriterion,
TagsCriterionOption, TagsCriterionOption,
} from "src/models/list-filter/criteria/tags"; } from "src/models/list-filter/criteria/tags";
@@ -167,6 +169,40 @@ const makeMovieScenesUrl = (movie: Partial<GQL.MovieDataFragment>) => {
return `/scenes?${filter.makeQueryParameters()}`; return `/scenes?${filter.makeQueryParameters()}`;
}; };
const makeParentTagsUrl = (tag: Partial<GQL.TagDataFragment>) => {
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<GQL.TagDataFragment>) => {
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<GQL.TagDataFragment>) => { const makeTagScenesUrl = (tag: Partial<GQL.TagDataFragment>) => {
if (!tag.id) return "#"; if (!tag.id) return "#";
const filter = new ListFilterModel(GQL.FilterMode.Scenes); const filter = new ListFilterModel(GQL.FilterMode.Scenes);
@@ -259,6 +295,8 @@ export default {
makeStudioImagesUrl, makeStudioImagesUrl,
makeStudioGalleriesUrl, makeStudioGalleriesUrl,
makeStudioMoviesUrl, makeStudioMoviesUrl,
makeParentTagsUrl,
makeChildTagsUrl,
makeTagSceneMarkersUrl, makeTagSceneMarkersUrl,
makeTagScenesUrl, makeTagScenesUrl,
makeTagPerformersUrl, makeTagPerformersUrl,