FR: Auto Tag Confirmation Modal (#6735)

* Improve folder list styling
---------
Co-authored-by: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
This commit is contained in:
Gykes 2026-03-22 22:16:59 -07:00 committed by GitHub
parent c5034422cb
commit e0f2c8e96d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 106 additions and 9 deletions

View file

@ -20,7 +20,13 @@ interface IDirectorySelectionDialogProps {
export const DirectorySelectionDialog: React.FC<
IDirectorySelectionDialogProps
> = ({ animation, allowEmpty = false, initialPaths = [], onClose }) => {
> = ({
animation,
allowEmpty = false,
initialPaths = [],
onClose,
children,
}) => {
const intl = useIntl();
const { configuration } = useConfigurationContext();
@ -91,6 +97,8 @@ export const DirectorySelectionDialog: React.FC<
</Button>
}
/>
{children}
</div>
</ModalComponent>
);

View file

@ -19,6 +19,10 @@ import { BooleanSetting, Setting, SettingGroup } from "../Inputs";
import { ManualLink } from "src/components/Help/context";
import { Icon } from "src/components/Shared/Icon";
import { faQuestionCircle } from "@fortawesome/free-solid-svg-icons";
import {
AutoTagConfirmDialog,
AutoTagWarning,
} from "src/components/Shared/AutoTagConfirmDialog";
import { useSettings } from "../context";
interface IAutoTagOptions {
@ -78,6 +82,7 @@ export const LibraryTasks: React.FC = () => {
const [dialogOpen, setDialogOpenState] = useState({
scan: false,
autoTag: false,
autoTagAlert: false,
identify: false,
generate: false,
});
@ -224,12 +229,29 @@ export const LibraryTasks: React.FC = () => {
}
}
function renderAutoTagAlert() {
return (
<AutoTagConfirmDialog
show={dialogOpen.autoTagAlert}
onConfirm={() => {
setDialogOpen({ autoTagAlert: false });
runAutoTag();
}}
onCancel={() => setDialogOpen({ autoTagAlert: false })}
/>
);
}
function renderAutoTagDialog() {
if (!dialogOpen.autoTag) {
return;
}
return <DirectorySelectionDialog onClose={onAutoTagDialogClosed} />;
return (
<DirectorySelectionDialog onClose={onAutoTagDialogClosed}>
<AutoTagWarning />
</DirectorySelectionDialog>
);
}
function onAutoTagDialogClosed(paths?: string[]) {
@ -341,6 +363,7 @@ export const LibraryTasks: React.FC = () => {
return (
<Form.Group>
{renderScanDialog()}
{renderAutoTagAlert()}
{renderAutoTagDialog()}
{maybeRenderIdentifyDialog()}
{renderGenerateDialog()}
@ -426,9 +449,9 @@ export const LibraryTasks: React.FC = () => {
variant="secondary"
type="submit"
className="mr-2"
onClick={() => runAutoTag()}
onClick={() => setDialogOpen({ autoTagAlert: true })}
>
<FormattedMessage id="actions.auto_tag" />
<FormattedMessage id="actions.auto_tag" />
</Button>
<Button
variant="secondary"

View file

@ -0,0 +1,52 @@
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { faExclamationTriangle } from "@fortawesome/free-solid-svg-icons";
import { ModalComponent } from "./Modal";
import { Icon } from "./Icon";
interface IAutoTagConfirmDialog {
show: boolean;
onConfirm: () => void;
onCancel: () => void;
}
export const AutoTagWarning = () => (
<>
<p>
<FormattedMessage id="config.tasks.auto_tag_based_on_filenames" />
</p>
<p>
<FormattedMessage id="config.tasks.auto_tag_confirm" />
</p>
<p className="lead">
<Icon icon={faExclamationTriangle} className="text-warning" />
<FormattedMessage id="config.tasks.auto_tag_warning" />
</p>
</>
);
export const AutoTagConfirmDialog: React.FC<IAutoTagConfirmDialog> = ({
show,
onConfirm,
onCancel,
}) => {
const intl = useIntl();
return (
<ModalComponent
show={show}
icon={faExclamationTriangle}
header={intl.formatMessage({ id: "actions.auto_tag" })}
accept={{
text: intl.formatMessage({ id: "actions.confirm" }),
variant: "danger",
onClick: onConfirm,
}}
cancel={{
onClick: onCancel,
}}
>
<AutoTagWarning />
</ModalComponent>
);
};

View file

@ -2,6 +2,7 @@ import { Button, Dropdown, Modal, SplitButton } from "react-bootstrap";
import React, { useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { ImageInput } from "./ImageInput";
import { AutoTagConfirmDialog } from "./AutoTagConfirmDialog";
import cx from "classnames";
interface IProps {
@ -30,6 +31,7 @@ interface IProps {
export const DetailsEditNavbar: React.FC<IProps> = (props: IProps) => {
const intl = useIntl();
const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState<boolean>(false);
const [isAutoTagAlertOpen, setIsAutoTagAlertOpen] = useState<boolean>(false);
function renderEditButton() {
if (props.isNew) return;
@ -114,14 +116,20 @@ export const DetailsEditNavbar: React.FC<IProps> = (props: IProps) => {
<Button
variant="secondary"
disabled={props.autoTagDisabled}
onClick={() => {
onClick={() => setIsAutoTagAlertOpen(true)}
>
<FormattedMessage id="actions.auto_tag" />
</Button>
<AutoTagConfirmDialog
show={isAutoTagAlertOpen}
onConfirm={() => {
setIsAutoTagAlertOpen(false);
if (props.onAutoTag) {
props.onAutoTag();
}
}}
>
<FormattedMessage id="actions.auto_tag" />
</Button>
onCancel={() => setIsAutoTagAlertOpen(false)}
/>
</div>
);
}

View file

@ -127,11 +127,15 @@
.folder-list {
list-style-type: none;
margin: 0;
max-height: 30vw;
max-height: 300px;
overflow-x: auto;
padding-bottom: 0.5rem;
padding-top: 1rem;
&:not(:last-child) {
margin-bottom: 1rem;
}
&-item {
white-space: nowrap;

View file

@ -512,6 +512,8 @@
"auto_tagging_paths": "Auto tagging the following paths"
},
"auto_tag_based_on_filenames": "Auto tag content based on file paths.",
"auto_tag_confirm": "This will attempt to match your content against existing metadata.",
"auto_tag_warning": "This process cannot be undone and may produce incorrect matches.",
"auto_tagging": "Auto tagging",
"backing_up_database": "Backing up database",
"backup_and_download": "Performs a backup of the database and downloads the resulting file.",