diff --git a/assets/translations/en.json b/assets/translations/en.json index a51f0da9c8..d83fcd1767 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -189,7 +189,9 @@ "euro": "Euro", "data_migration_title": "Data migration", "data_migration_notice": "During migration all services will be turned off.", - "start_migration_button": "Start migration" + "start_migration_button": "Start migration", + "migration_process": "Migrating...", + "migration_done": "Finish" } }, "not_ready_card": { diff --git a/assets/translations/ru.json b/assets/translations/ru.json index 906e9471ac..aa755a7c3c 100644 --- a/assets/translations/ru.json +++ b/assets/translations/ru.json @@ -189,7 +189,9 @@ "euro": "Евро", "data_migration_title": "Миграция данных", "data_migration_notice": "На время миграции данных все сервисы будут выключены.", - "start_migration_button": "Начать миграцию" + "start_migration_button": "Начать миграцию", + "migration_process": "Мигрируем...", + "migration_done": "Завершить" } }, "not_ready_card": { diff --git a/lib/logic/api_maps/graphql_maps/server_api/volume_api.dart b/lib/logic/api_maps/graphql_maps/server_api/volume_api.dart index ada66d58cb..06d6e5bc97 100644 --- a/lib/logic/api_maps/graphql_maps/server_api/volume_api.dart +++ b/lib/logic/api_maps/graphql_maps/server_api/volume_api.dart @@ -56,4 +56,23 @@ mixin VolumeApi on ApiMap { print(e); } } + + Future migrateToBinds(final Map serviceToDisk) async { + try { + final GraphQLClient client = await getClient(); + final input = Input$MigrateToBindsInput( + bitwardenBlockDevice: serviceToDisk['bitwarden']!, + emailBlockDevice: serviceToDisk['mailserver']!, + giteaBlockDevice: serviceToDisk['gitea']!, + nextcloudBlockDevice: serviceToDisk['nextcloud']!, + pleromaBlockDevice: serviceToDisk['pleroma']!, + ); + final variables = Variables$Mutation$MigrateToBinds(input: input); + final migrateMutation = + Options$Mutation$MigrateToBinds(variables: variables); + await client.mutate$MigrateToBinds(migrateMutation); + } catch (e) { + print(e); + } + } } diff --git a/lib/ui/pages/server_storage/migration_process_page.dart b/lib/ui/pages/server_storage/migration_process_page.dart new file mode 100644 index 0000000000..12dd8feaeb --- /dev/null +++ b/lib/ui/pages/server_storage/migration_process_page.dart @@ -0,0 +1,67 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:selfprivacy/logic/cubit/server_jobs/server_jobs_cubit.dart'; +import 'package:selfprivacy/logic/models/json/server_job.dart'; +import 'package:selfprivacy/ui/components/brand_button/filled_button.dart'; +import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.dart'; +import 'package:selfprivacy/ui/components/brand_linear_indicator/brand_linear_indicator.dart'; +import 'package:selfprivacy/ui/pages/root_route.dart'; +import 'package:selfprivacy/utils/route_transitions/basic.dart'; + +class MigrationProcessPage extends StatefulWidget { + const MigrationProcessPage({ + required this.jobUid, + final super.key, + }); + + final String jobUid; + + @override + State createState() => _MigrationProcessPageState(); +} + +class _MigrationProcessPageState extends State { + @override + void initState() { + super.initState(); + } + + @override + Widget build(final BuildContext context) { + final serverJobsState = context.watch().state; + final ServerJob job = serverJobsState.serverJobList.firstWhere( + (final ServerJob job) => job.uid == widget.jobUid, + ); + final double value = job.progress == null ? 0.0 : job.progress! / 100; + return BrandHeroScreen( + hasBackButton: false, + heroTitle: 'providers.storage.migration_process'.tr(), + heroSubtitle: job.statusText, + children: [ + BrandLinearIndicator( + value: value, + color: Theme.of(context).colorScheme.primary, + backgroundColor: Theme.of(context).colorScheme.surfaceVariant, + height: 14.0, + ), + const SizedBox(height: 16), + if (job.finishedAt != null) + Text( + job.result!, + style: Theme.of(context).textTheme.titleMedium, + ), + if (job.finishedAt != null) const SizedBox(height: 16), + if (job.finishedAt != null) + FilledButton( + title: 'providers.storage.migration_done'.tr(), + onPressed: () { + Navigator.of(context).pushAndRemoveUntil( + materialRoute(const RootPage()), + (final predicate) => false, + ); + }, + ) + ], + ); + } +}