From aad4ddc46df0cabf54f9d75bb5bc1ab302526e6a Mon Sep 17 00:00:00 2001
From: InfiniteTF
Date: Wed, 13 Jan 2021 01:57:53 +0100
Subject: [PATCH] Add batch delete for performers/tags/studios/movies (#1053)
* Add batch delete for performers/tags/studios/movies
* Fix ListFilter styling bug
---
graphql/documents/mutations/movie.graphql | 6 +-
graphql/documents/mutations/performer.graphql | 4 +
graphql/documents/mutations/studio.graphql | 4 +
graphql/documents/mutations/tag.graphql | 6 +-
graphql/schema/schema.graphql | 4 +
pkg/api/resolver_mutation_movie.go | 15 +++
pkg/api/resolver_mutation_performer.go | 15 +++
pkg/api/resolver_mutation_studio.go | 15 +++
pkg/api/resolver_mutation_tag.go | 16 +++
.../src/components/Changelog/versions/v050.md | 1 +
.../components/Images/DeleteImagesDialog.tsx | 2 +
ui/v2.5/src/components/List/ListFilter.tsx | 55 ++++----
ui/v2.5/src/components/Movies/MovieList.tsx | 25 +++-
.../components/Performers/PerformerList.tsx | 26 +++-
.../components/Scenes/DeleteScenesDialog.tsx | 2 +
ui/v2.5/src/components/Scenes/SceneList.tsx | 18 +--
.../components/Shared/DeleteEntityDialog.tsx | 123 ++++++++++++++++++
ui/v2.5/src/components/Shared/index.ts | 2 +
ui/v2.5/src/components/Studios/StudioList.tsx | 23 +++-
ui/v2.5/src/components/Tags/TagList.tsx | 17 ++-
ui/v2.5/src/core/StashService.ts | 30 +++++
21 files changed, 353 insertions(+), 56 deletions(-)
create mode 100644 ui/v2.5/src/components/Shared/DeleteEntityDialog.tsx
diff --git a/graphql/documents/mutations/movie.graphql b/graphql/documents/mutations/movie.graphql
index 527b7fddb..e1236b9dd 100644
--- a/graphql/documents/mutations/movie.graphql
+++ b/graphql/documents/mutations/movie.graphql
@@ -24,4 +24,8 @@ mutation MovieUpdate($input: MovieUpdateInput!) {
mutation MovieDestroy($id: ID!) {
movieDestroy(input: { id: $id })
-}
\ No newline at end of file
+}
+
+mutation MoviesDestroy($ids: [ID!]!) {
+ moviesDestroy(ids: $ids)
+}
diff --git a/graphql/documents/mutations/performer.graphql b/graphql/documents/mutations/performer.graphql
index 9ea5a4eff..0f29c12b4 100644
--- a/graphql/documents/mutations/performer.graphql
+++ b/graphql/documents/mutations/performer.graphql
@@ -55,3 +55,7 @@ mutation PerformerUpdate(
mutation PerformerDestroy($id: ID!) {
performerDestroy(input: { id: $id })
}
+
+mutation PerformersDestroy($ids: [ID!]!) {
+ performersDestroy(ids: $ids)
+}
diff --git a/graphql/documents/mutations/studio.graphql b/graphql/documents/mutations/studio.graphql
index 71015a3ac..d2d11d222 100644
--- a/graphql/documents/mutations/studio.graphql
+++ b/graphql/documents/mutations/studio.graphql
@@ -21,3 +21,7 @@ mutation StudioUpdate(
mutation StudioDestroy($id: ID!) {
studioDestroy(input: { id: $id })
}
+
+mutation StudiosDestroy($ids: [ID!]!) {
+ studiosDestroy(ids: $ids)
+}
diff --git a/graphql/documents/mutations/tag.graphql b/graphql/documents/mutations/tag.graphql
index 91ad0136b..6e2cd0b99 100644
--- a/graphql/documents/mutations/tag.graphql
+++ b/graphql/documents/mutations/tag.graphql
@@ -8,8 +8,12 @@ mutation TagDestroy($id: ID!) {
tagDestroy(input: { id: $id })
}
+mutation TagsDestroy($ids: [ID!]!) {
+ tagsDestroy(ids: $ids)
+}
+
mutation TagUpdate($input: TagUpdateInput!) {
tagUpdate(input: $input) {
...TagData
}
-}
\ No newline at end of file
+}
diff --git a/graphql/schema/schema.graphql b/graphql/schema/schema.graphql
index 7ae7a95aa..d69d4f77c 100644
--- a/graphql/schema/schema.graphql
+++ b/graphql/schema/schema.graphql
@@ -175,18 +175,22 @@ type Mutation {
performerCreate(input: PerformerCreateInput!): Performer
performerUpdate(input: PerformerUpdateInput!): Performer
performerDestroy(input: PerformerDestroyInput!): Boolean!
+ performersDestroy(ids: [ID!]!): Boolean!
studioCreate(input: StudioCreateInput!): Studio
studioUpdate(input: StudioUpdateInput!): Studio
studioDestroy(input: StudioDestroyInput!): Boolean!
+ studiosDestroy(ids: [ID!]!): Boolean!
movieCreate(input: MovieCreateInput!): Movie
movieUpdate(input: MovieUpdateInput!): Movie
movieDestroy(input: MovieDestroyInput!): Boolean!
+ moviesDestroy(ids: [ID!]!): Boolean!
tagCreate(input: TagCreateInput!): Tag
tagUpdate(input: TagUpdateInput!): Tag
tagDestroy(input: TagDestroyInput!): Boolean!
+ tagsDestroy(ids: [ID!]!): Boolean!
"""Change general configuration options"""
configureGeneral(input: ConfigGeneralInput!): ConfigGeneralResult!
diff --git a/pkg/api/resolver_mutation_movie.go b/pkg/api/resolver_mutation_movie.go
index 8af2a7126..23756054e 100644
--- a/pkg/api/resolver_mutation_movie.go
+++ b/pkg/api/resolver_mutation_movie.go
@@ -222,3 +222,18 @@ func (r *mutationResolver) MovieDestroy(ctx context.Context, input models.MovieD
}
return true, nil
}
+
+func (r *mutationResolver) MoviesDestroy(ctx context.Context, ids []string) (bool, error) {
+ qb := models.NewMovieQueryBuilder()
+ tx := database.DB.MustBeginTx(ctx, nil)
+ for _, id := range ids {
+ if err := qb.Destroy(id, tx); err != nil {
+ _ = tx.Rollback()
+ return false, err
+ }
+ }
+ if err := tx.Commit(); err != nil {
+ return false, err
+ }
+ return true, nil
+}
diff --git a/pkg/api/resolver_mutation_performer.go b/pkg/api/resolver_mutation_performer.go
index bf79f6ae6..d249891cf 100644
--- a/pkg/api/resolver_mutation_performer.go
+++ b/pkg/api/resolver_mutation_performer.go
@@ -242,3 +242,18 @@ func (r *mutationResolver) PerformerDestroy(ctx context.Context, input models.Pe
}
return true, nil
}
+
+func (r *mutationResolver) PerformersDestroy(ctx context.Context, ids []string) (bool, error) {
+ qb := models.NewPerformerQueryBuilder()
+ tx := database.DB.MustBeginTx(ctx, nil)
+ for _, id := range ids {
+ if err := qb.Destroy(id, tx); err != nil {
+ _ = tx.Rollback()
+ return false, err
+ }
+ }
+ if err := tx.Commit(); err != nil {
+ return false, err
+ }
+ return true, nil
+}
diff --git a/pkg/api/resolver_mutation_studio.go b/pkg/api/resolver_mutation_studio.go
index 163f3f5ec..c685d3155 100644
--- a/pkg/api/resolver_mutation_studio.go
+++ b/pkg/api/resolver_mutation_studio.go
@@ -182,3 +182,18 @@ func (r *mutationResolver) StudioDestroy(ctx context.Context, input models.Studi
}
return true, nil
}
+
+func (r *mutationResolver) StudiosDestroy(ctx context.Context, ids []string) (bool, error) {
+ qb := models.NewStudioQueryBuilder()
+ tx := database.DB.MustBeginTx(ctx, nil)
+ for _, id := range ids {
+ if err := qb.Destroy(id, tx); err != nil {
+ _ = tx.Rollback()
+ return false, err
+ }
+ }
+ if err := tx.Commit(); err != nil {
+ return false, err
+ }
+ return true, nil
+}
diff --git a/pkg/api/resolver_mutation_tag.go b/pkg/api/resolver_mutation_tag.go
index 96d0b4982..28fe22de6 100644
--- a/pkg/api/resolver_mutation_tag.go
+++ b/pkg/api/resolver_mutation_tag.go
@@ -152,3 +152,19 @@ func (r *mutationResolver) TagDestroy(ctx context.Context, input models.TagDestr
}
return true, nil
}
+
+func (r *mutationResolver) TagsDestroy(ctx context.Context, ids []string) (bool, error) {
+ qb := models.NewTagQueryBuilder()
+ tx := database.DB.MustBeginTx(ctx, nil)
+
+ for _, id := range ids {
+ if err := qb.Destroy(id, tx); err != nil {
+ _ = tx.Rollback()
+ return false, err
+ }
+ }
+ if err := tx.Commit(); err != nil {
+ return false, err
+ }
+ return true, nil
+}
diff --git a/ui/v2.5/src/components/Changelog/versions/v050.md b/ui/v2.5/src/components/Changelog/versions/v050.md
index 8e2e70076..f9f0d911e 100644
--- a/ui/v2.5/src/components/Changelog/versions/v050.md
+++ b/ui/v2.5/src/components/Changelog/versions/v050.md
@@ -6,6 +6,7 @@
* Allow configuration of visible navbar items.
### 🎨 Improvements
+* Add batch deleting of performers, tags, studios, and movies.
* Reset cache after scan/clean to ensure scenes are updated.
* Add more video/image resolution tags.
* Add option to strip file extension from scene title when populating from scanning task.
diff --git a/ui/v2.5/src/components/Images/DeleteImagesDialog.tsx b/ui/v2.5/src/components/Images/DeleteImagesDialog.tsx
index 3c3615018..7b37eeafc 100644
--- a/ui/v2.5/src/components/Images/DeleteImagesDialog.tsx
+++ b/ui/v2.5/src/components/Images/DeleteImagesDialog.tsx
@@ -76,11 +76,13 @@ export const DeleteImagesDialog: React.FC = (
setDeleteFile(!deleteFile)}
/>
setDeleteGenerated(!deleteGenerated)}
diff --git a/ui/v2.5/src/components/List/ListFilter.tsx b/ui/v2.5/src/components/List/ListFilter.tsx
index 28dbe10a4..4e59388cc 100644
--- a/ui/v2.5/src/components/List/ListFilter.tsx
+++ b/ui/v2.5/src/components/List/ListFilter.tsx
@@ -426,29 +426,25 @@ export const ListFilter: React.FC = (
}
function maybeRenderSelectedButtons() {
- if (props.itemsSelected) {
+ if (props.itemsSelected && (props.onEdit || props.onDelete)) {
return (
- <>
- {props.onEdit ? (
-
- Edit}>
-
-
-
- ) : undefined}
+
+ {props.onEdit && (
+ Edit}>
+
+
+ )}
- {props.onDelete ? (
-
- Delete}>
-
-
-
- ) : undefined}
- >
+ {props.onDelete && (
+ Delete}>
+
+
+ )}
+
);
}
}
@@ -456,8 +452,8 @@ export const ListFilter: React.FC = (
function render() {
return (
<>
-
-
+
+
= (
))}
-
- {maybeRenderSelectedButtons()}
- {renderMore()}
-
+ {maybeRenderSelectedButtons()}
-
- {renderDisplayModeOptions()}
-
+ {renderMore()}
+
+ {renderDisplayModeOptions()}
{maybeRenderZoom()}
-
+
{renderFilterTags()}
>
diff --git a/ui/v2.5/src/components/Movies/MovieList.tsx b/ui/v2.5/src/components/Movies/MovieList.tsx
index baa2dcc29..2e7a52a55 100644
--- a/ui/v2.5/src/components/Movies/MovieList.tsx
+++ b/ui/v2.5/src/components/Movies/MovieList.tsx
@@ -1,14 +1,17 @@
import React, { useState } from "react";
import _ from "lodash";
import Mousetrap from "mousetrap";
-import { FindMoviesQueryResult } from "src/core/generated-graphql";
+import { useHistory } from "react-router-dom";
+import {
+ FindMoviesQueryResult,
+ SlimMovieDataFragment,
+} from "src/core/generated-graphql";
import { ListFilterModel } from "src/models/list-filter/filter";
import { DisplayMode } from "src/models/list-filter/types";
-import { queryFindMovies } from "src/core/StashService";
+import { queryFindMovies, useMoviesDestroy } from "src/core/StashService";
import { showWhenSelected, useMoviesList } from "src/hooks/ListHook";
-import { useHistory } from "react-router-dom";
+import { ExportDialog, DeleteEntityDialog } from "src/components/Shared";
import { MovieCard } from "./MovieCard";
-import { ExportDialog } from "../Shared/ExportDialog";
export const MovieList: React.FC = () => {
const history = useHistory();
@@ -44,12 +47,26 @@ export const MovieList: React.FC = () => {
};
};
+ const renderDeleteDialog = (
+ selectedMovies: SlimMovieDataFragment[],
+ onClose: (confirmed: boolean) => void
+ ) => (
+
+ );
+
const listData = useMoviesList({
renderContent,
addKeybinds,
otherOperations,
selectable: true,
persistState: true,
+ renderDeleteDialog,
});
async function viewRandom(
diff --git a/ui/v2.5/src/components/Performers/PerformerList.tsx b/ui/v2.5/src/components/Performers/PerformerList.tsx
index 6614288a3..b7300a718 100644
--- a/ui/v2.5/src/components/Performers/PerformerList.tsx
+++ b/ui/v2.5/src/components/Performers/PerformerList.tsx
@@ -2,13 +2,19 @@ import _ from "lodash";
import React, { useState } from "react";
import { useHistory } from "react-router-dom";
import Mousetrap from "mousetrap";
-import { FindPerformersQueryResult } from "src/core/generated-graphql";
-import { queryFindPerformers } from "src/core/StashService";
+import {
+ FindPerformersQueryResult,
+ SlimPerformerDataFragment,
+} from "src/core/generated-graphql";
+import {
+ queryFindPerformers,
+ usePerformersDestroy,
+} from "src/core/StashService";
import { usePerformersList } from "src/hooks";
import { showWhenSelected } from "src/hooks/ListHook";
import { ListFilterModel } from "src/models/list-filter/filter";
import { DisplayMode } from "src/models/list-filter/types";
-import { ExportDialog } from "src/components/Shared/ExportDialog";
+import { ExportDialog, DeleteEntityDialog } from "src/components/Shared";
import { PerformerCard } from "./PerformerCard";
import { PerformerListTable } from "./PerformerListTable";
@@ -76,12 +82,26 @@ export const PerformerList: React.FC = () => {
}
}
+ const renderDeleteDialog = (
+ selectedPerformers: SlimPerformerDataFragment[],
+ onClose: (confirmed: boolean) => void
+ ) => (
+
+ );
+
const listData = usePerformersList({
otherOperations,
renderContent,
addKeybinds,
selectable: true,
persistState: true,
+ renderDeleteDialog,
});
async function getRandom(
diff --git a/ui/v2.5/src/components/Scenes/DeleteScenesDialog.tsx b/ui/v2.5/src/components/Scenes/DeleteScenesDialog.tsx
index bbf8d269f..6356f5669 100644
--- a/ui/v2.5/src/components/Scenes/DeleteScenesDialog.tsx
+++ b/ui/v2.5/src/components/Scenes/DeleteScenesDialog.tsx
@@ -76,11 +76,13 @@ export const DeleteScenesDialog: React.FC
= (
setDeleteFile(!deleteFile)}
/>
setDeleteGenerated(!deleteGenerated)}
diff --git a/ui/v2.5/src/components/Scenes/SceneList.tsx b/ui/v2.5/src/components/Scenes/SceneList.tsx
index ce67bb3f3..4f2df0914 100644
--- a/ui/v2.5/src/components/Scenes/SceneList.tsx
+++ b/ui/v2.5/src/components/Scenes/SceneList.tsx
@@ -68,13 +68,18 @@ export const SceneList: React.FC = ({
};
};
+ const renderDeleteDialog = (
+ selectedScenes: SlimSceneDataFragment[],
+ onClose: (confirmed: boolean) => void
+ ) => ;
+
const listData = useScenesList({
zoomable: true,
selectable: true,
otherOperations,
renderContent,
renderEditDialog: renderEditScenesDialog,
- renderDeleteDialog: renderDeleteScenesDialog,
+ renderDeleteDialog,
filterHook,
addKeybinds,
persistState,
@@ -166,17 +171,6 @@ export const SceneList: React.FC = ({
);
}
- function renderDeleteScenesDialog(
- selectedScenes: SlimSceneDataFragment[],
- onClose: (confirmed: boolean) => void
- ) {
- return (
- <>
-
- >
- );
- }
-
function renderSceneCard(
scene: SlimSceneDataFragment,
selectedIds: Set,
diff --git a/ui/v2.5/src/components/Shared/DeleteEntityDialog.tsx b/ui/v2.5/src/components/Shared/DeleteEntityDialog.tsx
new file mode 100644
index 000000000..87bf6d3ab
--- /dev/null
+++ b/ui/v2.5/src/components/Shared/DeleteEntityDialog.tsx
@@ -0,0 +1,123 @@
+import React, { useState } from "react";
+import { defineMessages, FormattedMessage, useIntl } from "react-intl";
+import { FetchResult } from "@apollo/client";
+
+import { Modal } from "src/components/Shared";
+import { useToast } from "src/hooks";
+
+interface IDeletionEntity {
+ id: string;
+ name?: string | null;
+}
+
+type DestroyMutation = (input: {
+ ids: string[];
+}) => [() => Promise, {}];
+
+interface IDeleteEntityDialogProps {
+ selected: IDeletionEntity[];
+ onClose: (confirmed: boolean) => void;
+ singularEntity: string;
+ pluralEntity: string;
+ destroyMutation: DestroyMutation;
+}
+
+const messages = defineMessages({
+ deleteHeader: {
+ id: "delete-header",
+ defaultMessage:
+ "Delete {count, plural, =1 {{singularEntity}} other {{pluralEntity}}}",
+ },
+ deleteToast: {
+ id: "delete-toast",
+ defaultMessage:
+ "Deleted {count, plural, =1 {{singularEntity}} other {{pluralEntity}}}",
+ },
+ deleteMessage: {
+ id: "delete-message",
+ defaultMessage:
+ "Are you sure you want to delete {count, plural, =1 {this {singularEntity}} other {these {pluralEntity}}}?",
+ },
+ overflowMessage: {
+ id: "overflow-message",
+ defaultMessage:
+ "...and {count} other {count, plural, =1 {{ singularEntity}} other {{ pluralEntity }}}.",
+ },
+});
+
+const DeleteEntityDialog: React.FC = ({
+ selected,
+ onClose,
+ singularEntity,
+ pluralEntity,
+ destroyMutation,
+}) => {
+ const intl = useIntl();
+ const Toast = useToast();
+ const [deleteEntities] = destroyMutation({ ids: selected.map((p) => p.id) });
+ const count = selected.length;
+
+ // Network state
+ const [isDeleting, setIsDeleting] = useState(false);
+
+ async function onDelete() {
+ setIsDeleting(true);
+ try {
+ await deleteEntities();
+ Toast.success({
+ content: intl.formatMessage(messages.deleteToast, {
+ count,
+ singularEntity,
+ pluralEntity,
+ }),
+ });
+ } catch (e) {
+ Toast.error(e);
+ }
+ setIsDeleting(false);
+ onClose(true);
+ }
+
+ return (
+ onClose(false),
+ text: "Cancel",
+ variant: "secondary",
+ }}
+ isRunning={isDeleting}
+ >
+
+
+
+
+ {selected.slice(0, 10).map((s) => (
+ - {s.name}
+ ))}
+ {selected.length > 10 && (
+
+ )}
+
+
+ );
+};
+
+export default DeleteEntityDialog;
diff --git a/ui/v2.5/src/components/Shared/index.ts b/ui/v2.5/src/components/Shared/index.ts
index 6395cf0ae..fd5b04863 100644
--- a/ui/v2.5/src/components/Shared/index.ts
+++ b/ui/v2.5/src/components/Shared/index.ts
@@ -24,3 +24,5 @@ export { default as ErrorMessage } from "./ErrorMessage";
export { default as TruncatedText } from "./TruncatedText";
export { BasicCard } from "./BasicCard";
export { RatingStars } from "./RatingStars";
+export { ExportDialog } from "./ExportDialog";
+export { default as DeleteEntityDialog } from "./DeleteEntityDialog";
diff --git a/ui/v2.5/src/components/Studios/StudioList.tsx b/ui/v2.5/src/components/Studios/StudioList.tsx
index abae73fd5..6156046d2 100644
--- a/ui/v2.5/src/components/Studios/StudioList.tsx
+++ b/ui/v2.5/src/components/Studios/StudioList.tsx
@@ -2,13 +2,16 @@ import React, { useState } from "react";
import _ from "lodash";
import { useHistory } from "react-router-dom";
import Mousetrap from "mousetrap";
-import { FindStudiosQueryResult } from "src/core/generated-graphql";
+import {
+ FindStudiosQueryResult,
+ SlimStudioDataFragment,
+} from "src/core/generated-graphql";
import { useStudiosList } from "src/hooks";
import { showWhenSelected } from "src/hooks/ListHook";
import { ListFilterModel } from "src/models/list-filter/filter";
import { DisplayMode } from "src/models/list-filter/types";
-import { queryFindStudios } from "src/core/StashService";
-import { ExportDialog } from "../Shared/ExportDialog";
+import { queryFindStudios, useStudiosDestroy } from "src/core/StashService";
+import { ExportDialog, DeleteEntityDialog } from "src/components/Shared";
import { StudioCard } from "./StudioCard";
interface IStudioList {
@@ -109,6 +112,19 @@ export const StudioList: React.FC = ({
}
}
+ const renderDeleteDialog = (
+ selectedStudios: SlimStudioDataFragment[],
+ onClose: (confirmed: boolean) => void
+ ) => (
+
+ );
+
const listData = useStudiosList({
renderContent,
filterHook,
@@ -116,6 +132,7 @@ export const StudioList: React.FC = ({
otherOperations,
selectable: true,
persistState: !fromParent,
+ renderDeleteDialog,
});
function renderStudios(
diff --git a/ui/v2.5/src/components/Tags/TagList.tsx b/ui/v2.5/src/components/Tags/TagList.tsx
index bba42d3d2..bb03f3a2f 100644
--- a/ui/v2.5/src/components/Tags/TagList.tsx
+++ b/ui/v2.5/src/components/Tags/TagList.tsx
@@ -12,11 +12,12 @@ import {
queryFindTags,
mutateMetadataAutoTag,
useTagDestroy,
+ useTagsDestroy,
} from "src/core/StashService";
import { useToast } from "src/hooks";
import { FormattedNumber } from "react-intl";
import { NavUtils } from "src/utils";
-import { Icon, Modal } from "src/components/Shared";
+import { Icon, Modal, DeleteEntityDialog } from "src/components/Shared";
import { TagCard } from "./TagCard";
import { ExportDialog } from "../Shared/ExportDialog";
@@ -121,6 +122,19 @@ export const TagList: React.FC = ({ filterHook }) => {
}
}
+ const renderDeleteDialog = (
+ selectedTags: GQL.TagDataFragment[],
+ onClose: (confirmed: boolean) => void
+ ) => (
+
+ );
+
const listData = useTagsList({
renderContent,
filterHook,
@@ -130,6 +144,7 @@ export const TagList: React.FC = ({ filterHook }) => {
zoomable: true,
defaultZoomIndex: 0,
persistState: true,
+ renderDeleteDialog,
});
function getDeleteTagInput() {
diff --git a/ui/v2.5/src/core/StashService.ts b/ui/v2.5/src/core/StashService.ts
index 8d0203e94..581108095 100644
--- a/ui/v2.5/src/core/StashService.ts
+++ b/ui/v2.5/src/core/StashService.ts
@@ -309,6 +309,18 @@ export const usePerformerDestroy = () =>
update: deleteCache(performerMutationImpactedQueries),
});
+export const usePerformersDestroy = (
+ variables: GQL.PerformersDestroyMutationVariables
+) =>
+ GQL.usePerformersDestroyMutation({
+ variables,
+ refetchQueries: getQueryNames([
+ GQL.FindPerformersDocument,
+ GQL.AllPerformersForFilterDocument,
+ ]),
+ update: deleteCache(performerMutationImpactedQueries),
+ });
+
const sceneMutationImpactedQueries = [
GQL.FindPerformerDocument,
GQL.FindPerformersDocument,
@@ -562,6 +574,12 @@ export const useStudioDestroy = (input: GQL.StudioDestroyInput) =>
update: deleteCache(studioMutationImpactedQueries),
});
+export const useStudiosDestroy = (input: GQL.StudiosDestroyMutationVariables) =>
+ GQL.useStudiosDestroyMutation({
+ variables: input,
+ update: deleteCache(studioMutationImpactedQueries),
+ });
+
export const movieMutationImpactedQueries = [
GQL.FindSceneDocument,
GQL.FindScenesDocument,
@@ -589,6 +607,12 @@ export const useMovieDestroy = (input: GQL.MovieDestroyInput) =>
update: deleteCache(movieMutationImpactedQueries),
});
+export const useMoviesDestroy = (input: GQL.MoviesDestroyMutationVariables) =>
+ GQL.useMoviesDestroyMutation({
+ variables: input,
+ update: deleteCache(movieMutationImpactedQueries),
+ });
+
export const tagMutationImpactedQueries = [
GQL.FindSceneDocument,
GQL.FindScenesDocument,
@@ -622,6 +646,12 @@ export const useTagDestroy = (input: GQL.TagDestroyInput) =>
update: deleteCache(tagMutationImpactedQueries),
});
+export const useTagsDestroy = (input: GQL.TagsDestroyMutationVariables) =>
+ GQL.useTagsDestroyMutation({
+ variables: input,
+ update: deleteCache(tagMutationImpactedQueries),
+ });
+
export const useConfigureGeneral = (input: GQL.ConfigGeneralInput) =>
GQL.useConfigureGeneralMutation({
variables: { input },