mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 04:44:37 +03:00
Merge pull request #102 from WithoutPants/delete_scene
Add Delete Scene button
This commit is contained in:
@@ -82,7 +82,12 @@ export const Scene: FunctionComponent<ISceneProps> = (props: ISceneProps) => {
|
||||
<Tab
|
||||
id="scene-edit-panel"
|
||||
title="Edit"
|
||||
panel={<SceneEditPanel scene={modifiedScene} onUpdate={(newScene) => setScene(newScene)} />}
|
||||
panel={
|
||||
<SceneEditPanel
|
||||
scene={modifiedScene}
|
||||
onUpdate={(newScene) => setScene(newScene)}
|
||||
onDelete={() => props.history.push("/scenes")}
|
||||
/>}
|
||||
/>
|
||||
</Tabs>
|
||||
</Card>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import {
|
||||
Button,
|
||||
Classes,
|
||||
Checkbox,
|
||||
Dialog,
|
||||
FormGroup,
|
||||
HTMLSelect,
|
||||
InputGroup,
|
||||
@@ -19,6 +22,7 @@ import { ValidGalleriesSelect } from "../../select/ValidGalleriesSelect";
|
||||
interface IProps {
|
||||
scene: GQL.SceneDataFragment;
|
||||
onUpdate: (scene: GQL.SceneDataFragment) => void;
|
||||
onDelete: () => void;
|
||||
}
|
||||
|
||||
export const SceneEditPanel: FunctionComponent<IProps> = (props: IProps) => {
|
||||
@@ -33,10 +37,15 @@ export const SceneEditPanel: FunctionComponent<IProps> = (props: IProps) => {
|
||||
const [performerIds, setPerformerIds] = useState<string[] | undefined>(undefined);
|
||||
const [tagIds, setTagIds] = useState<string[] | undefined>(undefined);
|
||||
|
||||
const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState<boolean>(false);
|
||||
const [deleteFile, setDeleteFile] = useState<boolean>(false);
|
||||
const [deleteGenerated, setDeleteGenerated] = useState<boolean>(true);
|
||||
|
||||
// Network state
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const updateScene = StashService.useSceneUpdate(getSceneInput());
|
||||
const deleteScene = StashService.useSceneDestroy(getSceneDeleteInput());
|
||||
|
||||
function updateSceneEditState(state: Partial<GQL.SceneDataFragment>) {
|
||||
const perfIds = !!state.performers ? state.performers.map((performer) => performer.id) : undefined;
|
||||
@@ -89,6 +98,28 @@ export const SceneEditPanel: FunctionComponent<IProps> = (props: IProps) => {
|
||||
setIsLoading(false);
|
||||
}
|
||||
|
||||
function getSceneDeleteInput(): GQL.SceneDestroyInput {
|
||||
return {
|
||||
id: props.scene.id,
|
||||
delete_file: deleteFile,
|
||||
delete_generated: deleteGenerated
|
||||
};
|
||||
}
|
||||
|
||||
async function onDelete() {
|
||||
setIsDeleteAlertOpen(false);
|
||||
setIsLoading(true);
|
||||
try {
|
||||
await deleteScene();
|
||||
ToastUtils.success("Deleted scene");
|
||||
} catch (e) {
|
||||
ErrorUtils.handle(e);
|
||||
}
|
||||
setIsLoading(false);
|
||||
|
||||
props.onDelete();
|
||||
}
|
||||
|
||||
function renderMultiSelect(type: "performers" | "tags", initialIds: string[] | undefined) {
|
||||
return (
|
||||
<FilterMultiSelect
|
||||
@@ -105,8 +136,39 @@ export const SceneEditPanel: FunctionComponent<IProps> = (props: IProps) => {
|
||||
);
|
||||
}
|
||||
|
||||
function renderDeleteAlert() {
|
||||
return (
|
||||
<>
|
||||
<Dialog
|
||||
canOutsideClickClose={false}
|
||||
canEscapeKeyClose={false}
|
||||
icon="trash"
|
||||
isCloseButtonShown={false}
|
||||
isOpen={isDeleteAlertOpen}
|
||||
title="Delete Scene?"
|
||||
>
|
||||
<div className={Classes.DIALOG_BODY}>
|
||||
<p>
|
||||
Are you sure you want to delete this scene? Unless the file is also deleted, this scene will be re-added when scan is performed.
|
||||
</p>
|
||||
<Checkbox checked={deleteFile} label="Delete file" onChange={() => setDeleteFile(!deleteFile)} />
|
||||
<Checkbox checked={deleteGenerated} label="Delete generated supporting files" onChange={() => setDeleteGenerated(!deleteGenerated)} />
|
||||
</div>
|
||||
|
||||
<div className={Classes.DIALOG_FOOTER}>
|
||||
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
|
||||
<Button intent="danger" onClick={() => onDelete()}>Delete</Button>
|
||||
<Button onClick={() => setIsDeleteAlertOpen(false)}>Cancel</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{renderDeleteAlert()}
|
||||
{isLoading ? <Spinner size={Spinner.SIZE_LARGE} /> : undefined}
|
||||
<div className="form-container " style={{width: "50%"}}>
|
||||
<FormGroup label="Title">
|
||||
@@ -170,7 +232,8 @@ export const SceneEditPanel: FunctionComponent<IProps> = (props: IProps) => {
|
||||
{renderMultiSelect("tags", tagIds)}
|
||||
</FormGroup>
|
||||
</div>
|
||||
<Button text="Save" intent="primary" onClick={() => onSave()}/>
|
||||
<Button className="edit-button" text="Save" intent="primary" onClick={() => onSave()}/>
|
||||
<Button className="edit-button" text="Delete" intent="danger" onClick={() => setIsDeleteAlertOpen(true)}/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -142,6 +142,10 @@ export class StashService {
|
||||
return GQL.useSceneUpdate({ variables: input });
|
||||
}
|
||||
|
||||
public static useSceneDestroy(input: GQL.SceneDestroyInput) {
|
||||
return GQL.useSceneDestroy({ variables: input });
|
||||
}
|
||||
|
||||
public static useStudioCreate(input: GQL.StudioCreateInput) {
|
||||
return GQL.useStudioCreate({ variables: input });
|
||||
}
|
||||
|
||||
@@ -99,6 +99,10 @@ video.preview {
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.edit-button {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.tag-item {
|
||||
margin: 5px;
|
||||
|
||||
@@ -216,4 +220,4 @@ span.block {
|
||||
& .tag-list-row:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user