Browse Source

Merge branch 'main' into #692

Nathan.fooo 2 years ago
parent
commit
2853831442
100 changed files with 582 additions and 324 deletions
  1. 1 1
      .github/workflows/ci.yaml
  2. 1 1
      .github/workflows/dart_lint.yml
  3. 1 1
      .github/workflows/dart_test.yml
  4. 2 2
      .github/workflows/release.yml
  5. 1 1
      .github/workflows/rust_lint.yml
  6. 3 2
      frontend/app_flowy/assets/translations/en.json
  7. 3 2
      frontend/app_flowy/lib/plugins/blank/blank.dart
  8. 0 0
      frontend/app_flowy/lib/plugins/board/application/board_bloc.dart
  9. 4 4
      frontend/app_flowy/lib/plugins/board/board.dart
  10. 0 0
      frontend/app_flowy/lib/plugins/board/presentation/board_page.dart
  11. 14 8
      frontend/app_flowy/lib/plugins/doc/application/doc_bloc.dart
  12. 0 0
      frontend/app_flowy/lib/plugins/doc/application/doc_service.dart
  13. 0 0
      frontend/app_flowy/lib/plugins/doc/application/prelude.dart
  14. 7 4
      frontend/app_flowy/lib/plugins/doc/application/share_bloc.dart
  15. 0 0
      frontend/app_flowy/lib/plugins/doc/application/share_service.dart
  16. 24 18
      frontend/app_flowy/lib/plugins/doc/document.dart
  17. 14 8
      frontend/app_flowy/lib/plugins/doc/document_page.dart
  18. 0 0
      frontend/app_flowy/lib/plugins/doc/presentation/banner.dart
  19. 0 0
      frontend/app_flowy/lib/plugins/doc/presentation/style_widgets.dart
  20. 0 0
      frontend/app_flowy/lib/plugins/doc/presentation/toolbar/check_button.dart
  21. 0 0
      frontend/app_flowy/lib/plugins/doc/presentation/toolbar/color_picker.dart
  22. 0 0
      frontend/app_flowy/lib/plugins/doc/presentation/toolbar/header_button.dart
  23. 0 0
      frontend/app_flowy/lib/plugins/doc/presentation/toolbar/history_button.dart
  24. 0 0
      frontend/app_flowy/lib/plugins/doc/presentation/toolbar/image_button.dart
  25. 0 0
      frontend/app_flowy/lib/plugins/doc/presentation/toolbar/link_button.dart
  26. 0 0
      frontend/app_flowy/lib/plugins/doc/presentation/toolbar/toggle_button.dart
  27. 0 0
      frontend/app_flowy/lib/plugins/doc/presentation/toolbar/tool_bar.dart
  28. 0 0
      frontend/app_flowy/lib/plugins/doc/presentation/toolbar/toolbar_icon_button.dart
  29. 11 8
      frontend/app_flowy/lib/plugins/doc/styles.dart
  30. 2 2
      frontend/app_flowy/lib/plugins/grid/application/block/block_cache.dart
  31. 0 0
      frontend/app_flowy/lib/plugins/grid/application/block/block_listener.dart
  32. 0 0
      frontend/app_flowy/lib/plugins/grid/application/cell/cell_listener.dart
  33. 0 0
      frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/cell_cache.dart
  34. 0 0
      frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/cell_data_loader.dart
  35. 0 0
      frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/cell_data_persistence.dart
  36. 0 0
      frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/cell_field_notifier.dart
  37. 3 3
      frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/cell_service.dart
  38. 24 11
      frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/context_builder.dart
  39. 0 0
      frontend/app_flowy/lib/plugins/grid/application/cell/checkbox_cell_bloc.dart
  40. 27 13
      frontend/app_flowy/lib/plugins/grid/application/cell/date_cal_bloc.dart
  41. 0 0
      frontend/app_flowy/lib/plugins/grid/application/cell/date_cell_bloc.dart
  42. 0 0
      frontend/app_flowy/lib/plugins/grid/application/cell/number_cell_bloc.dart
  43. 5 3
      frontend/app_flowy/lib/plugins/grid/application/cell/select_option_cell_bloc.dart
  44. 27 14
      frontend/app_flowy/lib/plugins/grid/application/cell/select_option_editor_bloc.dart
  45. 4 2
      frontend/app_flowy/lib/plugins/grid/application/cell/select_option_service.dart
  46. 0 0
      frontend/app_flowy/lib/plugins/grid/application/cell/text_cell_bloc.dart
  47. 0 0
      frontend/app_flowy/lib/plugins/grid/application/cell/url_cell_bloc.dart
  48. 0 0
      frontend/app_flowy/lib/plugins/grid/application/cell/url_cell_editor_bloc.dart
  49. 0 0
      frontend/app_flowy/lib/plugins/grid/application/field/field_action_sheet_bloc.dart
  50. 10 6
      frontend/app_flowy/lib/plugins/grid/application/field/field_cell_bloc.dart
  51. 0 0
      frontend/app_flowy/lib/plugins/grid/application/field/field_editor_bloc.dart
  52. 0 0
      frontend/app_flowy/lib/plugins/grid/application/field/field_listener.dart
  53. 0 0
      frontend/app_flowy/lib/plugins/grid/application/field/field_service.dart
  54. 0 0
      frontend/app_flowy/lib/plugins/grid/application/field/field_type_option_edit_bloc.dart
  55. 0 0
      frontend/app_flowy/lib/plugins/grid/application/field/grid_header_listener.dart
  56. 0 0
      frontend/app_flowy/lib/plugins/grid/application/field/grid_listener.dart
  57. 17 9
      frontend/app_flowy/lib/plugins/grid/application/field/type_option/date_bloc.dart
  58. 0 0
      frontend/app_flowy/lib/plugins/grid/application/field/type_option/edit_select_option_bloc.dart
  59. 9 5
      frontend/app_flowy/lib/plugins/grid/application/field/type_option/multi_select_type_option.dart
  60. 9 5
      frontend/app_flowy/lib/plugins/grid/application/field/type_option/number_bloc.dart
  61. 0 0
      frontend/app_flowy/lib/plugins/grid/application/field/type_option/number_format_bloc.dart
  62. 0 0
      frontend/app_flowy/lib/plugins/grid/application/field/type_option/select_option_type_option_bloc.dart
  63. 9 5
      frontend/app_flowy/lib/plugins/grid/application/field/type_option/single_select_type_option.dart
  64. 4 2
      frontend/app_flowy/lib/plugins/grid/application/field/type_option/type_option_service.dart
  65. 0 0
      frontend/app_flowy/lib/plugins/grid/application/grid_bloc.dart
  66. 9 5
      frontend/app_flowy/lib/plugins/grid/application/grid_header_bloc.dart
  67. 17 11
      frontend/app_flowy/lib/plugins/grid/application/grid_service.dart
  68. 0 0
      frontend/app_flowy/lib/plugins/grid/application/prelude.dart
  69. 5 3
      frontend/app_flowy/lib/plugins/grid/application/row/row_action_sheet_bloc.dart
  70. 12 6
      frontend/app_flowy/lib/plugins/grid/application/row/row_bloc.dart
  71. 5 3
      frontend/app_flowy/lib/plugins/grid/application/row/row_detail_bloc.dart
  72. 0 0
      frontend/app_flowy/lib/plugins/grid/application/row/row_listener.dart
  73. 21 10
      frontend/app_flowy/lib/plugins/grid/application/row/row_service.dart
  74. 16 9
      frontend/app_flowy/lib/plugins/grid/application/setting/property_bloc.dart
  75. 0 0
      frontend/app_flowy/lib/plugins/grid/application/setting/setting_bloc.dart
  76. 3 3
      frontend/app_flowy/lib/plugins/grid/grid.dart
  77. 0 0
      frontend/app_flowy/lib/plugins/grid/presentation/controller/flowy_table_selection.dart
  78. 0 0
      frontend/app_flowy/lib/plugins/grid/presentation/controller/grid_scroll.dart
  79. 26 17
      frontend/app_flowy/lib/plugins/grid/presentation/grid_page.dart
  80. 0 0
      frontend/app_flowy/lib/plugins/grid/presentation/layout/layout.dart
  81. 0 0
      frontend/app_flowy/lib/plugins/grid/presentation/layout/sizes.dart
  82. 21 8
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/cell_accessory.dart
  83. 34 13
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/cell_builder.dart
  84. 21 11
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/cell_cotainer.dart
  85. 0 0
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/cell_decoration.dart
  86. 0 0
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/cell_shortcuts.dart
  87. 9 4
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/checkbox_cell.dart
  88. 8 4
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_cell.dart
  89. 28 13
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart
  90. 9 5
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/number_cell.dart
  91. 1 0
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/prelude.dart
  92. 0 0
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart
  93. 17 9
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_cell.dart
  94. 36 17
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart
  95. 0 0
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/text_field.dart
  96. 3 2
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/text_cell.dart
  97. 7 4
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/url_cell/cell_editor.dart
  98. 37 26
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/url_cell/url_cell.dart
  99. 0 0
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/common/text_field.dart
  100. 1 1
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/footer/grid_footer.dart

+ 1 - 1
.github/workflows/ci.yaml

@@ -34,7 +34,7 @@ jobs:
         with:
           channel: 'stable'
           cache: true
-          flutter-version: '3.0.0'
+          flutter-version: '3.0.5'
 
       - name: Cache Cargo
         uses: actions/cache@v2

+ 1 - 1
.github/workflows/dart_lint.yml

@@ -23,7 +23,7 @@ jobs:
         uses: actions/checkout@v2
       - uses: subosito/flutter-action@v1
         with:
-          flutter-version: '3.0.0'
+          flutter-version: '3.0.5'
           channel: "stable"
       - uses: actions-rs/toolchain@v1
         with:

+ 1 - 1
.github/workflows/dart_test.yml

@@ -26,7 +26,7 @@ jobs:
       - uses: subosito/flutter-action@v2
         with:
           channel: 'stable'
-          flutter-version: '3.0.0'
+          flutter-version: '3.0.5'
           cache: true
 
       - name: Cache Cargo

+ 2 - 2
.github/workflows/release.yml

@@ -50,7 +50,7 @@ jobs:
         uses: subosito/flutter-action@v2
         with:
           channel: 'stable'
-          flutter-version: '3.0.0'
+          flutter-version: '3.0.5'
 
       - name: Pre build
         working-directory: frontend
@@ -99,7 +99,7 @@ jobs:
         uses: subosito/flutter-action@v2
         with:
           channel: 'stable'
-          flutter-version: '3.0.0'
+          flutter-version: '3.0.5'
 
       - name: Pre build
         working-directory: frontend

+ 1 - 1
.github/workflows/rust_lint.yml

@@ -22,7 +22,7 @@ jobs:
           override: true
       - uses: subosito/flutter-action@v1
         with:
-          flutter-version: '3.0.0'
+          flutter-version: '3.0.5'
           channel: "stable"
 
       - name: Rust Deps

+ 3 - 2
frontend/app_flowy/assets/translations/en.json

@@ -94,7 +94,8 @@
   },
   "tooltip": {
     "lightMode": "Switch to Light mode",
-    "darkMode": "Switch to Dark mode"
+    "darkMode": "Switch to Dark mode",
+    "openAsPage": "Open as a Page"
   },
   "notifications": {
     "export": {
@@ -215,4 +216,4 @@
       "timeHintTextInTwentyFourHour": "12:00"
     }
   }
-}
+}

+ 3 - 2
frontend/app_flowy/lib/workspace/presentation/plugins/blank/blank.dart → frontend/app_flowy/lib/plugins/blank/blank.dart

@@ -4,7 +4,7 @@ import 'package:flowy_infra_ui/style_widget/text.dart';
 import 'package:flutter/material.dart';
 
 import 'package:app_flowy/generated/locale_keys.g.dart';
-import 'package:app_flowy/plugin/plugin.dart';
+import 'package:app_flowy/startup/plugin/plugin.dart';
 
 class BlankPluginBuilder extends PluginBuilder {
   @override
@@ -42,7 +42,8 @@ class BlankPagePlugin extends Plugin {
 
 class BlankPagePluginDisplay extends PluginDisplay with NavigationItem {
   @override
-  Widget get leftBarItem => FlowyText.medium(LocaleKeys.blankPageTitle.tr(), fontSize: 12);
+  Widget get leftBarItem =>
+      FlowyText.medium(LocaleKeys.blankPageTitle.tr(), fontSize: 12);
 
   @override
   Widget buildWidget() => const BlankPage();

+ 0 - 0
frontend/app_flowy/lib/workspace/application/board/board_bloc.dart → frontend/app_flowy/lib/plugins/board/application/board_bloc.dart


+ 4 - 4
frontend/app_flowy/lib/workspace/presentation/plugins/board/board.dart → frontend/app_flowy/lib/plugins/board/board.dart

@@ -1,10 +1,10 @@
 import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
-import 'package:app_flowy/workspace/presentation/plugins/widgets/left_bar_item.dart';
+import 'package:app_flowy/workspace/presentation/widgets/left_bar_item.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
-import 'package:app_flowy/plugin/plugin.dart';
+import 'package:app_flowy/startup/plugin/plugin.dart';
 import 'package:flutter/material.dart';
 
-import 'src/board_page.dart';
+import 'presentation/board_page.dart';
 
 class BoardPluginBuilder implements PluginBuilder {
   @override
@@ -28,7 +28,7 @@ class BoardPluginBuilder implements PluginBuilder {
 
 class BoardPluginConfig implements PluginConfig {
   @override
-  bool get creatable => false;
+  bool get creatable => true;
 }
 
 class BoardPlugin extends Plugin {

+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/board/src/board_page.dart → frontend/app_flowy/lib/plugins/board/presentation/board_page.dart


+ 14 - 8
frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart → frontend/app_flowy/lib/plugins/doc/application/doc_bloc.dart

@@ -1,7 +1,7 @@
 import 'dart:convert';
-import 'package:app_flowy/workspace/application/doc/doc_service.dart';
-import 'package:app_flowy/workspace/application/trash/trash_service.dart';
+import 'package:app_flowy/plugins/trash/application/trash_service.dart';
 import 'package:app_flowy/workspace/application/view/view_listener.dart';
+import 'package:app_flowy/plugins/doc/application/doc_service.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder/trash.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
@@ -43,14 +43,17 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
           emit(state.copyWith(isDeleted: false));
         },
         deletePermanently: (DeletePermanently value) async {
-          final result = await trashService.deleteViews([Tuple2(view.id, TrashType.TrashView)]);
+          final result = await trashService
+              .deleteViews([Tuple2(view.id, TrashType.TrashView)]);
 
-          final newState = result.fold((l) => state.copyWith(forceClose: true), (r) => state);
+          final newState = result.fold(
+              (l) => state.copyWith(forceClose: true), (r) => state);
           emit(newState);
         },
         restorePage: (RestorePage value) async {
           final result = await trashService.putback(view.id);
-          final newState = result.fold((l) => state.copyWith(isDeleted: false), (r) => state);
+          final newState = result.fold(
+              (l) => state.copyWith(isDeleted: false), (r) => state);
           emit(newState);
         },
       );
@@ -93,10 +96,12 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
           final documentDelta = document.toDelta();
           _composeDelta(delta, documentDelta);
         });
-        emit(state.copyWith(loadingState: DocumentLoadingState.finish(left(unit))));
+        emit(state.copyWith(
+            loadingState: DocumentLoadingState.finish(left(unit))));
       },
       (err) {
-        emit(state.copyWith(loadingState: DocumentLoadingState.finish(right(err))));
+        emit(state.copyWith(
+            loadingState: DocumentLoadingState.finish(right(err))));
       },
     );
   }
@@ -156,5 +161,6 @@ class DocumentState with _$DocumentState {
 @freezed
 class DocumentLoadingState with _$DocumentLoadingState {
   const factory DocumentLoadingState.loading() = _Loading;
-  const factory DocumentLoadingState.finish(Either<Unit, FlowyError> successOrFail) = _Finish;
+  const factory DocumentLoadingState.finish(
+      Either<Unit, FlowyError> successOrFail) = _Finish;
 }

+ 0 - 0
frontend/app_flowy/lib/workspace/application/doc/doc_service.dart → frontend/app_flowy/lib/plugins/doc/application/doc_service.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/application/doc/prelude.dart → frontend/app_flowy/lib/plugins/doc/application/prelude.dart


+ 7 - 4
frontend/app_flowy/lib/workspace/application/doc/share_bloc.dart → frontend/app_flowy/lib/plugins/doc/application/share_bloc.dart

@@ -1,8 +1,8 @@
 import 'dart:async';
 import 'dart:io';
 import 'package:app_flowy/startup/tasks/rust_sdk.dart';
-import 'package:app_flowy/workspace/application/doc/share_service.dart';
 import 'package:app_flowy/workspace/application/markdown/delta_markdown.dart';
+import 'package:app_flowy/plugins/doc/application/share_service.dart';
 import 'package:flowy_sdk/protobuf/flowy-text-block/entities.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
@@ -14,13 +14,15 @@ part 'share_bloc.freezed.dart';
 class DocShareBloc extends Bloc<DocShareEvent, DocShareState> {
   ShareService service;
   ViewPB view;
-  DocShareBloc({required this.view, required this.service}) : super(const DocShareState.initial()) {
+  DocShareBloc({required this.view, required this.service})
+      : super(const DocShareState.initial()) {
     on<DocShareEvent>((event, emit) async {
       await event.map(
         shareMarkdown: (ShareMarkdown value) async {
           await service.exportMarkdown(view.id).then((result) {
             result.fold(
-              (value) => emit(DocShareState.finish(left(_convertDeltaToMarkdown(value)))),
+              (value) => emit(
+                  DocShareState.finish(left(_convertDeltaToMarkdown(value)))),
               (error) => emit(DocShareState.finish(right(error))),
             );
           });
@@ -73,5 +75,6 @@ class DocShareEvent with _$DocShareEvent {
 class DocShareState with _$DocShareState {
   const factory DocShareState.initial() = _Initial;
   const factory DocShareState.loading() = _Loading;
-  const factory DocShareState.finish(Either<ExportDataPB, FlowyError> successOrFail) = _Finish;
+  const factory DocShareState.finish(
+      Either<ExportDataPB, FlowyError> successOrFail) = _Finish;
 }

+ 0 - 0
frontend/app_flowy/lib/workspace/application/doc/share_service.dart → frontend/app_flowy/lib/plugins/doc/application/share_service.dart


+ 24 - 18
frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart → frontend/app_flowy/lib/plugins/doc/document.dart

@@ -1,14 +1,14 @@
 library docuemnt_plugin;
 
 import 'package:app_flowy/generated/locale_keys.g.dart';
-import 'package:app_flowy/plugin/plugin.dart';
+import 'package:app_flowy/startup/plugin/plugin.dart';
 import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/workspace/application/appearance.dart';
-import 'package:app_flowy/workspace/application/doc/share_bloc.dart';
 import 'package:app_flowy/workspace/application/view/view_listener.dart';
+import 'package:app_flowy/plugins/doc/application/share_bloc.dart';
 import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
 import 'package:app_flowy/workspace/presentation/home/toast.dart';
-import 'package:app_flowy/workspace/presentation/plugins/widgets/left_bar_item.dart';
+import 'package:app_flowy/workspace/presentation/widgets/left_bar_item.dart';
 import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
 import 'package:app_flowy/workspace/presentation/widgets/pop_up_action.dart';
 import 'package:clipboard/clipboard.dart';
@@ -26,12 +26,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:provider/provider.dart';
 
-import 'src/document_page.dart';
-
-export './src/document_page.dart';
-export './src/widget/toolbar/history_button.dart';
-export './src/widget/toolbar/tool_bar.dart';
-export './src/widget/toolbar/toolbar_icon_button.dart';
+import 'document_page.dart';
 
 class DocumentPluginBuilder extends PluginBuilder {
   @override
@@ -58,7 +53,9 @@ class DocumentPlugin implements Plugin {
   ViewListener? _listener;
   late PluginType _pluginType;
 
-  DocumentPlugin({required PluginType pluginType, required ViewPB view, Key? key}) : _view = view {
+  DocumentPlugin(
+      {required PluginType pluginType, required ViewPB view, Key? key})
+      : _view = view {
     _pluginType = pluginType;
     _listener = getIt<ViewListener>(param1: view);
     _listener?.start(onViewUpdated: (result) {
@@ -112,7 +109,8 @@ class DocumentPluginDisplay extends PluginDisplay<int> with NavigationItem {
 
 class DocumentShareButton extends StatelessWidget {
   final ViewPB view;
-  DocumentShareButton({Key? key, required this.view}) : super(key: ValueKey(view.hashCode));
+  DocumentShareButton({Key? key, required this.view})
+      : super(key: ValueKey(view.hashCode));
 
   @override
   Widget build(BuildContext context) {
@@ -149,7 +147,8 @@ class DocumentShareButton extends StatelessWidget {
                     fontSize: 12,
                     borderRadius: Corners.s6Border,
                     color: Colors.lightBlue,
-                    onPressed: () => _showActionList(context, Offset(-(buttonWidth / 2), 10)),
+                    onPressed: () => _showActionList(
+                        context, Offset(-(buttonWidth / 2), 10)),
                   ),
                 ),
               ),
@@ -165,7 +164,8 @@ class DocumentShareButton extends StatelessWidget {
       case ExportType.Link:
         break;
       case ExportType.Markdown:
-        FlutterClipboard.copy(exportData.data).then((value) => Log.info('copied to clipboard'));
+        FlutterClipboard.copy(exportData.data)
+            .then((value) => Log.info('copied to clipboard'));
         break;
       case ExportType.Text:
         break;
@@ -179,11 +179,15 @@ class DocumentShareButton extends StatelessWidget {
       result.fold(() {}, (action) {
         switch (action) {
           case ShareAction.markdown:
-            context.read<DocShareBloc>().add(const DocShareEvent.shareMarkdown());
-            showMessageToast('Exported to: ${LocaleKeys.notifications_export_path.tr()}');
+            context
+                .read<DocShareBloc>()
+                .add(const DocShareEvent.shareMarkdown());
+            showMessageToast(
+                'Exported to: ${LocaleKeys.notifications_export_path.tr()}');
             break;
           case ShareAction.copyLink:
-            FlowyAlertDialog(title: LocaleKeys.shareAction_workInProgress.tr()).show(context);
+            FlowyAlertDialog(title: LocaleKeys.shareAction_workInProgress.tr())
+                .show(context);
             break;
         }
       });
@@ -198,7 +202,8 @@ class DocumentShareButton extends StatelessWidget {
 
 class ShareActions with ActionList<ShareActionWrapper>, FlowyOverlayDelegate {
   final Function(dartz.Option<ShareAction>) onSelected;
-  final _items = ShareAction.values.map((action) => ShareActionWrapper(action)).toList();
+  final _items =
+      ShareAction.values.map((action) => ShareActionWrapper(action)).toList();
 
   ShareActions({required this.onSelected});
 
@@ -212,7 +217,8 @@ class ShareActions with ActionList<ShareActionWrapper>, FlowyOverlayDelegate {
   List<ShareActionWrapper> get items => _items;
 
   @override
-  void Function(dartz.Option<ShareActionWrapper> p1) get selectCallback => (result) {
+  void Function(dartz.Option<ShareActionWrapper> p1) get selectCallback =>
+      (result) {
         result.fold(
           () => onSelected(dartz.none()),
           (wrapper) => onSelected(

+ 14 - 8
frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/document_page.dart → frontend/app_flowy/lib/plugins/doc/document_page.dart

@@ -1,7 +1,7 @@
 import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/workspace/application/appearance.dart';
-import 'package:app_flowy/workspace/application/doc/doc_bloc.dart';
-import 'package:app_flowy/workspace/presentation/plugins/doc/document.dart';
+import 'package:app_flowy/plugins/doc/presentation/banner.dart';
+import 'package:app_flowy/plugins/doc/presentation/toolbar/tool_bar.dart';
 import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart';
 import 'package:flowy_infra_ui/widget/spacing.dart';
 import 'package:flutter_quill/flutter_quill.dart' as quill;
@@ -10,8 +10,8 @@ import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:provider/provider.dart';
+import 'application/doc_bloc.dart';
 import 'styles.dart';
-import 'widget/banner.dart';
 
 class DocumentPage extends StatefulWidget {
   final ViewPB view;
@@ -29,7 +29,8 @@ class _DocumentPageState extends State<DocumentPage> {
 
   @override
   void initState() {
-    documentBloc = getIt<DocumentBloc>(param1: super.widget.view)..add(const DocumentEvent.initial());
+    documentBloc = getIt<DocumentBloc>(param1: super.widget.view)
+      ..add(const DocumentEvent.initial());
     super.initState();
   }
 
@@ -39,10 +40,12 @@ class _DocumentPageState extends State<DocumentPage> {
       providers: [
         BlocProvider<DocumentBloc>.value(value: documentBloc),
       ],
-      child: BlocBuilder<DocumentBloc, DocumentState>(builder: (context, state) {
+      child:
+          BlocBuilder<DocumentBloc, DocumentState>(builder: (context, state) {
         return state.loadingState.map(
           // loading: (_) => const FlowyProgressIndicator(),
-          loading: (_) => SizedBox.expand(child: Container(color: Colors.transparent)),
+          loading: (_) =>
+              SizedBox.expand(child: Container(color: Colors.transparent)),
           finish: (result) => result.successOrFail.fold(
             (_) {
               if (state.forceClose) {
@@ -90,8 +93,11 @@ class _DocumentPageState extends State<DocumentPage> {
 
   Widget _renderBanner(BuildContext context) {
     return DocumentBanner(
-      onRestore: () => context.read<DocumentBloc>().add(const DocumentEvent.restorePage()),
-      onDelete: () => context.read<DocumentBloc>().add(const DocumentEvent.deletePermanently()),
+      onRestore: () =>
+          context.read<DocumentBloc>().add(const DocumentEvent.restorePage()),
+      onDelete: () => context
+          .read<DocumentBloc>()
+          .add(const DocumentEvent.deletePermanently()),
     );
   }
 

+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/banner.dart → frontend/app_flowy/lib/plugins/doc/presentation/banner.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/style_widgets.dart → frontend/app_flowy/lib/plugins/doc/presentation/style_widgets.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/check_button.dart → frontend/app_flowy/lib/plugins/doc/presentation/toolbar/check_button.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/color_picker.dart → frontend/app_flowy/lib/plugins/doc/presentation/toolbar/color_picker.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/header_button.dart → frontend/app_flowy/lib/plugins/doc/presentation/toolbar/header_button.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/history_button.dart → frontend/app_flowy/lib/plugins/doc/presentation/toolbar/history_button.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/image_button.dart → frontend/app_flowy/lib/plugins/doc/presentation/toolbar/image_button.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/link_button.dart → frontend/app_flowy/lib/plugins/doc/presentation/toolbar/link_button.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/toggle_button.dart → frontend/app_flowy/lib/plugins/doc/presentation/toolbar/toggle_button.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/tool_bar.dart → frontend/app_flowy/lib/plugins/doc/presentation/toolbar/tool_bar.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/widget/toolbar/toolbar_icon_button.dart → frontend/app_flowy/lib/plugins/doc/presentation/toolbar/toolbar_icon_button.dart


+ 11 - 8
frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/styles.dart → frontend/app_flowy/lib/plugins/doc/styles.dart

@@ -1,11 +1,10 @@
+import 'package:app_flowy/plugins/doc/presentation/style_widgets.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_quill/flutter_quill.dart';
 import 'package:provider/provider.dart';
 import 'package:tuple/tuple.dart';
 import 'package:flowy_infra/theme.dart';
 
-import 'widget/style_widgets.dart';
-
 DefaultStyles customStyles(BuildContext context) {
   const baseSpacing = Tuple2<double, double>(6, 0);
 
@@ -53,7 +52,8 @@ DefaultStyles customStyles(BuildContext context) {
           const Tuple2(8, 0),
           const Tuple2(0, 0),
           null),
-      paragraph: DefaultTextBlockStyle(baseStyle, const Tuple2(10, 0), const Tuple2(0, 0), null),
+      paragraph: DefaultTextBlockStyle(
+          baseStyle, const Tuple2(10, 0), const Tuple2(0, 0), null),
       bold: const TextStyle(fontWeight: FontWeight.bold),
       italic: const TextStyle(fontStyle: FontStyle.italic),
       small: const TextStyle(fontSize: 12, color: Colors.black45),
@@ -78,8 +78,8 @@ DefaultStyles customStyles(BuildContext context) {
           const Tuple2(0, 0),
           const Tuple2(0, 0),
           null),
-      lists:
-          DefaultListBlockStyle(baseStyle, baseSpacing, const Tuple2(0, 6), null, StyleWidgetBuilder.checkbox(theme)),
+      lists: DefaultListBlockStyle(baseStyle, baseSpacing, const Tuple2(0, 6),
+          null, StyleWidgetBuilder.checkbox(theme)),
       quote: DefaultTextBlockStyle(
           TextStyle(color: baseStyle.color!.withOpacity(0.6)),
           baseSpacing,
@@ -102,9 +102,12 @@ DefaultStyles customStyles(BuildContext context) {
             color: Colors.grey.shade50,
             borderRadius: BorderRadius.circular(2),
           )),
-      indent: DefaultTextBlockStyle(baseStyle, baseSpacing, const Tuple2(0, 6), null),
-      align: DefaultTextBlockStyle(baseStyle, const Tuple2(0, 0), const Tuple2(0, 0), null),
-      leading: DefaultTextBlockStyle(baseStyle, const Tuple2(0, 0), const Tuple2(0, 0), null),
+      indent: DefaultTextBlockStyle(
+          baseStyle, baseSpacing, const Tuple2(0, 6), null),
+      align: DefaultTextBlockStyle(
+          baseStyle, const Tuple2(0, 0), const Tuple2(0, 0), null),
+      leading: DefaultTextBlockStyle(
+          baseStyle, const Tuple2(0, 0), const Tuple2(0, 0), null),
       sizeSmall: const TextStyle(fontSize: 10),
       sizeLarge: const TextStyle(fontSize: 18),
       sizeHuge: const TextStyle(fontSize: 22));

+ 2 - 2
frontend/app_flowy/lib/workspace/application/grid/block/block_cache.dart → frontend/app_flowy/lib/plugins/grid/application/block/block_cache.dart

@@ -1,6 +1,6 @@
 import 'dart:async';
-import 'package:app_flowy/workspace/application/grid/grid_service.dart';
-import 'package:app_flowy/workspace/application/grid/row/row_service.dart';
+import 'package:app_flowy/plugins/grid/application/grid_service.dart';
+import 'package:app_flowy/plugins/grid/application/row/row_service.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
 

+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/block/block_listener.dart → frontend/app_flowy/lib/plugins/grid/application/block/block_listener.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/cell/cell_listener.dart → frontend/app_flowy/lib/plugins/grid/application/cell/cell_listener.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_cache.dart → frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/cell_cache.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_data_loader.dart → frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/cell_data_loader.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_data_persistence.dart → frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/cell_data_persistence.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_field_notifier.dart → frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/cell_field_notifier.dart


+ 3 - 3
frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_service.dart → frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/cell_service.dart

@@ -1,7 +1,7 @@
 import 'dart:async';
 import 'dart:collection';
 
-import 'package:app_flowy/workspace/application/grid/grid_service.dart';
+import 'package:app_flowy/plugins/grid/application/grid_service.dart';
 import 'package:dartz/dartz.dart';
 import 'package:equatable/equatable.dart';
 import 'package:flowy_sdk/dispatch/dispatch.dart';
@@ -14,8 +14,8 @@ import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option_entities.pb.dart';
 import 'package:flutter/foundation.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
-import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart';
-import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
+import 'package:app_flowy/plugins/grid/application/cell/cell_listener.dart';
+import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
 import 'dart:convert' show utf8;
 
 import '../../field/type_option/type_option_service.dart';

+ 24 - 11
frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/context_builder.dart → frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/context_builder.dart

@@ -1,8 +1,10 @@
 part of 'cell_service.dart';
 
 typedef GridCellController = IGridCellController<String, String>;
-typedef GridSelectOptionCellController = IGridCellController<SelectOptionCellDataPB, String>;
-typedef GridDateCellController = IGridCellController<DateCellDataPB, CalendarData>;
+typedef GridSelectOptionCellController
+    = IGridCellController<SelectOptionCellDataPB, String>;
+typedef GridDateCellController
+    = IGridCellController<DateCellDataPB, CalendarData>;
 typedef GridURLCellController = IGridCellController<URLCellDataPB, String>;
 
 class GridCellControllerBuilder {
@@ -19,7 +21,8 @@ class GridCellControllerBuilder {
         _cellId = cellId;
 
   IGridCellController build() {
-    final cellFieldNotifier = GridCellFieldNotifier(notifier: _GridFieldChangedNotifierImpl(_fieldCache));
+    final cellFieldNotifier = GridCellFieldNotifier(
+        notifier: _GridFieldChangedNotifierImpl(_fieldCache));
 
     switch (_cellId.fieldType) {
       case FieldType.Checkbox:
@@ -142,8 +145,10 @@ class IGridCellController<T, D> extends Equatable {
         _cellDataLoader = cellDataLoader,
         _cellDataPersistence = cellDataPersistence,
         _fieldNotifier = fieldNotifier,
-        _fieldService = FieldService(gridId: cellId.gridId, fieldId: cellId.field.id),
-        _cacheKey = GridCellCacheKey(rowId: cellId.rowId, fieldId: cellId.field.id);
+        _fieldService =
+            FieldService(gridId: cellId.gridId, fieldId: cellId.field.id),
+        _cacheKey =
+            GridCellCacheKey(rowId: cellId.rowId, fieldId: cellId.field.id);
 
   IGridCellController<T, D> clone() {
     return IGridCellController(
@@ -164,7 +169,9 @@ class IGridCellController<T, D> extends Equatable {
 
   FieldType get fieldType => cellId.field.fieldType;
 
-  VoidCallback? startListening({required void Function(T?) onCellChanged, VoidCallback? onCellFieldChanged}) {
+  VoidCallback? startListening(
+      {required void Function(T?) onCellChanged,
+      VoidCallback? onCellFieldChanged}) {
     if (isListening) {
       Log.error("Already started. It seems like you should call clone first");
       return null;
@@ -226,8 +233,11 @@ class IGridCellController<T, D> extends Equatable {
 
   /// Return the FieldTypeOptionDataPB that can be parsed into corresponding class using the [parser].
   /// [PD] is the type that the parser return.
-  Future<Either<PD, FlowyError>> getFieldTypeOption<PD, P extends TypeOptionDataParser>(P parser) {
-    return _fieldService.getFieldTypeOptionData(fieldType: fieldType).then((result) {
+  Future<Either<PD, FlowyError>>
+      getFieldTypeOption<PD, P extends TypeOptionDataParser>(P parser) {
+    return _fieldService
+        .getFieldTypeOptionData(fieldType: fieldType)
+        .then((result) {
       return result.fold(
         (data) => parser.fromBuffer(data.typeOptionData),
         (err) => right(err),
@@ -239,7 +249,9 @@ class IGridCellController<T, D> extends Equatable {
   /// You can set [dedeplicate] to true (default is false) to reduce the save operation.
   /// It's useful when you call this method when user editing the [TextField].
   /// The default debounce interval is 300 milliseconds.
-  void saveCellData(D data, {bool deduplicate = false, void Function(Option<FlowyError>)? resultCallback}) async {
+  void saveCellData(D data,
+      {bool deduplicate = false,
+      void Function(Option<FlowyError>)? resultCallback}) async {
     if (deduplicate) {
       _loadDataOperation?.cancel();
 
@@ -288,7 +300,8 @@ class IGridCellController<T, D> extends Equatable {
   }
 
   @override
-  List<Object> get props => [_cellsCache.get(_cacheKey) ?? "", cellId.rowId + cellId.field.id];
+  List<Object> get props =>
+      [_cellsCache.get(_cacheKey) ?? "", cellId.rowId + cellId.field.id];
 }
 
 class _GridFieldChangedNotifierImpl extends GridFieldChangedNotifier {
@@ -300,7 +313,7 @@ class _GridFieldChangedNotifierImpl extends GridFieldChangedNotifier {
   @override
   void dispose() {
     if (_onChangesetFn != null) {
-      _cache.removeListener(onChangsetListener: _onChangesetFn!);
+      _cache.removeListener(onChangesetListener: _onChangesetFn!);
       _onChangesetFn = null;
     }
   }

+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/cell/checkbox_cell_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/cell/checkbox_cell_bloc.dart


+ 27 - 13
frontend/app_flowy/lib/workspace/application/grid/cell/date_cal_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/cell/date_cal_bloc.dart

@@ -1,6 +1,7 @@
 import 'package:app_flowy/generated/locale_keys.g.dart';
-import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
-import 'package:easy_localization/easy_localization.dart' show StringTranslateExtension;
+import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
+import 'package:easy_localization/easy_localization.dart'
+    show StringTranslateExtension;
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-error-code/code.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
@@ -40,7 +41,8 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
           },
           didReceiveCellUpdate: (DateCellDataPB? cellData) {
             final calData = calDataFromCellData(cellData);
-            final time = calData.foldRight("", (dateData, previous) => dateData.time);
+            final time =
+                calData.foldRight("", (dateData, previous) => dateData.time);
             emit(state.copyWith(calData: calData, time: time));
           },
           setIncludeTime: (includeTime) async {
@@ -57,15 +59,18 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
               await _updateDateData(emit, time: time);
             }
           },
-          didUpdateCalData: (Option<CalendarData> data, Option<String> timeFormatError) {
-            emit(state.copyWith(calData: data, timeFormatError: timeFormatError));
+          didUpdateCalData:
+              (Option<CalendarData> data, Option<String> timeFormatError) {
+            emit(state.copyWith(
+                calData: data, timeFormatError: timeFormatError));
           },
         );
       },
     );
   }
 
-  Future<void> _updateDateData(Emitter<DateCalState> emit, {DateTime? date, String? time}) {
+  Future<void> _updateDateData(Emitter<DateCalState> emit,
+      {DateTime? date, String? time}) {
     final CalendarData newDateData = state.calData.fold(
       () => CalendarData(date: date ?? DateTime.now(), time: time),
       (dateData) {
@@ -84,13 +89,17 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
     return _saveDateData(emit, newDateData);
   }
 
-  Future<void> _saveDateData(Emitter<DateCalState> emit, CalendarData newCalData) async {
+  Future<void> _saveDateData(
+      Emitter<DateCalState> emit, CalendarData newCalData) async {
     if (state.calData == Some(newCalData)) {
       return;
     }
 
-    updateCalData(Option<CalendarData> calData, Option<String> timeFormatError) {
-      if (!isClosed) add(DateCalEvent.didUpdateCalData(calData, timeFormatError));
+    updateCalData(
+        Option<CalendarData> calData, Option<String> timeFormatError) {
+      if (!isClosed) {
+        add(DateCalEvent.didUpdateCalData(calData, timeFormatError));
+      }
     }
 
     cellContext.saveCellData(newCalData, resultCallback: (result) {
@@ -172,7 +181,9 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
     );
 
     result.fold(
-      (l) => emit(state.copyWith(dateTypeOption: newDateTypeOption, timeHintText: _timeHintText(newDateTypeOption))),
+      (l) => emit(state.copyWith(
+          dateTypeOption: newDateTypeOption,
+          timeHintText: _timeHintText(newDateTypeOption))),
       (err) => Log.error(err),
     );
   }
@@ -182,14 +193,17 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
 class DateCalEvent with _$DateCalEvent {
   const factory DateCalEvent.initial() = _Initial;
   const factory DateCalEvent.selectDay(DateTime day) = _SelectDay;
-  const factory DateCalEvent.setCalFormat(CalendarFormat format) = _CalendarFormat;
+  const factory DateCalEvent.setCalFormat(CalendarFormat format) =
+      _CalendarFormat;
   const factory DateCalEvent.setFocusedDay(DateTime day) = _FocusedDay;
   const factory DateCalEvent.setTimeFormat(TimeFormat timeFormat) = _TimeFormat;
   const factory DateCalEvent.setDateFormat(DateFormat dateFormat) = _DateFormat;
   const factory DateCalEvent.setIncludeTime(bool includeTime) = _IncludeTime;
   const factory DateCalEvent.setTime(String time) = _Time;
-  const factory DateCalEvent.didReceiveCellUpdate(DateCellDataPB? data) = _DidReceiveCellUpdate;
-  const factory DateCalEvent.didUpdateCalData(Option<CalendarData> data, Option<String> timeFormatError) =
+  const factory DateCalEvent.didReceiveCellUpdate(DateCellDataPB? data) =
+      _DidReceiveCellUpdate;
+  const factory DateCalEvent.didUpdateCalData(
+          Option<CalendarData> data, Option<String> timeFormatError) =
       _DidUpdateCalData;
 }
 

+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/cell/date_cell_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/cell/date_cell_bloc.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/cell/number_cell_bloc.dart


+ 5 - 3
frontend/app_flowy/lib/workspace/application/grid/cell/select_option_cell_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/cell/select_option_cell_bloc.dart

@@ -2,11 +2,12 @@ import 'dart:async';
 import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
-import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
+import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
 
 part 'select_option_cell_bloc.freezed.dart';
 
-class SelectOptionCellBloc extends Bloc<SelectOptionCellEvent, SelectOptionCellState> {
+class SelectOptionCellBloc
+    extends Bloc<SelectOptionCellEvent, SelectOptionCellState> {
   final GridSelectOptionCellController cellContext;
   void Function()? _onCellChangedFn;
 
@@ -66,7 +67,8 @@ class SelectOptionCellState with _$SelectOptionCellState {
     required List<SelectOptionPB> selectedOptions,
   }) = _SelectOptionCellState;
 
-  factory SelectOptionCellState.initial(GridSelectOptionCellController context) {
+  factory SelectOptionCellState.initial(
+      GridSelectOptionCellController context) {
     final data = context.getCellData();
 
     return SelectOptionCellState(

+ 27 - 14
frontend/app_flowy/lib/workspace/application/grid/cell/select_option_editor_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/cell/select_option_editor_bloc.dart

@@ -4,20 +4,22 @@ import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
-import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
+import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
 import 'select_option_service.dart';
 import 'package:collection/collection.dart';
 
 part 'select_option_editor_bloc.freezed.dart';
 
-class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOptionEditorState> {
+class SelectOptionCellEditorBloc
+    extends Bloc<SelectOptionEditorEvent, SelectOptionEditorState> {
   final SelectOptionService _selectOptionService;
   final GridSelectOptionCellController cellController;
   Timer? _delayOperation;
 
   SelectOptionCellEditorBloc({
     required this.cellController,
-  })  : _selectOptionService = SelectOptionService(cellId: cellController.cellId),
+  })  : _selectOptionService =
+            SelectOptionService(cellId: cellController.cellId),
         super(SelectOptionEditorState.initial(cellController)) {
     on<SelectOptionEditorEvent>(
       (event, emit) async {
@@ -87,7 +89,8 @@ class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOpt
   }
 
   void _onSelectOption(String optionId) {
-    final hasSelected = state.selectedOptions.firstWhereOrNull((option) => option.id == optionId);
+    final hasSelected = state.selectedOptions
+        .firstWhereOrNull((option) => option.id == optionId);
     if (hasSelected != null) {
       _selectOptionService.unSelect(optionId: optionId);
     } else {
@@ -96,7 +99,8 @@ class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOpt
   }
 
   void _filterOption(String optionName, Emitter<SelectOptionEditorState> emit) {
-    final _MakeOptionResult result = _makeOptions(Some(optionName), state.allOptions);
+    final _MakeOptionResult result =
+        _makeOptions(Some(optionName), state.allOptions);
     emit(state.copyWith(
       filter: Some(optionName),
       options: result.options,
@@ -112,7 +116,8 @@ class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOpt
           return;
         }
         return result.fold(
-          (data) => add(SelectOptionEditorEvent.didReceiveOptions(data.options, data.selectOptions)),
+          (data) => add(SelectOptionEditorEvent.didReceiveOptions(
+              data.options, data.selectOptions)),
           (err) {
             Log.error(err);
             return null;
@@ -122,7 +127,8 @@ class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOpt
     });
   }
 
-  _MakeOptionResult _makeOptions(Option<String> filter, List<SelectOptionPB> allOptions) {
+  _MakeOptionResult _makeOptions(
+      Option<String> filter, List<SelectOptionPB> allOptions) {
     final List<SelectOptionPB> options = List.from(allOptions);
     Option<String> createOption = filter;
 
@@ -165,12 +171,18 @@ class SelectOptionCellEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOpt
 class SelectOptionEditorEvent with _$SelectOptionEditorEvent {
   const factory SelectOptionEditorEvent.initial() = _Initial;
   const factory SelectOptionEditorEvent.didReceiveOptions(
-      List<SelectOptionPB> options, List<SelectOptionPB> selectedOptions) = _DidReceiveOptions;
-  const factory SelectOptionEditorEvent.newOption(String optionName) = _NewOption;
-  const factory SelectOptionEditorEvent.selectOption(String optionId) = _SelectOption;
-  const factory SelectOptionEditorEvent.updateOption(SelectOptionPB option) = _UpdateOption;
-  const factory SelectOptionEditorEvent.deleteOption(SelectOptionPB option) = _DeleteOption;
-  const factory SelectOptionEditorEvent.filterOption(String optionName) = _SelectOptionFilter;
+          List<SelectOptionPB> options, List<SelectOptionPB> selectedOptions) =
+      _DidReceiveOptions;
+  const factory SelectOptionEditorEvent.newOption(String optionName) =
+      _NewOption;
+  const factory SelectOptionEditorEvent.selectOption(String optionId) =
+      _SelectOption;
+  const factory SelectOptionEditorEvent.updateOption(SelectOptionPB option) =
+      _UpdateOption;
+  const factory SelectOptionEditorEvent.deleteOption(SelectOptionPB option) =
+      _DeleteOption;
+  const factory SelectOptionEditorEvent.filterOption(String optionName) =
+      _SelectOptionFilter;
 }
 
 @freezed
@@ -183,7 +195,8 @@ class SelectOptionEditorState with _$SelectOptionEditorState {
     required Option<String> filter,
   }) = _SelectOptionEditorState;
 
-  factory SelectOptionEditorState.initial(GridSelectOptionCellController context) {
+  factory SelectOptionEditorState.initial(
+      GridSelectOptionCellController context) {
     final data = context.getCellData(loadIfNotExist: false);
     return SelectOptionEditorState(
       options: data?.options ?? [],

+ 4 - 2
frontend/app_flowy/lib/workspace/application/grid/cell/select_option_service.dart → frontend/app_flowy/lib/plugins/grid/application/cell/select_option_service.dart

@@ -2,7 +2,7 @@ import 'package:dartz/dartz.dart';
 import 'package:flowy_sdk/dispatch/dispatch.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart';
-import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart';
+import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_service.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
 import 'cell_service/cell_service.dart';
 
@@ -15,7 +15,9 @@ class SelectOptionService {
   String get rowId => cellId.rowId;
 
   Future<Either<Unit, FlowyError>> create({required String name}) {
-    return TypeOptionService(gridId: gridId, fieldId: fieldId).newOption(name: name).then(
+    return TypeOptionService(gridId: gridId, fieldId: fieldId)
+        .newOption(name: name)
+        .then(
       (result) {
         return result.fold(
           (option) {

+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/cell/text_cell_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/cell/text_cell_bloc.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/cell/url_cell_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/cell/url_cell_bloc.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/cell/url_cell_editor_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/cell/url_cell_editor_bloc.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/field/field_action_sheet_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/field/field_action_sheet_bloc.dart


+ 10 - 6
frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/field/field_cell_bloc.dart

@@ -1,5 +1,5 @@
-import 'package:app_flowy/workspace/application/grid/field/field_listener.dart';
-import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
+import 'package:app_flowy/plugins/grid/application/field/field_listener.dart';
+import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
@@ -15,7 +15,8 @@ class FieldCellBloc extends Bloc<FieldCellEvent, FieldCellState> {
   FieldCellBloc({
     required GridFieldCellContext cellContext,
   })  : _fieldListener = SingleFieldListener(fieldId: cellContext.field.id),
-        _fieldService = FieldService(gridId: cellContext.gridId, fieldId: cellContext.field.id),
+        _fieldService = FieldService(
+            gridId: cellContext.gridId, fieldId: cellContext.field.id),
         super(FieldCellState.initial(cellContext)) {
     on<FieldCellEvent>(
       (event, emit) async {
@@ -62,8 +63,10 @@ class FieldCellBloc extends Bloc<FieldCellEvent, FieldCellState> {
 @freezed
 class FieldCellEvent with _$FieldCellEvent {
   const factory FieldCellEvent.initial() = _InitialCell;
-  const factory FieldCellEvent.didReceiveFieldUpdate(GridFieldPB field) = _DidReceiveFieldUpdate;
-  const factory FieldCellEvent.startUpdateWidth(double offset) = _StartUpdateWidth;
+  const factory FieldCellEvent.didReceiveFieldUpdate(GridFieldPB field) =
+      _DidReceiveFieldUpdate;
+  const factory FieldCellEvent.startUpdateWidth(double offset) =
+      _StartUpdateWidth;
   const factory FieldCellEvent.endUpdateWidth() = _EndUpdateWidth;
 }
 
@@ -75,7 +78,8 @@ class FieldCellState with _$FieldCellState {
     required double width,
   }) = _FieldCellState;
 
-  factory FieldCellState.initial(GridFieldCellContext cellContext) => FieldCellState(
+  factory FieldCellState.initial(GridFieldCellContext cellContext) =>
+      FieldCellState(
         gridId: cellContext.gridId,
         field: cellContext.field,
         width: cellContext.field.width.toDouble(),

+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/field/field_editor_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/field/field_editor_bloc.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart → frontend/app_flowy/lib/plugins/grid/application/field/field_listener.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart → frontend/app_flowy/lib/plugins/grid/application/field/field_service.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/field/field_type_option_edit_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/field/field_type_option_edit_bloc.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/field/grid_header_listener.dart → frontend/app_flowy/lib/plugins/grid/application/field/grid_header_listener.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart → frontend/app_flowy/lib/plugins/grid/application/field/grid_listener.dart


+ 17 - 9
frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/field/type_option/date_bloc.dart

@@ -1,4 +1,4 @@
-import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart';
+import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_service.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
@@ -16,20 +16,24 @@ class DateTypeOptionDataParser extends TypeOptionDataParser<DateTypeOption> {
   }
 }
 
-class DateTypeOptionBloc extends Bloc<DateTypeOptionEvent, DateTypeOptionState> {
+class DateTypeOptionBloc
+    extends Bloc<DateTypeOptionEvent, DateTypeOptionState> {
   DateTypeOptionBloc({required DateTypeOptionContext typeOptionContext})
       : super(DateTypeOptionState.initial(typeOptionContext.typeOption)) {
     on<DateTypeOptionEvent>(
       (event, emit) async {
         event.map(
           didSelectDateFormat: (_DidSelectDateFormat value) {
-            emit(state.copyWith(typeOption: _updateTypeOption(dateFormat: value.format)));
+            emit(state.copyWith(
+                typeOption: _updateTypeOption(dateFormat: value.format)));
           },
           didSelectTimeFormat: (_DidSelectTimeFormat value) {
-            emit(state.copyWith(typeOption: _updateTypeOption(timeFormat: value.format)));
+            emit(state.copyWith(
+                typeOption: _updateTypeOption(timeFormat: value.format)));
           },
           includeTime: (_IncludeTime value) {
-            emit(state.copyWith(typeOption: _updateTypeOption(includeTime: value.includeTime)));
+            emit(state.copyWith(
+                typeOption: _updateTypeOption(includeTime: value.includeTime)));
           },
         );
       },
@@ -65,9 +69,12 @@ class DateTypeOptionBloc extends Bloc<DateTypeOptionEvent, DateTypeOptionState>
 
 @freezed
 class DateTypeOptionEvent with _$DateTypeOptionEvent {
-  const factory DateTypeOptionEvent.didSelectDateFormat(DateFormat format) = _DidSelectDateFormat;
-  const factory DateTypeOptionEvent.didSelectTimeFormat(TimeFormat format) = _DidSelectTimeFormat;
-  const factory DateTypeOptionEvent.includeTime(bool includeTime) = _IncludeTime;
+  const factory DateTypeOptionEvent.didSelectDateFormat(DateFormat format) =
+      _DidSelectDateFormat;
+  const factory DateTypeOptionEvent.didSelectTimeFormat(TimeFormat format) =
+      _DidSelectTimeFormat;
+  const factory DateTypeOptionEvent.includeTime(bool includeTime) =
+      _IncludeTime;
 }
 
 @freezed
@@ -76,5 +83,6 @@ class DateTypeOptionState with _$DateTypeOptionState {
     required DateTypeOption typeOption,
   }) = _DateTypeOptionState;
 
-  factory DateTypeOptionState.initial(DateTypeOption typeOption) => DateTypeOptionState(typeOption: typeOption);
+  factory DateTypeOptionState.initial(DateTypeOption typeOption) =>
+      DateTypeOptionState(typeOption: typeOption);
 }

+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/field/type_option/edit_select_option_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/field/type_option/edit_select_option_bloc.dart


+ 9 - 5
frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_type_option.dart → frontend/app_flowy/lib/plugins/grid/application/field/type_option/multi_select_type_option.dart

@@ -1,4 +1,4 @@
-import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
+import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/multi_select_type_option.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
@@ -7,7 +7,8 @@ import 'package:protobuf/protobuf.dart';
 import 'select_option_type_option_bloc.dart';
 import 'type_option_service.dart';
 
-class MultiSelectTypeOptionContext extends TypeOptionWidgetContext<MultiSelectTypeOption>
+class MultiSelectTypeOptionContext
+    extends TypeOptionWidgetContext<MultiSelectTypeOption>
     with SelectOptionTypeOptionAction {
   final TypeOptionService service;
 
@@ -25,7 +26,8 @@ class MultiSelectTypeOptionContext extends TypeOptionWidgetContext<MultiSelectTy
     return (SelectOptionPB option) {
       typeOption.freeze();
       typeOption = typeOption.rebuild((typeOption) {
-        final index = typeOption.options.indexWhere((element) => element.id == option.id);
+        final index =
+            typeOption.options.indexWhere((element) => element.id == option.id);
         if (index != -1) {
           typeOption.options.removeAt(index);
         }
@@ -61,7 +63,8 @@ class MultiSelectTypeOptionContext extends TypeOptionWidgetContext<MultiSelectTy
     return (SelectOptionPB option) {
       typeOption.freeze();
       typeOption = typeOption.rebuild((typeOption) {
-        final index = typeOption.options.indexWhere((element) => element.id == option.id);
+        final index =
+            typeOption.options.indexWhere((element) => element.id == option.id);
         if (index != -1) {
           typeOption.options[index] = option;
         }
@@ -71,7 +74,8 @@ class MultiSelectTypeOptionContext extends TypeOptionWidgetContext<MultiSelectTy
   }
 }
 
-class MultiSelectTypeOptionWidgetDataParser extends TypeOptionDataParser<MultiSelectTypeOption> {
+class MultiSelectTypeOptionWidgetDataParser
+    extends TypeOptionDataParser<MultiSelectTypeOption> {
   @override
   MultiSelectTypeOption fromBuffer(List<int> buffer) {
     return MultiSelectTypeOption.fromBuffer(buffer);

+ 9 - 5
frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/field/type_option/number_bloc.dart

@@ -1,4 +1,4 @@
-import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart';
+import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_service.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/format.pbenum.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
@@ -10,14 +10,16 @@ part 'number_bloc.freezed.dart';
 
 typedef NumberTypeOptionContext = TypeOptionWidgetContext<NumberTypeOption>;
 
-class NumberTypeOptionWidgetDataParser extends TypeOptionDataParser<NumberTypeOption> {
+class NumberTypeOptionWidgetDataParser
+    extends TypeOptionDataParser<NumberTypeOption> {
   @override
   NumberTypeOption fromBuffer(List<int> buffer) {
     return NumberTypeOption.fromBuffer(buffer);
   }
 }
 
-class NumberTypeOptionBloc extends Bloc<NumberTypeOptionEvent, NumberTypeOptionState> {
+class NumberTypeOptionBloc
+    extends Bloc<NumberTypeOptionEvent, NumberTypeOptionState> {
   NumberTypeOptionBloc({required NumberTypeOptionContext typeOptionContext})
       : super(NumberTypeOptionState.initial(typeOptionContext.typeOption)) {
     on<NumberTypeOptionEvent>(
@@ -46,7 +48,8 @@ class NumberTypeOptionBloc extends Bloc<NumberTypeOptionEvent, NumberTypeOptionS
 
 @freezed
 class NumberTypeOptionEvent with _$NumberTypeOptionEvent {
-  const factory NumberTypeOptionEvent.didSelectFormat(NumberFormat format) = _DidSelectFormat;
+  const factory NumberTypeOptionEvent.didSelectFormat(NumberFormat format) =
+      _DidSelectFormat;
 }
 
 @freezed
@@ -55,7 +58,8 @@ class NumberTypeOptionState with _$NumberTypeOptionState {
     required NumberTypeOption typeOption,
   }) = _NumberTypeOptionState;
 
-  factory NumberTypeOptionState.initial(NumberTypeOption typeOption) => NumberTypeOptionState(
+  factory NumberTypeOptionState.initial(NumberTypeOption typeOption) =>
+      NumberTypeOptionState(
         typeOption: typeOption,
       );
 }

+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_format_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/field/type_option/number_format_bloc.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/field/type_option/select_option_type_option_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/field/type_option/select_option_type_option_bloc.dart


+ 9 - 5
frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_type_option.dart → frontend/app_flowy/lib/plugins/grid/application/field/type_option/single_select_type_option.dart

@@ -1,4 +1,4 @@
-import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
+import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/single_select_type_option.pb.dart';
@@ -7,7 +7,8 @@ import 'package:protobuf/protobuf.dart';
 import 'select_option_type_option_bloc.dart';
 import 'type_option_service.dart';
 
-class SingleSelectTypeOptionContext extends TypeOptionWidgetContext<SingleSelectTypeOptionPB>
+class SingleSelectTypeOptionContext
+    extends TypeOptionWidgetContext<SingleSelectTypeOptionPB>
     with SelectOptionTypeOptionAction {
   final TypeOptionService service;
 
@@ -25,7 +26,8 @@ class SingleSelectTypeOptionContext extends TypeOptionWidgetContext<SingleSelect
     return (SelectOptionPB option) {
       typeOption.freeze();
       typeOption = typeOption.rebuild((typeOption) {
-        final index = typeOption.options.indexWhere((element) => element.id == option.id);
+        final index =
+            typeOption.options.indexWhere((element) => element.id == option.id);
         if (index != -1) {
           typeOption.options.removeAt(index);
         }
@@ -61,7 +63,8 @@ class SingleSelectTypeOptionContext extends TypeOptionWidgetContext<SingleSelect
     return (SelectOptionPB option) {
       typeOption.freeze();
       typeOption = typeOption.rebuild((typeOption) {
-        final index = typeOption.options.indexWhere((element) => element.id == option.id);
+        final index =
+            typeOption.options.indexWhere((element) => element.id == option.id);
         if (index != -1) {
           typeOption.options[index] = option;
         }
@@ -71,7 +74,8 @@ class SingleSelectTypeOptionContext extends TypeOptionWidgetContext<SingleSelect
   }
 }
 
-class SingleSelectTypeOptionWidgetDataParser extends TypeOptionDataParser<SingleSelectTypeOptionPB> {
+class SingleSelectTypeOptionWidgetDataParser
+    extends TypeOptionDataParser<SingleSelectTypeOptionPB> {
   @override
   SingleSelectTypeOptionPB fromBuffer(List<int> buffer) {
     return SingleSelectTypeOptionPB.fromBuffer(buffer);

+ 4 - 2
frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart → frontend/app_flowy/lib/plugins/grid/application/field/type_option/type_option_service.dart

@@ -1,6 +1,6 @@
 import 'dart:typed_data';
 
-import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
+import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
 import 'package:dartz/dartz.dart';
 import 'package:flowy_sdk/dispatch/dispatch.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
@@ -92,7 +92,9 @@ class TypeOptionContext2<T> {
       return Future(() => left(_data!));
     }
 
-    return _fieldService.getFieldTypeOptionData(fieldType: field.fieldType).then((result) {
+    return _fieldService
+        .getFieldTypeOptionData(fieldType: field.fieldType)
+        .then((result) {
       return result.fold(
         (data) {
           _data = dataBuilder.fromBuffer(data.typeOptionData);

+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/grid_bloc.dart


+ 9 - 5
frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/grid_header_bloc.dart

@@ -1,4 +1,4 @@
-import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
+import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
@@ -33,7 +33,8 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
     );
   }
 
-  Future<void> _moveField(_MoveField value, Emitter<GridHeaderState> emit) async {
+  Future<void> _moveField(
+      _MoveField value, Emitter<GridHeaderState> emit) async {
     final fields = List<GridFieldPB>.from(state.fields);
     fields.insert(value.toIndex, fields.removeAt(value.fromIndex));
     emit(state.copyWith(fields: fields));
@@ -62,13 +63,16 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
 @freezed
 class GridHeaderEvent with _$GridHeaderEvent {
   const factory GridHeaderEvent.initial() = _InitialHeader;
-  const factory GridHeaderEvent.didReceiveFieldUpdate(List<GridFieldPB> fields) = _DidReceiveFieldUpdate;
-  const factory GridHeaderEvent.moveField(GridFieldPB field, int fromIndex, int toIndex) = _MoveField;
+  const factory GridHeaderEvent.didReceiveFieldUpdate(
+      List<GridFieldPB> fields) = _DidReceiveFieldUpdate;
+  const factory GridHeaderEvent.moveField(
+      GridFieldPB field, int fromIndex, int toIndex) = _MoveField;
 }
 
 @freezed
 class GridHeaderState with _$GridHeaderState {
-  const factory GridHeaderState({required List<GridFieldPB> fields}) = _GridHeaderState;
+  const factory GridHeaderState({required List<GridFieldPB> fields}) =
+      _GridHeaderState;
 
   factory GridHeaderState.initial(List<GridFieldPB> fields) {
     // final List<GridFieldPB> newFields = List.from(fields);

+ 17 - 11
frontend/app_flowy/lib/workspace/application/grid/grid_service.dart → frontend/app_flowy/lib/plugins/grid/application/grid_service.dart

@@ -1,6 +1,6 @@
 import 'dart:collection';
 
-import 'package:app_flowy/workspace/application/grid/field/grid_listenr.dart';
+import 'package:app_flowy/plugins/grid/application/field/grid_listener.dart';
 import 'package:dartz/dartz.dart';
 import 'package:flowy_sdk/dispatch/dispatch.dart';
 import 'package:flowy_sdk/log.dart';
@@ -26,13 +26,15 @@ class GridService {
     return GridEventGetGrid(payload).send();
   }
 
-  Future<Either<GridRowPB, FlowyError>> createRow({Option<String>? startRowId}) {
+  Future<Either<GridRowPB, FlowyError>> createRow(
+      {Option<String>? startRowId}) {
     CreateRowPayloadPB payload = CreateRowPayloadPB.create()..gridId = gridId;
     startRowId?.fold(() => null, (id) => payload.startRowId = id);
     return GridEventCreateRow(payload).send();
   }
 
-  Future<Either<RepeatedGridFieldPB, FlowyError>> getFields({required List<GridFieldIdPB> fieldIds}) {
+  Future<Either<RepeatedGridFieldPB, FlowyError>> getFields(
+      {required List<GridFieldIdPB> fieldIds}) {
     final payload = QueryFieldPayloadPB.create()
       ..gridId = gridId
       ..fieldIds = RepeatedGridFieldIdPB(items: fieldIds);
@@ -64,9 +66,11 @@ class GridFieldCache {
   final GridFieldsListener _fieldListener;
   FieldsNotifier? _fieldNotifier = FieldsNotifier();
   final Map<FieldsCallback, VoidCallback> _fieldsCallbackMap = {};
-  final Map<FieldChangesetCallback, FieldChangesetCallback> _changesetCallbackMap = {};
+  final Map<FieldChangesetCallback, FieldChangesetCallback>
+      _changesetCallbackMap = {};
 
-  GridFieldCache({required this.gridId}) : _fieldListener = GridFieldsListener(gridId: gridId) {
+  GridFieldCache({required this.gridId})
+      : _fieldListener = GridFieldsListener(gridId: gridId) {
     _fieldListener.start(onFieldsChanged: (result) {
       result.fold(
         (changeset) {
@@ -88,7 +92,8 @@ class GridFieldCache {
     _fieldNotifier = null;
   }
 
-  UnmodifiableListView<GridFieldPB> get unmodifiableFields => UnmodifiableListView(_fieldNotifier?.fields ?? []);
+  UnmodifiableListView<GridFieldPB> get unmodifiableFields =>
+      UnmodifiableListView(_fieldNotifier?.fields ?? []);
 
   List<GridFieldPB> get fields => [..._fieldNotifier?.fields ?? []];
 
@@ -127,7 +132,7 @@ class GridFieldCache {
 
   void removeListener({
     FieldsCallback? onFieldsListener,
-    FieldChangesetCallback? onChangsetListener,
+    FieldChangesetCallback? onChangesetListener,
   }) {
     if (onFieldsListener != null) {
       final fn = _fieldsCallbackMap.remove(onFieldsListener);
@@ -136,8 +141,8 @@ class GridFieldCache {
       }
     }
 
-    if (onChangsetListener != null) {
-      _changesetCallbackMap.remove(onChangsetListener);
+    if (onChangesetListener != null) {
+      _changesetCallbackMap.remove(onChangesetListener);
     }
   }
 
@@ -175,7 +180,8 @@ class GridFieldCache {
     }
     final List<GridFieldPB> newFields = fields;
     for (final updatedField in updatedFields) {
-      final index = newFields.indexWhere((field) => field.id == updatedField.id);
+      final index =
+          newFields.indexWhere((field) => field.id == updatedField.id);
       if (index != -1) {
         newFields.removeAt(index);
         newFields.insert(index, updatedField);
@@ -219,7 +225,7 @@ class GridRowCacheFieldNotifierImpl extends GridRowCacheFieldNotifier {
     }
 
     if (_onChangesetFn != null) {
-      _cache.removeListener(onChangsetListener: _onChangesetFn!);
+      _cache.removeListener(onChangesetListener: _onChangesetFn!);
       _onChangesetFn = null;
     }
   }

+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/prelude.dart → frontend/app_flowy/lib/plugins/grid/application/prelude.dart


+ 5 - 3
frontend/app_flowy/lib/workspace/application/grid/row/row_action_sheet_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/row/row_action_sheet_bloc.dart

@@ -1,4 +1,4 @@
-import 'package:app_flowy/workspace/application/grid/row/row_service.dart';
+import 'package:app_flowy/plugins/grid/application/row/row_service.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
@@ -8,7 +8,8 @@ import 'package:dartz/dartz.dart';
 
 part 'row_action_sheet_bloc.freezed.dart';
 
-class RowActionSheetBloc extends Bloc<RowActionSheetEvent, RowActionSheetState> {
+class RowActionSheetBloc
+    extends Bloc<RowActionSheetEvent, RowActionSheetState> {
   final RowService _rowService;
 
   RowActionSheetBloc({required GridRowInfo rowData})
@@ -56,7 +57,8 @@ class RowActionSheetState with _$RowActionSheetState {
     required GridRowInfo rowData,
   }) = _RowActionSheetState;
 
-  factory RowActionSheetState.initial(GridRowInfo rowData) => RowActionSheetState(
+  factory RowActionSheetState.initial(GridRowInfo rowData) =>
+      RowActionSheetState(
         rowData: rowData,
       );
 }

+ 12 - 6
frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/row/row_bloc.dart

@@ -1,5 +1,5 @@
 import 'dart:collection';
-import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
+import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
 import 'package:equatable/equatable.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
@@ -34,7 +34,9 @@ class RowBloc extends Bloc<RowEvent, RowState> {
             _rowService.createRow();
           },
           didReceiveCellDatas: (_DidReceiveCellDatas value) async {
-            final fields = value.gridCellMap.values.map((e) => GridCellEquatable(e.field)).toList();
+            final fields = value.gridCellMap.values
+                .map((e) => GridCellEquatable(e.field))
+                .toList();
             final snapshots = UnmodifiableListView(fields);
             emit(state.copyWith(
               gridCellMap: value.gridCellMap,
@@ -59,7 +61,8 @@ class RowBloc extends Bloc<RowEvent, RowState> {
   Future<void> _startListening() async {
     _rowListenFn = _rowCache.addListener(
       rowId: state.rowInfo.id,
-      onCellUpdated: (cellDatas, reason) => add(RowEvent.didReceiveCellDatas(cellDatas, reason)),
+      onCellUpdated: (cellDatas, reason) =>
+          add(RowEvent.didReceiveCellDatas(cellDatas, reason)),
       listenWhen: () => !isClosed,
     );
   }
@@ -69,7 +72,8 @@ class RowBloc extends Bloc<RowEvent, RowState> {
 class RowEvent with _$RowEvent {
   const factory RowEvent.initial() = _InitialRow;
   const factory RowEvent.createRow() = _CreateRow;
-  const factory RowEvent.didReceiveCellDatas(GridCellMap gridCellMap, GridRowChangeReason reason) =
+  const factory RowEvent.didReceiveCellDatas(
+          GridCellMap gridCellMap, GridRowChangeReason reason) =
       _DidReceiveCellDatas;
 }
 
@@ -82,10 +86,12 @@ class RowState with _$RowState {
     GridRowChangeReason? changeReason,
   }) = _RowState;
 
-  factory RowState.initial(GridRowInfo rowInfo, GridCellMap cellDataMap) => RowState(
+  factory RowState.initial(GridRowInfo rowInfo, GridCellMap cellDataMap) =>
+      RowState(
         rowInfo: rowInfo,
         gridCellMap: cellDataMap,
-        snapshots: UnmodifiableListView(cellDataMap.values.map((e) => GridCellEquatable(e.field)).toList()),
+        snapshots: UnmodifiableListView(
+            cellDataMap.values.map((e) => GridCellEquatable(e.field)).toList()),
       );
 }
 

+ 5 - 3
frontend/app_flowy/lib/workspace/application/grid/row/row_detail_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/row/row_detail_bloc.dart

@@ -1,4 +1,4 @@
-import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
+import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'dart:async';
@@ -42,7 +42,8 @@ class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
   Future<void> _startListening() async {
     _rowListenFn = _rowCache.addListener(
       rowId: rowInfo.id,
-      onCellUpdated: (cellDatas, reason) => add(RowDetailEvent.didReceiveCellDatas(cellDatas.values.toList())),
+      onCellUpdated: (cellDatas, reason) =>
+          add(RowDetailEvent.didReceiveCellDatas(cellDatas.values.toList())),
       listenWhen: () => !isClosed,
     );
   }
@@ -58,7 +59,8 @@ class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
 @freezed
 class RowDetailEvent with _$RowDetailEvent {
   const factory RowDetailEvent.initial() = _Initial;
-  const factory RowDetailEvent.didReceiveCellDatas(List<GridCellIdentifier> gridCells) = _DidReceiveCellDatas;
+  const factory RowDetailEvent.didReceiveCellDatas(
+      List<GridCellIdentifier> gridCells) = _DidReceiveCellDatas;
 }
 
 @freezed

+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart → frontend/app_flowy/lib/plugins/grid/application/row/row_listener.dart


+ 21 - 10
frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart → frontend/app_flowy/lib/plugins/grid/application/row/row_service.dart

@@ -1,5 +1,5 @@
 import 'dart:collection';
-import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
+import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
 import 'package:dartz/dartz.dart';
 import 'package:flowy_sdk/dispatch/dispatch.dart';
 import 'package:flowy_sdk/log.dart';
@@ -53,9 +53,12 @@ class GridRowCache {
         _rowChangeReasonNotifier = _GridRowChangesetNotifier(),
         _fieldNotifier = notifier {
     //
-    notifier.onFieldsChanged(() => _rowChangeReasonNotifier.receive(const GridRowChangeReason.fieldDidChange()));
+    notifier.onFieldsChanged(() => _rowChangeReasonNotifier
+        .receive(const GridRowChangeReason.fieldDidChange()));
     notifier.onFieldChanged((field) => _cellCache.remove(field.id));
-    _rowInfos = block.rows.map((rowInfo) => buildGridRow(rowInfo.id, rowInfo.height.toDouble())).toList();
+    _rowInfos = block.rows
+        .map((rowInfo) => buildGridRow(rowInfo.id, rowInfo.height.toDouble()))
+        .toList();
   }
 
   Future<void> dispose() async {
@@ -81,7 +84,9 @@ class GridRowCache {
 
     final List<GridRowInfo> newRows = [];
     final DeletedIndexs deletedIndex = [];
-    final Map<String, String> deletedRowByRowId = {for (var rowId in deletedRows) rowId: rowId};
+    final Map<String, String> deletedRowByRowId = {
+      for (var rowId in deletedRows) rowId: rowId
+    };
 
     _rowInfos.asMap().forEach((index, row) {
       if (deletedRowByRowId[row.id] == null) {
@@ -107,7 +112,8 @@ class GridRowCache {
         rowId: insertRow.rowId,
       );
       insertIndexs.add(insertIndex);
-      _rowInfos.insert(insertRow.index, (buildGridRow(insertRow.rowId, insertRow.height.toDouble())));
+      _rowInfos.insert(insertRow.index,
+          (buildGridRow(insertRow.rowId, insertRow.height.toDouble())));
     }
 
     _rowChangeReasonNotifier.receive(GridRowChangeReason.insert(insertIndexs));
@@ -126,7 +132,8 @@ class GridRowCache {
         _rowByRowId[rowId] = updatedRow.row;
 
         _rowInfos.removeAt(index);
-        _rowInfos.insert(index, buildGridRow(rowId, updatedRow.row.height.toDouble()));
+        _rowInfos.insert(
+            index, buildGridRow(rowId, updatedRow.row.height.toDouble()));
         updatedIndexs[rowId] = UpdatedIndex(index: index, rowId: rowId);
       }
     }
@@ -225,7 +232,8 @@ class GridRowCache {
     updatedRow.freeze();
 
     _rowByRowId[updatedRow.id] = updatedRow;
-    final index = _rowInfos.indexWhere((gridRow) => gridRow.id == updatedRow.id);
+    final index =
+        _rowInfos.indexWhere((gridRow) => gridRow.id == updatedRow.id);
     if (index != -1) {
       // update the corresponding row in _rows if they are not the same
       if (_rowInfos[index].rawRow != updatedRow) {
@@ -237,7 +245,8 @@ class GridRowCache {
         updatedIndexs[row.id] = UpdatedIndex(index: index, rowId: row.id);
 
         //
-        _rowChangeReasonNotifier.receive(GridRowChangeReason.update(updatedIndexs));
+        _rowChangeReasonNotifier
+            .receive(GridRowChangeReason.update(updatedIndexs));
       }
     }
   }
@@ -275,7 +284,8 @@ class RowService {
   final String blockId;
   final String rowId;
 
-  RowService({required this.gridId, required this.blockId, required this.rowId});
+  RowService(
+      {required this.gridId, required this.blockId, required this.rowId});
 
   Future<Either<GridRowPB, FlowyError>> createRow() {
     CreateRowPayloadPB payload = CreateRowPayloadPB.create()
@@ -285,7 +295,8 @@ class RowService {
     return GridEventCreateRow(payload).send();
   }
 
-  Future<Either<Unit, FlowyError>> moveRow(String rowId, int fromIndex, int toIndex) {
+  Future<Either<Unit, FlowyError>> moveRow(
+      String rowId, int fromIndex, int toIndex) {
     final payload = MoveItemPayloadPB.create()
       ..gridId = gridId
       ..itemId = rowId

+ 16 - 9
frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/setting/property_bloc.dart

@@ -1,5 +1,5 @@
-import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
-import 'package:app_flowy/workspace/application/grid/grid_service.dart';
+import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
+import 'package:app_flowy/plugins/grid/application/grid_service.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
@@ -22,8 +22,10 @@ class GridPropertyBloc extends Bloc<GridPropertyEvent, GridPropertyState> {
             _startListening();
           },
           setFieldVisibility: (_SetFieldVisibility value) async {
-            final fieldService = FieldService(gridId: gridId, fieldId: value.fieldId);
-            final result = await fieldService.updateField(visibility: value.visibility);
+            final fieldService =
+                FieldService(gridId: gridId, fieldId: value.fieldId);
+            final result =
+                await fieldService.updateField(visibility: value.visibility);
             result.fold(
               (l) => null,
               (err) => Log.error(err),
@@ -50,7 +52,8 @@ class GridPropertyBloc extends Bloc<GridPropertyEvent, GridPropertyState> {
   }
 
   void _startListening() {
-    _onFieldsFn = (fields) => add(GridPropertyEvent.didReceiveFieldUpdate(fields));
+    _onFieldsFn =
+        (fields) => add(GridPropertyEvent.didReceiveFieldUpdate(fields));
     _fieldCache.addListener(
       onFields: _onFieldsFn,
       listenWhen: () => !isClosed,
@@ -61,9 +64,12 @@ class GridPropertyBloc extends Bloc<GridPropertyEvent, GridPropertyState> {
 @freezed
 class GridPropertyEvent with _$GridPropertyEvent {
   const factory GridPropertyEvent.initial() = _Initial;
-  const factory GridPropertyEvent.setFieldVisibility(String fieldId, bool visibility) = _SetFieldVisibility;
-  const factory GridPropertyEvent.didReceiveFieldUpdate(List<GridFieldPB> fields) = _DidReceiveFieldUpdate;
-  const factory GridPropertyEvent.moveField(int fromIndex, int toIndex) = _MoveField;
+  const factory GridPropertyEvent.setFieldVisibility(
+      String fieldId, bool visibility) = _SetFieldVisibility;
+  const factory GridPropertyEvent.didReceiveFieldUpdate(
+      List<GridFieldPB> fields) = _DidReceiveFieldUpdate;
+  const factory GridPropertyEvent.moveField(int fromIndex, int toIndex) =
+      _MoveField;
 }
 
 @freezed
@@ -73,7 +79,8 @@ class GridPropertyState with _$GridPropertyState {
     required List<GridFieldPB> fields,
   }) = _GridPropertyState;
 
-  factory GridPropertyState.initial(String gridId, List<GridFieldPB> fields) => GridPropertyState(
+  factory GridPropertyState.initial(String gridId, List<GridFieldPB> fields) =>
+      GridPropertyState(
         gridId: gridId,
         fields: fields,
       );

+ 0 - 0
frontend/app_flowy/lib/workspace/application/grid/setting/setting_bloc.dart → frontend/app_flowy/lib/plugins/grid/application/setting/setting_bloc.dart


+ 3 - 3
frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart → frontend/app_flowy/lib/plugins/grid/grid.dart

@@ -1,12 +1,12 @@
 import 'package:app_flowy/generated/locale_keys.g.dart';
-import 'package:app_flowy/plugin/plugin.dart';
+import 'package:app_flowy/startup/plugin/plugin.dart';
 import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
-import 'package:app_flowy/workspace/presentation/plugins/widgets/left_bar_item.dart';
+import 'package:app_flowy/workspace/presentation/widgets/left_bar_item.dart';
 import 'package:easy_localization/easy_localization.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
 import 'package:flutter/material.dart';
 
-import 'src/grid_page.dart';
+import 'presentation/grid_page.dart';
 
 class GridPluginBuilder implements PluginBuilder {
   @override

+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/controller/flowy_table_selection.dart → frontend/app_flowy/lib/plugins/grid/presentation/controller/flowy_table_selection.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/controller/grid_scroll.dart → frontend/app_flowy/lib/plugins/grid/presentation/controller/grid_scroll.dart


+ 26 - 17
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart → frontend/app_flowy/lib/plugins/grid/presentation/grid_page.dart

@@ -1,6 +1,6 @@
 import 'package:app_flowy/startup/startup.dart';
-import 'package:app_flowy/workspace/application/grid/grid_bloc.dart';
-import 'package:app_flowy/workspace/application/grid/row/row_service.dart';
+import 'package:app_flowy/plugins/grid/application/grid_bloc.dart';
+import 'package:app_flowy/plugins/grid/application/row/row_service.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
 import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart';
@@ -35,13 +35,15 @@ class _GridPageState extends State<GridPage> {
     return MultiBlocProvider(
       providers: [
         BlocProvider<GridBloc>(
-          create: (context) => getIt<GridBloc>(param1: widget.view)..add(const GridEvent.initial()),
+          create: (context) => getIt<GridBloc>(param1: widget.view)
+            ..add(const GridEvent.initial()),
         ),
       ],
       child: BlocBuilder<GridBloc, GridState>(
         builder: (context, state) {
           return state.loadingState.map(
-            loading: (_) => const Center(child: CircularProgressIndicator.adaptive()),
+            loading: (_) =>
+                const Center(child: CircularProgressIndicator.adaptive()),
             finish: (result) => result.successOrFail.fold(
               (_) => const GridShortcuts(child: FlowyGrid()),
               (err) => FlowyErrorPage(err.toString()),
@@ -76,7 +78,8 @@ class FlowyGrid extends StatefulWidget {
 }
 
 class _FlowyGridState extends State<FlowyGrid> {
-  final _scrollController = GridScrollController(scrollGroupContorller: LinkedScrollControllerGroup());
+  final _scrollController = GridScrollController(
+      scrollGroupContorller: LinkedScrollControllerGroup());
   late ScrollController headerScrollController;
 
   @override
@@ -204,7 +207,8 @@ class _GridRowsState extends State<_GridRows> {
             for (final item in value.items) {
               _key.currentState?.removeItem(
                 item.index,
-                (context, animation) => _renderRow(context, item.row, animation),
+                (context, animation) =>
+                    _renderRow(context, item.row, animation),
               );
             }
           },
@@ -215,8 +219,10 @@ class _GridRowsState extends State<_GridRows> {
         return SliverAnimatedList(
           key: _key,
           initialItemCount: context.read<GridBloc>().state.rowInfos.length,
-          itemBuilder: (BuildContext context, int index, Animation<double> animation) {
-            final GridRowInfo rowInfo = context.read<GridBloc>().state.rowInfos[index];
+          itemBuilder:
+              (BuildContext context, int index, Animation<double> animation) {
+            final GridRowInfo rowInfo =
+                context.read<GridBloc>().state.rowInfos[index];
             return _renderRow(context, rowInfo, animation);
           },
         );
@@ -229,7 +235,8 @@ class _GridRowsState extends State<_GridRows> {
     GridRowInfo rowInfo,
     Animation<double> animation,
   ) {
-    final rowCache = context.read<GridBloc>().getRowCache(rowInfo.blockId, rowInfo.id);
+    final rowCache =
+        context.read<GridBloc>().getRowCache(rowInfo.blockId, rowInfo.id);
     final fieldCache = context.read<GridBloc>().fieldCache;
     if (rowCache != null) {
       return SizeTransition(
@@ -266,10 +273,10 @@ class _GridFooter extends StatelessWidget {
                 SizedBox(width: GridSize.leadingHeaderPadding),
                 Column(
                   crossAxisAlignment: CrossAxisAlignment.start,
-                  children:  [
+                  children: [
                     const SizedBox(width: 120, child: GridAddRowButton()),
                     const SizedBox(height: 30),
-                    _rowCountTextWidget(theme: theme,count: rowCount)
+                    _rowCountTextWidget(theme: theme, count: rowCount)
                   ],
                 ),
               ],
@@ -280,16 +287,18 @@ class _GridFooter extends StatelessWidget {
     );
   }
 
-  Widget _rowCountTextWidget({required AppTheme theme, required int count}){
+  Widget _rowCountTextWidget({required AppTheme theme, required int count}) {
     return Row(
       mainAxisAlignment: MainAxisAlignment.start,
       children: [
-        FlowyText.regular('Count : ',
-         fontSize: 13,
-         color: theme.shader3,
+        FlowyText.regular(
+          'Count : ',
+          fontSize: 13,
+          color: theme.shader3,
         ),
-        FlowyText.regular(count.toString(),
-         fontSize: 13,
+        FlowyText.regular(
+          count.toString(),
+          fontSize: 13,
         ),
       ],
     );

+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart → frontend/app_flowy/lib/plugins/grid/presentation/layout/layout.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart → frontend/app_flowy/lib/plugins/grid/presentation/layout/sizes.dart


+ 21 - 8
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_accessory.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/cell_accessory.dart

@@ -1,11 +1,12 @@
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra_ui/style_widget/hover.dart';
-import 'package:flutter/widgets.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flutter/material.dart';
 import 'package:provider/provider.dart';
 import 'package:flowy_infra/size.dart';
 import 'package:styled_widget/styled_widget.dart';
+import 'package:app_flowy/generated/locale_keys.g.dart';
+import 'package:easy_localization/easy_localization.dart';
 
 class GridCellAccessoryBuildContext {
   final BuildContext anchorContext;
@@ -39,7 +40,13 @@ class PrimaryCellAccessory extends StatelessWidget with GridCellAccessory {
       return const SizedBox();
     } else {
       final theme = context.watch<AppTheme>();
-      return svgWidget("grid/expander", color: theme.main1);
+      return Tooltip(
+        message: LocaleKeys.tooltip_openAsPage.tr(),
+        child: svgWidget(
+          "grid/expander",
+          color: theme.main1,
+        ),
+      );
     }
   }
 
@@ -50,7 +57,8 @@ class PrimaryCellAccessory extends StatelessWidget with GridCellAccessory {
   bool enable() => !isCellEditing;
 }
 
-typedef AccessoryBuilder = List<GridCellAccessory> Function(GridCellAccessoryBuildContext buildContext);
+typedef AccessoryBuilder = List<GridCellAccessory> Function(
+    GridCellAccessoryBuildContext buildContext);
 
 abstract class CellAccessory extends Widget {
   const CellAccessory({Key? key}) : super(key: key);
@@ -81,7 +89,8 @@ class _AccessoryHoverState extends State<AccessoryHover> {
   @override
   void initState() {
     _hoverState = AccessoryHoverState();
-    _listenerFn = () => _hoverState.onHover = widget.child.onAccessoryHover?.value ?? false;
+    _listenerFn = () =>
+        _hoverState.onHover = widget.child.onAccessoryHover?.value ?? false;
     widget.child.onAccessoryHover?.addListener(_listenerFn!);
 
     super.initState();
@@ -159,7 +168,8 @@ class _Background extends StatelessWidget {
       builder: (context, state, child) {
         if (state.onHover) {
           return FlowyHoverContainer(
-            style: HoverStyle(borderRadius: Corners.s6Border, hoverColor: theme.shader6),
+            style: HoverStyle(
+                borderRadius: Corners.s6Border, hoverColor: theme.shader6),
           );
         } else {
           return const SizedBox();
@@ -171,14 +181,17 @@ class _Background extends StatelessWidget {
 
 class CellAccessoryContainer extends StatelessWidget {
   final List<GridCellAccessory> accessories;
-  const CellAccessoryContainer({required this.accessories, Key? key}) : super(key: key);
+  const CellAccessoryContainer({required this.accessories, Key? key})
+      : super(key: key);
 
   @override
   Widget build(BuildContext context) {
     final theme = context.watch<AppTheme>();
-    final children = accessories.where((accessory) => accessory.enable()).map((accessory) {
+    final children =
+        accessories.where((accessory) => accessory.enable()).map((accessory) {
       final hover = FlowyHover(
-        style: HoverStyle(hoverColor: theme.bg3, backgroundColor: theme.surface),
+        style:
+            HoverStyle(hoverColor: theme.bg3, backgroundColor: theme.surface),
         builder: (_, onHover) => Container(
           width: 26,
           height: 26,

+ 34 - 13
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/cell_builder.dart

@@ -1,5 +1,5 @@
-import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
-import 'package:app_flowy/workspace/application/grid/grid_service.dart';
+import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
+import 'package:app_flowy/plugins/grid/application/grid_service.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter/widgets.dart';
@@ -30,19 +30,36 @@ class GridCellBuilder {
     final key = cell.key();
     switch (cell.fieldType) {
       case FieldType.Checkbox:
-        return GridCheckboxCell(cellControllerBuilder: cellControllerBuilder, key: key);
+        return GridCheckboxCell(
+            cellControllerBuilder: cellControllerBuilder, key: key);
       case FieldType.DateTime:
-        return GridDateCell(cellControllerBuilder: cellControllerBuilder, key: key, style: style);
+        return GridDateCell(
+            cellControllerBuilder: cellControllerBuilder,
+            key: key,
+            style: style);
       case FieldType.SingleSelect:
-        return GridSingleSelectCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
+        return GridSingleSelectCell(
+            cellContorllerBuilder: cellControllerBuilder,
+            style: style,
+            key: key);
       case FieldType.MultiSelect:
-        return GridMultiSelectCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
+        return GridMultiSelectCell(
+            cellContorllerBuilder: cellControllerBuilder,
+            style: style,
+            key: key);
       case FieldType.Number:
-        return GridNumberCell(cellContorllerBuilder: cellControllerBuilder, key: key);
+        return GridNumberCell(
+            cellContorllerBuilder: cellControllerBuilder, key: key);
       case FieldType.RichText:
-        return GridTextCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
+        return GridTextCell(
+            cellContorllerBuilder: cellControllerBuilder,
+            style: style,
+            key: key);
       case FieldType.URL:
-        return GridURLCell(cellContorllerBuilder: cellControllerBuilder, style: style, key: key);
+        return GridURLCell(
+            cellContorllerBuilder: cellControllerBuilder,
+            style: style,
+            key: key);
     }
     throw UnimplementedError;
   }
@@ -65,7 +82,8 @@ abstract class CellEditable {
   ValueNotifier<bool> get onCellEditing;
 }
 
-abstract class GridCellWidget extends StatefulWidget implements CellAccessory, CellEditable, CellShortcuts {
+abstract class GridCellWidget extends StatefulWidget
+    implements CellAccessory, CellEditable, CellShortcuts {
   GridCellWidget({Key? key}) : super(key: key) {
     onCellEditing.addListener(() {
       onCellFocus.value = onCellEditing.value;
@@ -83,7 +101,8 @@ abstract class GridCellWidget extends StatefulWidget implements CellAccessory, C
   final ValueNotifier<bool> onCellEditing = ValueNotifier<bool>(false);
 
   @override
-  List<GridCellAccessory> Function(GridCellAccessoryBuildContext buildContext)? get accessoryBuilder => null;
+  List<GridCellAccessory> Function(GridCellAccessoryBuildContext buildContext)?
+      get accessoryBuilder => null;
 
   @override
   final GridCellFocusListener beginFocus = GridCellFocusListener();
@@ -129,12 +148,14 @@ abstract class GridCellState<T extends GridCellWidget> extends State<T> {
   void onInsert(String value) {}
 }
 
-abstract class GridFocusNodeCellState<T extends GridCellWidget> extends GridCellState<T> {
+abstract class GridFocusNodeCellState<T extends GridCellWidget>
+    extends GridCellState<T> {
   SingleListenrFocusNode focusNode = SingleListenrFocusNode();
 
   @override
   void initState() {
-    widget.shortcutHandlers[CellKeyboardKey.onEnter] = () => focusNode.unfocus();
+    widget.shortcutHandlers[CellKeyboardKey.onEnter] =
+        () => focusNode.unfocus();
     _listenOnFocusNodeChanged();
     super.initState();
   }

+ 21 - 11
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_cotainer.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/cell_cotainer.dart

@@ -1,10 +1,10 @@
-import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
-import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flutter/widgets.dart';
 import 'package:provider/provider.dart';
 import 'package:styled_widget/styled_widget.dart';
 
+import '../../layout/sizes.dart';
+import '../row/grid_row.dart';
 import 'cell_accessory.dart';
 import 'cell_builder.dart';
 import 'cell_shortcuts.dart';
@@ -24,9 +24,11 @@ class CellContainer extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return ChangeNotifierProxyProvider<RegionStateNotifier, CellContainerNotifier>(
+    return ChangeNotifierProxyProvider<RegionStateNotifier,
+        CellContainerNotifier>(
       create: (_) => CellContainerNotifier(child),
-      update: (_, rowStateNotifier, cellStateNotifier) => cellStateNotifier!..onEnter = rowStateNotifier.onEnter,
+      update: (_, rowStateNotifier, cellStateNotifier) =>
+          cellStateNotifier!..onEnter = rowStateNotifier.onEnter,
       child: Selector<CellContainerNotifier, bool>(
         selector: (context, notifier) => notifier.isFocus,
         builder: (context, isFocus, _) {
@@ -39,7 +41,8 @@ class CellContainer extends StatelessWidget {
             ));
 
             if (accessories.isNotEmpty) {
-              container = CellEnterRegion(child: container, accessories: accessories);
+              container =
+                  CellEnterRegion(child: container, accessories: accessories);
             }
           }
 
@@ -65,7 +68,8 @@ class CellContainer extends StatelessWidget {
       return BoxDecoration(border: Border.fromBorderSide(borderSide));
     } else {
       final borderSide = BorderSide(color: theme.shader5, width: 1.0);
-      return BoxDecoration(border: Border(right: borderSide, bottom: borderSide));
+      return BoxDecoration(
+          border: Border(right: borderSide, bottom: borderSide));
     }
   }
 }
@@ -73,7 +77,9 @@ class CellContainer extends StatelessWidget {
 class CellEnterRegion extends StatelessWidget {
   final Widget child;
   final List<GridCellAccessory> accessories;
-  const CellEnterRegion({required this.child, required this.accessories, Key? key}) : super(key: key);
+  const CellEnterRegion(
+      {required this.child, required this.accessories, Key? key})
+      : super(key: key);
 
   @override
   Widget build(BuildContext context) {
@@ -82,13 +88,18 @@ class CellEnterRegion extends StatelessWidget {
       builder: (context, onEnter, _) {
         List<Widget> children = [child];
         if (onEnter) {
-          children.add(CellAccessoryContainer(accessories: accessories).positioned(right: 0));
+          children.add(CellAccessoryContainer(accessories: accessories)
+              .positioned(right: 0));
         }
 
         return MouseRegion(
           cursor: SystemMouseCursors.click,
-          onEnter: (p) => Provider.of<CellContainerNotifier>(context, listen: false).onEnter = true,
-          onExit: (p) => Provider.of<CellContainerNotifier>(context, listen: false).onEnter = false,
+          onEnter: (p) =>
+              Provider.of<CellContainerNotifier>(context, listen: false)
+                  .onEnter = true,
+          onExit: (p) =>
+              Provider.of<CellContainerNotifier>(context, listen: false)
+                  .onEnter = false,
           child: Stack(
             alignment: AlignmentDirectional.center,
             fit: StackFit.expand,
@@ -102,7 +113,6 @@ class CellEnterRegion extends StatelessWidget {
 
 class CellContainerNotifier extends ChangeNotifier {
   final CellEditable cellEditable;
-  bool mouted = false;
   VoidCallback? _onCellFocusListener;
   bool _isFocus = false;
   bool _onEnter = false;

+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_decoration.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/cell_decoration.dart


+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_shortcuts.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/cell_shortcuts.dart


+ 9 - 4
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/checkbox_cell.dart

@@ -1,5 +1,5 @@
 import 'package:app_flowy/startup/startup.dart';
-import 'package:app_flowy/workspace/application/grid/prelude.dart';
+import 'package:app_flowy/plugins/grid/application/prelude.dart';
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra_ui/style_widget/icon_button.dart';
 import 'package:flutter/widgets.dart';
@@ -23,7 +23,8 @@ class _CheckboxCellState extends GridCellState<GridCheckboxCell> {
   @override
   void initState() {
     final cellContext = widget.cellControllerBuilder.build();
-    _cellBloc = getIt<CheckboxCellBloc>(param1: cellContext)..add(const CheckboxCellEvent.initial());
+    _cellBloc = getIt<CheckboxCellBloc>(param1: cellContext)
+      ..add(const CheckboxCellEvent.initial());
     super.initState();
   }
 
@@ -33,11 +34,15 @@ class _CheckboxCellState extends GridCellState<GridCheckboxCell> {
       value: _cellBloc,
       child: BlocBuilder<CheckboxCellBloc, CheckboxCellState>(
         builder: (context, state) {
-          final icon = state.isSelected ? svgWidget('editor/editor_check') : svgWidget('editor/editor_uncheck');
+          final icon = state.isSelected
+              ? svgWidget('editor/editor_check')
+              : svgWidget('editor/editor_uncheck');
           return Align(
             alignment: Alignment.centerLeft,
             child: FlowyIconButton(
-              onPressed: () => context.read<CheckboxCellBloc>().add(const CheckboxCellEvent.select()),
+              onPressed: () => context
+                  .read<CheckboxCellBloc>()
+                  .add(const CheckboxCellEvent.select()),
               iconPadding: EdgeInsets.zero,
               icon: icon,
               width: 20,

+ 8 - 4
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell/date_cell.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_cell.dart

@@ -2,7 +2,7 @@ import 'package:flowy_infra_ui/style_widget/text.dart';
 import 'package:flutter/widgets.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:app_flowy/startup/startup.dart';
-import 'package:app_flowy/workspace/application/grid/prelude.dart';
+import 'package:app_flowy/plugins/grid/application/prelude.dart';
 
 import '../cell_builder.dart';
 import 'date_editor.dart';
@@ -44,13 +44,16 @@ class _DateCellState extends GridCellState<GridDateCell> {
   @override
   void initState() {
     final cellContext = widget.cellControllerBuilder.build();
-    _cellBloc = getIt<DateCellBloc>(param1: cellContext)..add(const DateCellEvent.initial());
+    _cellBloc = getIt<DateCellBloc>(param1: cellContext)
+      ..add(const DateCellEvent.initial());
     super.initState();
   }
 
   @override
   Widget build(BuildContext context) {
-    final alignment = widget.cellStyle != null ? widget.cellStyle!.alignment : Alignment.center;
+    final alignment = widget.cellStyle != null
+        ? widget.cellStyle!.alignment
+        : Alignment.center;
     return BlocProvider.value(
       value: _cellBloc,
       child: BlocBuilder<DateCellBloc, DateCellState>(
@@ -77,7 +80,8 @@ class _DateCellState extends GridCellState<GridDateCell> {
   void _showCalendar(BuildContext context) {
     final bloc = context.read<DateCellBloc>();
     widget.onCellEditing.value = true;
-    final calendar = DateCellEditor(onDismissed: () => widget.onCellEditing.value = false);
+    final calendar =
+        DateCellEditor(onDismissed: () => widget.onCellEditing.value = false);
     calendar.show(
       context,
       cellController: bloc.cellContext.clone(),

+ 28 - 13
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell/date_editor.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart

@@ -1,7 +1,5 @@
 import 'package:app_flowy/generated/locale_keys.g.dart';
-import 'package:app_flowy/workspace/application/grid/cell/date_cal_bloc.dart';
-import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
-import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart';
+import 'package:app_flowy/plugins/grid/application/cell/date_cal_bloc.dart';
 import 'package:easy_localization/easy_localization.dart';
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
@@ -15,7 +13,10 @@ import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:table_calendar/table_calendar.dart';
-import 'package:app_flowy/workspace/application/grid/prelude.dart';
+import 'package:app_flowy/plugins/grid/application/prelude.dart';
+
+import '../../../layout/sizes.dart';
+import '../../header/type_option/date.dart';
 
 final kToday = DateTime.now();
 final kFirstDay = DateTime(kToday.year, kToday.month - 3, kToday.day);
@@ -35,7 +36,8 @@ class DateCellEditor with FlowyOverlayDelegate {
   }) async {
     DateCellEditor.remove(context);
 
-    final result = await cellController.getFieldTypeOption(DateTypeOptionDataParser());
+    final result =
+        await cellController.getFieldTypeOption(DateTypeOptionDataParser());
     result.fold(
       (dateTypeOption) {
         final calendar = _CellCalendarWidget(
@@ -167,7 +169,9 @@ class _CellCalendarWidget extends StatelessWidget {
           },
           onDaySelected: (selectedDay, focusedDay) {
             _CalDateTimeSetting.hide(context);
-            context.read<DateCalBloc>().add(DateCalEvent.selectDay(selectedDay));
+            context
+                .read<DateCalBloc>()
+                .add(DateCalEvent.selectDay(selectedDay));
           },
           onFormatChanged: (format) {
             _CalDateTimeSetting.hide(context);
@@ -175,7 +179,9 @@ class _CellCalendarWidget extends StatelessWidget {
           },
           onPageChanged: (focusedDay) {
             _CalDateTimeSetting.hide(context);
-            context.read<DateCalBloc>().add(DateCalEvent.setFocusedDay(focusedDay));
+            context
+                .read<DateCalBloc>()
+                .add(DateCalEvent.setFocusedDay(focusedDay));
           },
         );
       },
@@ -200,11 +206,14 @@ class _IncludeTimeButton extends StatelessWidget {
               children: [
                 svgWidget("grid/clock", color: theme.iconColor),
                 const HSpace(4),
-                FlowyText.medium(LocaleKeys.grid_field_includeTime.tr(), fontSize: 14),
+                FlowyText.medium(LocaleKeys.grid_field_includeTime.tr(),
+                    fontSize: 14),
                 const Spacer(),
                 Switch(
                   value: includeTime,
-                  onChanged: (newValue) => context.read<DateCalBloc>().add(DateCalEvent.setIncludeTime(newValue)),
+                  onChanged: (newValue) => context
+                      .read<DateCalBloc>()
+                      .add(DateCalEvent.setIncludeTime(newValue)),
                 ),
               ],
             ),
@@ -294,7 +303,9 @@ class _DateTypeOptionButton extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     final theme = context.watch<AppTheme>();
-    final title = LocaleKeys.grid_field_dateFormat.tr() + " &" + LocaleKeys.grid_field_timeFormat.tr();
+    final title = LocaleKeys.grid_field_dateFormat.tr() +
+        " &" +
+        LocaleKeys.grid_field_timeFormat.tr();
     return BlocSelector<DateCalBloc, DateCalState, DateTypeOption>(
       selector: (state) => state.dateTypeOption,
       builder: (context, dateTypeOption) {
@@ -321,7 +332,9 @@ class _DateTypeOptionButton extends StatelessWidget {
 class _CalDateTimeSetting extends StatefulWidget {
   final DateTypeOption dateTypeOption;
   final Function(DateCalEvent) onEvent;
-  const _CalDateTimeSetting({required this.dateTypeOption, required this.onEvent, Key? key}) : super(key: key);
+  const _CalDateTimeSetting(
+      {required this.dateTypeOption, required this.onEvent, Key? key})
+      : super(key: key);
 
   @override
   State<_CalDateTimeSetting> createState() => _CalDateTimeSettingState();
@@ -358,7 +371,8 @@ class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {
       DateFormatButton(onTap: () {
         final list = DateFormatList(
           selectedFormat: widget.dateTypeOption.dateFormat,
-          onSelected: (format) => widget.onEvent(DateCalEvent.setDateFormat(format)),
+          onSelected: (format) =>
+              widget.onEvent(DateCalEvent.setDateFormat(format)),
         );
         _showOverlay(context, list);
       }),
@@ -367,7 +381,8 @@ class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {
         onTap: () {
           final list = TimeFormatList(
             selectedFormat: widget.dateTypeOption.timeFormat,
-            onSelected: (format) => widget.onEvent(DateCalEvent.setTimeFormat(format)),
+            onSelected: (format) =>
+                widget.onEvent(DateCalEvent.setTimeFormat(format)),
           );
           _showOverlay(context, list);
         },

+ 9 - 5
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/number_cell.dart

@@ -1,6 +1,6 @@
 import 'dart:async';
 import 'package:app_flowy/startup/startup.dart';
-import 'package:app_flowy/workspace/application/grid/prelude.dart';
+import 'package:app_flowy/plugins/grid/application/prelude.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 
@@ -26,8 +26,10 @@ class _NumberCellState extends GridFocusNodeCellState<GridNumberCell> {
   @override
   void initState() {
     final cellContext = widget.cellContorllerBuilder.build();
-    _cellBloc = getIt<NumberCellBloc>(param1: cellContext)..add(const NumberCellEvent.initial());
-    _controller = TextEditingController(text: contentFromState(_cellBloc.state));
+    _cellBloc = getIt<NumberCellBloc>(param1: cellContext)
+      ..add(const NumberCellEvent.initial());
+    _controller =
+        TextEditingController(text: contentFromState(_cellBloc.state));
     super.initState();
   }
 
@@ -39,7 +41,8 @@ class _NumberCellState extends GridFocusNodeCellState<GridNumberCell> {
         listeners: [
           BlocListener<NumberCellBloc, NumberCellState>(
             listenWhen: (p, c) => p.content != c.content,
-            listener: (context, state) => _controller.text = contentFromState(state),
+            listener: (context, state) =>
+                _controller.text = contentFromState(state),
           ),
         ],
         child: TextField(
@@ -70,7 +73,8 @@ class _NumberCellState extends GridFocusNodeCellState<GridNumberCell> {
     if (mounted) {
       _delayOperation?.cancel();
       _delayOperation = Timer(const Duration(milliseconds: 300), () {
-        if (_cellBloc.isClosed == false && _controller.text != contentFromState(_cellBloc.state)) {
+        if (_cellBloc.isClosed == false &&
+            _controller.text != contentFromState(_cellBloc.state)) {
           _cellBloc.add(NumberCellEvent.updateCell(_controller.text));
         }
       });

+ 1 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/prelude.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/prelude.dart

@@ -4,3 +4,4 @@ export 'number_cell.dart';
 export 'date_cell/date_cell.dart';
 export 'checkbox_cell.dart';
 export 'select_option_cell/select_option_cell.dart';
+export 'url_cell/url_cell.dart';

+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/extension.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart


+ 17 - 9
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/select_option_cell.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_cell.dart

@@ -1,6 +1,6 @@
 import 'package:app_flowy/startup/startup.dart';
-import 'package:app_flowy/workspace/application/grid/prelude.dart';
-import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart';
+import 'package:app_flowy/plugins/grid/application/prelude.dart';
+
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/style_widget/text.dart';
 // ignore: unused_import
@@ -9,6 +9,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 
+import '../cell_builder.dart';
 import 'extension.dart';
 import 'select_option_editor.dart';
 
@@ -45,8 +46,10 @@ class _SingleSelectCellState extends State<GridSingleSelectCell> {
 
   @override
   void initState() {
-    final cellContext = widget.cellContorllerBuilder.build() as GridSelectOptionCellController;
-    _cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)..add(const SelectOptionCellEvent.initial());
+    final cellContext =
+        widget.cellContorllerBuilder.build() as GridSelectOptionCellController;
+    _cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)
+      ..add(const SelectOptionCellEvent.initial());
     super.initState();
   }
 
@@ -99,8 +102,10 @@ class _MultiSelectCellState extends State<GridMultiSelectCell> {
 
   @override
   void initState() {
-    final cellContext = widget.cellContorllerBuilder.build() as GridSelectOptionCellController;
-    _cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)..add(const SelectOptionCellEvent.initial());
+    final cellContext =
+        widget.cellContorllerBuilder.build() as GridSelectOptionCellController;
+    _cellBloc = getIt<SelectOptionCellBloc>(param1: cellContext)
+      ..add(const SelectOptionCellEvent.initial());
     super.initState();
   }
 
@@ -147,7 +152,8 @@ class _SelectOptionCell extends StatelessWidget {
     if (selectOptions.isEmpty && cellStyle != null) {
       child = Align(
         alignment: Alignment.centerLeft,
-        child: FlowyText.medium(cellStyle!.placeholder, fontSize: 14, color: theme.shader3),
+        child: FlowyText.medium(cellStyle!.placeholder,
+            fontSize: 14, color: theme.shader3),
       );
     } else {
       final tags = selectOptions
@@ -172,8 +178,10 @@ class _SelectOptionCell extends StatelessWidget {
         InkWell(
           onTap: () {
             onFocus(true);
-            final cellContext = cellContorllerBuilder.build() as GridSelectOptionCellController;
-            SelectOptionCellEditor.show(context, cellContext, () => onFocus(false));
+            final cellContext =
+                cellContorllerBuilder.build() as GridSelectOptionCellController;
+            SelectOptionCellEditor.show(
+                context, cellContext, () => onFocus(false));
           },
         ),
       ],

+ 36 - 17
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/select_option_editor.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart

@@ -1,9 +1,7 @@
 import 'dart:collection';
-import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
-import 'package:app_flowy/workspace/application/grid/cell/select_option_editor_bloc.dart';
-import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
-import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/select_option_editor.dart';
-import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/common/text_field.dart';
+import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
+import 'package:app_flowy/plugins/grid/application/cell/select_option_editor_bloc.dart';
+
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/flowy_infra_ui.dart';
@@ -18,6 +16,9 @@ import 'package:easy_localization/easy_localization.dart';
 import 'package:app_flowy/generated/locale_keys.g.dart';
 import 'package:textfield_tags/textfield_tags.dart';
 
+import '../../../layout/sizes.dart';
+import '../../common/text_field.dart';
+import '../../header/type_option/select_option_editor.dart';
 import 'extension.dart';
 import 'text_field.dart';
 
@@ -105,7 +106,8 @@ class _OptionList extends StatelessWidget {
       builder: (context, state) {
         List<Widget> cells = [];
         cells.addAll(state.options.map((option) {
-          return _SelectOptionCell(option, state.selectedOptions.contains(option));
+          return _SelectOptionCell(
+              option, state.selectedOptions.contains(option));
         }).toList());
 
         state.createOption.fold(
@@ -146,8 +148,10 @@ class _TextField extends StatelessWidget {
   Widget build(BuildContext context) {
     return BlocBuilder<SelectOptionCellEditorBloc, SelectOptionEditorState>(
       builder: (context, state) {
-        final optionMap = LinkedHashMap<String, SelectOptionPB>.fromIterable(state.selectedOptions,
-            key: (option) => option.name, value: (option) => option);
+        final optionMap = LinkedHashMap<String, SelectOptionPB>.fromIterable(
+            state.selectedOptions,
+            key: (option) => option.name,
+            value: (option) => option);
 
         return SizedBox(
           height: 42,
@@ -156,12 +160,17 @@ class _TextField extends StatelessWidget {
             selectedOptionMap: optionMap,
             distanceToText: _editorPannelWidth * 0.7,
             tagController: _tagController,
-            onClick: () => FlowyOverlay.of(context).remove(SelectOptionTypeOptionEditor.identifier),
+            onClick: () => FlowyOverlay.of(context)
+                .remove(SelectOptionTypeOptionEditor.identifier),
             newText: (text) {
-              context.read<SelectOptionCellEditorBloc>().add(SelectOptionEditorEvent.filterOption(text));
+              context
+                  .read<SelectOptionCellEditorBloc>()
+                  .add(SelectOptionEditorEvent.filterOption(text));
             },
             onNewTag: (tagName) {
-              context.read<SelectOptionCellEditorBloc>().add(SelectOptionEditorEvent.newOption(tagName));
+              context
+                  .read<SelectOptionCellEditorBloc>()
+                  .add(SelectOptionEditorEvent.newOption(tagName));
             },
           ),
         );
@@ -208,7 +217,9 @@ class _CreateOptionCell extends StatelessWidget {
         SelectOptionTag(
           name: name,
           color: theme.shader6,
-          onSelected: () => context.read<SelectOptionCellEditorBloc>().add(SelectOptionEditorEvent.newOption(name)),
+          onSelected: () => context
+              .read<SelectOptionCellEditorBloc>()
+              .add(SelectOptionEditorEvent.newOption(name)),
         ),
       ],
     );
@@ -218,7 +229,8 @@ class _CreateOptionCell extends StatelessWidget {
 class _SelectOptionCell extends StatelessWidget {
   final SelectOptionPB option;
   final bool isSelected;
-  const _SelectOptionCell(this.option, this.isSelected, {Key? key}) : super(key: key);
+  const _SelectOptionCell(this.option, this.isSelected, {Key? key})
+      : super(key: key);
 
   @override
   Widget build(BuildContext context) {
@@ -232,7 +244,9 @@ class _SelectOptionCell extends StatelessWidget {
             child: SelectOptionTagCell(
               option: option,
               onSelected: (option) {
-                context.read<SelectOptionCellEditorBloc>().add(SelectOptionEditorEvent.selectOption(option.id));
+                context
+                    .read<SelectOptionCellEditorBloc>()
+                    .add(SelectOptionEditorEvent.selectOption(option.id));
               },
               children: [
                 if (isSelected)
@@ -258,12 +272,17 @@ class _SelectOptionCell extends StatelessWidget {
     final pannel = SelectOptionTypeOptionEditor(
       option: option,
       onDeleted: () {
-        context.read<SelectOptionCellEditorBloc>().add(SelectOptionEditorEvent.deleteOption(option));
+        context
+            .read<SelectOptionCellEditorBloc>()
+            .add(SelectOptionEditorEvent.deleteOption(option));
       },
       onUpdated: (updatedOption) {
-        context.read<SelectOptionCellEditorBloc>().add(SelectOptionEditorEvent.updateOption(updatedOption));
+        context
+            .read<SelectOptionCellEditorBloc>()
+            .add(SelectOptionEditorEvent.updateOption(updatedOption));
       },
-      key: ValueKey(option.id), // Use ValueKey to refresh the UI, otherwise, it will remain the old value.
+      key: ValueKey(option
+          .id), // Use ValueKey to refresh the UI, otherwise, it will remain the old value.
     );
     final overlayIdentifier = (SelectOptionTypeOptionEditor).toString();
 

+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/text_field.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/text_field.dart


+ 3 - 2
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/text_cell.dart

@@ -2,7 +2,7 @@ import 'dart:async';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:app_flowy/startup/startup.dart';
-import 'package:app_flowy/workspace/application/grid/prelude.dart';
+import 'package:app_flowy/plugins/grid/application/prelude.dart';
 import 'cell_builder.dart';
 
 class GridTextCellStyle extends GridCellStyle {
@@ -86,7 +86,8 @@ class _GridTextCellState extends GridFocusNodeCellState<GridTextCell> {
     if (mounted) {
       _delayOperation?.cancel();
       _delayOperation = Timer(const Duration(milliseconds: 300), () {
-        if (_cellBloc.isClosed == false && _controller.text != _cellBloc.state.content) {
+        if (_cellBloc.isClosed == false &&
+            _controller.text != _cellBloc.state.content) {
           _cellBloc.add(TextCellEvent.updateText(_controller.text));
         }
       });

+ 7 - 4
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/url_cell/cell_editor.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/url_cell/cell_editor.dart

@@ -1,5 +1,5 @@
-import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
-import 'package:app_flowy/workspace/application/grid/cell/url_cell_editor_bloc.dart';
+import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
+import 'package:app_flowy/plugins/grid/application/cell/url_cell_editor_bloc.dart';
 import 'package:flowy_infra_ui/flowy_infra_ui.dart';
 import 'package:flutter/material.dart';
 import 'dart:async';
@@ -9,7 +9,9 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 class URLCellEditor extends StatefulWidget with FlowyOverlayDelegate {
   final GridURLCellController cellController;
   final VoidCallback completed;
-  const URLCellEditor({required this.cellController, required this.completed, Key? key}) : super(key: key);
+  const URLCellEditor(
+      {required this.cellController, required this.completed, Key? key})
+      : super(key: key);
 
   @override
   State<URLCellEditor> createState() => _URLCellEditorState();
@@ -105,7 +107,8 @@ class _URLCellEditorState extends State<URLCellEditor> {
 
   Future<void> focusChanged() async {
     if (mounted) {
-      if (_cellBloc.isClosed == false && _controller.text != _cellBloc.state.content) {
+      if (_cellBloc.isClosed == false &&
+          _controller.text != _cellBloc.state.content) {
         _cellBloc.add(URLCellEditorEvent.updateText(_controller.text));
       }
     }

+ 37 - 26
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/url_cell/url_cell.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/url_cell/url_cell.dart

@@ -1,16 +1,16 @@
 import 'dart:async';
 import 'package:app_flowy/generated/locale_keys.g.dart';
-import 'package:app_flowy/workspace/application/grid/cell/url_cell_bloc.dart';
+import 'package:app_flowy/plugins/grid/application/cell/url_cell_bloc.dart';
 import 'package:app_flowy/workspace/presentation/home/toast.dart';
-import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_accessory.dart';
 import 'package:easy_localization/easy_localization.dart';
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:app_flowy/workspace/application/grid/prelude.dart';
+import 'package:app_flowy/plugins/grid/application/prelude.dart';
 import 'package:url_launcher/url_launcher.dart';
+import '../cell_accessory.dart';
 import '../cell_builder.dart';
 import 'cell_editor.dart';
 
@@ -48,34 +48,41 @@ class GridURLCell extends GridCellWidget {
   @override
   GridCellState<GridURLCell> createState() => _GridURLCellState();
 
-  GridCellAccessory accessoryFromType(GridURLCellAccessoryType ty, GridCellAccessoryBuildContext buildContext) {
+  GridCellAccessory accessoryFromType(
+      GridURLCellAccessoryType ty, GridCellAccessoryBuildContext buildContext) {
     switch (ty) {
       case GridURLCellAccessoryType.edit:
-        final cellContext = cellContorllerBuilder.build() as GridURLCellController;
-        return _EditURLAccessory(cellContext: cellContext, anchorContext: buildContext.anchorContext);
+        final cellContext =
+            cellContorllerBuilder.build() as GridURLCellController;
+        return _EditURLAccessory(
+            cellContext: cellContext,
+            anchorContext: buildContext.anchorContext);
 
       case GridURLCellAccessoryType.copyURL:
-        final cellContext = cellContorllerBuilder.build() as GridURLCellController;
+        final cellContext =
+            cellContorllerBuilder.build() as GridURLCellController;
         return _CopyURLAccessory(cellContext: cellContext);
     }
   }
 
   @override
-  List<GridCellAccessory> Function(GridCellAccessoryBuildContext buildContext) get accessoryBuilder => (buildContext) {
-        final List<GridCellAccessory> accessories = [];
-        if (cellStyle != null) {
-          accessories.addAll(cellStyle!.accessoryTypes.map((ty) {
-            return accessoryFromType(ty, buildContext);
-          }));
-        }
-
-        // If the accessories is empty then the default accessory will be GridURLCellAccessoryType.edit
-        if (accessories.isEmpty) {
-          accessories.add(accessoryFromType(GridURLCellAccessoryType.edit, buildContext));
-        }
-
-        return accessories;
-      };
+  List<GridCellAccessory> Function(GridCellAccessoryBuildContext buildContext)
+      get accessoryBuilder => (buildContext) {
+            final List<GridCellAccessory> accessories = [];
+            if (cellStyle != null) {
+              accessories.addAll(cellStyle!.accessoryTypes.map((ty) {
+                return accessoryFromType(ty, buildContext);
+              }));
+            }
+
+            // If the accessories is empty then the default accessory will be GridURLCellAccessoryType.edit
+            if (accessories.isEmpty) {
+              accessories.add(accessoryFromType(
+                  GridURLCellAccessoryType.edit, buildContext));
+            }
+
+            return accessories;
+          };
 }
 
 class _GridURLCellState extends GridCellState<GridURLCell> {
@@ -83,7 +90,8 @@ class _GridURLCellState extends GridCellState<GridURLCell> {
 
   @override
   void initState() {
-    final cellContext = widget.cellContorllerBuilder.build() as GridURLCellController;
+    final cellContext =
+        widget.cellContorllerBuilder.build() as GridURLCellController;
     _cellBloc = URLCellBloc(cellContext: cellContext);
     _cellBloc.add(const URLCellEvent.initial());
     super.initState();
@@ -132,7 +140,8 @@ class _GridURLCellState extends GridCellState<GridURLCell> {
     if (url.isNotEmpty && await canLaunchUrl(uri)) {
       await launchUrl(uri);
     } else {
-      final cellContext = widget.cellContorllerBuilder.build() as GridURLCellController;
+      final cellContext =
+          widget.cellContorllerBuilder.build() as GridURLCellController;
       widget.onCellEditing.value = true;
       URLCellEditor.show(context, cellContext, () {
         widget.onCellEditing.value = false;
@@ -177,7 +186,8 @@ class _EditURLAccessory extends StatelessWidget with GridCellAccessory {
 
 class _CopyURLAccessory extends StatelessWidget with GridCellAccessory {
   final GridURLCellController cellContext;
-  const _CopyURLAccessory({required this.cellContext, Key? key}) : super(key: key);
+  const _CopyURLAccessory({required this.cellContext, Key? key})
+      : super(key: key);
 
   @override
   Widget build(BuildContext context) {
@@ -187,7 +197,8 @@ class _CopyURLAccessory extends StatelessWidget with GridCellAccessory {
 
   @override
   void onTap() {
-    final content = cellContext.getCellData(loadIfNotExist: false)?.content ?? "";
+    final content =
+        cellContext.getCellData(loadIfNotExist: false)?.content ?? "";
     Clipboard.setData(ClipboardData(text: content));
     showMessageToast(LocaleKeys.grid_row_copyProperty.tr());
   }

+ 0 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/common/text_field.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/common/text_field.dart


+ 1 - 1
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart → frontend/app_flowy/lib/plugins/grid/presentation/widgets/footer/grid_footer.dart

@@ -1,4 +1,4 @@
-import 'package:app_flowy/workspace/application/grid/grid_bloc.dart';
+import 'package:app_flowy/plugins/grid/application/grid_bloc.dart';
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/style_widget/button.dart';

Some files were not shown because too many files changed in this diff