From f0c6e789cd4f0a6baec2dfa15a0c85b49a25bf2a Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Sat, 4 Oct 2025 21:48:44 +0200 Subject: [PATCH] Add backup flags to backup import --- public/locales/en.json | 2 +- src/features/backup/Backup.constants.ts | 3 ++- src/features/backup/Backup.types.ts | 4 ++-- .../component/BackupFlagInclusionDialog.tsx | 12 ++++++++---- src/features/backup/screens/Backup.tsx | 14 ++++++++++---- src/lib/graphql/generated/graphql.ts | 19 +++++++++++++------ src/lib/graphql/mutations/BackupMutation.ts | 4 ++-- src/lib/requests/RequestManager.ts | 9 +++------ 8 files changed, 41 insertions(+), 26 deletions(-) diff --git a/public/locales/en.json b/public/locales/en.json index f531064d..9289d1bf 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -1260,7 +1260,7 @@ "settings": "Settings" }, "history": "History", - "manga": "Manga", + "manga": "Library entries", "server_settings": "Server settings", "tracking": "Tracking" }, diff --git a/src/features/backup/Backup.constants.ts b/src/features/backup/Backup.constants.ts index 95e22551..d841e50b 100644 --- a/src/features/backup/Backup.constants.ts +++ b/src/features/backup/Backup.constants.ts @@ -10,6 +10,7 @@ import { BackupFlag, BackupFlagGroup } from '@/features/backup/Backup.types.ts'; import { TranslationKey } from '@/base/Base.types.ts'; export const BACKUP_FLAGS_TO_TRANSLATION: Record = { + includeManga: 'settings.backup.flag.manga', includeCategories: 'settings.backup.flag.categories', includeChapters: 'settings.backup.flag.chapters', includeClientData: 'settings.backup.flag.client_data', @@ -26,6 +27,6 @@ export const BACKUP_FLAG_GROUP_TO_TRANSLATION: Record = { - [BackupFlagGroup.LIBRARY]: ['includeChapters', 'includeTracking', 'includeHistory', 'includeCategories'], + [BackupFlagGroup.LIBRARY]: ['includeManga', 'includeChapters', 'includeTracking', 'includeHistory', 'includeCategories'], [BackupFlagGroup.SETTINGS]: ['includeClientData', 'includeServerSettings'], }; diff --git a/src/features/backup/Backup.types.ts b/src/features/backup/Backup.types.ts index 6672d6f1..a3209fb1 100644 --- a/src/features/backup/Backup.types.ts +++ b/src/features/backup/Backup.types.ts @@ -6,13 +6,13 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { CreateBackupInput } from '@/lib/graphql/generated/graphql.ts'; +import { PartialBackupFlagsInput } from '@/lib/graphql/generated/graphql.ts'; export enum BackupFlagGroup { LIBRARY = 'library', SETTINGS = 'settings', } -export type BackupFlag = keyof Omit; +export type BackupFlag = keyof PartialBackupFlagsInput; export type BackupFlagInclusionState = Record; diff --git a/src/features/backup/component/BackupFlagInclusionDialog.tsx b/src/features/backup/component/BackupFlagInclusionDialog.tsx index 992870c8..7055c444 100644 --- a/src/features/backup/component/BackupFlagInclusionDialog.tsx +++ b/src/features/backup/component/BackupFlagInclusionDialog.tsx @@ -26,7 +26,11 @@ import { } from '@/features/backup/Backup.constants.ts'; import { BackupFlagGroup, BackupFlagInclusionState } from '@/features/backup/Backup.types.ts'; -export const BackupFlagInclusionDialog = ({ onCancel, onConfirm }: DialogProps) => { +export const BackupFlagInclusionDialog = ({ + onCancel, + onConfirm, + title, +}: DialogProps & { title: string }) => { const { t } = useTranslation(); const [includeStateByFlag, setIncludeStateByFlag] = useState( @@ -34,12 +38,12 @@ export const BackupFlagInclusionDialog = ({ onCancel, onConfirm }: DialogProps - {t('settings.backup.action.create.label.title')} + + {title} {Object.entries(BACKUP_FLAGS_BY_GROUP).map(([group, flags]) => ( - + {t(BACKUP_FLAG_GROUP_TO_TRANSLATION[group as BackupFlagGroup])} {flags.map((flag) => ( { - const backupFlagInclusionState = await GlobalDialogManager.show(BackupFlagInclusionDialog); + const flags = await GlobalDialogManager.show(BackupFlagInclusionDialog, { + title: t('settings.backup.action.create.label.title'), + }); makeToast(t('settings.backup.action.create.label.in_progress'), 'info'); try { - const backupFileResponse = await requestManager.createBackupFile(backupFlagInclusionState).response; + const backupFileResponse = await requestManager.createBackupFile({ flags }).response; const backupFileUrl = backupFileResponse.data?.createBackup.url; if (!backupFileUrl) { @@ -171,11 +173,15 @@ export function Backup() { return false; }; - const restoreBackup = async (file: File) => { + const restoreBackup = async (backup: File) => { + const flags = await GlobalDialogManager.show(BackupFlagInclusionDialog, { + title: t('settings.backup.action.restore.label.title'), + }); + try { makeToast(t('settings.backup.action.restore.label.in_progress'), 'info'); - const response = await requestManager.restoreBackupFile(file).response; + const response = await requestManager.restoreBackupFile({ backup, flags }).response; backupRestoreId = response.data?.restoreBackup.id; setTriggerReRender(Date.now()); } catch (e) { diff --git a/src/lib/graphql/generated/graphql.ts b/src/lib/graphql/generated/graphql.ts index 264e44b5..c22700d4 100644 --- a/src/lib/graphql/generated/graphql.ts +++ b/src/lib/graphql/generated/graphql.ts @@ -336,12 +336,7 @@ export type ConnectKoSyncAccountInput = { export type CreateBackupInput = { clientMutationId?: InputMaybe; - includeCategories?: InputMaybe; - includeChapters?: InputMaybe; - includeClientData?: InputMaybe; - includeHistory?: InputMaybe; - includeServerSettings?: InputMaybe; - includeTracking?: InputMaybe; + flags?: InputMaybe; }; export type CreateBackupPayload = { @@ -1646,6 +1641,16 @@ export type PageInfo = { startCursor?: Maybe; }; +export type PartialBackupFlagsInput = { + includeCategories?: InputMaybe; + includeChapters?: InputMaybe; + includeClientData?: InputMaybe; + includeHistory?: InputMaybe; + includeManga?: InputMaybe; + includeServerSettings?: InputMaybe; + includeTracking?: InputMaybe; +}; + export type PartialSettingsType = Settings & { __typename?: 'PartialSettingsType'; authMode?: Maybe; @@ -2066,6 +2071,7 @@ export type ResetSettingsPayload = { export type RestoreBackupInput = { backup: Scalars['Upload']['input']; clientMutationId?: InputMaybe; + flags?: InputMaybe; }; export type RestoreBackupPayload = { @@ -3266,6 +3272,7 @@ export type CreateBackupMutation = { __typename?: 'Mutation', createBackup: { __ export type RestoreBackupMutationVariables = Exact<{ backup: Scalars['Upload']['input']; + flags?: InputMaybe; }>; diff --git a/src/lib/graphql/mutations/BackupMutation.ts b/src/lib/graphql/mutations/BackupMutation.ts index b8174617..83027826 100644 --- a/src/lib/graphql/mutations/BackupMutation.ts +++ b/src/lib/graphql/mutations/BackupMutation.ts @@ -17,8 +17,8 @@ export const CREATE_BACKUP = gql` `; export const RESTORE_BACKUP = gql` - mutation RESTORE_BACKUP($backup: Upload!) { - restoreBackup(input: { backup: $backup }) { + mutation RESTORE_BACKUP($backup: Upload!, $flags: PartialBackupFlagsInput) { + restoreBackup(input: { backup: $backup, flags: $flags }) { id status { mangaProgress diff --git a/src/lib/requests/RequestManager.ts b/src/lib/requests/RequestManager.ts index 1a14994b..e86d788a 100644 --- a/src/lib/requests/RequestManager.ts +++ b/src/lib/requests/RequestManager.ts @@ -219,6 +219,7 @@ import { CreateBackupInput, CreateBackupMutation, CreateBackupMutationVariables, + RestoreBackupInput, } from '@/lib/graphql/generated/graphql.ts'; import { GET_GLOBAL_METADATAS } from '@/lib/graphql/queries/GlobalMetadataQuery.ts'; import { DELETE_GLOBAL_METADATA, SET_GLOBAL_METADATA } from '@/lib/graphql/mutations/GlobalMetadataMutation.ts'; @@ -2720,13 +2721,13 @@ export class RequestManager { } public restoreBackupFile( - file: File, + input: RestoreBackupInput, options?: MutationOptions, ): AbortableApolloMutationResponse { return this.doRequest( GQLMethod.MUTATION, RESTORE_BACKUP, - { backup: file }, + input, { ...options, }, @@ -2747,10 +2748,6 @@ export class RequestManager { return this.doRequest(GQLMethod.USE_QUERY, GET_RESTORE_STATUS, { id }, options); } - public getExportBackupUrl(): string { - return this.getValidUrlFor('backup/export/file'); - } - public startDownloads( options?: MutationOptions, ): AbortableApolloMutationResponse {