Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Icons to tags if they have parent/child tags #3931

2 changes: 0 additions & 2 deletions graphql/documents/data/scene-marker.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ fragment SceneMarkerData on SceneMarker {
primary_tag {
id
name
aliases
}

tags {
id
name
aliases
}
}
2 changes: 2 additions & 0 deletions graphql/documents/data/tag-slim.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ fragment SlimTagData on Tag {
name
aliases
image_path
parent_count
child_count
}
3 changes: 3 additions & 0 deletions graphql/schema/types/tag.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ type Tag {

parents: [Tag!]!
children: [Tag!]!

parent_count: Int! # Resolver
child_count: Int! # Resolver
}

input TagCreateInput {
Expand Down
22 changes: 22 additions & 0 deletions internal/api/resolver_model_tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,25 @@ func (r *tagResolver) ImagePath(ctx context.Context, obj *models.Tag) (*string,
imagePath := urlbuilders.NewTagURLBuilder(baseURL, obj).GetTagImageURL(hasImage)
return &imagePath, nil
}

func (r *tagResolver) ParentCount(ctx context.Context, obj *models.Tag) (ret int, err error) {
if err := r.withReadTxn(ctx, func(ctx context.Context) error {
ret, err = r.repository.Tag.CountByParentTagID(ctx, obj.ID)
return err
}); err != nil {
return ret, err
}

return ret, nil
}

func (r *tagResolver) ChildCount(ctx context.Context, obj *models.Tag) (ret int, err error) {
if err := r.withReadTxn(ctx, func(ctx context.Context) error {
ret, err = r.repository.Tag.CountByChildTagID(ctx, obj.ID)
return err
}); err != nil {
return ret, err
}

return ret, nil
}
42 changes: 42 additions & 0 deletions pkg/models/mocks/TagReaderWriter.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pkg/models/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ type TagReader interface {
FindByParentTagID(ctx context.Context, parentID int) ([]*Tag, error)
FindByChildTagID(ctx context.Context, childID int) ([]*Tag, error)
Count(ctx context.Context) (int, error)
CountByParentTagID(ctx context.Context, parentID int) (int, error)
CountByChildTagID(ctx context.Context, childID int) (int, error)
All(ctx context.Context) ([]*Tag, error)
// TODO - this interface is temporary until the filter schema can fully
// support the query needed
Expand Down
14 changes: 14 additions & 0 deletions pkg/sqlite/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,20 @@ func (qb *TagStore) FindByChildTagID(ctx context.Context, parentID int) ([]*mode
return qb.queryTags(ctx, query, args)
}

func (qb *TagStore) CountByParentTagID(ctx context.Context, parentID int) (int, error) {
q := dialect.Select(goqu.COUNT("*")).From(goqu.T("tags")).
InnerJoin(goqu.T("tags_relations"), goqu.On(goqu.I("tags_relations.parent_id").Eq(goqu.I("tags.id")))).
Where(goqu.I("tags_relations.child_id").Eq(goqu.V(parentID))) // Pass the parentID here
return count(ctx, q)
}

func (qb *TagStore) CountByChildTagID(ctx context.Context, childID int) (int, error) {
q := dialect.Select(goqu.COUNT("*")).From(goqu.T("tags")).
InnerJoin(goqu.T("tags_relations"), goqu.On(goqu.I("tags_relations.child_id").Eq(goqu.I("tags.id")))).
Where(goqu.I("tags_relations.parent_id").Eq(goqu.V(childID))) // Pass the childID here
return count(ctx, q)
}

func (qb *TagStore) Count(ctx context.Context) (int, error) {
q := dialect.Select(goqu.COUNT("*")).From(qb.table())
return count(ctx, q)
Expand Down
19 changes: 10 additions & 9 deletions ui/v2.5/src/components/Scenes/SceneDetails/PrimaryTags.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,19 @@ export const PrimaryTags: React.FC<IPrimaryTags> = ({
}) => {
if (!sceneMarkers?.length) return <div />;

const primaries: Record<string, GQL.SlimTagDataFragment> = {};
const primaryTags: Record<string, GQL.SceneMarkerDataFragment[]> = {};
const primaryTagNames: Record<string, string> = {};
const markersByTag: Record<string, GQL.SceneMarkerDataFragment[]> = {};
sceneMarkers.forEach((m) => {
if (primaryTags[m.primary_tag.id]) primaryTags[m.primary_tag.id].push(m);
else {
primaryTags[m.primary_tag.id] = [m];
primaries[m.primary_tag.id] = m.primary_tag;
if (primaryTagNames[m.primary_tag.id]) {
markersByTag[m.primary_tag.id].push(m);
} else {
primaryTagNames[m.primary_tag.id] = m.primary_tag.name;
markersByTag[m.primary_tag.id] = [m];
}
});

const primaryCards = Object.keys(primaryTags).map((id) => {
const markers = primaryTags[id].map((marker) => {
const primaryCards = Object.keys(markersByTag).map((id) => {
const markers = markersByTag[id].map((marker) => {
const tags = marker.tags.map((tag) => (
<Badge key={tag.id} variant="secondary" className="tag-item">
{tag.name}
Expand Down Expand Up @@ -59,7 +60,7 @@ export const PrimaryTags: React.FC<IPrimaryTags> = ({

return (
<Card className="primary-card col-12 col-sm-6 col-xl-6" key={id}>
<h3>{primaries[id].name}</h3>
<h3>{primaryTagNames[id]}</h3>
<Card.Body className="primary-card-body">{markers}</Card.Body>
</Card>
);
Expand Down
48 changes: 44 additions & 4 deletions ui/v2.5/src/components/Tags/TagDetails/TagDetailsPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from "react";
import { Badge } from "react-bootstrap";
import { Badge, OverlayTrigger, Tooltip } from "react-bootstrap";
import { FormattedMessage } from "react-intl";
import { Link } from "react-router-dom";
import { Icon } from "../../Shared/Icon";
import * as GQL from "src/core/generated-graphql";
import { faFolderTree } from "@fortawesome/free-solid-svg-icons";

interface ITagDetails {
tag: GQL.TagDataFragment;
Expand Down Expand Up @@ -41,9 +43,28 @@ export const TagDetailsPanel: React.FC<ITagDetails> = ({ tag }) => {
<FormattedMessage id="parent_tags" />
</dt>
<dd className="col-9 col-xl-10">
{tag.parents.map((p) => (
{tag.children.map((p) => (
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this changed? Shouldn't this be parents?

<Badge key={p.id} className="tag-item" variant="secondary">
<Link to={`/tags/${p.id}`}>{p.name}</Link>
<Link to={`/tags/${p.id}`}>
{p.name}
{p.child_count !== 0 && (
<>
<span className="icon-wrapper">
<span className="vertical-line">|</span>
<OverlayTrigger
placement="top"
overlay={
<Tooltip id="tag-hierarchy-tooltip">
Explore tag hierarchy
</Tooltip>
}
>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why this overlay is here. Clicking on the icon doesn't do anything different than clicking elsewhere on the badge. The text needs to be internationalised as well.

<Icon icon={faFolderTree} className="tag-icon" />
</OverlayTrigger>
</span>
</>
)}
</Link>
</Badge>
))}
</dd>
Expand All @@ -64,7 +85,26 @@ export const TagDetailsPanel: React.FC<ITagDetails> = ({ tag }) => {
<dd className="col-9 col-xl-10">
{tag.children.map((c) => (
<Badge key={c.id} className="tag-item" variant="secondary">
<Link to={`/tags/${c.id}`}>{c.name}</Link>
<Link to={`/tags/${c.id}`}>
{c.name}
{c.child_count !== 0 && (
<>
<span className="icon-wrapper">
<span className="vertical-line">|</span>
<OverlayTrigger
placement="top"
overlay={
<Tooltip id="tag-hierarchy-tooltip">
Explore tag hierarchy
</Tooltip>
}
>
<Icon icon={faFolderTree} className="tag-icon" />
</OverlayTrigger>
</span>
</>
)}
</Link>
</Badge>
))}
</dd>
Expand Down
18 changes: 18 additions & 0 deletions ui/v2.5/src/components/Tags/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,21 @@
padding: 0;
}
}

.tag-item {
.icon-wrapper {
color: #202b33;
opacity: 0.5;
padding-left: 6px;
}
}

.tag-item {
.tag-icon {
color: #202b33;
margin: 0;
opacity: 0.5;
padding-left: 3px;
transform: scale(0.7);
}
}