mirror of
				https://github.com/AppFlowy-IO/AppFlowy.git
				synced 2025-11-04 03:54:44 +00:00 
			
		
		
		
	chore: config option editor ui
This commit is contained in:
		
							parent
							
								
									271a8485b6
								
							
						
					
					
						commit
						5358203a46
					
				@ -186,7 +186,8 @@
 | 
				
			|||||||
      "blueColor": "Blue",
 | 
					      "blueColor": "Blue",
 | 
				
			||||||
      "deleteTag": "Delete tag",
 | 
					      "deleteTag": "Delete tag",
 | 
				
			||||||
      "colorPannelTitle": "Colors",
 | 
					      "colorPannelTitle": "Colors",
 | 
				
			||||||
      "pannelTitle": "Select an option"
 | 
					      "pannelTitle": "Select an option or create one",
 | 
				
			||||||
 | 
					      "searchOption": "Search for an option"
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -151,7 +151,7 @@ void _resolveGridDeps(GetIt getIt) {
 | 
				
			|||||||
    (view, _) => GridBloc(view: view, service: GridService()),
 | 
					    (view, _) => GridBloc(view: view, service: GridService()),
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getIt.registerFactoryParam<RowBloc, GridRowData, void>(
 | 
					  getIt.registerFactoryParam<RowBloc, RowData, void>(
 | 
				
			||||||
    (data, _) => RowBloc(
 | 
					    (data, _) => RowBloc(
 | 
				
			||||||
      rowData: data,
 | 
					      rowData: data,
 | 
				
			||||||
      rowlistener: RowListener(rowId: data.rowId),
 | 
					      rowlistener: RowListener(rowId: data.rowId),
 | 
				
			||||||
@ -179,35 +179,35 @@ void _resolveGridDeps(GetIt getIt) {
 | 
				
			|||||||
    ),
 | 
					    ),
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getIt.registerFactoryParam<TextCellBloc, FutureCellData, void>(
 | 
					  getIt.registerFactoryParam<TextCellBloc, CellData, void>(
 | 
				
			||||||
    (cellData, _) => TextCellBloc(
 | 
					    (cellData, _) => TextCellBloc(
 | 
				
			||||||
      service: CellService(),
 | 
					      service: CellService(),
 | 
				
			||||||
      cellData: cellData,
 | 
					      cellData: cellData,
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getIt.registerFactoryParam<SelectionCellBloc, FutureCellData, void>(
 | 
					  getIt.registerFactoryParam<SelectionCellBloc, CellData, void>(
 | 
				
			||||||
    (cellData, _) => SelectionCellBloc(
 | 
					    (cellData, _) => SelectionCellBloc(
 | 
				
			||||||
      service: CellService(),
 | 
					      service: CellService(),
 | 
				
			||||||
      cellData: cellData,
 | 
					      cellData: cellData,
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getIt.registerFactoryParam<NumberCellBloc, FutureCellData, void>(
 | 
					  getIt.registerFactoryParam<NumberCellBloc, CellData, void>(
 | 
				
			||||||
    (cellData, _) => NumberCellBloc(
 | 
					    (cellData, _) => NumberCellBloc(
 | 
				
			||||||
      service: CellService(),
 | 
					      service: CellService(),
 | 
				
			||||||
      cellData: cellData,
 | 
					      cellData: cellData,
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getIt.registerFactoryParam<DateCellBloc, FutureCellData, void>(
 | 
					  getIt.registerFactoryParam<DateCellBloc, CellData, void>(
 | 
				
			||||||
    (cellData, _) => DateCellBloc(
 | 
					    (cellData, _) => DateCellBloc(
 | 
				
			||||||
      service: CellService(),
 | 
					      service: CellService(),
 | 
				
			||||||
      cellData: cellData,
 | 
					      cellData: cellData,
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getIt.registerFactoryParam<CheckboxCellBloc, FutureCellData, void>(
 | 
					  getIt.registerFactoryParam<CheckboxCellBloc, CellData, void>(
 | 
				
			||||||
    (cellData, _) => CheckboxCellBloc(
 | 
					    (cellData, _) => CheckboxCellBloc(
 | 
				
			||||||
      service: CellService(),
 | 
					      service: CellService(),
 | 
				
			||||||
      cellData: cellData,
 | 
					      cellData: cellData,
 | 
				
			||||||
 | 
				
			|||||||
@ -9,11 +9,11 @@ part 'checkbox_cell_bloc.freezed.dart';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> {
 | 
					class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> {
 | 
				
			||||||
  final CellService service;
 | 
					  final CellService service;
 | 
				
			||||||
  // final FutureCellData cellData;
 | 
					  // final CellData cellData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  CheckboxCellBloc({
 | 
					  CheckboxCellBloc({
 | 
				
			||||||
    required this.service,
 | 
					    required this.service,
 | 
				
			||||||
    required FutureCellData cellData,
 | 
					    required CellData cellData,
 | 
				
			||||||
  }) : super(CheckboxCellState.initial()) {
 | 
					  }) : super(CheckboxCellState.initial()) {
 | 
				
			||||||
    on<CheckboxCellEvent>(
 | 
					    on<CheckboxCellEvent>(
 | 
				
			||||||
      (event, emit) async {
 | 
					      (event, emit) async {
 | 
				
			||||||
 | 
				
			|||||||
@ -9,7 +9,7 @@ part 'date_cell_bloc.freezed.dart';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class DateCellBloc extends Bloc<DateCellEvent, DateCellState> {
 | 
					class DateCellBloc extends Bloc<DateCellEvent, DateCellState> {
 | 
				
			||||||
  final CellService service;
 | 
					  final CellService service;
 | 
				
			||||||
  final FutureCellData cellData;
 | 
					  final CellData cellData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  DateCellBloc({
 | 
					  DateCellBloc({
 | 
				
			||||||
    required this.service,
 | 
					    required this.service,
 | 
				
			||||||
 | 
				
			|||||||
@ -12,7 +12,7 @@ class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  NumberCellBloc({
 | 
					  NumberCellBloc({
 | 
				
			||||||
    required this.service,
 | 
					    required this.service,
 | 
				
			||||||
    required FutureCellData cellData,
 | 
					    required CellData cellData,
 | 
				
			||||||
  }) : super(NumberCellState.initial()) {
 | 
					  }) : super(NumberCellState.initial()) {
 | 
				
			||||||
    on<NumberCellEvent>(
 | 
					    on<NumberCellEvent>(
 | 
				
			||||||
      (event, emit) async {
 | 
					      (event, emit) async {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,7 @@
 | 
				
			|||||||
 | 
					import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
 | 
				
			||||||
import 'package:app_flowy/workspace/application/grid/row/row_service.dart';
 | 
					import 'package:app_flowy/workspace/application/grid/row/row_service.dart';
 | 
				
			||||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
 | 
					import 'package:flowy_sdk/log.dart';
 | 
				
			||||||
 | 
					import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
 | 
				
			||||||
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
 | 
					import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
 | 
				
			||||||
import 'package:flutter_bloc/flutter_bloc.dart';
 | 
					import 'package:flutter_bloc/flutter_bloc.dart';
 | 
				
			||||||
import 'package:freezed_annotation/freezed_annotation.dart';
 | 
					import 'package:freezed_annotation/freezed_annotation.dart';
 | 
				
			||||||
@ -13,12 +15,17 @@ class SelectionCellBloc extends Bloc<SelectionCellEvent, SelectionCellState> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  SelectionCellBloc({
 | 
					  SelectionCellBloc({
 | 
				
			||||||
    required this.service,
 | 
					    required this.service,
 | 
				
			||||||
    required FutureCellData cellData,
 | 
					    required CellData cellData,
 | 
				
			||||||
  }) : super(SelectionCellState.initial()) {
 | 
					  }) : super(SelectionCellState.initial(cellData)) {
 | 
				
			||||||
    on<SelectionCellEvent>(
 | 
					    on<SelectionCellEvent>(
 | 
				
			||||||
      (event, emit) async {
 | 
					      (event, emit) async {
 | 
				
			||||||
        await event.map(
 | 
					        await event.map(
 | 
				
			||||||
          initial: (_InitialCell value) async {},
 | 
					          initial: (_InitialCell value) async {
 | 
				
			||||||
 | 
					            _loadOptions();
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          didReceiveOptions: (_DidReceiveOptions value) {
 | 
				
			||||||
 | 
					            emit(state.copyWith(options: value.options, selectedOptions: value.selectedOptions));
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
@ -28,19 +35,57 @@ class SelectionCellBloc extends Bloc<SelectionCellEvent, SelectionCellState> {
 | 
				
			|||||||
  Future<void> close() async {
 | 
					  Future<void> close() async {
 | 
				
			||||||
    return super.close();
 | 
					    return super.close();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void _loadOptions() async {
 | 
				
			||||||
 | 
					    final result = await FieldContextLoaderAdaptor(
 | 
				
			||||||
 | 
					      gridId: state.cellData.gridId,
 | 
				
			||||||
 | 
					      field: state.cellData.field,
 | 
				
			||||||
 | 
					    ).load();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    result.fold(
 | 
				
			||||||
 | 
					      (context) {
 | 
				
			||||||
 | 
					        List<SelectOption> options = [];
 | 
				
			||||||
 | 
					        switch (state.cellData.field.fieldType) {
 | 
				
			||||||
 | 
					          case FieldType.MultiSelect:
 | 
				
			||||||
 | 
					            options.addAll(MultiSelectTypeOption.fromBuffer(context.typeOptionData).options);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case FieldType.SingleSelect:
 | 
				
			||||||
 | 
					            options.addAll(SingleSelectTypeOption.fromBuffer(context.typeOptionData).options);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          default:
 | 
				
			||||||
 | 
					            Log.error("Invalid field type, expect single select or multiple select");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final ids = state.cellData.cell?.content.split(',');
 | 
				
			||||||
 | 
					        final selectedOptions = ids?.map((id) => options.firstWhere((option) => option.id == id)).toList() ?? [];
 | 
				
			||||||
 | 
					        add(SelectionCellEvent.didReceiveOptions(options, selectedOptions));
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      (err) => Log.error(err),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@freezed
 | 
					@freezed
 | 
				
			||||||
class SelectionCellEvent with _$SelectionCellEvent {
 | 
					class SelectionCellEvent with _$SelectionCellEvent {
 | 
				
			||||||
  const factory SelectionCellEvent.initial() = _InitialCell;
 | 
					  const factory SelectionCellEvent.initial() = _InitialCell;
 | 
				
			||||||
 | 
					  const factory SelectionCellEvent.didReceiveOptions(
 | 
				
			||||||
 | 
					    List<SelectOption> options,
 | 
				
			||||||
 | 
					    List<SelectOption> selectedOptions,
 | 
				
			||||||
 | 
					  ) = _DidReceiveOptions;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@freezed
 | 
					@freezed
 | 
				
			||||||
class SelectionCellState with _$SelectionCellState {
 | 
					class SelectionCellState with _$SelectionCellState {
 | 
				
			||||||
  const factory SelectionCellState() = _SelectionCellState;
 | 
					  const factory SelectionCellState({
 | 
				
			||||||
  // required String girdId,
 | 
					    required CellData cellData,
 | 
				
			||||||
  //   required Field field,
 | 
					    required List<SelectOption> options,
 | 
				
			||||||
  //   required List<SelectOption> options,
 | 
					    required List<SelectOption> selectedOptions,
 | 
				
			||||||
 | 
					  }) = _SelectionCellState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  factory SelectionCellState.initial() => const SelectionCellState();
 | 
					  factory SelectionCellState.initial(CellData cellData) => SelectionCellState(
 | 
				
			||||||
 | 
					        cellData: cellData,
 | 
				
			||||||
 | 
					        options: [],
 | 
				
			||||||
 | 
					        selectedOptions: [],
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -11,16 +11,18 @@ import 'cell_service.dart';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part 'selection_editor_bloc.freezed.dart';
 | 
					part 'selection_editor_bloc.freezed.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SelectionEditorBloc extends Bloc<SelectionEditorEvent, SelectionEditorState> {
 | 
					class SelectOptionEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOptionEditorState> {
 | 
				
			||||||
  final CellService service = CellService();
 | 
					  final CellService service = CellService();
 | 
				
			||||||
  final FieldListener _listener;
 | 
					  final FieldListener _listener;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SelectionEditorBloc({
 | 
					  SelectOptionEditorBloc({
 | 
				
			||||||
    required String gridId,
 | 
					    required String gridId,
 | 
				
			||||||
    required Field field,
 | 
					    required Field field,
 | 
				
			||||||
 | 
					    required List<SelectOption> options,
 | 
				
			||||||
 | 
					    required List<SelectOption> selectedOptions,
 | 
				
			||||||
  })  : _listener = FieldListener(fieldId: field.id),
 | 
					  })  : _listener = FieldListener(fieldId: field.id),
 | 
				
			||||||
        super(SelectionEditorState.initial(gridId, field)) {
 | 
					        super(SelectOptionEditorState.initial(gridId, field, options, selectedOptions)) {
 | 
				
			||||||
    on<SelectionEditorEvent>(
 | 
					    on<SelectOptionEditorEvent>(
 | 
				
			||||||
      (event, emit) async {
 | 
					      (event, emit) async {
 | 
				
			||||||
        await event.map(
 | 
					        await event.map(
 | 
				
			||||||
          initial: (_Initial value) async {
 | 
					          initial: (_Initial value) async {
 | 
				
			||||||
@ -34,6 +36,7 @@ class SelectionEditorBloc extends Bloc<SelectionEditorEvent, SelectionEditorStat
 | 
				
			|||||||
          didReceiveOptions: (_DidReceiveOptions value) {
 | 
					          didReceiveOptions: (_DidReceiveOptions value) {
 | 
				
			||||||
            emit(state.copyWith(options: value.options));
 | 
					            emit(state.copyWith(options: value.options));
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
 | 
					          newOption: (_newOption value) {},
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
@ -48,7 +51,7 @@ class SelectionEditorBloc extends Bloc<SelectionEditorEvent, SelectionEditorStat
 | 
				
			|||||||
  void _startListening() {
 | 
					  void _startListening() {
 | 
				
			||||||
    _listener.updateFieldNotifier.addPublishListener((result) {
 | 
					    _listener.updateFieldNotifier.addPublishListener((result) {
 | 
				
			||||||
      result.fold(
 | 
					      result.fold(
 | 
				
			||||||
        (field) => add(SelectionEditorEvent.didReceiveFieldUpdate(field)),
 | 
					        (field) => add(SelectOptionEditorEvent.didReceiveFieldUpdate(field)),
 | 
				
			||||||
        (err) => Log.error(err),
 | 
					        (err) => Log.error(err),
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
@ -70,7 +73,7 @@ class SelectionEditorBloc extends Bloc<SelectionEditorEvent, SelectionEditorStat
 | 
				
			|||||||
            Log.error("Invalid field type, expect single select or multiple select");
 | 
					            Log.error("Invalid field type, expect single select or multiple select");
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        add(SelectionEditorEvent.didReceiveOptions(options));
 | 
					        add(SelectOptionEditorEvent.didReceiveOptions(options));
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      (err) => Log.error(err),
 | 
					      (err) => Log.error(err),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
@ -78,25 +81,33 @@ class SelectionEditorBloc extends Bloc<SelectionEditorEvent, SelectionEditorStat
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@freezed
 | 
					@freezed
 | 
				
			||||||
class SelectionEditorEvent with _$SelectionEditorEvent {
 | 
					class SelectOptionEditorEvent with _$SelectOptionEditorEvent {
 | 
				
			||||||
  const factory SelectionEditorEvent.initial() = _Initial;
 | 
					  const factory SelectOptionEditorEvent.initial() = _Initial;
 | 
				
			||||||
  const factory SelectionEditorEvent.didReceiveFieldUpdate(Field field) = _DidReceiveFieldUpdate;
 | 
					  const factory SelectOptionEditorEvent.didReceiveFieldUpdate(Field field) = _DidReceiveFieldUpdate;
 | 
				
			||||||
  const factory SelectionEditorEvent.didReceiveOptions(List<SelectOption> options) = _DidReceiveOptions;
 | 
					  const factory SelectOptionEditorEvent.didReceiveOptions(List<SelectOption> options) = _DidReceiveOptions;
 | 
				
			||||||
 | 
					  const factory SelectOptionEditorEvent.newOption(String optionName) = _newOption;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@freezed
 | 
					@freezed
 | 
				
			||||||
class SelectionEditorState with _$SelectionEditorState {
 | 
					class SelectOptionEditorState with _$SelectOptionEditorState {
 | 
				
			||||||
  const factory SelectionEditorState({
 | 
					  const factory SelectOptionEditorState({
 | 
				
			||||||
    required String gridId,
 | 
					    required String gridId,
 | 
				
			||||||
    required Field field,
 | 
					    required Field field,
 | 
				
			||||||
    required List<SelectOption> options,
 | 
					    required List<SelectOption> options,
 | 
				
			||||||
  }) = _SelectionEditorState;
 | 
					    required List<SelectOption> selectedOptions,
 | 
				
			||||||
 | 
					  }) = _SelectOptionEditorState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  factory SelectionEditorState.initial(String gridId, Field field) {
 | 
					  factory SelectOptionEditorState.initial(
 | 
				
			||||||
    return SelectionEditorState(
 | 
					    String gridId,
 | 
				
			||||||
 | 
					    Field field,
 | 
				
			||||||
 | 
					    List<SelectOption> options,
 | 
				
			||||||
 | 
					    List<SelectOption> selectedOptions,
 | 
				
			||||||
 | 
					  ) {
 | 
				
			||||||
 | 
					    return SelectOptionEditorState(
 | 
				
			||||||
      gridId: gridId,
 | 
					      gridId: gridId,
 | 
				
			||||||
      field: field,
 | 
					      field: field,
 | 
				
			||||||
      options: [],
 | 
					      options: options,
 | 
				
			||||||
 | 
					      selectedOptions: selectedOptions,
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -11,7 +11,7 @@ class TextCellBloc extends Bloc<TextCellEvent, TextCellState> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  TextCellBloc({
 | 
					  TextCellBloc({
 | 
				
			||||||
    required this.service,
 | 
					    required this.service,
 | 
				
			||||||
    required FutureCellData cellData,
 | 
					    required CellData cellData,
 | 
				
			||||||
  }) : super(TextCellState.initial(cellData)) {
 | 
					  }) : super(TextCellState.initial(cellData)) {
 | 
				
			||||||
    on<TextCellEvent>(
 | 
					    on<TextCellEvent>(
 | 
				
			||||||
      (event, emit) async {
 | 
					      (event, emit) async {
 | 
				
			||||||
@ -53,7 +53,7 @@ class TextCellBloc extends Bloc<TextCellEvent, TextCellState> {
 | 
				
			|||||||
@freezed
 | 
					@freezed
 | 
				
			||||||
class TextCellEvent with _$TextCellEvent {
 | 
					class TextCellEvent with _$TextCellEvent {
 | 
				
			||||||
  const factory TextCellEvent.initial() = _InitialCell;
 | 
					  const factory TextCellEvent.initial() = _InitialCell;
 | 
				
			||||||
  const factory TextCellEvent.didReceiveCellData(GridCellData cellData) = _DidReceiveCellData;
 | 
					  const factory TextCellEvent.didReceiveCellData(CellData cellData) = _DidReceiveCellData;
 | 
				
			||||||
  const factory TextCellEvent.updateText(String text) = _UpdateText;
 | 
					  const factory TextCellEvent.updateText(String text) = _UpdateText;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -61,10 +61,10 @@ class TextCellEvent with _$TextCellEvent {
 | 
				
			|||||||
class TextCellState with _$TextCellState {
 | 
					class TextCellState with _$TextCellState {
 | 
				
			||||||
  const factory TextCellState({
 | 
					  const factory TextCellState({
 | 
				
			||||||
    required String content,
 | 
					    required String content,
 | 
				
			||||||
    required FutureCellData cellData,
 | 
					    required CellData cellData,
 | 
				
			||||||
  }) = _TextCellState;
 | 
					  }) = _TextCellState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  factory TextCellState.initial(FutureCellData cellData) => TextCellState(
 | 
					  factory TextCellState.initial(CellData cellData) => TextCellState(
 | 
				
			||||||
        content: cellData.cell?.content ?? "",
 | 
					        content: cellData.cell?.content ?? "",
 | 
				
			||||||
        cellData: cellData,
 | 
					        cellData: cellData,
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
 | 
				
			|||||||
@ -169,14 +169,14 @@ class GridBlockRow {
 | 
				
			|||||||
  });
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GridRowData extends Equatable {
 | 
					class RowData extends Equatable {
 | 
				
			||||||
  final String gridId;
 | 
					  final String gridId;
 | 
				
			||||||
  final String rowId;
 | 
					  final String rowId;
 | 
				
			||||||
  final String blockId;
 | 
					  final String blockId;
 | 
				
			||||||
  final List<Field> fields;
 | 
					  final List<Field> fields;
 | 
				
			||||||
  final double height;
 | 
					  final double height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const GridRowData({
 | 
					  const RowData({
 | 
				
			||||||
    required this.gridId,
 | 
					    required this.gridId,
 | 
				
			||||||
    required this.rowId,
 | 
					    required this.rowId,
 | 
				
			||||||
    required this.blockId,
 | 
					    required this.blockId,
 | 
				
			||||||
@ -184,8 +184,8 @@ class GridRowData extends Equatable {
 | 
				
			|||||||
    required this.height,
 | 
					    required this.height,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  factory GridRowData.fromBlockRow(GridBlockRow row, List<Field> fields) {
 | 
					  factory RowData.fromBlockRow(GridBlockRow row, List<Field> fields) {
 | 
				
			||||||
    return GridRowData(
 | 
					    return RowData(
 | 
				
			||||||
      gridId: row.gridId,
 | 
					      gridId: row.gridId,
 | 
				
			||||||
      rowId: row.rowId,
 | 
					      rowId: row.rowId,
 | 
				
			||||||
      blockId: row.blockId,
 | 
					      blockId: row.blockId,
 | 
				
			||||||
 | 
				
			|||||||
@ -13,14 +13,14 @@ import 'package:dartz/dartz.dart';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part 'row_bloc.freezed.dart';
 | 
					part 'row_bloc.freezed.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef CellDataMap = LinkedHashMap<String, GridCellData>;
 | 
					typedef CellDataMap = LinkedHashMap<String, CellData>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RowBloc extends Bloc<RowEvent, RowState> {
 | 
					class RowBloc extends Bloc<RowEvent, RowState> {
 | 
				
			||||||
  final RowService rowService;
 | 
					  final RowService rowService;
 | 
				
			||||||
  final RowListener rowlistener;
 | 
					  final RowListener rowlistener;
 | 
				
			||||||
  final GridFieldsListener fieldListener;
 | 
					  final GridFieldsListener fieldListener;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  RowBloc({required GridRowData rowData, required this.rowlistener})
 | 
					  RowBloc({required RowData rowData, required this.rowlistener})
 | 
				
			||||||
      : rowService = RowService(
 | 
					      : rowService = RowService(
 | 
				
			||||||
          gridId: rowData.gridId,
 | 
					          gridId: rowData.gridId,
 | 
				
			||||||
          blockId: rowData.blockId,
 | 
					          blockId: rowData.blockId,
 | 
				
			||||||
@ -112,7 +112,7 @@ class RowBloc extends Bloc<RowEvent, RowState> {
 | 
				
			|||||||
    var map = CellDataMap.new();
 | 
					    var map = CellDataMap.new();
 | 
				
			||||||
    for (final field in state.fields) {
 | 
					    for (final field in state.fields) {
 | 
				
			||||||
      if (field.visibility) {
 | 
					      if (field.visibility) {
 | 
				
			||||||
        map[field.id] = GridCellData(
 | 
					        map[field.id] = CellData(
 | 
				
			||||||
          rowId: row.id,
 | 
					          rowId: row.id,
 | 
				
			||||||
          gridId: rowService.gridId,
 | 
					          gridId: rowService.gridId,
 | 
				
			||||||
          blockId: rowService.blockId,
 | 
					          blockId: rowService.blockId,
 | 
				
			||||||
@ -143,7 +143,7 @@ class RowState with _$RowState {
 | 
				
			|||||||
    required Option<CellDataMap> cellDataMap,
 | 
					    required Option<CellDataMap> cellDataMap,
 | 
				
			||||||
  }) = _RowState;
 | 
					  }) = _RowState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  factory RowState.initial(GridRowData data) => RowState(
 | 
					  factory RowState.initial(RowData data) => RowState(
 | 
				
			||||||
        rowId: data.rowId,
 | 
					        rowId: data.rowId,
 | 
				
			||||||
        rowHeight: data.height,
 | 
					        rowHeight: data.height,
 | 
				
			||||||
        fields: data.fields,
 | 
					        fields: data.fields,
 | 
				
			||||||
 | 
				
			|||||||
@ -29,16 +29,14 @@ class RowService {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef FutureCellData = GridCellData;
 | 
					class CellData extends Equatable {
 | 
				
			||||||
 | 
					 | 
				
			||||||
class GridCellData extends Equatable {
 | 
					 | 
				
			||||||
  final String gridId;
 | 
					  final String gridId;
 | 
				
			||||||
  final String rowId;
 | 
					  final String rowId;
 | 
				
			||||||
  final String blockId;
 | 
					  final String blockId;
 | 
				
			||||||
  final Field field;
 | 
					  final Field field;
 | 
				
			||||||
  final Cell? cell;
 | 
					  final Cell? cell;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const GridCellData({
 | 
					  const CellData({
 | 
				
			||||||
    required this.rowId,
 | 
					    required this.rowId,
 | 
				
			||||||
    required this.gridId,
 | 
					    required this.gridId,
 | 
				
			||||||
    required this.blockId,
 | 
					    required this.blockId,
 | 
				
			||||||
 | 
				
			|||||||
@ -157,7 +157,7 @@ class _FlowyGridState extends State<FlowyGrid> {
 | 
				
			|||||||
            (context, index) {
 | 
					            (context, index) {
 | 
				
			||||||
              final blockRow = context.read<GridBloc>().state.rows[index];
 | 
					              final blockRow = context.read<GridBloc>().state.rows[index];
 | 
				
			||||||
              final fields = context.read<GridBloc>().state.fields;
 | 
					              final fields = context.read<GridBloc>().state.fields;
 | 
				
			||||||
              final rowData = GridRowData.fromBlockRow(blockRow, fields);
 | 
					              final rowData = RowData.fromBlockRow(blockRow, fields);
 | 
				
			||||||
              return GridRowWidget(data: rowData, key: ValueKey(rowData.rowId));
 | 
					              return GridRowWidget(data: rowData, key: ValueKey(rowData.rowId));
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            childCount: context.read<GridBloc>().state.rows.length,
 | 
					            childCount: context.read<GridBloc>().state.rows.length,
 | 
				
			||||||
 | 
				
			|||||||
@ -9,8 +9,9 @@ class GridSize {
 | 
				
			|||||||
  static double get leadingHeaderPadding => 30 * scale;
 | 
					  static double get leadingHeaderPadding => 30 * scale;
 | 
				
			||||||
  static double get trailHeaderPadding => 140 * scale;
 | 
					  static double get trailHeaderPadding => 140 * scale;
 | 
				
			||||||
  static double get headerContainerPadding => 0 * scale;
 | 
					  static double get headerContainerPadding => 0 * scale;
 | 
				
			||||||
  static double get cellContentPadding => 10 * scale;
 | 
					  static double get cellHPadding => 10 * scale;
 | 
				
			||||||
  static double get typeOptionItemHeight => 30 * scale;
 | 
					  static double get cellVPadding => 8 * scale;
 | 
				
			||||||
 | 
					  static double get typeOptionItemHeight => 32 * scale;
 | 
				
			||||||
  static double get typeOptionSeparatorHeight => 6 * scale;
 | 
					  static double get typeOptionSeparatorHeight => 6 * scale;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
@ -19,13 +20,13 @@ class GridSize {
 | 
				
			|||||||
        vertical: GridSize.headerContainerPadding,
 | 
					        vertical: GridSize.headerContainerPadding,
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
  static EdgeInsets get cellContentInsets => EdgeInsets.symmetric(
 | 
					  static EdgeInsets get cellContentInsets => EdgeInsets.symmetric(
 | 
				
			||||||
        horizontal: GridSize.cellContentPadding,
 | 
					        horizontal: GridSize.cellHPadding,
 | 
				
			||||||
        vertical: GridSize.cellContentPadding,
 | 
					        vertical: GridSize.cellVPadding,
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static EdgeInsets get fieldContentInsets => EdgeInsets.symmetric(
 | 
					  static EdgeInsets get fieldContentInsets => EdgeInsets.symmetric(
 | 
				
			||||||
        horizontal: GridSize.cellContentPadding,
 | 
					        horizontal: GridSize.cellHPadding,
 | 
				
			||||||
        vertical: GridSize.cellContentPadding,
 | 
					        vertical: GridSize.cellVPadding,
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static EdgeInsets get typeOptionContentInsets => const EdgeInsets.symmetric(
 | 
					  static EdgeInsets get typeOptionContentInsets => const EdgeInsets.symmetric(
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,7 @@ import 'number_cell.dart';
 | 
				
			|||||||
import 'selection_cell/selection_cell.dart';
 | 
					import 'selection_cell/selection_cell.dart';
 | 
				
			||||||
import 'text_cell.dart';
 | 
					import 'text_cell.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Widget buildGridCell(FutureCellData cellData) {
 | 
					Widget buildGridCell(CellData cellData) {
 | 
				
			||||||
  final key = ValueKey(cellData.field.id + cellData.rowId);
 | 
					  final key = ValueKey(cellData.field.id + cellData.rowId);
 | 
				
			||||||
  switch (cellData.field.fieldType) {
 | 
					  switch (cellData.field.fieldType) {
 | 
				
			||||||
    case FieldType.Checkbox:
 | 
					    case FieldType.Checkbox:
 | 
				
			||||||
 | 
				
			|||||||
@ -38,7 +38,7 @@ class CellContainer extends StatelessWidget {
 | 
				
			|||||||
            ),
 | 
					            ),
 | 
				
			||||||
            decoration: _makeBoxDecoration(context, state),
 | 
					            decoration: _makeBoxDecoration(context, state),
 | 
				
			||||||
            padding: GridSize.cellContentInsets,
 | 
					            padding: GridSize.cellContentInsets,
 | 
				
			||||||
            child: Center(child: IntrinsicHeight(child: child)),
 | 
					            child: Center(child: child),
 | 
				
			||||||
          );
 | 
					          );
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@ import 'package:flutter/widgets.dart';
 | 
				
			|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
 | 
					import 'package:flutter_bloc/flutter_bloc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CheckboxCell extends StatefulWidget {
 | 
					class CheckboxCell extends StatefulWidget {
 | 
				
			||||||
  final FutureCellData cellData;
 | 
					  final CellData cellData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const CheckboxCell({
 | 
					  const CheckboxCell({
 | 
				
			||||||
    required this.cellData,
 | 
					    required this.cellData,
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@ import 'package:flutter/widgets.dart';
 | 
				
			|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
 | 
					import 'package:flutter_bloc/flutter_bloc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DateCell extends StatefulWidget {
 | 
					class DateCell extends StatefulWidget {
 | 
				
			||||||
  final FutureCellData cellData;
 | 
					  final CellData cellData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const DateCell({
 | 
					  const DateCell({
 | 
				
			||||||
    required this.cellData,
 | 
					    required this.cellData,
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
 | 
				
			|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
 | 
					import 'package:flutter_bloc/flutter_bloc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class NumberCell extends StatefulWidget {
 | 
					class NumberCell extends StatefulWidget {
 | 
				
			||||||
  final FutureCellData cellData;
 | 
					  final CellData cellData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const NumberCell({
 | 
					  const NumberCell({
 | 
				
			||||||
    required this.cellData,
 | 
					    required this.cellData,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,6 @@
 | 
				
			|||||||
 | 
					import 'dart:collection';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'package:flowy_infra/size.dart';
 | 
				
			||||||
import 'package:flowy_infra/theme.dart';
 | 
					import 'package:flowy_infra/theme.dart';
 | 
				
			||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
 | 
					import 'package:flowy_infra_ui/style_widget/text.dart';
 | 
				
			||||||
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
 | 
					import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
 | 
				
			||||||
@ -61,10 +64,19 @@ extension SelectOptionColorExtension on SelectOptionColor {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SelectOptionTextField extends StatelessWidget {
 | 
					class SelectOptionTextField extends StatelessWidget {
 | 
				
			||||||
  final TextEditingController _controller;
 | 
					 | 
				
			||||||
  final FocusNode _focusNode;
 | 
					  final FocusNode _focusNode;
 | 
				
			||||||
 | 
					  final TextEditingController _controller;
 | 
				
			||||||
 | 
					  final TextfieldTagsController tagController;
 | 
				
			||||||
 | 
					  final LinkedHashMap<String, SelectOption> optionMap;
 | 
				
			||||||
 | 
					  final double distanceToText;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final Function(String) onNewTag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SelectOptionTextField({
 | 
					  SelectOptionTextField({
 | 
				
			||||||
 | 
					    required this.optionMap,
 | 
				
			||||||
 | 
					    required this.distanceToText,
 | 
				
			||||||
 | 
					    required this.tagController,
 | 
				
			||||||
 | 
					    required this.onNewTag,
 | 
				
			||||||
    TextEditingController? controller,
 | 
					    TextEditingController? controller,
 | 
				
			||||||
    FocusNode? focusNode,
 | 
					    FocusNode? focusNode,
 | 
				
			||||||
    Key? key,
 | 
					    Key? key,
 | 
				
			||||||
@ -74,26 +86,45 @@ class SelectOptionTextField extends StatelessWidget {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    final theme = context.watch<AppTheme>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return TextFieldTags(
 | 
					    return TextFieldTags(
 | 
				
			||||||
      textEditingController: _controller,
 | 
					      textEditingController: _controller,
 | 
				
			||||||
      initialTags: ["abc", "bdf"],
 | 
					      textfieldTagsController: tagController,
 | 
				
			||||||
 | 
					      initialTags: optionMap.keys.toList(),
 | 
				
			||||||
      focusNode: _focusNode,
 | 
					      focusNode: _focusNode,
 | 
				
			||||||
      textSeparators: const [' ', ','],
 | 
					      textSeparators: const [' ', ','],
 | 
				
			||||||
      inputfieldBuilder: (BuildContext context, editController, focusNode, error, onChanged, onSubmitted) {
 | 
					      inputfieldBuilder: (BuildContext context, editController, focusNode, error, onChanged, onSubmitted) {
 | 
				
			||||||
        return ((context, sc, tags, onTagDelegate) {
 | 
					        return ((context, sc, tags, onTagDelegate) {
 | 
				
			||||||
 | 
					          tags.retainWhere((name) => optionMap.containsKey(name) == false);
 | 
				
			||||||
 | 
					          if (tags.isNotEmpty) {
 | 
				
			||||||
 | 
					            assert(tags.length == 1);
 | 
				
			||||||
 | 
					            onNewTag(tags.first);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          return TextField(
 | 
					          return TextField(
 | 
				
			||||||
            controller: editController,
 | 
					            controller: editController,
 | 
				
			||||||
            focusNode: focusNode,
 | 
					            focusNode: focusNode,
 | 
				
			||||||
            onChanged: onChanged,
 | 
					            onChanged: onChanged,
 | 
				
			||||||
            onSubmitted: onSubmitted,
 | 
					            onSubmitted: onSubmitted,
 | 
				
			||||||
            onEditingComplete: () => focusNode.unfocus(),
 | 
					 | 
				
			||||||
            maxLines: 1,
 | 
					            maxLines: 1,
 | 
				
			||||||
            style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
 | 
					            style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
 | 
				
			||||||
            decoration: InputDecoration(
 | 
					            decoration: InputDecoration(
 | 
				
			||||||
              contentPadding: EdgeInsets.zero,
 | 
					              border: OutlineInputBorder(
 | 
				
			||||||
              border: InputBorder.none,
 | 
					                borderSide: BorderSide(color: theme.shader3, width: 1.0),
 | 
				
			||||||
 | 
					                borderRadius: Corners.s10Border,
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
              isDense: true,
 | 
					              isDense: true,
 | 
				
			||||||
              prefixIcon: _renderTags(tags, sc),
 | 
					              prefixIcon: _renderTags(sc),
 | 
				
			||||||
 | 
					              hintText: LocaleKeys.grid_selectOption_searchOption.tr(),
 | 
				
			||||||
 | 
					              prefixIconConstraints: BoxConstraints(maxWidth: distanceToText),
 | 
				
			||||||
 | 
					              focusedBorder: OutlineInputBorder(
 | 
				
			||||||
 | 
					                borderSide: BorderSide(
 | 
				
			||||||
 | 
					                  color: theme.main1,
 | 
				
			||||||
 | 
					                  width: 1.0,
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                borderRadius: Corners.s10Border,
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
          );
 | 
					          );
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
@ -101,41 +132,26 @@ class SelectOptionTextField extends StatelessWidget {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Widget? _renderTags(List<String> tags, ScrollController sc) {
 | 
					  Widget? _renderTags(ScrollController sc) {
 | 
				
			||||||
    if (tags.isEmpty) {
 | 
					    if (optionMap.isEmpty) {
 | 
				
			||||||
      return null;
 | 
					      return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return SingleChildScrollView(
 | 
					    final children = optionMap.values.map((option) => SelectOptionTag(option: option)).toList();
 | 
				
			||||||
      controller: sc,
 | 
					    return Padding(
 | 
				
			||||||
      scrollDirection: Axis.horizontal,
 | 
					      padding: const EdgeInsets.all(8.0),
 | 
				
			||||||
      child: Row(children: [
 | 
					      child: SingleChildScrollView(
 | 
				
			||||||
        Container(
 | 
					        controller: sc,
 | 
				
			||||||
          decoration: BoxDecoration(
 | 
					        scrollDirection: Axis.horizontal,
 | 
				
			||||||
            color: Color.fromARGB(255, 74, 137, 92),
 | 
					        child: Row(children: children),
 | 
				
			||||||
            shape: BoxShape.rectangle,
 | 
					      ),
 | 
				
			||||||
            borderRadius: BorderRadius.circular(6.0),
 | 
					 | 
				
			||||||
          ),
 | 
					 | 
				
			||||||
          child: FlowyText.medium("efc", fontSize: 12),
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        Container(
 | 
					 | 
				
			||||||
          decoration: BoxDecoration(
 | 
					 | 
				
			||||||
            color: Color.fromARGB(255, 74, 137, 92),
 | 
					 | 
				
			||||||
            shape: BoxShape.rectangle,
 | 
					 | 
				
			||||||
            borderRadius: BorderRadius.circular(6.0),
 | 
					 | 
				
			||||||
          ),
 | 
					 | 
				
			||||||
          child: FlowyText.medium("abc", fontSize: 12),
 | 
					 | 
				
			||||||
          margin: const EdgeInsets.symmetric(horizontal: 5.0),
 | 
					 | 
				
			||||||
          padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0),
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
      ]),
 | 
					 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SelectionBadge extends StatelessWidget {
 | 
					class SelectOptionTag extends StatelessWidget {
 | 
				
			||||||
  final SelectOption option;
 | 
					  final SelectOption option;
 | 
				
			||||||
  const SelectionBadge({required this.option, Key? key}) : super(key: key);
 | 
					  const SelectOptionTag({required this.option, Key? key}) : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
@ -143,9 +159,11 @@ class SelectionBadge extends StatelessWidget {
 | 
				
			|||||||
      decoration: BoxDecoration(
 | 
					      decoration: BoxDecoration(
 | 
				
			||||||
        color: option.color.make(context),
 | 
					        color: option.color.make(context),
 | 
				
			||||||
        shape: BoxShape.rectangle,
 | 
					        shape: BoxShape.rectangle,
 | 
				
			||||||
        borderRadius: BorderRadius.circular(6.0),
 | 
					        borderRadius: BorderRadius.circular(8.0),
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
      child: FlowyText.medium(option.name, fontSize: 12),
 | 
					      child: Center(child: FlowyText.medium(option.name, fontSize: 12)),
 | 
				
			||||||
 | 
					      margin: const EdgeInsets.symmetric(horizontal: 3.0),
 | 
				
			||||||
 | 
					      padding: const EdgeInsets.symmetric(horizontal: 6.0),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -6,9 +6,10 @@ import 'package:flutter/material.dart';
 | 
				
			|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
 | 
					import 'package:flutter_bloc/flutter_bloc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'extension.dart';
 | 
					import 'extension.dart';
 | 
				
			||||||
 | 
					import 'selection_editor.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SingleSelectCell extends StatefulWidget {
 | 
					class SingleSelectCell extends StatefulWidget {
 | 
				
			||||||
  final FutureCellData cellData;
 | 
					  final CellData cellData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const SingleSelectCell({
 | 
					  const SingleSelectCell({
 | 
				
			||||||
    required this.cellData,
 | 
					    required this.cellData,
 | 
				
			||||||
@ -20,30 +21,28 @@ class SingleSelectCell extends StatefulWidget {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _SingleSelectCellState extends State<SingleSelectCell> {
 | 
					class _SingleSelectCellState extends State<SingleSelectCell> {
 | 
				
			||||||
  late CellFocusNode _focusNode;
 | 
					 | 
				
			||||||
  late SelectionCellBloc _cellBloc;
 | 
					  late SelectionCellBloc _cellBloc;
 | 
				
			||||||
  late TextEditingController _controller;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  void initState() {
 | 
					  void initState() {
 | 
				
			||||||
    _cellBloc = getIt<SelectionCellBloc>(param1: widget.cellData);
 | 
					    _cellBloc = getIt<SelectionCellBloc>(param1: widget.cellData)..add(const SelectionCellEvent.initial());
 | 
				
			||||||
    _controller = TextEditingController();
 | 
					 | 
				
			||||||
    _focusNode = CellFocusNode();
 | 
					 | 
				
			||||||
    super.initState();
 | 
					    super.initState();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    _focusNode.addCallback(context, () {
 | 
					 | 
				
			||||||
      Log.info(_focusNode.hasFocus);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    return BlocProvider.value(
 | 
					    return BlocProvider.value(
 | 
				
			||||||
      value: _cellBloc,
 | 
					      value: _cellBloc,
 | 
				
			||||||
      child: BlocBuilder<SelectionCellBloc, SelectionCellState>(
 | 
					      child: BlocBuilder<SelectionCellBloc, SelectionCellState>(
 | 
				
			||||||
        builder: (context, state) {
 | 
					        builder: (context, state) {
 | 
				
			||||||
          return SelectOptionTextField(
 | 
					          final children = state.selectedOptions.map((option) => SelectOptionTag(option: option)).toList();
 | 
				
			||||||
            focusNode: _focusNode,
 | 
					          return SizedBox.expand(
 | 
				
			||||||
            controller: _controller,
 | 
					            child: InkWell(
 | 
				
			||||||
 | 
					              onTap: () {
 | 
				
			||||||
 | 
					                SelectionEditor.show(context, state.cellData, state.options, state.selectedOptions);
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              child: Row(children: children),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
          );
 | 
					          );
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
@ -53,14 +52,13 @@ class _SingleSelectCellState extends State<SingleSelectCell> {
 | 
				
			|||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Future<void> dispose() async {
 | 
					  Future<void> dispose() async {
 | 
				
			||||||
    _cellBloc.close();
 | 
					    _cellBloc.close();
 | 
				
			||||||
    _focusNode.dispose();
 | 
					 | 
				
			||||||
    super.dispose();
 | 
					    super.dispose();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//----------------------------------------------------------------
 | 
					//----------------------------------------------------------------
 | 
				
			||||||
class MultiSelectCell extends StatefulWidget {
 | 
					class MultiSelectCell extends StatefulWidget {
 | 
				
			||||||
  final FutureCellData cellData;
 | 
					  final CellData cellData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const MultiSelectCell({
 | 
					  const MultiSelectCell({
 | 
				
			||||||
    required this.cellData,
 | 
					    required this.cellData,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,9 @@
 | 
				
			|||||||
 | 
					import 'dart:collection';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:app_flowy/workspace/application/grid/cell_bloc/selection_editor_bloc.dart';
 | 
					import 'package:app_flowy/workspace/application/grid/cell_bloc/selection_editor_bloc.dart';
 | 
				
			||||||
import 'package:app_flowy/workspace/application/grid/row/row_service.dart';
 | 
					import 'package:app_flowy/workspace/application/grid/row/row_service.dart';
 | 
				
			||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
 | 
					import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
 | 
				
			||||||
 | 
					import 'package:flowy_infra/image.dart';
 | 
				
			||||||
import 'package:flowy_infra/theme.dart';
 | 
					import 'package:flowy_infra/theme.dart';
 | 
				
			||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
 | 
					import 'package:flowy_infra_ui/flowy_infra_ui.dart';
 | 
				
			||||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
 | 
					import 'package:flowy_infra_ui/style_widget/hover.dart';
 | 
				
			||||||
@ -12,42 +15,81 @@ import 'package:flutter/material.dart';
 | 
				
			|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
 | 
					import 'package:flutter_bloc/flutter_bloc.dart';
 | 
				
			||||||
import 'package:easy_localization/easy_localization.dart';
 | 
					import 'package:easy_localization/easy_localization.dart';
 | 
				
			||||||
import 'package:app_flowy/generated/locale_keys.g.dart';
 | 
					import 'package:app_flowy/generated/locale_keys.g.dart';
 | 
				
			||||||
 | 
					import 'package:textfield_tags/textfield_tags.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'extension.dart';
 | 
					import 'extension.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SelectionEditor extends StatelessWidget {
 | 
					const double _editorPannelWidth = 300;
 | 
				
			||||||
  final GridCellData cellData;
 | 
					 | 
				
			||||||
  const SelectionEditor({required this.cellData, Key? key}) : super(key: key);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void show(BuildContext context) {
 | 
					class SelectionEditor extends StatelessWidget {
 | 
				
			||||||
    FlowyOverlay.of(context).insertWithAnchor(
 | 
					  final CellData cellData;
 | 
				
			||||||
      widget: OverlayContainer(
 | 
					  final List<SelectOption> options;
 | 
				
			||||||
        child: this,
 | 
					  final List<SelectOption> selectedOptions;
 | 
				
			||||||
        constraints: BoxConstraints.loose(const Size(240, 200)),
 | 
					
 | 
				
			||||||
      ),
 | 
					  const SelectionEditor({
 | 
				
			||||||
      identifier: toString(),
 | 
					    required this.cellData,
 | 
				
			||||||
      anchorContext: context,
 | 
					    required this.options,
 | 
				
			||||||
      anchorDirection: AnchorDirection.bottomWithLeftAligned,
 | 
					    required this.selectedOptions,
 | 
				
			||||||
    );
 | 
					    Key? key,
 | 
				
			||||||
 | 
					  }) : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static String identifier() {
 | 
				
			||||||
 | 
					    return (SelectionEditor).toString();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return BlocProvider(
 | 
					    return BlocProvider(
 | 
				
			||||||
      create: (context) => SelectionEditorBloc(gridId: cellData.gridId, field: cellData.field),
 | 
					      create: (context) => SelectOptionEditorBloc(
 | 
				
			||||||
      child: BlocBuilder<SelectionEditorBloc, SelectionEditorState>(
 | 
					        gridId: cellData.gridId,
 | 
				
			||||||
 | 
					        field: cellData.field,
 | 
				
			||||||
 | 
					        options: options,
 | 
				
			||||||
 | 
					        selectedOptions: selectedOptions,
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					      child: BlocBuilder<SelectOptionEditorBloc, SelectOptionEditorState>(
 | 
				
			||||||
        builder: (context, state) {
 | 
					        builder: (context, state) {
 | 
				
			||||||
          return Column(
 | 
					          return CustomScrollView(
 | 
				
			||||||
            children: const [
 | 
					            shrinkWrap: true,
 | 
				
			||||||
              _Title(),
 | 
					            slivers: [
 | 
				
			||||||
              VSpace(10),
 | 
					              SliverToBoxAdapter(child: _TextField()),
 | 
				
			||||||
              _OptionList(),
 | 
					              const SliverToBoxAdapter(child: VSpace(10)),
 | 
				
			||||||
 | 
					              const SliverToBoxAdapter(child: _Title()),
 | 
				
			||||||
 | 
					              const SliverToBoxAdapter(child: _OptionList()),
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
          );
 | 
					          );
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static void show(
 | 
				
			||||||
 | 
					    BuildContext context,
 | 
				
			||||||
 | 
					    CellData cellData,
 | 
				
			||||||
 | 
					    List<SelectOption> options,
 | 
				
			||||||
 | 
					    List<SelectOption> selectedOptions,
 | 
				
			||||||
 | 
					  ) {
 | 
				
			||||||
 | 
					    SelectionEditor.hide(context);
 | 
				
			||||||
 | 
					    final editor = SelectionEditor(
 | 
				
			||||||
 | 
					      cellData: cellData,
 | 
				
			||||||
 | 
					      options: options,
 | 
				
			||||||
 | 
					      selectedOptions: selectedOptions,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    FlowyOverlay.of(context).insertWithAnchor(
 | 
				
			||||||
 | 
					      widget: OverlayContainer(
 | 
				
			||||||
 | 
					        child: SizedBox(width: _editorPannelWidth, child: editor),
 | 
				
			||||||
 | 
					        constraints: BoxConstraints.loose(const Size(_editorPannelWidth, 300)),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					      identifier: SelectionEditor.identifier(),
 | 
				
			||||||
 | 
					      anchorContext: context,
 | 
				
			||||||
 | 
					      anchorDirection: AnchorDirection.bottomWithCenterAligned,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static void hide(BuildContext context) {
 | 
				
			||||||
 | 
					    FlowyOverlay.of(context).remove(identifier());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _OptionList extends StatelessWidget {
 | 
					class _OptionList extends StatelessWidget {
 | 
				
			||||||
@ -55,9 +97,9 @@ class _OptionList extends StatelessWidget {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return BlocBuilder<SelectionEditorBloc, SelectionEditorState>(
 | 
					    return BlocBuilder<SelectOptionEditorBloc, SelectOptionEditorState>(
 | 
				
			||||||
      builder: (context, state) {
 | 
					      builder: (context, state) {
 | 
				
			||||||
        final cells = state.options.map((option) => _SelectionCell(option)).toList();
 | 
					        final cells = state.options.map((option) => _SelectOptionCell(option)).toList();
 | 
				
			||||||
        final list = ListView.separated(
 | 
					        final list = ListView.separated(
 | 
				
			||||||
          shrinkWrap: true,
 | 
					          shrinkWrap: true,
 | 
				
			||||||
          controller: ScrollController(),
 | 
					          controller: ScrollController(),
 | 
				
			||||||
@ -76,40 +118,84 @@ class _OptionList extends StatelessWidget {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _TextField extends StatelessWidget {
 | 
				
			||||||
 | 
					  final TextfieldTagsController _tagController = TextfieldTagsController();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _TextField({Key? key}) : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return BlocConsumer<SelectOptionEditorBloc, SelectOptionEditorState>(
 | 
				
			||||||
 | 
					      listener: (context, state) {},
 | 
				
			||||||
 | 
					      buildWhen: (previous, current) => previous.field.id != current.field.id,
 | 
				
			||||||
 | 
					      builder: (context, state) {
 | 
				
			||||||
 | 
					        final optionMap = LinkedHashMap<String, SelectOption>.fromIterable(state.selectedOptions,
 | 
				
			||||||
 | 
					            key: (option) => option.name, value: (option) => option);
 | 
				
			||||||
 | 
					        return SizedBox(
 | 
				
			||||||
 | 
					          height: 42,
 | 
				
			||||||
 | 
					          child: SelectOptionTextField(
 | 
				
			||||||
 | 
					            optionMap: optionMap,
 | 
				
			||||||
 | 
					            distanceToText: _editorPannelWidth * 0.7,
 | 
				
			||||||
 | 
					            tagController: _tagController,
 | 
				
			||||||
 | 
					            onNewTag: (newTagName) {
 | 
				
			||||||
 | 
					              context.read<SelectOptionEditorBloc>().add(SelectOptionEditorEvent.newOption(newTagName));
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _Title extends StatelessWidget {
 | 
					class _Title extends StatelessWidget {
 | 
				
			||||||
  const _Title({Key? key}) : super(key: key);
 | 
					  const _Title({Key? key}) : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    final theme = context.watch<AppTheme>();
 | 
				
			||||||
    return SizedBox(
 | 
					    return SizedBox(
 | 
				
			||||||
      height: GridSize.typeOptionItemHeight,
 | 
					      height: GridSize.typeOptionItemHeight,
 | 
				
			||||||
      child: FlowyText.medium(LocaleKeys.grid_selectOption_pannelTitle.tr(), fontSize: 12),
 | 
					      child: Padding(
 | 
				
			||||||
    );
 | 
					        padding: const EdgeInsets.symmetric(horizontal: 6),
 | 
				
			||||||
  }
 | 
					        child: FlowyText.medium(
 | 
				
			||||||
}
 | 
					          LocaleKeys.grid_selectOption_pannelTitle.tr(),
 | 
				
			||||||
 | 
					          fontSize: 12,
 | 
				
			||||||
class _SelectionCell extends StatelessWidget {
 | 
					          color: theme.shader3,
 | 
				
			||||||
  final SelectOption option;
 | 
					        ),
 | 
				
			||||||
  const _SelectionCell(this.option, {Key? key}) : super(key: key);
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
  @override
 | 
					  }
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					}
 | 
				
			||||||
    final theme = context.watch<AppTheme>();
 | 
					
 | 
				
			||||||
 | 
					class _SelectOptionCell extends StatelessWidget {
 | 
				
			||||||
    // return FlowyButton(
 | 
					  final SelectOption option;
 | 
				
			||||||
    //   text: FlowyText.medium(fieldType.title(), fontSize: 12),
 | 
					  const _SelectOptionCell(this.option, {Key? key}) : super(key: key);
 | 
				
			||||||
    //   hoverColor: theme.hover,
 | 
					
 | 
				
			||||||
    //   onTap: () => onSelectField(fieldType),
 | 
					  @override
 | 
				
			||||||
    //   leftIcon: svgWidget(fieldType.iconName(), color: theme.iconColor),
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    // );
 | 
					    final theme = context.watch<AppTheme>();
 | 
				
			||||||
 | 
					    return SizedBox(
 | 
				
			||||||
    return InkWell(
 | 
					      height: GridSize.typeOptionItemHeight,
 | 
				
			||||||
      onTap: () {},
 | 
					      child: InkWell(
 | 
				
			||||||
      child: FlowyHover(
 | 
					        onTap: () {},
 | 
				
			||||||
        config: HoverDisplayConfig(hoverColor: theme.hover),
 | 
					        child: FlowyHover(
 | 
				
			||||||
        builder: (_, onHover) {
 | 
					          config: HoverDisplayConfig(hoverColor: theme.hover),
 | 
				
			||||||
          return SelectionBadge(option: option);
 | 
					          builder: (_, onHover) {
 | 
				
			||||||
        },
 | 
					            List<Widget> children = [
 | 
				
			||||||
 | 
					              SelectOptionTag(option: option),
 | 
				
			||||||
 | 
					              const Spacer(),
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (onHover) {
 | 
				
			||||||
 | 
					              children.add(svgWidget("editor/details", color: theme.iconColor));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return Padding(
 | 
				
			||||||
 | 
					              padding: const EdgeInsets.all(3.0),
 | 
				
			||||||
 | 
					              child: Row(children: children),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 | 
				
			|||||||
import 'cell_container.dart';
 | 
					import 'cell_container.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GridTextCell extends GridCell {
 | 
					class GridTextCell extends GridCell {
 | 
				
			||||||
  final FutureCellData cellData;
 | 
					  final CellData cellData;
 | 
				
			||||||
  const GridTextCell({
 | 
					  const GridTextCell({
 | 
				
			||||||
    required this.cellData,
 | 
					    required this.cellData,
 | 
				
			||||||
    Key? key,
 | 
					    Key? key,
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					import 'package:app_flowy/startup/startup.dart';
 | 
				
			||||||
 | 
					import 'package:app_flowy/workspace/application/grid/prelude.dart';
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:flutter_bloc/flutter_bloc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NumberCell extends StatefulWidget {
 | 
				
			||||||
 | 
					  final CellData cellData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const NumberCell({
 | 
				
			||||||
 | 
					    required this.cellData,
 | 
				
			||||||
 | 
					    Key? key,
 | 
				
			||||||
 | 
					  }) : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  State<NumberCell> createState() => _NumberCellState();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _NumberCellState extends State<NumberCell> {
 | 
				
			||||||
 | 
					  late NumberCellBloc _cellBloc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  void initState() {
 | 
				
			||||||
 | 
					    _cellBloc = getIt<NumberCellBloc>(param1: widget.cellData);
 | 
				
			||||||
 | 
					    super.initState();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return BlocProvider.value(
 | 
				
			||||||
 | 
					      value: _cellBloc,
 | 
				
			||||||
 | 
					      child: BlocBuilder<NumberCellBloc, NumberCellState>(
 | 
				
			||||||
 | 
					        builder: (context, state) {
 | 
				
			||||||
 | 
					          return Container();
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Future<void> dispose() async {
 | 
				
			||||||
 | 
					    _cellBloc.close();
 | 
				
			||||||
 | 
					    super.dispose();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -10,7 +10,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 | 
				
			|||||||
import 'package:provider/provider.dart';
 | 
					import 'package:provider/provider.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GridRowWidget extends StatefulWidget {
 | 
					class GridRowWidget extends StatefulWidget {
 | 
				
			||||||
  final GridRowData data;
 | 
					  final RowData data;
 | 
				
			||||||
  const GridRowWidget({required this.data, Key? key}) : super(key: key);
 | 
					  const GridRowWidget({required this.data, Key? key}) : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					import 'package:app_flowy/startup/startup.dart';
 | 
				
			||||||
 | 
					import 'package:app_flowy/workspace/application/grid/prelude.dart';
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:flutter_bloc/flutter_bloc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NumberCell extends StatefulWidget {
 | 
				
			||||||
 | 
					  final CellData cellData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const NumberCell({
 | 
				
			||||||
 | 
					    required this.cellData,
 | 
				
			||||||
 | 
					    Key? key,
 | 
				
			||||||
 | 
					  }) : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  State<NumberCell> createState() => _NumberCellState();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _NumberCellState extends State<NumberCell> {
 | 
				
			||||||
 | 
					  late NumberCellBloc _cellBloc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  void initState() {
 | 
				
			||||||
 | 
					    _cellBloc = getIt<NumberCellBloc>(param1: widget.cellData);
 | 
				
			||||||
 | 
					    super.initState();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return BlocProvider.value(
 | 
				
			||||||
 | 
					      value: _cellBloc,
 | 
				
			||||||
 | 
					      child: BlocBuilder<NumberCellBloc, NumberCellState>(
 | 
				
			||||||
 | 
					        builder: (context, state) {
 | 
				
			||||||
 | 
					          return Container();
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Future<void> dispose() async {
 | 
				
			||||||
 | 
					    _cellBloc.close();
 | 
				
			||||||
 | 
					    super.dispose();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -44,7 +44,7 @@ class FlowyText extends StatelessWidget {
 | 
				
			|||||||
        softWrap: false,
 | 
					        softWrap: false,
 | 
				
			||||||
        textAlign: textAlign,
 | 
					        textAlign: textAlign,
 | 
				
			||||||
        style: TextStyle(
 | 
					        style: TextStyle(
 | 
				
			||||||
          color: theme.textColor,
 | 
					          color: color ?? theme.textColor,
 | 
				
			||||||
          fontWeight: fontWeight,
 | 
					          fontWeight: fontWeight,
 | 
				
			||||||
          fontSize: fontSize + 2,
 | 
					          fontSize: fontSize + 2,
 | 
				
			||||||
          fontFamily: 'Mulish',
 | 
					          fontFamily: 'Mulish',
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
 | 
				
			|||||||
use std::collections::HashMap;
 | 
					use std::collections::HashMap;
 | 
				
			||||||
use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString};
 | 
					use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub const DEFAULT_ROW_HEIGHT: i32 = 36;
 | 
					pub const DEFAULT_ROW_HEIGHT: i32 = 42;
 | 
				
			||||||
pub const DEFAULT_FIELD_WIDTH: i32 = 150;
 | 
					pub const DEFAULT_FIELD_WIDTH: i32 = 150;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
 | 
					#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user