mirror of
https://github.com/stashapp/stash.git
synced 2025-12-09 09:53:40 +01:00
Touch up Performer Page (#2200)
* Moves "Edit" and "Autotag" out of performer tabs * Smoothen out fedit submission behavior
This commit is contained in:
parent
be5dc7e545
commit
baf148625c
12 changed files with 160 additions and 188 deletions
|
|
@ -1,4 +1,5 @@
|
|||
### 🎨 Improvements
|
||||
* Made Performer page consistent with Studio and Tag pages. ([#2200](https://github.com/stashapp/stash/pull/2200))
|
||||
* Add gender icons to performers. ([#2179](https://github.com/stashapp/stash/pull/2179))
|
||||
* Add button to test credentials when adding/editing stash-box endpoints. ([#2173](https://github.com/stashapp/stash/pull/2173))
|
||||
* Show counts on list tabs in Performer, Studio and Tag pages. ([#2169](https://github.com/stashapp/stash/pull/2169))
|
||||
|
|
|
|||
|
|
@ -470,7 +470,7 @@ export const MovieEditPanel: React.FC<IMovieEditPanel> = ({
|
|||
</Form>
|
||||
|
||||
<DetailsEditNavbar
|
||||
objectName={movie?.name ?? "movie"}
|
||||
objectName={movie?.name ?? intl.formatMessage({ id: "movie" })}
|
||||
isNew={isNew}
|
||||
isEditing={isEditing}
|
||||
onToggleEdit={onCancel}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ const GenderIcon: React.FC<IIconProps> = ({ gender, className }) => {
|
|||
: faTransgenderAlt;
|
||||
return (
|
||||
<FontAwesomeIcon
|
||||
title={intl.formatMessage({ id: "gender." + gender })}
|
||||
title={intl.formatMessage({ id: "gender_types." + gender })}
|
||||
className={className}
|
||||
icon={icon}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useEffect, useMemo, useState } from "react";
|
||||
import { Button, Tabs, Tab, Badge } from "react-bootstrap";
|
||||
import { Button, Tabs, Tab, Badge, Col, Row } from "react-bootstrap";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
import { useParams, useHistory } from "react-router-dom";
|
||||
import { Helmet } from "react-helmet";
|
||||
|
|
@ -10,9 +10,11 @@ import {
|
|||
useFindPerformer,
|
||||
usePerformerUpdate,
|
||||
usePerformerDestroy,
|
||||
mutateMetadataAutoTag,
|
||||
} from "src/core/StashService";
|
||||
import {
|
||||
CountryFlag,
|
||||
DetailsEditNavbar,
|
||||
ErrorMessage,
|
||||
Icon,
|
||||
LoadingIndicator,
|
||||
|
|
@ -21,7 +23,6 @@ import { useLightbox, useToast } from "src/hooks";
|
|||
import { TextUtils } from "src/utils";
|
||||
import { RatingStars } from "src/components/Scenes/SceneDetails/RatingStars";
|
||||
import { PerformerDetailsPanel } from "./PerformerDetailsPanel";
|
||||
import { PerformerOperationsPanel } from "./PerformerOperationsPanel";
|
||||
import { PerformerScenesPanel } from "./PerformerScenesPanel";
|
||||
import { PerformerGalleriesPanel } from "./PerformerGalleriesPanel";
|
||||
import { PerformerMoviesPanel } from "./PerformerMoviesPanel";
|
||||
|
|
@ -44,6 +45,7 @@ const PerformerPage: React.FC<IProps> = ({ performer }) => {
|
|||
|
||||
const [imagePreview, setImagePreview] = useState<string | null>();
|
||||
const [imageEncoding, setImageEncoding] = useState<boolean>(false);
|
||||
const [isEditing, setIsEditing] = useState<boolean>(false);
|
||||
|
||||
// if undefined then get the existing image
|
||||
// if null then get the default (no) image
|
||||
|
|
@ -68,9 +70,7 @@ const PerformerPage: React.FC<IProps> = ({ performer }) => {
|
|||
tab === "scenes" ||
|
||||
tab === "galleries" ||
|
||||
tab === "images" ||
|
||||
tab === "movies" ||
|
||||
tab === "edit" ||
|
||||
tab === "operations"
|
||||
tab === "movies"
|
||||
? tab
|
||||
: "details";
|
||||
const setActiveTabKey = (newTab: string | null) => {
|
||||
|
|
@ -84,14 +84,24 @@ const PerformerPage: React.FC<IProps> = ({ performer }) => {
|
|||
|
||||
const onImageEncoding = (isEncoding = false) => setImageEncoding(isEncoding);
|
||||
|
||||
async function onAutoTag() {
|
||||
try {
|
||||
await mutateMetadataAutoTag({ performers: [performer.id] });
|
||||
Toast.success({
|
||||
content: intl.formatMessage({ id: "toast.started_auto_tagging" }),
|
||||
});
|
||||
} catch (e) {
|
||||
Toast.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
// set up hotkeys
|
||||
useEffect(() => {
|
||||
Mousetrap.bind("a", () => setActiveTabKey("details"));
|
||||
Mousetrap.bind("e", () => setActiveTabKey("edit"));
|
||||
Mousetrap.bind("e", () => setIsEditing(!isEditing));
|
||||
Mousetrap.bind("c", () => setActiveTabKey("scenes"));
|
||||
Mousetrap.bind("g", () => setActiveTabKey("galleries"));
|
||||
Mousetrap.bind("m", () => setActiveTabKey("movies"));
|
||||
Mousetrap.bind("o", () => setActiveTabKey("operations"));
|
||||
Mousetrap.bind("f", () => setFavorite(!performer.favorite));
|
||||
|
||||
// numeric keypresses get caught by jwplayer, so blur the element
|
||||
|
|
@ -139,85 +149,108 @@ const PerformerPage: React.FC<IProps> = ({ performer }) => {
|
|||
}
|
||||
|
||||
const renderTabs = () => (
|
||||
<Tabs
|
||||
activeKey={activeTabKey}
|
||||
onSelect={setActiveTabKey}
|
||||
id="performer-details"
|
||||
unmountOnExit
|
||||
>
|
||||
<Tab eventKey="details" title={intl.formatMessage({ id: "details" })}>
|
||||
<PerformerDetailsPanel performer={performer} />
|
||||
</Tab>
|
||||
<Tab
|
||||
eventKey="scenes"
|
||||
title={
|
||||
<React.Fragment>
|
||||
{intl.formatMessage({ id: "scenes" })}
|
||||
<Badge className="left-spacing" pill variant="secondary">
|
||||
{intl.formatNumber(performer.scene_count ?? 0)}
|
||||
</Badge>
|
||||
</React.Fragment>
|
||||
}
|
||||
<React.Fragment>
|
||||
<Col>
|
||||
<Row xs={8}>
|
||||
<DetailsEditNavbar
|
||||
objectName={
|
||||
performer?.name ?? intl.formatMessage({ id: "performer" })
|
||||
}
|
||||
onToggleEdit={() => {
|
||||
setIsEditing(!isEditing);
|
||||
}}
|
||||
onDelete={onDelete}
|
||||
onAutoTag={onAutoTag}
|
||||
isNew={false}
|
||||
isEditing={false}
|
||||
onSave={() => {}}
|
||||
onImageChange={() => {}}
|
||||
/>
|
||||
</Row>
|
||||
</Col>
|
||||
<Tabs
|
||||
activeKey={activeTabKey}
|
||||
onSelect={setActiveTabKey}
|
||||
id="performer-details"
|
||||
unmountOnExit
|
||||
>
|
||||
<PerformerScenesPanel performer={performer} />
|
||||
</Tab>
|
||||
<Tab
|
||||
eventKey="galleries"
|
||||
title={
|
||||
<React.Fragment>
|
||||
{intl.formatMessage({ id: "galleries" })}
|
||||
<Badge className="left-spacing" pill variant="secondary">
|
||||
{intl.formatNumber(performer.gallery_count ?? 0)}
|
||||
</Badge>
|
||||
</React.Fragment>
|
||||
}
|
||||
>
|
||||
<PerformerGalleriesPanel performer={performer} />
|
||||
</Tab>
|
||||
<Tab
|
||||
eventKey="images"
|
||||
title={
|
||||
<React.Fragment>
|
||||
{intl.formatMessage({ id: "images" })}
|
||||
<Badge className="left-spacing" pill variant="secondary">
|
||||
{intl.formatNumber(performer.image_count ?? 0)}
|
||||
</Badge>
|
||||
</React.Fragment>
|
||||
}
|
||||
>
|
||||
<PerformerImagesPanel performer={performer} />
|
||||
</Tab>
|
||||
<Tab
|
||||
eventKey="movies"
|
||||
title={
|
||||
<React.Fragment>
|
||||
{intl.formatMessage({ id: "movies" })}
|
||||
<Badge className="left-spacing" pill variant="secondary">
|
||||
{intl.formatNumber(performer.movie_count ?? 0)}
|
||||
</Badge>
|
||||
</React.Fragment>
|
||||
}
|
||||
>
|
||||
<PerformerMoviesPanel performer={performer} />
|
||||
</Tab>
|
||||
<Tab eventKey="edit" title={intl.formatMessage({ id: "actions.edit" })}>
|
||||
<Tab eventKey="details" title={intl.formatMessage({ id: "details" })}>
|
||||
<PerformerDetailsPanel performer={performer} />
|
||||
</Tab>
|
||||
<Tab
|
||||
eventKey="scenes"
|
||||
title={
|
||||
<React.Fragment>
|
||||
{intl.formatMessage({ id: "scenes" })}
|
||||
<Badge className="left-spacing" pill variant="secondary">
|
||||
{intl.formatNumber(performer.scene_count ?? 0)}
|
||||
</Badge>
|
||||
</React.Fragment>
|
||||
}
|
||||
>
|
||||
<PerformerScenesPanel performer={performer} />
|
||||
</Tab>
|
||||
<Tab
|
||||
eventKey="galleries"
|
||||
title={
|
||||
<React.Fragment>
|
||||
{intl.formatMessage({ id: "galleries" })}
|
||||
<Badge className="left-spacing" pill variant="secondary">
|
||||
{intl.formatNumber(performer.gallery_count ?? 0)}
|
||||
</Badge>
|
||||
</React.Fragment>
|
||||
}
|
||||
>
|
||||
<PerformerGalleriesPanel performer={performer} />
|
||||
</Tab>
|
||||
<Tab
|
||||
eventKey="images"
|
||||
title={
|
||||
<React.Fragment>
|
||||
{intl.formatMessage({ id: "images" })}
|
||||
<Badge className="left-spacing" pill variant="secondary">
|
||||
{intl.formatNumber(performer.image_count ?? 0)}
|
||||
</Badge>
|
||||
</React.Fragment>
|
||||
}
|
||||
>
|
||||
<PerformerImagesPanel performer={performer} />
|
||||
</Tab>
|
||||
<Tab
|
||||
eventKey="movies"
|
||||
title={
|
||||
<React.Fragment>
|
||||
{intl.formatMessage({ id: "movies" })}
|
||||
<Badge className="left-spacing" pill variant="secondary">
|
||||
{intl.formatNumber(performer.movie_count ?? 0)}
|
||||
</Badge>
|
||||
</React.Fragment>
|
||||
}
|
||||
>
|
||||
<PerformerMoviesPanel performer={performer} />
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
function renderTabsOrEditPanel() {
|
||||
if (isEditing) {
|
||||
return (
|
||||
<PerformerEditPanel
|
||||
performer={performer}
|
||||
isVisible={activeTabKey === "edit"}
|
||||
isVisible={isEditing}
|
||||
isNew={false}
|
||||
onDelete={onDelete}
|
||||
onImageChange={onImageChange}
|
||||
onImageEncoding={onImageEncoding}
|
||||
onCancelEditing={() => {
|
||||
setIsEditing(false);
|
||||
}}
|
||||
/>
|
||||
</Tab>
|
||||
<Tab
|
||||
eventKey="operations"
|
||||
title={intl.formatMessage({ id: "operations" })}
|
||||
>
|
||||
<PerformerOperationsPanel performer={performer} />
|
||||
</Tab>
|
||||
</Tabs>
|
||||
);
|
||||
);
|
||||
} else {
|
||||
return renderTabs();
|
||||
}
|
||||
}
|
||||
|
||||
function maybeRenderAge() {
|
||||
if (performer?.birthdate) {
|
||||
|
|
@ -375,7 +408,7 @@ const PerformerPage: React.FC<IProps> = ({ performer }) => {
|
|||
</div>
|
||||
</div>
|
||||
<div className="performer-body">
|
||||
<div className="performer-tabs">{renderTabs()}</div>
|
||||
<div className="performer-tabs">{renderTabsOrEditPanel()}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -96,10 +96,10 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
|
|||
return (
|
||||
<dl className="details-list">
|
||||
<TextField
|
||||
id="gender.gender"
|
||||
id="gender"
|
||||
value={
|
||||
performer.gender
|
||||
? intl.formatMessage({ id: "gender." + performer.gender })
|
||||
? intl.formatMessage({ id: "gender_types." + performer.gender })
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { Button, Form, Col, Row, Badge, Dropdown } from "react-bootstrap";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import Mousetrap from "mousetrap";
|
||||
import * as GQL from "src/core/generated-graphql";
|
||||
import * as yup from "yup";
|
||||
|
|
@ -18,7 +18,6 @@ import {
|
|||
ImageInput,
|
||||
LoadingIndicator,
|
||||
CollapseButton,
|
||||
Modal,
|
||||
TagSelect,
|
||||
URLField,
|
||||
} from "src/components/Shared";
|
||||
|
|
@ -46,20 +45,19 @@ interface IPerformerDetails {
|
|||
performer: Partial<GQL.PerformerDataFragment>;
|
||||
isNew?: boolean;
|
||||
isVisible: boolean;
|
||||
onDelete?: () => void;
|
||||
onImageChange?: (image?: string | null) => void;
|
||||
onImageEncoding?: (loading?: boolean) => void;
|
||||
onCancelEditing?: () => void;
|
||||
}
|
||||
|
||||
export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
||||
performer,
|
||||
isNew,
|
||||
isVisible,
|
||||
onDelete,
|
||||
onImageChange,
|
||||
onImageEncoding,
|
||||
onCancelEditing,
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const Toast = useToast();
|
||||
const history = useHistory();
|
||||
|
||||
|
|
@ -67,7 +65,6 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||
const [scraper, setScraper] = useState<GQL.Scraper | IStashBox | undefined>();
|
||||
const [newTags, setNewTags] = useState<GQL.ScrapedTag[]>();
|
||||
const [isScraperModalOpen, setIsScraperModalOpen] = useState<boolean>(false);
|
||||
const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState<boolean>(false);
|
||||
|
||||
// Network state
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
|
@ -361,7 +358,17 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||
async function onSave(performerInput: InputValues) {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
if (!isNew) {
|
||||
if (isNew) {
|
||||
const input = getCreateValues(performerInput);
|
||||
const result = await createPerformer({
|
||||
variables: {
|
||||
input,
|
||||
},
|
||||
});
|
||||
if (result.data?.performerCreate) {
|
||||
history.push(`/performers/${result.data.performerCreate.id}`);
|
||||
}
|
||||
} else {
|
||||
const input = getUpdateValues(performerInput);
|
||||
|
||||
await updatePerformer({
|
||||
|
|
@ -372,20 +379,14 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||
},
|
||||
},
|
||||
});
|
||||
history.push(`/performers/${performer.id}`);
|
||||
} else {
|
||||
const input = getCreateValues(performerInput);
|
||||
const result = await createPerformer({
|
||||
variables: {
|
||||
input,
|
||||
},
|
||||
});
|
||||
if (result.data?.performerCreate) {
|
||||
history.push(`/performers/${result.data.performerCreate.id}`);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
Toast.error(e);
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
if (!isNew && onCancelEditing) {
|
||||
onCancelEditing();
|
||||
}
|
||||
setIsLoading(false);
|
||||
}
|
||||
|
|
@ -397,12 +398,6 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||
onSave?.(formik.values);
|
||||
});
|
||||
|
||||
if (!isNew) {
|
||||
Mousetrap.bind("d d", () => {
|
||||
setIsDeleteAlertOpen(true);
|
||||
});
|
||||
}
|
||||
|
||||
return () => {
|
||||
Mousetrap.unbind("s s");
|
||||
|
||||
|
|
@ -655,25 +650,17 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||
setScraper(undefined);
|
||||
}
|
||||
|
||||
function renderButtons() {
|
||||
function renderButtons(classNames: string) {
|
||||
return (
|
||||
<Row>
|
||||
<Col className="mt-3" xs={12}>
|
||||
<Button
|
||||
className="mr-2"
|
||||
variant="primary"
|
||||
disabled={!formik.dirty}
|
||||
onClick={() => formik.submitForm()}
|
||||
>
|
||||
<FormattedMessage id="actions.save" />
|
||||
</Button>
|
||||
{!isNew ? (
|
||||
<Col className={classNames} xs={12}>
|
||||
{!isNew && onCancelEditing ? (
|
||||
<Button
|
||||
className="mr-2"
|
||||
variant="danger"
|
||||
onClick={() => setIsDeleteAlertOpen(true)}
|
||||
variant="primary"
|
||||
onClick={() => onCancelEditing()}
|
||||
>
|
||||
<FormattedMessage id="actions.delete" />
|
||||
<FormattedMessage id="actions.cancel" />
|
||||
</Button>
|
||||
) : (
|
||||
""
|
||||
|
|
@ -685,12 +672,19 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||
onImageURL={onImageChangeURL}
|
||||
/>
|
||||
<Button
|
||||
className="mx-2"
|
||||
className="mr-2"
|
||||
variant="danger"
|
||||
onClick={() => formik.setFieldValue("image", null)}
|
||||
>
|
||||
<FormattedMessage id="actions.clear_image" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="success"
|
||||
disabled={!formik.dirty}
|
||||
onClick={() => formik.submitForm()}
|
||||
>
|
||||
<FormattedMessage id="actions.save" />
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
|
|
@ -716,28 +710,6 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||
) : undefined;
|
||||
};
|
||||
|
||||
function renderDeleteAlert() {
|
||||
return (
|
||||
<Modal
|
||||
show={isDeleteAlertOpen}
|
||||
icon="trash-alt"
|
||||
accept={{
|
||||
text: intl.formatMessage({ id: "actions.delete" }),
|
||||
variant: "danger",
|
||||
onClick: onDelete,
|
||||
}}
|
||||
cancel={{ onClick: () => setIsDeleteAlertOpen(false) }}
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="dialogs.delete_confirm"
|
||||
values={{ entityName: performer.name }}
|
||||
/>
|
||||
</p>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
function renderTagsField() {
|
||||
return (
|
||||
<Form.Group controlId="tags" as={Row}>
|
||||
|
|
@ -837,7 +809,6 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||
|
||||
return (
|
||||
<>
|
||||
{renderDeleteAlert()}
|
||||
{renderScrapeModal()}
|
||||
{maybeRenderScrapeDialog()}
|
||||
|
||||
|
|
@ -845,6 +816,7 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||
when={formik.dirty}
|
||||
message="Unsaved changes. Are you sure you want to leave?"
|
||||
/>
|
||||
{renderButtons("mb-3")}
|
||||
|
||||
<Form noValidate onSubmit={formik.handleSubmit} id="performer-edit">
|
||||
<Form.Group controlId="name" as={Row}>
|
||||
|
|
@ -880,7 +852,7 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||
|
||||
<Form.Group as={Row}>
|
||||
<Form.Label column xs={labelXS} xl={labelXL}>
|
||||
<FormattedMessage id="gender.gender" />
|
||||
<FormattedMessage id="gender" />
|
||||
</Form.Label>
|
||||
<Col xs="auto">
|
||||
<Form.Control
|
||||
|
|
@ -970,7 +942,7 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||
|
||||
{renderStashIDs()}
|
||||
|
||||
{renderButtons()}
|
||||
{renderButtons("mt-3")}
|
||||
</Form>
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
import { Button } from "react-bootstrap";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
import * as GQL from "src/core/generated-graphql";
|
||||
import { mutateMetadataAutoTag } from "src/core/StashService";
|
||||
import { useToast } from "src/hooks";
|
||||
|
||||
interface IPerformerOperationsProps {
|
||||
performer: GQL.PerformerDataFragment;
|
||||
}
|
||||
|
||||
export const PerformerOperationsPanel: React.FC<IPerformerOperationsProps> = ({
|
||||
performer,
|
||||
}) => {
|
||||
const Toast = useToast();
|
||||
const intl = useIntl();
|
||||
|
||||
async function onAutoTag() {
|
||||
try {
|
||||
await mutateMetadataAutoTag({ performers: [performer.id] });
|
||||
Toast.success({
|
||||
content: intl.formatMessage({ id: "toast.started_auto_tagging" }),
|
||||
});
|
||||
} catch (e) {
|
||||
Toast.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Button onClick={onAutoTag}>
|
||||
<FormattedMessage id="actions.auto_tag" />
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
|
@ -429,7 +429,7 @@ export const PerformerScrapeDialog: React.FC<IPerformerScrapeDialogProps> = (
|
|||
onChange={(value) => setAliases(value)}
|
||||
/>
|
||||
{renderScrapedGenderRow(
|
||||
intl.formatMessage({ id: "gender.gender" }),
|
||||
intl.formatMessage({ id: "gender" }),
|
||||
gender,
|
||||
(value) => setGender(value)
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@ export const StudioEditPanel: React.FC<IStudioEditPanel> = ({
|
|||
</Form>
|
||||
|
||||
<DetailsEditNavbar
|
||||
objectName={studio?.name ?? "studio"}
|
||||
objectName={studio?.name ?? intl.formatMessage({ id: "studio" })}
|
||||
isNew={isNew}
|
||||
isEditing
|
||||
onToggleEdit={onCancel}
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ const PerformerModal: React.FC<IPerformerModalProps> = ({
|
|||
{renderField(
|
||||
"gender",
|
||||
performer.gender
|
||||
? intl.formatMessage({ id: "gender." + performer.gender })
|
||||
? intl.formatMessage({ id: "gender_types." + performer.gender })
|
||||
: ""
|
||||
)}
|
||||
{renderField("birthdate", performer.birthdate)}
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ export const TagEditPanel: React.FC<ITagEditPanel> = ({
|
|||
</Form>
|
||||
|
||||
<DetailsEditNavbar
|
||||
objectName={tag?.name ?? "tag"}
|
||||
objectName={tag?.name ?? intl.formatMessage({ id: "tag" })}
|
||||
isNew={isNew}
|
||||
isEditing={isEditing}
|
||||
onToggleEdit={onCancel}
|
||||
|
|
|
|||
|
|
@ -691,8 +691,8 @@
|
|||
"galleries": "Galleries",
|
||||
"gallery": "Gallery",
|
||||
"gallery_count": "Gallery Count",
|
||||
"gender": {
|
||||
"gender": "Gender",
|
||||
"gender": "Gender",
|
||||
"gender_types": {
|
||||
"MALE": "Male",
|
||||
"FEMALE": "Female",
|
||||
"TRANSGENDER_MALE": "Transgender Male",
|
||||
|
|
|
|||
Loading…
Reference in a new issue