mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: add check workspace health button in settings page (#5631)
This commit is contained in:
parent
b24fbc6b60
commit
a1dec0f269
@ -109,7 +109,7 @@ class UserBackendService implements IUserBackendService {
|
|||||||
return UserEventOpenWorkspace(payload).send();
|
return UserEventOpenWorkspace(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<FlowyResult<WorkspacePB, FlowyError>> getCurrentWorkspace() {
|
static Future<FlowyResult<WorkspacePB, FlowyError>> getCurrentWorkspace() {
|
||||||
return FolderEventReadCurrentWorkspace().send().then((result) {
|
return FolderEventReadCurrentWorkspace().send().then((result) {
|
||||||
return result.fold(
|
return result.fold(
|
||||||
(workspace) => FlowyResult.success(workspace),
|
(workspace) => FlowyResult.success(workspace),
|
||||||
|
@ -22,7 +22,7 @@ class WorkspaceSettingsBloc
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final currentWorkspace =
|
final currentWorkspace =
|
||||||
await _userService!.getCurrentWorkspace().getOrThrow();
|
await UserBackendService.getCurrentWorkspace().getOrThrow();
|
||||||
|
|
||||||
final workspaces =
|
final workspaces =
|
||||||
await _userService!.getWorkspaces().getOrThrow();
|
await _userService!.getWorkspaces().getOrThrow();
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import 'package:flutter/foundation.dart';
|
|
||||||
|
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/shared/feature_flags.dart';
|
import 'package:appflowy/shared/feature_flags.dart';
|
||||||
import 'package:appflowy/user/application/user_listener.dart';
|
import 'package:appflowy/user/application/user_listener.dart';
|
||||||
@ -12,6 +10,7 @@ import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
|||||||
import 'package:appflowy_result/appflowy_result.dart';
|
import 'package:appflowy_result/appflowy_result.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:protobuf/protobuf.dart';
|
import 'package:protobuf/protobuf.dart';
|
||||||
@ -406,7 +405,7 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
|
|||||||
)> _fetchWorkspaces() async {
|
)> _fetchWorkspaces() async {
|
||||||
try {
|
try {
|
||||||
final currentWorkspace =
|
final currentWorkspace =
|
||||||
await _userService.getCurrentWorkspace().getOrThrow();
|
await UserBackendService.getCurrentWorkspace().getOrThrow();
|
||||||
final workspaces = await _userService.getWorkspaces().getOrThrow();
|
final workspaces = await _userService.getWorkspaces().getOrThrow();
|
||||||
if (workspaces.isEmpty) {
|
if (workspaces.isEmpty) {
|
||||||
workspaces.add(convertWorkspacePBToUserWorkspace(currentWorkspace));
|
workspaces.add(convertWorkspacePBToUserWorkspace(currentWorkspace));
|
||||||
|
@ -0,0 +1,115 @@
|
|||||||
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
|
import 'package:appflowy/user/application/user_service.dart';
|
||||||
|
import 'package:appflowy/workspace/application/view/view_ext.dart';
|
||||||
|
import 'package:appflowy/workspace/application/view/view_service.dart';
|
||||||
|
import 'package:appflowy/workspace/presentation/settings/shared/settings_category.dart';
|
||||||
|
import 'package:appflowy/workspace/presentation/settings/shared/single_setting_action.dart';
|
||||||
|
import 'package:appflowy_backend/log.dart';
|
||||||
|
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||||
|
import 'package:appflowy_result/appflowy_result.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class FixDataWidget extends StatelessWidget {
|
||||||
|
const FixDataWidget({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SettingsCategory(
|
||||||
|
title: LocaleKeys.settings_manageDataPage_data_fixYourData.tr(),
|
||||||
|
children: [
|
||||||
|
SingleSettingAction(
|
||||||
|
labelMaxLines: 4,
|
||||||
|
label: LocaleKeys.settings_manageDataPage_data_fixYourDataDescription
|
||||||
|
.tr(),
|
||||||
|
buttonLabel: LocaleKeys.settings_manageDataPage_data_fixButton.tr(),
|
||||||
|
onPressed: () {
|
||||||
|
FixDataManager.checkWorkspaceHealth(dryRun: true);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FixDataManager {
|
||||||
|
static Future<void> checkWorkspaceHealth({
|
||||||
|
required bool dryRun,
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
final currentWorkspace =
|
||||||
|
await UserBackendService.getCurrentWorkspace().getOrThrow();
|
||||||
|
// get all the views in the workspace
|
||||||
|
final result = await ViewBackendService.getAllViews().getOrThrow();
|
||||||
|
final allViews = result.items;
|
||||||
|
|
||||||
|
// dump all the views in the workspace
|
||||||
|
dumpViews('all views', allViews);
|
||||||
|
|
||||||
|
// get the workspace
|
||||||
|
final workspaces = allViews.where(
|
||||||
|
(e) => e.parentViewId == '' && e.id == currentWorkspace.id,
|
||||||
|
);
|
||||||
|
dumpViews('workspaces', workspaces.toList());
|
||||||
|
|
||||||
|
if (workspaces.length != 1) {
|
||||||
|
Log.error('Failed to fix workspace: workspace not found');
|
||||||
|
// there should be only one workspace
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final workspace = workspaces.first;
|
||||||
|
|
||||||
|
// check the health of the spaces
|
||||||
|
await checkSpaceHealth(workspace: workspace, allViews: allViews);
|
||||||
|
|
||||||
|
// add other checks here
|
||||||
|
// ...
|
||||||
|
} catch (e) {
|
||||||
|
Log.error('Failed to fix space relation: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> checkSpaceHealth({
|
||||||
|
required ViewPB workspace,
|
||||||
|
required List<ViewPB> allViews,
|
||||||
|
bool dryRun = true,
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
final workspaceChildViews =
|
||||||
|
await ViewBackendService.getChildViews(viewId: workspace.id)
|
||||||
|
.getOrThrow();
|
||||||
|
final workspaceChildViewIds =
|
||||||
|
workspaceChildViews.map((e) => e.id).toSet();
|
||||||
|
final spaces = allViews.where((e) => e.isSpace).toList();
|
||||||
|
|
||||||
|
//
|
||||||
|
for (final space in spaces) {
|
||||||
|
// the space is the top level view, so its parent view id should be the workspace id
|
||||||
|
// and the workspace should have the space in its child views
|
||||||
|
if (space.parentViewId != workspace.id ||
|
||||||
|
!workspaceChildViewIds.contains(space.id)) {
|
||||||
|
Log.info('found an issue: space is not in the workspace: $space');
|
||||||
|
if (!dryRun) {
|
||||||
|
// move the space to the workspace if it is not in the workspace
|
||||||
|
await ViewBackendService.moveViewV2(
|
||||||
|
viewId: space.id,
|
||||||
|
newParentId: workspace.id,
|
||||||
|
prevViewId: null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
workspaceChildViewIds.add(space.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
Log.error('Failed to check space health: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dumpViews(String prefix, List<ViewPB> views) {
|
||||||
|
for (int i = 0; i < views.length; i++) {
|
||||||
|
final view = views[i];
|
||||||
|
Log.info('$prefix $i: $view)');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:appflowy/core/helpers/url_launcher.dart';
|
import 'package:appflowy/core/helpers/url_launcher.dart';
|
||||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
@ -13,6 +10,7 @@ import 'package:appflowy/util/theme_extension.dart';
|
|||||||
import 'package:appflowy/workspace/application/settings/setting_file_importer_bloc.dart';
|
import 'package:appflowy/workspace/application/settings/setting_file_importer_bloc.dart';
|
||||||
import 'package:appflowy/workspace/application/settings/settings_location_cubit.dart';
|
import 'package:appflowy/workspace/application/settings/settings_location_cubit.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/toast.dart';
|
import 'package:appflowy/workspace/presentation/home/toast.dart';
|
||||||
|
import 'package:appflowy/workspace/presentation/settings/pages/fix_data_widget.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/shared/setting_action.dart';
|
import 'package:appflowy/workspace/presentation/settings/shared/setting_action.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/shared/settings_alert_dialog.dart';
|
import 'package:appflowy/workspace/presentation/settings/shared/settings_alert_dialog.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/shared/settings_body.dart';
|
import 'package:appflowy/workspace/presentation/settings/shared/settings_body.dart';
|
||||||
@ -29,6 +27,8 @@ import 'package:flowy_infra_ui/style_widget/button.dart';
|
|||||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:fluttertoast/fluttertoast.dart';
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
|
|
||||||
@ -110,7 +110,10 @@ class SettingsManageDataView extends StatelessWidget {
|
|||||||
if (kDebugMode) ...[
|
if (kDebugMode) ...[
|
||||||
SettingsCategory(
|
SettingsCategory(
|
||||||
title: LocaleKeys.settings_files_exportData.tr(),
|
title: LocaleKeys.settings_files_exportData.tr(),
|
||||||
children: const [SettingsExportFileWidget()],
|
children: const [
|
||||||
|
SettingsExportFileWidget(),
|
||||||
|
FixDataWidget(),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
SettingsCategory(
|
SettingsCategory(
|
||||||
|
@ -59,7 +59,7 @@ class AppFlowyUnitTest {
|
|||||||
|
|
||||||
WorkspacePB get currentWorkspace => workspace;
|
WorkspacePB get currentWorkspace => workspace;
|
||||||
Future<void> _loadWorkspace() async {
|
Future<void> _loadWorkspace() async {
|
||||||
final result = await userService.getCurrentWorkspace();
|
final result = await UserBackendService.getCurrentWorkspace();
|
||||||
result.fold(
|
result.fold(
|
||||||
(value) => workspace = value,
|
(value) => workspace = value,
|
||||||
(error) {
|
(error) {
|
||||||
|
@ -491,6 +491,11 @@
|
|||||||
"description": "Clearing the cache will cause images and fonts to be re-downloaded on load. This action will not remove or modify your data.",
|
"description": "Clearing the cache will cause images and fonts to be re-downloaded on load. This action will not remove or modify your data.",
|
||||||
"successHint": "Cache cleared!"
|
"successHint": "Cache cleared!"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"fixYourData": "Fix your data",
|
||||||
|
"fixButton": "Fix",
|
||||||
|
"fixYourDataDescription": "If you're experiencing issues with your data, you can try to fix it here."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"shortcutsPage": {
|
"shortcutsPage": {
|
||||||
|
Loading…
Reference in New Issue
Block a user