mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 21:04:37 +03:00
Show stash-ids with their endpoint (#4216)
This commit is contained in:
@@ -3,10 +3,10 @@ import { useIntl } from "react-intl";
|
|||||||
import { TagLink } from "src/components/Shared/TagLink";
|
import { TagLink } from "src/components/Shared/TagLink";
|
||||||
import * as GQL from "src/core/generated-graphql";
|
import * as GQL from "src/core/generated-graphql";
|
||||||
import TextUtils from "src/utils/text";
|
import TextUtils from "src/utils/text";
|
||||||
import { getStashboxBase } from "src/utils/stashbox";
|
|
||||||
import { cmToImperial, cmToInches, kgToLbs } from "src/utils/units";
|
import { cmToImperial, cmToInches, kgToLbs } from "src/utils/units";
|
||||||
import { DetailItem } from "src/components/Shared/DetailItem";
|
import { DetailItem } from "src/components/Shared/DetailItem";
|
||||||
import { CountryFlag } from "src/components/Shared/CountryFlag";
|
import { CountryFlag } from "src/components/Shared/CountryFlag";
|
||||||
|
import { StashIDPill } from "src/components/Shared/StashID";
|
||||||
|
|
||||||
interface IPerformerDetails {
|
interface IPerformerDetails {
|
||||||
performer: GQL.PerformerDataFragment;
|
performer: GQL.PerformerDataFragment;
|
||||||
@@ -42,25 +42,11 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ul className="pl-0">
|
<ul className="pl-0">
|
||||||
{performer.stash_ids.map((stashID) => {
|
{performer.stash_ids.map((stashID) => (
|
||||||
const base = getStashboxBase(stashID.endpoint);
|
<li key={stashID.stash_id} className="row no-gutters">
|
||||||
const link = base ? (
|
<StashIDPill stashID={stashID} linkType="performers" />
|
||||||
<a
|
</li>
|
||||||
href={`${base}performers/${stashID.stash_id}`}
|
))}
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
{stashID.stash_id}
|
|
||||||
</a>
|
|
||||||
) : (
|
|
||||||
stashID.stash_id
|
|
||||||
);
|
|
||||||
return (
|
|
||||||
<li key={stashID.stash_id} className="row no-gutters">
|
|
||||||
{link}
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ul>
|
</ul>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import {
|
|||||||
import { StringListInput } from "src/components/Shared/StringListInput";
|
import { StringListInput } from "src/components/Shared/StringListInput";
|
||||||
import isEqual from "lodash-es/isEqual";
|
import isEqual from "lodash-es/isEqual";
|
||||||
import { DateInput } from "src/components/Shared/DateInput";
|
import { DateInput } from "src/components/Shared/DateInput";
|
||||||
|
import { StashIDPill } from "src/components/Shared/StashID";
|
||||||
|
|
||||||
const isScraper = (
|
const isScraper = (
|
||||||
scraper: GQL.Scraper | GQL.StashBox
|
scraper: GQL.Scraper | GQL.StashBox
|
||||||
@@ -792,18 +793,6 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||||||
<Col sm={fieldXS} xl={fieldXL}>
|
<Col sm={fieldXS} xl={fieldXL}>
|
||||||
<ul className="pl-0">
|
<ul className="pl-0">
|
||||||
{formik.values.stash_ids.map((stashID) => {
|
{formik.values.stash_ids.map((stashID) => {
|
||||||
const base = stashID.endpoint.match(/https?:\/\/.*?\//)?.[0];
|
|
||||||
const link = base ? (
|
|
||||||
<a
|
|
||||||
href={`${base}performers/${stashID.stash_id}`}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
{stashID.stash_id}
|
|
||||||
</a>
|
|
||||||
) : (
|
|
||||||
stashID.stash_id
|
|
||||||
);
|
|
||||||
return (
|
return (
|
||||||
<li key={stashID.stash_id} className="row no-gutters mb-1">
|
<li key={stashID.stash_id} className="row no-gutters mb-1">
|
||||||
<Button
|
<Button
|
||||||
@@ -814,7 +803,7 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||||||
>
|
>
|
||||||
<Icon icon={faTrashAlt} />
|
<Icon icon={faTrashAlt} />
|
||||||
</Button>
|
</Button>
|
||||||
{link}
|
<StashIDPill stashID={stashID} linkType="performers" />
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ import {
|
|||||||
Performer,
|
Performer,
|
||||||
PerformerSelect,
|
PerformerSelect,
|
||||||
} from "src/components/Performers/PerformerSelect";
|
} from "src/components/Performers/PerformerSelect";
|
||||||
|
import { StashIDPill } from "src/components/Shared/StashID";
|
||||||
|
|
||||||
const SceneScrapeDialog = lazyComponent(() => import("./SceneScrapeDialog"));
|
const SceneScrapeDialog = lazyComponent(() => import("./SceneScrapeDialog"));
|
||||||
const SceneQueryModal = lazyComponent(() => import("./SceneQueryModal"));
|
const SceneQueryModal = lazyComponent(() => import("./SceneQueryModal"));
|
||||||
@@ -904,19 +905,6 @@ export const SceneEditPanel: React.FC<IProps> = ({
|
|||||||
</Form.Label>
|
</Form.Label>
|
||||||
<ul className="pl-0">
|
<ul className="pl-0">
|
||||||
{formik.values.stash_ids.map((stashID) => {
|
{formik.values.stash_ids.map((stashID) => {
|
||||||
const base =
|
|
||||||
stashID.endpoint.match(/https?:\/\/.*?\//)?.[0];
|
|
||||||
const link = base ? (
|
|
||||||
<a
|
|
||||||
href={`${base}scenes/${stashID.stash_id}`}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
{stashID.stash_id}
|
|
||||||
</a>
|
|
||||||
) : (
|
|
||||||
stashID.stash_id
|
|
||||||
);
|
|
||||||
return (
|
return (
|
||||||
<li key={stashID.stash_id} className="row no-gutters">
|
<li key={stashID.stash_id} className="row no-gutters">
|
||||||
<Button
|
<Button
|
||||||
@@ -934,7 +922,7 @@ export const SceneEditPanel: React.FC<IProps> = ({
|
|||||||
>
|
>
|
||||||
<Icon icon={faTrashAlt} />
|
<Icon icon={faTrashAlt} />
|
||||||
</Button>
|
</Button>
|
||||||
{link}
|
<StashIDPill stashID={stashID} linkType="scenes" />
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ import { mutateSceneSetPrimaryFile } from "src/core/StashService";
|
|||||||
import { useToast } from "src/hooks/Toast";
|
import { useToast } from "src/hooks/Toast";
|
||||||
import NavUtils from "src/utils/navigation";
|
import NavUtils from "src/utils/navigation";
|
||||||
import TextUtils from "src/utils/text";
|
import TextUtils from "src/utils/text";
|
||||||
import { getStashboxBase } from "src/utils/stashbox";
|
|
||||||
import { TextField, URLField, URLsField } from "src/utils/field";
|
import { TextField, URLField, URLsField } from "src/utils/field";
|
||||||
|
import { StashIDPill } from "src/components/Shared/StashID";
|
||||||
|
|
||||||
interface IFileInfoPanelProps {
|
interface IFileInfoPanelProps {
|
||||||
sceneID: string;
|
sceneID: string;
|
||||||
@@ -197,21 +197,9 @@ export const SceneFileInfoPanel: React.FC<ISceneFileInfoPanelProps> = (
|
|||||||
<dd>
|
<dd>
|
||||||
<dl>
|
<dl>
|
||||||
{props.scene.stash_ids.map((stashID) => {
|
{props.scene.stash_ids.map((stashID) => {
|
||||||
const base = getStashboxBase(stashID.endpoint);
|
|
||||||
const link = base ? (
|
|
||||||
<a
|
|
||||||
href={`${base}scenes/${stashID.stash_id}`}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
{stashID.stash_id}
|
|
||||||
</a>
|
|
||||||
) : (
|
|
||||||
stashID.stash_id
|
|
||||||
);
|
|
||||||
return (
|
return (
|
||||||
<dd key={stashID.stash_id} className="row no-gutters">
|
<dd key={stashID.stash_id} className="row no-gutters">
|
||||||
{link}
|
<StashIDPill stashID={stashID} linkType="scenes" />
|
||||||
</dd>
|
</dd>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
34
ui/v2.5/src/components/Shared/StashID.tsx
Normal file
34
ui/v2.5/src/components/Shared/StashID.tsx
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import React, { useMemo } from "react";
|
||||||
|
import { StashId } from "src/core/generated-graphql";
|
||||||
|
import { ConfigurationContext } from "src/hooks/Config";
|
||||||
|
import { getStashboxBase } from "src/utils/stashbox";
|
||||||
|
|
||||||
|
type LinkType = "performers" | "scenes" | "studios";
|
||||||
|
|
||||||
|
export const StashIDPill: React.FC<{
|
||||||
|
stashID: StashId;
|
||||||
|
linkType: LinkType;
|
||||||
|
}> = ({ stashID, linkType }) => {
|
||||||
|
const { configuration } = React.useContext(ConfigurationContext);
|
||||||
|
|
||||||
|
const { endpoint, stash_id } = stashID;
|
||||||
|
|
||||||
|
const endpointName = useMemo(() => {
|
||||||
|
return (
|
||||||
|
configuration?.general.stashBoxes.find((sb) => sb.endpoint === endpoint)
|
||||||
|
?.name ?? endpoint
|
||||||
|
);
|
||||||
|
}, [configuration?.general.stashBoxes, endpoint]);
|
||||||
|
|
||||||
|
const base = getStashboxBase(endpoint);
|
||||||
|
const link = `${base}${linkType}/${stash_id}`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span className="stash-id-pill" data-endpoint={endpointName}>
|
||||||
|
<span>{endpointName}</span>
|
||||||
|
<a href={link} target="_blank" rel="noopener noreferrer">
|
||||||
|
{stash_id}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -480,3 +480,32 @@ div.react-datepicker {
|
|||||||
.string-list-row .input-group {
|
.string-list-row .input-group {
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stash-id-pill {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 90%;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1;
|
||||||
|
padding-bottom: 0.25em;
|
||||||
|
padding-top: 0.25em;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: baseline;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
span,
|
||||||
|
a {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0.25em 0.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
background-color: $primary;
|
||||||
|
border-radius: 0.25rem 0 0 0.25rem;
|
||||||
|
min-width: 5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
background-color: $secondary;
|
||||||
|
border-radius: 0 0.25rem 0.25rem 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import * as GQL from "src/core/generated-graphql";
|
import * as GQL from "src/core/generated-graphql";
|
||||||
import { DetailItem } from "src/components/Shared/DetailItem";
|
import { DetailItem } from "src/components/Shared/DetailItem";
|
||||||
|
import { StashIDPill } from "src/components/Shared/StashID";
|
||||||
|
|
||||||
interface IStudioDetailsPanel {
|
interface IStudioDetailsPanel {
|
||||||
studio: GQL.StudioDataFragment;
|
studio: GQL.StudioDataFragment;
|
||||||
@@ -21,21 +22,9 @@ export const StudioDetailsPanel: React.FC<IStudioDetailsPanel> = ({
|
|||||||
return (
|
return (
|
||||||
<ul className="pl-0">
|
<ul className="pl-0">
|
||||||
{studio.stash_ids.map((stashID) => {
|
{studio.stash_ids.map((stashID) => {
|
||||||
const base = stashID.endpoint.match(/https?:\/\/.*?\//)?.[0];
|
|
||||||
const link = base ? (
|
|
||||||
<a
|
|
||||||
href={`${base}studios/${stashID.stash_id}`}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
{stashID.stash_id}
|
|
||||||
</a>
|
|
||||||
) : (
|
|
||||||
stashID.stash_id
|
|
||||||
);
|
|
||||||
return (
|
return (
|
||||||
<li key={stashID.stash_id} className="row no-gutters">
|
<li key={stashID.stash_id} className="row no-gutters">
|
||||||
{link}
|
<StashIDPill stashID={stashID} linkType="studios" />
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { faTrashAlt } from "@fortawesome/free-solid-svg-icons";
|
|||||||
import isEqual from "lodash-es/isEqual";
|
import isEqual from "lodash-es/isEqual";
|
||||||
import { useToast } from "src/hooks/Toast";
|
import { useToast } from "src/hooks/Toast";
|
||||||
import { handleUnsavedChanges } from "src/utils/navigation";
|
import { handleUnsavedChanges } from "src/utils/navigation";
|
||||||
|
import { StashIDPill } from "src/components/Shared/StashID";
|
||||||
|
|
||||||
interface IStudioEditPanel {
|
interface IStudioEditPanel {
|
||||||
studio: Partial<GQL.StudioDataFragment>;
|
studio: Partial<GQL.StudioDataFragment>;
|
||||||
@@ -165,18 +166,6 @@ export const StudioEditPanel: React.FC<IStudioEditPanel> = ({
|
|||||||
<Col xs={fieldXS} xl={fieldXL}>
|
<Col xs={fieldXS} xl={fieldXL}>
|
||||||
<ul className="pl-0">
|
<ul className="pl-0">
|
||||||
{formik.values.stash_ids.map((stashID) => {
|
{formik.values.stash_ids.map((stashID) => {
|
||||||
const base = stashID.endpoint.match(/https?:\/\/.*?\//)?.[0];
|
|
||||||
const link = base ? (
|
|
||||||
<a
|
|
||||||
href={`${base}studios/${stashID.stash_id}`}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
{stashID.stash_id}
|
|
||||||
</a>
|
|
||||||
) : (
|
|
||||||
stashID.stash_id
|
|
||||||
);
|
|
||||||
return (
|
return (
|
||||||
<li key={stashID.stash_id} className="row no-gutters">
|
<li key={stashID.stash_id} className="row no-gutters">
|
||||||
<Button
|
<Button
|
||||||
@@ -190,7 +179,7 @@ export const StudioEditPanel: React.FC<IStudioEditPanel> = ({
|
|||||||
>
|
>
|
||||||
<Icon icon={faTrashAlt} />
|
<Icon icon={faTrashAlt} />
|
||||||
</Button>
|
</Button>
|
||||||
{link}
|
<StashIDPill stashID={stashID} linkType="studios" />
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
Reference in New Issue
Block a user