mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 12:24:38 +03:00
Add parent/sub-tags to tag cards (#1792)
This commit is contained in:
@@ -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" />
|
||||||
|
|
||||||
|
<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" />
|
||||||
|
|
||||||
|
<Link to={NavUtils.makeParentTagsUrl(tag)}>
|
||||||
|
{tag.parents.length}
|
||||||
|
<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" />
|
||||||
|
|
||||||
|
<Link to={NavUtils.makeChildTagsUrl(tag)}>
|
||||||
|
{tag.children.length}
|
||||||
|
<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}
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user