diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/application/field/field_action_sheet_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database_view/application/field/field_action_sheet_bloc.dart index d72ced9fbe..929cbb9a3c 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/application/field/field_action_sheet_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/application/field/field_action_sheet_bloc.dart @@ -4,6 +4,7 @@ import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart import 'package:appflowy_backend/protobuf/flowy-database2/field_settings_entities.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; +import 'field_info.dart'; import 'field_service.dart'; part 'field_action_sheet_bloc.freezed.dart'; @@ -14,17 +15,18 @@ class FieldActionSheetBloc final FieldBackendService fieldService; final FieldSettingsBackendService fieldSettingsService; - FieldActionSheetBloc({required FieldContext fieldCellContext}) - : fieldId = fieldCellContext.fieldInfo.id, + FieldActionSheetBloc({ + required String viewId, + required FieldInfo fieldInfo, + }) : fieldId = fieldInfo.id, fieldService = FieldBackendService( - viewId: fieldCellContext.viewId, - fieldId: fieldCellContext.fieldInfo.id, + viewId: viewId, + fieldId: fieldInfo.id, ), - fieldSettingsService = - FieldSettingsBackendService(viewId: fieldCellContext.viewId), + fieldSettingsService = FieldSettingsBackendService(viewId: viewId), super( FieldActionSheetState.initial( - TypeOptionPB.create()..field_2 = fieldCellContext.fieldInfo.field, + TypeOptionPB.create()..field_2 = fieldInfo.field, ), ) { on( diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/application/field/field_cell_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database_view/application/field/field_cell_bloc.dart index b916177a55..807f683c5a 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/application/field/field_cell_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/application/field/field_cell_bloc.dart @@ -1,77 +1,55 @@ import 'dart:math'; -import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart'; +import 'package:appflowy/plugins/database_view/application/field_settings/field_settings_service.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -import 'dart:async'; -import 'field_listener.dart'; -import 'field_service.dart'; +import 'field_info.dart'; part 'field_cell_bloc.freezed.dart'; class FieldCellBloc extends Bloc { - final SingleFieldListener _fieldListener; - final FieldBackendService _fieldBackendSvc; + FieldInfo fieldInfo; + final FieldSettingsBackendService _fieldSettingsService; - FieldCellBloc({ - required FieldContext fieldContext, - }) : _fieldListener = - SingleFieldListener(fieldId: fieldContext.fieldInfo.id), - _fieldBackendSvc = FieldBackendService( - viewId: fieldContext.viewId, - fieldId: fieldContext.fieldInfo.id, + FieldCellBloc({required String viewId, required this.fieldInfo}) + : _fieldSettingsService = FieldSettingsBackendService( + viewId: viewId, ), - super(FieldCellState.initial(fieldContext)) { + super(FieldCellState.initial(fieldInfo)) { on( (event, emit) async { event.when( - initial: () { - _startListening(); - }, - didReceiveFieldUpdate: (field) { - emit(state.copyWith(field: fieldContext.fieldInfo.field)); + onFieldChanged: (newFieldInfo) { + fieldInfo = newFieldInfo; + emit(FieldCellState.initial(newFieldInfo)); }, onResizeStart: () { - emit(state.copyWith(resizeStart: state.width)); + emit(state.copyWith(isResizing: true, resizeStart: state.width)); }, startUpdateWidth: (offset) { final width = max(offset + state.resizeStart, 50).toDouble(); emit(state.copyWith(width: width)); }, endUpdateWidth: () { - if (state.width != state.field.width.toDouble()) { - _fieldBackendSvc.updateField(width: state.width); + if (state.width != fieldInfo.fieldSettings?.width.toDouble()) { + _fieldSettingsService.updateFieldSettings( + fieldId: fieldInfo.id, + width: state.width, + ); } + emit(state.copyWith(isResizing: false, resizeStart: 0)); }, ); }, ); } - - @override - Future close() async { - await _fieldListener.stop(); - return super.close(); - } - - void _startListening() { - _fieldListener.start( - onFieldChanged: (updatedField) { - if (isClosed) { - return; - } - add(FieldCellEvent.didReceiveFieldUpdate(updatedField)); - }, - ); - } } @freezed class FieldCellEvent with _$FieldCellEvent { - const factory FieldCellEvent.initial() = _InitialCell; - const factory FieldCellEvent.didReceiveFieldUpdate(FieldPB field) = - _DidReceiveFieldUpdate; + const factory FieldCellEvent.onFieldChanged(FieldInfo newFieldInfo) = + _OnFieldChanged; const factory FieldCellEvent.onResizeStart() = _OnResizeStart; const factory FieldCellEvent.startUpdateWidth(double offset) = _StartUpdateWidth; @@ -81,16 +59,16 @@ class FieldCellEvent with _$FieldCellEvent { @freezed class FieldCellState with _$FieldCellState { const factory FieldCellState({ - required String viewId, - required FieldPB field, + required FieldInfo fieldInfo, required double width, + required bool isResizing, required double resizeStart, }) = _FieldCellState; - factory FieldCellState.initial(FieldContext cellContext) => FieldCellState( - viewId: cellContext.viewId, - field: cellContext.fieldInfo.field, - width: cellContext.fieldInfo.field.width.toDouble(), + factory FieldCellState.initial(FieldInfo fieldInfo) => FieldCellState( + fieldInfo: fieldInfo, + isResizing: false, + width: fieldInfo.fieldSettings!.width.toDouble(), resizeStart: 0, ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/application/field/field_service.dart b/frontend/appflowy_flutter/lib/plugins/database_view/application/field/field_service.dart index 6cf15e8b44..9d83019063 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/application/field/field_service.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/application/field/field_service.dart @@ -1,12 +1,8 @@ -import 'package:appflowy/plugins/database_view/application/field/field_info.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/database_entities.pb.dart'; import 'package:dartz/dartz.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; - -part 'field_service.freezed.dart'; /// FieldService consists of lots of event functions. We define the events in the backend(Rust), /// you can find the corresponding event implementation in event_map.rs of the corresponding crate. @@ -104,11 +100,3 @@ class FieldBackendService { return DatabaseEventGetPrimaryField(payload).send(); } } - -@freezed -class FieldContext with _$FieldContext { - const factory FieldContext({ - required String viewId, - required FieldInfo fieldInfo, - }) = _FieldCellContext; -} diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/application/field_settings/field_settings_service.dart b/frontend/appflowy_flutter/lib/plugins/database_view/application/field_settings/field_settings_service.dart index e699b61ad8..8c66949958 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/application/field_settings/field_settings_service.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/application/field_settings/field_settings_service.dart @@ -58,6 +58,7 @@ class FieldSettingsBackendService { Future> updateFieldSettings({ required String fieldId, FieldVisibility? fieldVisibility, + double? width, }) { final FieldSettingsChangesetPB payload = FieldSettingsChangesetPB.create() ..viewId = viewId @@ -67,6 +68,10 @@ class FieldSettingsBackendService { payload.visibility = fieldVisibility; } + if (width != null) { + payload.width = width.round(); + } + return DatabaseEventUpdateFieldSettings(payload).send(); } } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/board/application/board_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database_view/board/application/board_bloc.dart index 8c5d99c126..f9cfb22c02 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/board/application/board_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/board/application/board_bloc.dart @@ -6,9 +6,7 @@ import 'package:appflowy/plugins/database_view/application/field/field_info.dart import 'package:appflowy/plugins/database_view/application/group/group_service.dart'; import 'package:appflowy/plugins/database_view/application/row/row_service.dart'; import 'package:appflowy_board/appflowy_board.dart'; -import 'package:collection/collection.dart'; import 'package:dartz/dartz.dart'; -import 'package:equatable/equatable.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart'; @@ -400,29 +398,6 @@ class BoardState with _$BoardState { ); } -class GridFieldEquatable extends Equatable { - final UnmodifiableListView _fields; - const GridFieldEquatable( - UnmodifiableListView fields, - ) : _fields = fields; - - @override - List get props { - if (_fields.isEmpty) { - return []; - } - - return [ - _fields.length, - _fields - .map((field) => field.width) - .reduce((value, element) => value + element), - ]; - } - - UnmodifiableListView get value => UnmodifiableListView(_fields); -} - class GroupItem extends AppFlowyGroupItem { final RowMetaPB row; final FieldInfo fieldInfo; diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/calendar/presentation/toolbar/calendar_layout_setting.dart b/frontend/appflowy_flutter/lib/plugins/database_view/calendar/presentation/toolbar/calendar_layout_setting.dart index 7b4a031424..d9149b9966 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/calendar/presentation/toolbar/calendar_layout_setting.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/calendar/presentation/toolbar/calendar_layout_setting.dart @@ -4,7 +4,6 @@ import 'package:appflowy/plugins/database_view/application/field/field_controlle import 'package:appflowy/plugins/database_view/application/setting/property_bloc.dart'; import 'package:appflowy/plugins/database_view/calendar/application/calendar_setting_bloc.dart'; import 'package:appflowy/plugins/database_view/grid/presentation/layout/sizes.dart'; -import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/presentation/widgets/toggle/toggle.dart'; import 'package:appflowy/workspace/presentation/widgets/toggle/toggle_style.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; @@ -234,9 +233,9 @@ class LayoutDateField extends StatelessWidget { offset: const Offset(-14, 0), popupBuilder: (context) { return BlocProvider( - create: (context) => getIt( - param1: viewId, - param2: fieldController, + create: (context) => DatabasePropertyBloc( + viewId: viewId, + fieldController: fieldController, )..add(const DatabasePropertyEvent.initial()), child: BlocBuilder( builder: (context, state) { diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/application/grid_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/application/grid_bloc.dart index d5fef3b3c7..f1b976a1cb 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/application/grid_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/application/grid_bloc.dart @@ -6,13 +6,11 @@ import 'package:appflowy/plugins/database_view/application/row/row_service.dart' import 'package:appflowy/plugins/database_view/grid/presentation/widgets/filter/filter_info.dart'; import 'package:appflowy/plugins/database_view/grid/presentation/widgets/sort/sort_info.dart'; import 'package:dartz/dartz.dart'; -import 'package:equatable/equatable.dart'; import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import '../../application/database_controller.dart'; -import 'dart:collection'; part 'grid_bloc.freezed.dart'; @@ -54,7 +52,7 @@ class GridBloc extends Bloc { didReceiveFieldUpdate: (fields) { emit( state.copyWith( - fields: GridFieldEquatable(fields), + fields: FieldList(fields), ), ); }, @@ -175,7 +173,7 @@ class GridState with _$GridState { const factory GridState({ required String viewId, required Option grid, - required GridFieldEquatable fields, + required FieldList fields, required List rowInfos, required int rowCount, required LoadingState loadingState, @@ -186,7 +184,7 @@ class GridState with _$GridState { }) = _GridState; factory GridState.initial(String viewId) => GridState( - fields: GridFieldEquatable(UnmodifiableListView([])), + fields: FieldList([]), rowInfos: [], rowCount: 0, grid: none(), @@ -199,26 +197,7 @@ class GridState with _$GridState { ); } -class GridFieldEquatable extends Equatable { - final List _fieldInfos; - const GridFieldEquatable( - List fieldInfos, - ) : _fieldInfos = fieldInfos; - - @override - List get props { - if (_fieldInfos.isEmpty) { - return []; - } - - return [ - _fieldInfos.length, - _fieldInfos - .map((fieldInfo) => fieldInfo.field.width) - .reduce((value, element) => value + element), - ]; - } - - UnmodifiableListView get value => - UnmodifiableListView(_fieldInfos); +@freezed +class FieldList with _$FieldList { + factory FieldList(List fields) = _FieldList; } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/application/row/row_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/application/row/row_bloc.dart index 9842bd5f0c..cf436df89f 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/application/row/row_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/application/row/row_bloc.dart @@ -132,7 +132,7 @@ class GridCellEquatable extends Equatable { _fieldInfo.id, _fieldInfo.fieldType, _fieldInfo.field.visibility, - _fieldInfo.field.width, + _fieldInfo.fieldSettings?.width, ]; } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/grid_page.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/grid_page.dart index defba2c6bf..99c4151bcc 100755 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/grid_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/grid_page.dart @@ -172,7 +172,7 @@ class _GridPageContentState extends State { return BlocBuilder( buildWhen: (previous, current) => previous.fields != current.fields, builder: (context, state) { - final contentWidth = GridLayout.headerWidth(state.fields.value); + final contentWidth = GridLayout.headerWidth(state.fields.fields); return Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/layout/layout.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/layout/layout.dart index 29acb595d1..2b1882be1f 100755 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/layout/layout.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/layout/layout.dart @@ -6,7 +6,7 @@ class GridLayout { if (fields.isEmpty) return 0; final fieldsWidth = fields - .map((fieldInfo) => fieldInfo.field.width.toDouble()) + .map((fieldInfo) => fieldInfo.fieldSettings!.width.toDouble()) .reduce((value, element) => value + element); return fieldsWidth + diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_cell.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_cell.dart index e3cacc6140..6d832235c0 100755 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_cell.dart @@ -1,6 +1,6 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/plugins/database_view/application/field/field_cell_bloc.dart'; -import 'package:appflowy/plugins/database_view/application/field/field_service.dart'; +import 'package:appflowy/plugins/database_view/application/field/field_info.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:flowy_infra/theme_extension.dart'; @@ -15,31 +15,41 @@ import 'field_cell_action_sheet.dart'; import 'field_type_extension.dart'; class GridFieldCell extends StatefulWidget { - final FieldContext cellContext; + final String viewId; + final FieldInfo fieldInfo; const GridFieldCell({ - Key? key, - required this.cellContext, - }) : super(key: key); + super.key, + required this.viewId, + required this.fieldInfo, + }); @override State createState() => _GridFieldCellState(); } class _GridFieldCellState extends State { + late final FieldCellBloc _bloc; late PopoverController popoverController; @override void initState() { - popoverController = PopoverController(); super.initState(); + popoverController = PopoverController(); + _bloc = FieldCellBloc(viewId: widget.viewId, fieldInfo: widget.fieldInfo); + } + + @override + didUpdateWidget(covariant oldWidget) { + if (widget.fieldInfo != oldWidget.fieldInfo && !_bloc.isClosed) { + _bloc.add(FieldCellEvent.onFieldChanged(widget.fieldInfo)); + } + super.didUpdateWidget(oldWidget); } @override Widget build(BuildContext context) { - return BlocProvider( - create: (context) { - return FieldCellBloc(fieldContext: widget.cellContext); - }, + return BlocProvider.value( + value: _bloc, child: BlocBuilder( builder: (context, state) { final button = AppFlowyPopover( @@ -50,11 +60,12 @@ class _GridFieldCellState extends State { controller: popoverController, popupBuilder: (BuildContext context) { return GridFieldCellActionSheet( - cellContext: widget.cellContext, + viewId: widget.viewId, + fieldInfo: widget.fieldInfo, ); }, child: FieldCellButton( - field: widget.cellContext.fieldInfo.field, + field: widget.fieldInfo.field, onTap: () => popoverController.show(), ), ); @@ -78,6 +89,12 @@ class _GridFieldCellState extends State { ), ); } + + @override + Future dispose() async { + super.dispose(); + await _bloc.close(); + } } class _GridHeaderCellContainer extends StatelessWidget { diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_cell_action_sheet.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_cell_action_sheet.dart index 3f4de78de9..199ac1e6e0 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_cell_action_sheet.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_cell_action_sheet.dart @@ -1,8 +1,8 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/plugins/database_view/application/field/field_action_sheet_bloc.dart'; +import 'package:appflowy/plugins/database_view/application/field/field_info.dart'; import 'package:appflowy/plugins/database_view/application/field/field_service.dart'; import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart'; -import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; @@ -20,9 +20,13 @@ import '../../layout/sizes.dart'; import 'field_editor.dart'; class GridFieldCellActionSheet extends StatefulWidget { - final FieldContext cellContext; - const GridFieldCellActionSheet({required this.cellContext, Key? key}) - : super(key: key); + final String viewId; + final FieldInfo fieldInfo; + const GridFieldCellActionSheet({ + required this.viewId, + required this.fieldInfo, + Key? key, + }) : super(key: key); @override State createState() => _GridFieldCellActionSheetState(); @@ -37,31 +41,35 @@ class _GridFieldCellActionSheetState extends State { return SizedBox( width: 400, child: FieldEditor( - viewId: widget.cellContext.viewId, - fieldInfo: widget.cellContext.fieldInfo, + viewId: widget.viewId, + fieldInfo: widget.fieldInfo, typeOptionLoader: FieldTypeOptionLoader( - viewId: widget.cellContext.viewId, - field: widget.cellContext.fieldInfo.field, + viewId: widget.viewId, + field: widget.fieldInfo.field, ), ), ); } return BlocProvider( - create: (context) => - getIt(param1: widget.cellContext), + create: (context) => FieldActionSheetBloc( + viewId: widget.viewId, + fieldInfo: widget.fieldInfo, + ), child: IntrinsicWidth( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ _EditFieldButton( - cellContext: widget.cellContext, onTap: () { setState(() => _showFieldEditor = true); }, ), VSpace(GridSize.typeOptionSeparatorHeight), - _FieldOperationList(widget.cellContext), + _FieldOperationList( + viewId: widget.viewId, + fieldInfo: widget.fieldInfo, + ), ], ), ), @@ -70,10 +78,8 @@ class _GridFieldCellActionSheetState extends State { } class _EditFieldButton extends StatelessWidget { - final FieldContext cellContext; final void Function()? onTap; - const _EditFieldButton({required this.cellContext, Key? key, this.onTap}) - : super(key: key); + const _EditFieldButton({Key? key, this.onTap}) : super(key: key); @override Widget build(BuildContext context) { @@ -96,8 +102,13 @@ class _EditFieldButton extends StatelessWidget { } class _FieldOperationList extends StatelessWidget { - final FieldContext fieldContext; - const _FieldOperationList(this.fieldContext, {Key? key}) : super(key: key); + final String viewId; + final FieldInfo fieldInfo; + const _FieldOperationList({ + required this.viewId, + required this.fieldInfo, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -128,7 +139,7 @@ class _FieldOperationList extends StatelessWidget { bool enable = true; // If the field is primary, delete and duplicate are disabled. - if (fieldContext.fieldInfo.isPrimary) { + if (fieldInfo.isPrimary) { switch (action) { case FieldAction.hide: break; @@ -145,7 +156,8 @@ class _FieldOperationList extends StatelessWidget { child: SizedBox( height: GridSize.popoverItemHeight, child: FieldActionCell( - fieldInfo: fieldContext, + viewId: viewId, + fieldInfo: fieldInfo, action: action, enable: enable, ), @@ -155,11 +167,13 @@ class _FieldOperationList extends StatelessWidget { } class FieldActionCell extends StatelessWidget { - final FieldContext fieldInfo; + final String viewId; + final FieldInfo fieldInfo; final FieldAction action; final bool enable; const FieldActionCell({ + required this.viewId, required this.fieldInfo, required this.action, required this.enable, @@ -177,7 +191,7 @@ class FieldActionCell extends StatelessWidget { ? AFThemeExtension.of(context).textColor : Theme.of(context).disabledColor, ), - onTap: () => action.run(context, fieldInfo), + onTap: () => action.run(context, viewId, fieldInfo), leftIcon: FlowySvg( action.icon(), color: enable @@ -217,7 +231,7 @@ extension _FieldActionExtension on FieldAction { } } - void run(BuildContext context, FieldContext fieldContext) { + void run(BuildContext context, String viewId, FieldInfo fieldInfo) { switch (this) { case FieldAction.hide: context @@ -228,8 +242,8 @@ extension _FieldActionExtension on FieldAction { PopoverContainer.of(context).close(); FieldBackendService( - viewId: fieldContext.viewId, - fieldId: fieldContext.fieldInfo.id, + viewId: viewId, + fieldId: fieldInfo.id, ).duplicateField(); break; @@ -240,8 +254,8 @@ extension _FieldActionExtension on FieldAction { title: LocaleKeys.grid_field_deleteFieldPromptMessage.tr(), confirm: () { FieldBackendService( - viewId: fieldContext.viewId, - fieldId: fieldContext.fieldInfo.field.id, + viewId: viewId, + fieldId: fieldInfo.field.id, ).deleteField(); }, ).show(context); diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/grid_header.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/grid_header.dart index 71f9f1375f..022991015a 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/grid_header.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/grid_header.dart @@ -1,10 +1,8 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/database_view/application/field/field_controller.dart'; -import 'package:appflowy/plugins/database_view/application/field/field_service.dart'; import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart'; import 'package:appflowy/plugins/database_view/grid/application/grid_header_bloc.dart'; -import 'package:appflowy/startup/startup.dart'; import 'package:appflowy_backend/log.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; @@ -42,9 +40,9 @@ class _GridHeaderSliverAdaptorState extends State { Widget build(BuildContext context) { return BlocProvider( create: (context) { - return getIt( - param1: widget.viewId, - param2: widget.fieldController, + return GridHeaderBloc( + viewId: widget.viewId, + fieldController: widget.fieldController, )..add(const GridHeaderEvent.initial()); }, child: BlocBuilder( @@ -96,15 +94,10 @@ class _GridHeaderState extends State<_GridHeader> { builder: (context, state) { final cells = state.fields .map( - (field) => FieldContext( + (fieldInfo) => GridFieldCell( + key: _getKeyById(fieldInfo.id), viewId: widget.viewId, - fieldInfo: field, - ), - ) - .map( - (ctx) => GridFieldCell( - key: _getKeyById(ctx.fieldInfo.id), - cellContext: ctx, + fieldInfo: fieldInfo, ), ) .toList(); @@ -136,7 +129,7 @@ class _GridHeaderState extends State<_GridHeader> { int newIndex, ) { if (cells.length > oldIndex) { - final field = cells[oldIndex].cellContext.fieldInfo.field; + final field = cells[oldIndex].fieldInfo.field; context .read() .add(GridHeaderEvent.moveField(field, oldIndex, newIndex)); diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/row/row.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/row/row.dart index f1f0976e84..96bf4baf64 100755 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/row/row.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/row/row.dart @@ -276,7 +276,7 @@ class RowContent extends StatelessWidget { final GridCellWidget child = builder.build(cellId); return CellContainer( - width: cellId.fieldInfo.field.width.toDouble(), + width: cellId.fieldInfo.fieldSettings?.width.toDouble() ?? 140, isPrimary: cellId.fieldInfo.field.isPrimary, cellContainerNotifier: CellContainerNotifier(child), accessoryBuilder: (buildContext) { diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/setting/setting_property_list.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/setting/setting_property_list.dart index 53e43ea4dc..f2fb63970e 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/setting/setting_property_list.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/setting/setting_property_list.dart @@ -6,7 +6,6 @@ import 'package:appflowy/plugins/database_view/application/field/field_info.dart import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart'; import 'package:appflowy/plugins/database_view/application/setting/property_bloc.dart'; import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/field_type_extension.dart'; -import 'package:appflowy/startup/startup.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:collection/collection.dart'; @@ -40,9 +39,9 @@ class _DatabasePropertyListState extends State { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => getIt( - param1: widget.viewId, - param2: widget.fieldController, + create: (context) => DatabasePropertyBloc( + viewId: widget.viewId, + fieldController: widget.fieldController, )..add(const DatabasePropertyEvent.initial()), child: BlocBuilder( builder: (context, state) { diff --git a/frontend/appflowy_flutter/lib/startup/deps_resolver.dart b/frontend/appflowy_flutter/lib/startup/deps_resolver.dart index a14ada4100..bc66aaf878 100644 --- a/frontend/appflowy_flutter/lib/startup/deps_resolver.dart +++ b/frontend/appflowy_flutter/lib/startup/deps_resolver.dart @@ -1,11 +1,6 @@ import 'package:appflowy/core/config/kv.dart'; import 'package:appflowy/core/network_monitor.dart'; import 'package:appflowy/env/env.dart'; -import 'package:appflowy/plugins/database_view/application/field/field_action_sheet_bloc.dart'; -import 'package:appflowy/plugins/database_view/application/field/field_controller.dart'; -import 'package:appflowy/plugins/database_view/application/field/field_service.dart'; -import 'package:appflowy/plugins/database_view/application/setting/property_bloc.dart'; -import 'package:appflowy/plugins/database_view/grid/application/grid_header_bloc.dart'; import 'package:appflowy/plugins/document/application/prelude.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/clipboard_service.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/openai/service/openai_client.dart'; @@ -48,7 +43,7 @@ class DependencyResolver { _resolveHomeDeps(getIt); _resolveFolderDeps(getIt); _resolveDocDeps(getIt); - _resolveGridDeps(getIt); + // _resolveGridDeps(getIt); _resolveCommonService(getIt, mode); } } @@ -218,21 +213,3 @@ void _resolveDocDeps(GetIt getIt) { (view, _) => DocumentBloc(view: view), ); } - -void _resolveGridDeps(GetIt getIt) { - getIt.registerFactoryParam( - (viewId, fieldController) => GridHeaderBloc( - viewId: viewId, - fieldController: fieldController, - ), - ); - - getIt.registerFactoryParam( - (data, _) => FieldActionSheetBloc(fieldCellContext: data), - ); - - getIt.registerFactoryParam( - (viewId, cache) => - DatabasePropertyBloc(viewId: viewId, fieldController: cache), - ); -} diff --git a/frontend/appflowy_flutter/test/bloc_test/board_test/util.dart b/frontend/appflowy_flutter/test/bloc_test/board_test/util.dart index d9c11130fe..0e4b92b9e8 100644 --- a/frontend/appflowy_flutter/test/bloc_test/board_test/util.dart +++ b/frontend/appflowy_flutter/test/bloc_test/board_test/util.dart @@ -3,7 +3,6 @@ import 'package:appflowy/plugins/database_view/application/cell/cell_controller_ import 'package:appflowy/plugins/database_view/application/field/field_controller.dart'; import 'package:appflowy/plugins/database_view/application/field/field_editor_bloc.dart'; import 'package:appflowy/plugins/database_view/application/field/field_info.dart'; -import 'package:appflowy/plugins/database_view/application/field/field_service.dart'; import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart'; import 'package:appflowy/plugins/database_view/application/row/row_cache.dart'; import 'package:appflowy/plugins/database_view/application/row/row_controller.dart'; @@ -141,11 +140,6 @@ class BoardTestContext { return fieldInfo; } - FieldContext singleSelectFieldCellContext() { - final fieldInfo = singleSelectFieldContext(); - return FieldContext(viewId: gridView.id, fieldInfo: fieldInfo); - } - FieldInfo textFieldContext() { final fieldInfo = fieldContexts .firstWhere((element) => element.fieldType == FieldType.RichText); diff --git a/frontend/appflowy_flutter/test/bloc_test/grid_test/field/field_cell_bloc_test.dart b/frontend/appflowy_flutter/test/bloc_test/grid_test/field/field_cell_bloc_test.dart index e36b9587c8..3aa656f393 100644 --- a/frontend/appflowy_flutter/test/bloc_test/grid_test/field/field_cell_bloc_test.dart +++ b/frontend/appflowy_flutter/test/bloc_test/grid_test/field/field_cell_bloc_test.dart @@ -1,5 +1,4 @@ import 'package:appflowy/plugins/database_view/application/field/field_cell_bloc.dart'; -import 'package:appflowy/plugins/database_view/application/field/field_service.dart'; import 'package:bloc_test/bloc_test.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -23,11 +22,9 @@ void main() { blocTest( 'update field width', build: () => FieldCellBloc( - fieldContext: FieldContext( - fieldInfo: context.fieldContexts[0], - viewId: context.gridView.id, - ), - )..add(const FieldCellEvent.initial()), + fieldInfo: context.fieldContexts[0], + viewId: context.gridView.id, + ), act: (bloc) { width = bloc.state.width; bloc.add(const FieldCellEvent.onResizeStart()); @@ -42,11 +39,9 @@ void main() { blocTest( 'field width should not be lesser than 50px', build: () => FieldCellBloc( - fieldContext: FieldContext( - fieldInfo: context.fieldContexts[0], - viewId: context.gridView.id, - ), - )..add(const FieldCellEvent.initial()), + viewId: context.gridView.id, + fieldInfo: context.fieldContexts[0], + ), act: (bloc) { bloc.add(const FieldCellEvent.onResizeStart()); bloc.add(const FieldCellEvent.startUpdateWidth(-110)); diff --git a/frontend/appflowy_flutter/test/bloc_test/grid_test/grid_header_bloc_test.dart b/frontend/appflowy_flutter/test/bloc_test/grid_test/grid_header_bloc_test.dart index 571cb11d89..29bb34d7b6 100644 --- a/frontend/appflowy_flutter/test/bloc_test/grid_test/grid_header_bloc_test.dart +++ b/frontend/appflowy_flutter/test/bloc_test/grid_test/grid_header_bloc_test.dart @@ -18,7 +18,8 @@ void main() { setUp(() async { context = await gridTest.createTestGrid(); actionSheetBloc = FieldActionSheetBloc( - fieldCellContext: context.singleSelectFieldCellContext(), + viewId: context.gridView.id, + fieldInfo: context.singleSelectFieldContext(), ); }); diff --git a/frontend/appflowy_flutter/test/bloc_test/grid_test/util.dart b/frontend/appflowy_flutter/test/bloc_test/grid_test/util.dart index 52a981fcb6..7df94f3944 100644 --- a/frontend/appflowy_flutter/test/bloc_test/grid_test/util.dart +++ b/frontend/appflowy_flutter/test/bloc_test/grid_test/util.dart @@ -3,7 +3,6 @@ import 'package:appflowy/plugins/database_view/application/cell/cell_controller_ import 'package:appflowy/plugins/database_view/application/field/field_controller.dart'; import 'package:appflowy/plugins/database_view/application/field/field_editor_bloc.dart'; import 'package:appflowy/plugins/database_view/application/field/field_info.dart'; -import 'package:appflowy/plugins/database_view/application/field/field_service.dart'; import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart'; import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_service.dart'; import 'package:appflowy/plugins/database_view/application/row/row_cache.dart'; @@ -88,11 +87,6 @@ class GridTestContext { return fieldInfo; } - FieldContext singleSelectFieldCellContext() { - final fieldInfo = singleSelectFieldContext(); - return FieldContext(viewId: gridView.id, fieldInfo: fieldInfo); - } - FieldInfo textFieldContext() { final fieldInfo = fieldContexts .firstWhere((element) => element.fieldType == FieldType.RichText); diff --git a/frontend/rust-lib/flowy-database2/src/entities/field_entities.rs b/frontend/rust-lib/flowy-database2/src/entities/field_entities.rs index 5d25b290f1..d3a0e7c096 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/field_entities.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/field_entities.rs @@ -521,13 +521,6 @@ impl FieldType { self.clone().into() } - pub fn default_cell_width(&self) -> i32 { - match self { - FieldType::DateTime | FieldType::LastEditedTime | FieldType::CreatedTime => 180, - _ => 150, - } - } - pub fn default_name(&self) -> String { let s = match self { FieldType::RichText => "Text", diff --git a/frontend/rust-lib/flowy-database2/src/entities/field_settings_entities.rs b/frontend/rust-lib/flowy-database2/src/entities/field_settings_entities.rs index d7b828c444..a995607952 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/field_settings_entities.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/field_settings_entities.rs @@ -15,6 +15,9 @@ pub struct FieldSettingsPB { #[pb(index = 2)] pub visibility: FieldVisibility, + + #[pb(index = 3)] + pub width: i32, } impl From for FieldSettingsPB { @@ -22,6 +25,7 @@ impl From for FieldSettingsPB { Self { field_id: value.field_id, visibility: value.visibility, + width: value.width, } } } @@ -99,6 +103,9 @@ pub struct FieldSettingsChangesetPB { #[pb(index = 3, one_of)] pub visibility: Option, + + #[pb(index = 4, one_of)] + pub width: Option, } impl From for FieldSettingsChangesetPB { @@ -107,6 +114,7 @@ impl From for FieldSettingsChangesetPB { view_id: value.view_id, field_id: value.field_id, visibility: value.visibility, + width: value.width, } } } @@ -119,6 +127,7 @@ impl TryFrom for FieldSettingsChangesetParams { view_id: value.view_id, field_id: value.field_id, visibility: value.visibility, + width: value.width, }) } } diff --git a/frontend/rust-lib/flowy-database2/src/event_handler.rs b/frontend/rust-lib/flowy-database2/src/event_handler.rs index b680364f1e..c49c783339 100644 --- a/frontend/rust-lib/flowy-database2/src/event_handler.rs +++ b/frontend/rust-lib/flowy-database2/src/event_handler.rs @@ -892,10 +892,8 @@ pub(crate) async fn get_field_settings_handler( let (view_id, field_ids) = data.into_inner().try_into()?; let database_editor = manager.get_database_with_view_id(&view_id).await?; - let layout_ty = database_editor.get_layout_type(view_id.as_ref()).await; - let field_settings = database_editor - .get_field_settings(&view_id, layout_ty, field_ids.clone()) + .get_field_settings(&view_id, field_ids.clone()) .await? .into_iter() .map(FieldSettingsPB::from) @@ -915,10 +913,8 @@ pub(crate) async fn get_all_field_settings_handler( let view_id = data.into_inner(); let database_editor = manager.get_database_with_view_id(view_id.as_ref()).await?; - let layout_ty = database_editor.get_layout_type(view_id.as_ref()).await; - let field_settings = database_editor - .get_all_field_settings(view_id.as_ref(), layout_ty) + .get_all_field_settings(view_id.as_ref()) .await? .into_iter() .map(FieldSettingsPB::from) diff --git a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs index 9d4f1ab4bd..ed2851b6fa 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs @@ -1090,57 +1090,27 @@ impl DatabaseEditor { pub async fn get_field_settings( &self, view_id: &str, - layout_ty: DatabaseLayout, field_ids: Vec, ) -> FlowyResult> { let view = self.database_views.get_view_editor(view_id).await?; - let default_field_settings = default_field_settings_by_layout_map() - .get(&layout_ty) - .unwrap() - .to_owned(); - let found_field_settings = view.v_get_field_settings(&field_ids).await; - - let field_settings = field_ids - .into_iter() - .map(|field_id| { - if let Some(field_settings) = found_field_settings.get(&field_id) { - field_settings.to_owned() - } else { - FieldSettings::try_from_anymap(field_id, default_field_settings.clone()).unwrap() - } - }) + let field_settings = view + .v_get_field_settings(&field_ids) + .await + .into_values() .collect(); Ok(field_settings) } - pub async fn get_all_field_settings( - &self, - view_id: &str, - layout_ty: DatabaseLayout, - ) -> FlowyResult> { - let view = self.database_views.get_view_editor(view_id).await?; - let default_field_settings = default_field_settings_by_layout_map() - .get(&layout_ty) - .unwrap() - .to_owned(); - let fields = self.get_fields(view_id, None); - - let found_field_settings = view.v_get_all_field_settings().await; - - let field_settings = fields - .into_iter() - .map(|field| { - if let Some(field_settings) = found_field_settings.get(&field.id) { - field_settings.to_owned() - } else { - FieldSettings::try_from_anymap(field.id, default_field_settings.clone()).unwrap() - } - }) + pub async fn get_all_field_settings(&self, view_id: &str) -> FlowyResult> { + let field_ids = self + .get_fields(view_id, None) + .iter() + .map(|field| field.id.clone()) .collect(); - Ok(field_settings) + self.get_field_settings(view_id, field_ids).await } pub async fn update_field_settings_with_changeset( @@ -1149,7 +1119,12 @@ impl DatabaseEditor { ) -> FlowyResult<()> { let view = self.database_views.get_view_editor(¶ms.view_id).await?; view - .v_update_field_settings(¶ms.view_id, ¶ms.field_id, params.visibility) + .v_update_field_settings( + ¶ms.view_id, + ¶ms.field_id, + params.visibility, + params.width, + ) .await?; Ok(()) @@ -1417,38 +1392,37 @@ impl DatabaseViewOperation for DatabaseViewOperationImpl { view_id: &str, field_ids: &[String], ) -> HashMap { - let field_settings_map = self - .database - .lock() - .get_field_settings(view_id, Some(field_ids)); + let (layout_type, field_settings_map) = { + let database = self.database.lock(); + let layout_type = database.views.get_database_view_layout(view_id); + let field_settings_map = database.get_field_settings(view_id, Some(field_ids)); + (layout_type, field_settings_map) + }; - field_settings_map - .into_iter() - .filter_map(|(field_id, field_settings)| { - let field_settings = FieldSettings::try_from_anymap(field_id.clone(), field_settings); - if let Ok(settings) = field_settings { - Some((field_id, settings)) + let default_field_settings = default_field_settings_by_layout_map() + .get(&layout_type) + .unwrap() + .to_owned(); + + let field_settings = field_ids + .iter() + .map(|field_id| { + if !field_settings_map.contains_key(field_id) { + let field_settings = + FieldSettings::from_anymap(field_id, layout_type, &default_field_settings); + (field_id.clone(), field_settings) } else { - None + let field_settings = FieldSettings::from_anymap( + field_id, + layout_type, + field_settings_map.get(field_id).unwrap(), + ); + (field_id.clone(), field_settings) } }) - .collect() - } + .collect(); - fn get_all_field_settings(&self, view_id: &str) -> HashMap { - let field_settings_map = self.database.lock().get_field_settings(view_id, None); - - field_settings_map - .into_iter() - .filter_map(|(field_id, field_settings)| { - let field_settings = FieldSettings::try_from_anymap(field_id.clone(), field_settings); - if let Ok(settings) = field_settings { - Some((field_id, settings)) - } else { - None - } - }) - .collect() + field_settings } fn update_field_settings( @@ -1456,25 +1430,29 @@ impl DatabaseViewOperation for DatabaseViewOperationImpl { view_id: &str, field_id: &str, visibility: Option, + width: Option, ) { let field_settings_map = self.get_field_settings(view_id, &[field_id.to_string()]); let new_field_settings = if let Some(field_settings) = field_settings_map.get(field_id) { - let mut field_settings = field_settings.to_owned(); - field_settings.visibility = visibility.unwrap_or(field_settings.visibility); - field_settings + FieldSettings { + field_id: field_settings.field_id.clone(), + visibility: visibility.unwrap_or(field_settings.visibility.clone()), + width: width.unwrap_or(field_settings.width), + } } else { - let layout_ty = self.get_layout_for_view(view_id); - let mut field_settings = FieldSettings::try_from_anymap( - field_id.to_string(), - default_field_settings_by_layout_map() - .get(&layout_ty) - .unwrap() - .to_owned(), - ) - .unwrap(); - field_settings.visibility = visibility.unwrap_or(field_settings.visibility); - field_settings + let layout_type = self.get_layout_for_view(view_id); + let default_field_settings = default_field_settings_by_layout_map() + .get(&layout_type) + .unwrap() + .to_owned(); + let field_settings = + FieldSettings::from_anymap(field_id, layout_type, &default_field_settings); + FieldSettings { + field_id: field_settings.field_id.clone(), + visibility: visibility.unwrap_or(field_settings.visibility), + width: width.unwrap_or(field_settings.width), + } }; self.database.lock().update_field_settings( diff --git a/frontend/rust-lib/flowy-database2/src/services/database/util.rs b/frontend/rust-lib/flowy-database2/src/services/database/util.rs index 69bac217c8..057cdea5e8 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database/util.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database/util.rs @@ -58,7 +58,9 @@ pub(crate) fn database_view_setting_pb_from_view(view: DatabaseView) -> Database .field_settings .into_inner() .into_iter() - .flat_map(|(field_id, field_settings)| FieldSettings::try_from_anymap(field_id, field_settings)) + .map(|(field_id, field_settings)| { + FieldSettings::from_anymap(&field_id, view.layout, &field_settings) + }) .map(FieldSettingsPB::from) .collect::>(); diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs index 276ef48273..0c63a64d73 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs @@ -844,19 +844,20 @@ impl DatabaseViewEditor { self.delegate.get_field_settings(&self.view_id, field_ids) } - pub async fn v_get_all_field_settings(&self) -> HashMap { - self.delegate.get_all_field_settings(&self.view_id) - } + // pub async fn v_get_all_field_settings(&self) -> HashMap { + // self.delegate.get_all_field_settings(&self.view_id) + // } pub async fn v_update_field_settings( &self, view_id: &str, field_id: &str, visibility: Option, + width: Option, ) -> FlowyResult<()> { self .delegate - .update_field_settings(view_id, field_id, visibility); + .update_field_settings(view_id, field_id, visibility, width); Ok(()) } diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_operation.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_operation.rs index 77472a3452..99df59b512 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_operation.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_operation.rs @@ -115,12 +115,11 @@ pub trait DatabaseViewOperation: Send + Sync + 'static { field_ids: &[String], ) -> HashMap; - fn get_all_field_settings(&self, view_id: &str) -> HashMap; - fn update_field_settings( &self, view_id: &str, field_id: &str, visibility: Option, + width: Option, ); } diff --git a/frontend/rust-lib/flowy-database2/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-database2/src/services/field/field_builder.rs index 95347214af..7a2009de91 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/field_builder.rs @@ -15,7 +15,7 @@ impl FieldBuilder { field_type.clone().into(), false, ); - field.width = field_type.default_cell_width() as i64; + field.width = 150; field .type_options .insert(field_type.to_string(), type_option_data.into()); diff --git a/frontend/rust-lib/flowy-database2/src/services/field_settings/entities.rs b/frontend/rust-lib/flowy-database2/src/services/field_settings/entities.rs index ab3dd8d824..674864afca 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field_settings/entities.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field_settings/entities.rs @@ -1,32 +1,42 @@ -use anyhow::bail; use collab::core::any_map::AnyMapExtension; -use collab_database::views::{FieldSettingsMap, FieldSettingsMapBuilder}; +use collab_database::views::{DatabaseLayout, FieldSettingsMap, FieldSettingsMapBuilder}; use crate::entities::FieldVisibility; +use crate::services::field_settings::default_field_visibility; /// Stores the field settings for a single field #[derive(Debug, Clone)] pub struct FieldSettings { pub field_id: String, pub visibility: FieldVisibility, + pub width: i32, } pub const VISIBILITY: &str = "visibility"; +pub const WIDTH: &str = "width"; + +pub const DEFAULT_WIDTH: i32 = 150; impl FieldSettings { - pub fn try_from_anymap( - field_id: String, - field_settings: FieldSettingsMap, - ) -> Result { - let visibility = match field_settings.get_i64_value(VISIBILITY) { - Some(visbility) => visbility.into(), - _ => bail!("Invalid field settings data"), - }; + pub fn from_anymap( + field_id: &str, + layout_type: DatabaseLayout, + field_settings: &FieldSettingsMap, + ) -> Self { + let visibility = field_settings + .get_i64_value(VISIBILITY) + .map(Into::into) + .unwrap_or_else(|| default_field_visibility(layout_type)); + let width = field_settings + .get_i64_value(WIDTH) + .map(|value| value as i32) + .unwrap_or(DEFAULT_WIDTH); - Ok(Self { - field_id, + Self { + field_id: field_id.to_string(), visibility, - }) + width, + } } } @@ -34,14 +44,16 @@ impl From for FieldSettingsMap { fn from(field_settings: FieldSettings) -> Self { FieldSettingsMapBuilder::new() .insert_i64_value(VISIBILITY, field_settings.visibility.into()) + .insert_i64_value(WIDTH, field_settings.width as i64) .build() } } /// Contains the changeset to a field's settings. -/// A `Some` value for constitutes a change in that particular setting +/// A `Some` value constitutes a change in that particular setting pub struct FieldSettingsChangesetParams { pub view_id: String, pub field_id: String, pub visibility: Option, + pub width: Option, } diff --git a/frontend/rust-lib/flowy-database2/src/services/field_settings/field_settings_builder.rs b/frontend/rust-lib/flowy-database2/src/services/field_settings/field_settings_builder.rs index 01c0a6b875..751b84eafd 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field_settings/field_settings_builder.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field_settings/field_settings_builder.rs @@ -1,7 +1,5 @@ use std::collections::HashMap; -use std::sync::Arc; -use collab_database::database::MutexDatabase; use collab_database::fields::Field; use collab_database::views::{ DatabaseLayout, FieldSettingsByFieldIdMap, FieldSettingsMap, FieldSettingsMapBuilder, @@ -14,7 +12,7 @@ use crate::services::field_settings::{FieldSettings, VISIBILITY}; /// Helper struct to create a new field setting pub struct FieldSettingsBuilder { - field_settings: FieldSettings, + inner: FieldSettings, } impl FieldSettingsBuilder { @@ -22,57 +20,49 @@ impl FieldSettingsBuilder { let field_settings = FieldSettings { field_id: field_id.to_string(), visibility: FieldVisibility::AlwaysShown, + width: 150, }; - Self { field_settings } - } - - pub fn field_id(mut self, field_id: &str) -> Self { - self.field_settings.field_id = field_id.to_string(); - self + Self { + inner: field_settings, + } } pub fn visibility(mut self, visibility: FieldVisibility) -> Self { - self.field_settings.visibility = visibility; + self.inner.visibility = visibility; + self + } + + pub fn width(mut self, width: i32) -> Self { + self.inner.width = width; self } pub fn build(self) -> FieldSettings { - self.field_settings + self.inner } } -pub struct DatabaseFieldSettingsMapBuilder { - pub fields: Vec, - pub database_layout: DatabaseLayout, +#[inline] +pub fn default_field_visibility(layout_type: DatabaseLayout) -> FieldVisibility { + match layout_type { + DatabaseLayout::Grid => FieldVisibility::AlwaysShown, + DatabaseLayout::Board => FieldVisibility::HideWhenEmpty, + DatabaseLayout::Calendar => FieldVisibility::HideWhenEmpty, + } } -impl DatabaseFieldSettingsMapBuilder { - pub fn new(fields: Vec, database_layout: DatabaseLayout) -> Self { - Self { - fields, - database_layout, - } - } - - pub fn from_database(database: Arc, database_layout: DatabaseLayout) -> Self { - let fields = database.lock().get_fields(None); - Self { - fields, - database_layout, - } - } - - pub fn build(self) -> FieldSettingsByFieldIdMap { - self - .fields - .into_iter() - .map(|field| { - let field_settings = field_settings_for_field(self.database_layout, &field); - (field.id, field_settings) - }) - .collect::>() - .into() - } +pub fn default_field_settings_for_fields( + fields: &Vec, + layout_type: DatabaseLayout, +) -> FieldSettingsByFieldIdMap { + fields + .iter() + .map(|field| { + let field_settings = field_settings_for_field(layout_type, field); + (field.id.clone(), field_settings) + }) + .collect::>() + .into() } pub fn field_settings_for_field( @@ -82,11 +72,7 @@ pub fn field_settings_for_field( let visibility = if field.is_primary { FieldVisibility::AlwaysShown } else { - match database_layout { - DatabaseLayout::Grid => FieldVisibility::AlwaysShown, - DatabaseLayout::Board => FieldVisibility::HideWhenEmpty, - DatabaseLayout::Calendar => FieldVisibility::HideWhenEmpty, - } + default_field_visibility(database_layout) }; FieldSettingsBuilder::new(&field.id) @@ -98,11 +84,7 @@ pub fn field_settings_for_field( pub fn default_field_settings_by_layout_map() -> HashMap { let mut map = HashMap::new(); for layout_ty in DatabaseLayout::iter() { - let visibility = match layout_ty { - DatabaseLayout::Grid => FieldVisibility::AlwaysShown, - DatabaseLayout::Board => FieldVisibility::HideWhenEmpty, - DatabaseLayout::Calendar => FieldVisibility::HideWhenEmpty, - }; + let visibility = default_field_visibility(layout_ty); let field_settings = FieldSettingsMapBuilder::new() .insert_i64_value(VISIBILITY, visibility.into()) .build(); diff --git a/frontend/rust-lib/flowy-database2/src/services/share/csv/import.rs b/frontend/rust-lib/flowy-database2/src/services/share/csv/import.rs index ee16cdc94d..037c53597d 100644 --- a/frontend/rust-lib/flowy-database2/src/services/share/csv/import.rs +++ b/frontend/rust-lib/flowy-database2/src/services/share/csv/import.rs @@ -9,7 +9,7 @@ use flowy_error::{FlowyError, FlowyResult}; use crate::entities::FieldType; use crate::services::field::{default_type_option_data_from_type, CELL_DATA}; -use crate::services::field_settings::DatabaseFieldSettingsMapBuilder; +use crate::services::field_settings::default_field_settings_for_fields; use crate::services::share::csv::CSVFormat; #[derive(Default)] @@ -97,8 +97,7 @@ fn database_from_fields_and_rows( }) .collect::>(); - let field_settings = - DatabaseFieldSettingsMapBuilder::new(fields.clone(), DatabaseLayout::Grid).build(); + let field_settings = default_field_settings_for_fields(&fields, DatabaseLayout::Grid); let created_rows = rows .iter() diff --git a/frontend/rust-lib/flowy-database2/src/template.rs b/frontend/rust-lib/flowy-database2/src/template.rs index 23a217638c..bc3f23bc05 100644 --- a/frontend/rust-lib/flowy-database2/src/template.rs +++ b/frontend/rust-lib/flowy-database2/src/template.rs @@ -7,7 +7,7 @@ use crate::services::cell::{insert_select_option_cell, insert_text_cell}; use crate::services::field::{ FieldBuilder, SelectOption, SelectOptionColor, SingleSelectTypeOption, }; -use crate::services::field_settings::DatabaseFieldSettingsMapBuilder; +use crate::services::field_settings::default_field_settings_for_fields; use crate::services::setting::{BoardLayoutSetting, CalendarLayoutSetting}; pub fn make_default_grid(view_id: &str, name: &str) -> CreateDatabaseParams { @@ -29,8 +29,7 @@ pub fn make_default_grid(view_id: &str, name: &str) -> CreateDatabaseParams { let fields = vec![text_field, single_select, checkbox_field]; - let field_settings = - DatabaseFieldSettingsMapBuilder::new(fields.clone(), DatabaseLayout::Grid).build(); + let field_settings = default_field_settings_for_fields(&fields, DatabaseLayout::Grid); CreateDatabaseParams { database_id: gen_database_id(), @@ -90,8 +89,7 @@ pub fn make_default_board(view_id: &str, name: &str) -> CreateDatabaseParams { let fields = vec![text_field, single_select]; - let field_settings = - DatabaseFieldSettingsMapBuilder::new(fields.clone(), DatabaseLayout::Board).build(); + let field_settings = default_field_settings_for_fields(&fields, DatabaseLayout::Board); let mut layout_settings = LayoutSettings::default(); layout_settings.insert(DatabaseLayout::Board, BoardLayoutSetting::new().into()); @@ -134,8 +132,7 @@ pub fn make_default_calendar(view_id: &str, name: &str) -> CreateDatabaseParams let fields = vec![text_field, date_field, multi_select_field]; - let field_settings = - DatabaseFieldSettingsMapBuilder::new(fields.clone(), DatabaseLayout::Calendar).build(); + let field_settings = default_field_settings_for_fields(&fields, DatabaseLayout::Calendar); let mut layout_settings = LayoutSettings::default(); layout_settings.insert( diff --git a/frontend/rust-lib/flowy-database2/tests/database/field_settings_test/script.rs b/frontend/rust-lib/flowy-database2/tests/database/field_settings_test/script.rs index 492221184a..e5251bd121 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/field_settings_test/script.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/field_settings_test/script.rs @@ -1,4 +1,3 @@ -use collab_database::views::DatabaseLayout; use flowy_database2::entities::FieldVisibility; use flowy_database2::services::field_settings::FieldSettingsChangesetParams; @@ -8,16 +7,17 @@ use crate::database::database_editor::DatabaseEditorTest; pub enum FieldSettingsScript { AssertFieldSettings { field_ids: Vec, - layout_ty: DatabaseLayout, visibility: FieldVisibility, + width: i32, }, AssertAllFieldSettings { - layout_ty: DatabaseLayout, visibility: FieldVisibility, + width: i32, }, UpdateFieldSettings { field_id: String, visibility: Option, + width: Option, }, } @@ -51,41 +51,42 @@ impl FieldSettingsTest { match script { FieldSettingsScript::AssertFieldSettings { field_ids, - layout_ty, visibility, + width, } => { let field_settings = self .editor - .get_field_settings(&self.view_id, layout_ty, field_ids) + .get_field_settings(&self.view_id, field_ids) .await .unwrap(); for field_settings in field_settings.into_iter() { - assert_eq!(field_settings.visibility, visibility) + assert_eq!(field_settings.width, width); + assert_eq!(field_settings.visibility, visibility); } }, - FieldSettingsScript::AssertAllFieldSettings { - layout_ty, - visibility, - } => { + FieldSettingsScript::AssertAllFieldSettings { visibility, width } => { let field_settings = self .editor - .get_all_field_settings(&self.view_id, layout_ty) + .get_all_field_settings(&self.view_id) .await .unwrap(); for field_settings in field_settings.into_iter() { - assert_eq!(field_settings.visibility, visibility) + assert_eq!(field_settings.width, width); + assert_eq!(field_settings.visibility, visibility); } }, FieldSettingsScript::UpdateFieldSettings { field_id, visibility, + width, } => { let params = FieldSettingsChangesetParams { view_id: self.view_id.clone(), field_id, visibility, + width, }; let _ = self .editor diff --git a/frontend/rust-lib/flowy-database2/tests/database/field_settings_test/test.rs b/frontend/rust-lib/flowy-database2/tests/database/field_settings_test/test.rs index 749f1c9419..3c8963b8e6 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/field_settings_test/test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/field_settings_test/test.rs @@ -1,6 +1,6 @@ -use collab_database::views::DatabaseLayout; use flowy_database2::entities::FieldType; use flowy_database2::entities::FieldVisibility; +use flowy_database2::services::field_settings::DEFAULT_WIDTH; use crate::database::field_settings_test::script::FieldSettingsScript::*; use crate::database::field_settings_test::script::FieldSettingsTest; @@ -10,8 +10,8 @@ use crate::database::field_settings_test::script::FieldSettingsTest; async fn get_default_field_settings() { let mut test = FieldSettingsTest::new_grid().await; let scripts = vec![AssertAllFieldSettings { - layout_ty: DatabaseLayout::Grid, visibility: FieldVisibility::AlwaysShown, + width: DEFAULT_WIDTH, }]; test.run_scripts(scripts).await; @@ -26,13 +26,13 @@ async fn get_default_field_settings() { let scripts = vec![ AssertFieldSettings { field_ids: non_primary_field_ids.clone(), - layout_ty: DatabaseLayout::Board, visibility: FieldVisibility::HideWhenEmpty, + width: DEFAULT_WIDTH, }, AssertFieldSettings { field_ids: vec![primary_field_id.clone()], - layout_ty: DatabaseLayout::Board, visibility: FieldVisibility::AlwaysShown, + width: DEFAULT_WIDTH, }, ]; test.run_scripts(scripts).await; @@ -48,13 +48,13 @@ async fn get_default_field_settings() { let scripts = vec![ AssertFieldSettings { field_ids: non_primary_field_ids.clone(), - layout_ty: DatabaseLayout::Calendar, visibility: FieldVisibility::HideWhenEmpty, + width: DEFAULT_WIDTH, }, AssertFieldSettings { field_ids: vec![primary_field_id.clone()], - layout_ty: DatabaseLayout::Calendar, visibility: FieldVisibility::AlwaysShown, + width: DEFAULT_WIDTH, }, ]; test.run_scripts(scripts).await; @@ -75,21 +75,22 @@ async fn update_field_settings_test() { let scripts = vec![ AssertFieldSettings { field_ids: non_primary_field_ids, - layout_ty: DatabaseLayout::Board, visibility: FieldVisibility::HideWhenEmpty, + width: DEFAULT_WIDTH, }, AssertFieldSettings { field_ids: vec![primary_field_id.clone()], - layout_ty: DatabaseLayout::Board, visibility: FieldVisibility::AlwaysShown, + width: DEFAULT_WIDTH, }, UpdateFieldSettings { field_id: primary_field_id, visibility: Some(FieldVisibility::HideWhenEmpty), + width: None, }, AssertAllFieldSettings { - layout_ty: DatabaseLayout::Board, visibility: FieldVisibility::HideWhenEmpty, + width: DEFAULT_WIDTH, }, ]; test.run_scripts(scripts).await; diff --git a/frontend/rust-lib/flowy-database2/tests/database/mock_data/board_mock_data.rs b/frontend/rust-lib/flowy-database2/tests/database/mock_data/board_mock_data.rs index d26f3bd59f..1e21cb9474 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/mock_data/board_mock_data.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/mock_data/board_mock_data.rs @@ -1,6 +1,6 @@ use collab_database::database::{gen_database_id, gen_database_view_id, gen_row_id, DatabaseData}; use collab_database::views::{DatabaseLayout, DatabaseView, LayoutSetting, LayoutSettings}; -use flowy_database2::services::field_settings::DatabaseFieldSettingsMapBuilder; +use flowy_database2::services::field_settings::default_field_settings_for_fields; use flowy_database2::services::setting::BoardLayoutSetting; use strum::IntoEnumIterator; @@ -131,8 +131,7 @@ pub fn make_test_board() -> DatabaseData { let board_setting: LayoutSetting = BoardLayoutSetting::new().into(); - let field_settings = - DatabaseFieldSettingsMapBuilder::new(fields.clone(), DatabaseLayout::Board).build(); + let field_settings = default_field_settings_for_fields(&fields, DatabaseLayout::Board); // We have many assumptions base on the number of the rows, so do not change the number of the loop. for i in 0..5 { diff --git a/frontend/rust-lib/flowy-database2/tests/database/mock_data/calendar_mock_data.rs b/frontend/rust-lib/flowy-database2/tests/database/mock_data/calendar_mock_data.rs index c41433e591..7587c8ca4f 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/mock_data/calendar_mock_data.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/mock_data/calendar_mock_data.rs @@ -1,6 +1,6 @@ use collab_database::database::{gen_database_id, gen_database_view_id, gen_row_id, DatabaseData}; use collab_database::views::{DatabaseLayout, DatabaseView, LayoutSetting, LayoutSettings}; -use flowy_database2::services::field_settings::DatabaseFieldSettingsMapBuilder; +use flowy_database2::services::field_settings::default_field_settings_for_fields; use strum::IntoEnumIterator; use flowy_database2::entities::FieldType; @@ -40,8 +40,7 @@ pub fn make_test_calendar() -> DatabaseData { let calendar_setting: LayoutSetting = CalendarLayoutSetting::new(date_field_id).into(); - let field_settings = - DatabaseFieldSettingsMapBuilder::new(fields.clone(), DatabaseLayout::Calendar).build(); + let field_settings = default_field_settings_for_fields(&fields, DatabaseLayout::Calendar); for i in 0..5 { let mut row_builder = TestRowBuilder::new(gen_row_id(), &fields); diff --git a/frontend/rust-lib/flowy-database2/tests/database/mock_data/grid_mock_data.rs b/frontend/rust-lib/flowy-database2/tests/database/mock_data/grid_mock_data.rs index fcba0a73f2..52790c2b27 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/mock_data/grid_mock_data.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/mock_data/grid_mock_data.rs @@ -1,6 +1,6 @@ use collab_database::database::{gen_database_id, gen_database_view_id, gen_row_id, DatabaseData}; use collab_database::views::{DatabaseLayout, DatabaseView}; -use flowy_database2::services::field_settings::DatabaseFieldSettingsMapBuilder; +use flowy_database2::services::field_settings::default_field_settings_for_fields; use strum::IntoEnumIterator; use flowy_database2::entities::FieldType; @@ -131,8 +131,7 @@ pub fn make_test_grid() -> DatabaseData { } } - let field_settings = - DatabaseFieldSettingsMapBuilder::new(fields.clone(), DatabaseLayout::Grid).build(); + let field_settings = default_field_settings_for_fields(&fields, DatabaseLayout::Grid); for i in 0..7 { let mut row_builder = TestRowBuilder::new(gen_row_id(), &fields); @@ -297,8 +296,7 @@ pub fn make_no_date_test_grid() -> DatabaseData { } } - let field_settings = - DatabaseFieldSettingsMapBuilder::new(fields.clone(), DatabaseLayout::Grid).build(); + let field_settings = default_field_settings_for_fields(&fields, DatabaseLayout::Grid); for i in 0..3 { let mut row_builder = TestRowBuilder::new(gen_row_id(), &fields);