feat: implement checklist UI

This commit is contained in:
nathan
2022-11-29 22:40:49 +08:00
parent b4671c1d99
commit 1ba299815e
64 changed files with 715 additions and 110 deletions

View File

@ -358,7 +358,7 @@ Widget? _buildHeaderIcon(GroupData customData) {
break;
case FieldType.URL:
break;
case FieldType.CheckList:
case FieldType.Checklist:
break;
}

View File

@ -59,7 +59,7 @@ class BoardCellBuilder {
editableNotifier: cellNotifier,
key: key,
);
case FieldType.CheckList:
case FieldType.Checklist:
return BoardChecklistCell(
key: key,
);

View File

@ -5,6 +5,8 @@ typedef GridCheckboxCellController = IGridCellController<String, String>;
typedef GridNumberCellController = IGridCellController<String, String>;
typedef GridSelectOptionCellController
= IGridCellController<SelectOptionCellDataPB, String>;
typedef GridChecklistCellController
= IGridCellController<SelectOptionCellDataPB, String>;
typedef GridDateCellController
= IGridCellController<DateCellDataPB, CalendarData>;
typedef GridURLCellController = IGridCellController<URLCellDataPB, String>;
@ -81,7 +83,7 @@ class GridCellControllerBuilder {
);
case FieldType.MultiSelect:
case FieldType.SingleSelect:
case FieldType.CheckList:
case FieldType.Checklist:
final cellDataLoader = GridCellDataLoader(
cellId: _cellId,
parser: SelectOptionCellDataParser(),

View File

@ -0,0 +1,93 @@
import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async';
import 'cell_service/cell_service.dart';
import 'select_option_service.dart';
part 'checklist_cell_bloc.freezed.dart';
class ChecklistCellBloc extends Bloc<ChecklistCellEvent, ChecklistCellState> {
final GridChecklistCellController cellController;
final SelectOptionFFIService _selectOptionService;
void Function()? _onCellChangedFn;
ChecklistCellBloc({
required this.cellController,
}) : _selectOptionService =
SelectOptionFFIService(cellId: cellController.cellId),
super(ChecklistCellState.initial(cellController)) {
on<ChecklistCellEvent>(
(event, emit) async {
await event.when(
initial: () async {
_startListening();
_loadOptions();
},
didReceiveOptions: (data) {
emit(state.copyWith(
allOptions: data.options,
selectedOptions: data.selectOptions,
percent: data.selectOptions.length.toDouble() /
data.options.length.toDouble(),
));
},
);
},
);
}
@override
Future<void> close() async {
if (_onCellChangedFn != null) {
cellController.removeListener(_onCellChangedFn!);
_onCellChangedFn = null;
}
await cellController.dispose();
return super.close();
}
void _startListening() {
_onCellChangedFn = cellController.startListening(
onCellFieldChanged: () {
_loadOptions();
},
onCellChanged: (_) {},
);
}
void _loadOptions() {
_selectOptionService.getOptionContext().then((result) {
if (isClosed) return;
return result.fold(
(data) => add(ChecklistCellEvent.didReceiveOptions(data)),
(err) => Log.error(err),
);
});
}
}
@freezed
class ChecklistCellEvent with _$ChecklistCellEvent {
const factory ChecklistCellEvent.initial() = _InitialCell;
const factory ChecklistCellEvent.didReceiveOptions(
SelectOptionCellDataPB data) = _DidReceiveCellUpdate;
}
@freezed
class ChecklistCellState with _$ChecklistCellState {
const factory ChecklistCellState({
required List<SelectOptionPB> allOptions,
required List<SelectOptionPB> selectedOptions,
required double percent,
}) = _ChecklistCellState;
factory ChecklistCellState.initial(
GridChecklistCellController cellController) {
return const ChecklistCellState(
allOptions: [],
selectedOptions: [],
percent: 0,
);
}
}

View File

@ -0,0 +1,194 @@
import 'dart:async';
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'select_option_service.dart';
part 'checklist_cell_editor_bloc.freezed.dart';
class ChecklistCellEditorBloc
extends Bloc<ChecklistCellEditorEvent, ChecklistCellEditorState> {
final SelectOptionFFIService _selectOptionService;
final GridChecklistCellController cellController;
Timer? _delayOperation;
ChecklistCellEditorBloc({
required this.cellController,
}) : _selectOptionService =
SelectOptionFFIService(cellId: cellController.cellId),
super(ChecklistCellEditorState.initial(cellController)) {
on<ChecklistCellEditorEvent>(
(event, emit) async {
await event.when(
initial: () async {
_startListening();
_loadOptions();
},
didReceiveOptions: (data) {
emit(state.copyWith(
allOptions: _makeChecklistSelectOptions(data, state.predicate),
percent: _percentFromSelectOptionCellData(data),
));
},
newOption: (optionName) {
_createOption(optionName);
emit(state.copyWith(
predicate: '',
));
},
deleteOption: (option) {
_deleteOption([option]);
},
updateOption: (option) {
_updateOption(option);
},
selectOption: (optionId) {
_selectOptionService.select(optionIds: [optionId]);
},
unSelectOption: (optionId) {
_selectOptionService.unSelect(optionIds: [optionId]);
},
filterOption: (String predicate) {},
);
},
);
}
@override
Future<void> close() async {
_delayOperation?.cancel();
await cellController.dispose();
return super.close();
}
void _createOption(String name) async {
final result = await _selectOptionService.create(
name: name,
isSelected: false,
);
result.fold((l) => {}, (err) => Log.error(err));
}
void _deleteOption(List<SelectOptionPB> options) async {
final result = await _selectOptionService.delete(options: options);
result.fold((l) => null, (err) => Log.error(err));
}
void _updateOption(SelectOptionPB option) async {
final result = await _selectOptionService.update(
option: option,
);
result.fold((l) => null, (err) => Log.error(err));
}
void _loadOptions() {
_selectOptionService.getOptionContext().then((result) {
if (isClosed) return;
return result.fold(
(data) => add(ChecklistCellEditorEvent.didReceiveOptions(data)),
(err) => Log.error(err),
);
});
}
void _startListening() {
cellController.startListening(
onCellChanged: ((data) {
if (!isClosed && data != null) {
add(ChecklistCellEditorEvent.didReceiveOptions(data));
}
}),
onCellFieldChanged: () {
_loadOptions();
},
);
}
}
@freezed
class ChecklistCellEditorEvent with _$ChecklistCellEditorEvent {
const factory ChecklistCellEditorEvent.initial() = _Initial;
const factory ChecklistCellEditorEvent.didReceiveOptions(
SelectOptionCellDataPB data) = _DidReceiveOptions;
const factory ChecklistCellEditorEvent.newOption(String optionName) =
_NewOption;
const factory ChecklistCellEditorEvent.selectOption(String optionId) =
_SelectOption;
const factory ChecklistCellEditorEvent.unSelectOption(String optionId) =
_UnSelectOption;
const factory ChecklistCellEditorEvent.updateOption(SelectOptionPB option) =
_UpdateOption;
const factory ChecklistCellEditorEvent.deleteOption(SelectOptionPB option) =
_DeleteOption;
const factory ChecklistCellEditorEvent.filterOption(String predicate) =
_FilterOption;
}
@freezed
class ChecklistCellEditorState with _$ChecklistCellEditorState {
const factory ChecklistCellEditorState({
required List<ChecklistSelectOption> allOptions,
required Option<String> createOption,
required double percent,
required String predicate,
}) = _ChecklistCellEditorState;
factory ChecklistCellEditorState.initial(
GridSelectOptionCellController context) {
final data = context.getCellData(loadIfNotExist: true);
return ChecklistCellEditorState(
allOptions: _makeChecklistSelectOptions(data, ''),
createOption: none(),
percent: _percentFromSelectOptionCellData(data),
predicate: '',
);
}
}
double _percentFromSelectOptionCellData(SelectOptionCellDataPB? data) {
if (data == null) return 0;
final a = data.selectOptions.length.toDouble();
final b = data.options.length.toDouble();
if (a > b) return 1.0;
return a / b;
}
List<ChecklistSelectOption> _makeChecklistSelectOptions(
SelectOptionCellDataPB? data, String predicate) {
if (data == null) {
return [];
}
final List<ChecklistSelectOption> options = [];
final List<SelectOptionPB> allOptions = List.from(data.options);
if (predicate.isNotEmpty) {
allOptions.retainWhere((element) => element.name.contains(predicate));
}
final selectedOptionIds = data.selectOptions.map((e) => e.id).toList();
for (final option in allOptions) {
options.add(
ChecklistSelectOption(selectedOptionIds.contains(option.id), option),
);
}
return options;
}
class ChecklistSelectOption {
final bool isSelected;
final SelectOptionPB data;
ChecklistSelectOption(this.isSelected, this.data);
}

View File

@ -1,26 +1,24 @@
import 'dart:async';
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'select_option_service.dart';
part 'select_option_editor_bloc.freezed.dart';
class SelectOptionCellEditorBloc
extends Bloc<SelectOptionEditorEvent, SelectOptionEditorState> {
final SelectOptionService _selectOptionService;
final SelectOptionFFIService _selectOptionService;
final GridSelectOptionCellController cellController;
Timer? _delayOperation;
SelectOptionCellEditorBloc({
required this.cellController,
}) : _selectOptionService =
SelectOptionService(cellId: cellController.cellId),
SelectOptionFFIService(cellId: cellController.cellId),
super(SelectOptionEditorState.initial(cellController)) {
on<SelectOptionEditorEvent>(
(event, emit) async {

View File

@ -6,15 +6,16 @@ import 'package:app_flowy/plugins/grid/application/field/type_option/type_option
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
import 'cell_service/cell_service.dart';
class SelectOptionService {
class SelectOptionFFIService {
final GridCellIdentifier cellId;
SelectOptionService({required this.cellId});
SelectOptionFFIService({required this.cellId});
String get gridId => cellId.gridId;
String get fieldId => cellId.fieldInfo.id;
String get rowId => cellId.rowId;
Future<Either<Unit, FlowyError>> create({required String name}) {
Future<Either<Unit, FlowyError>> create(
{required String name, bool isSelected = true}) {
return TypeOptionFFIService(gridId: gridId, fieldId: fieldId)
.newOption(name: name)
.then(
@ -26,8 +27,13 @@ class SelectOptionService {
..fieldId = fieldId
..rowId = rowId;
final payload = SelectOptionChangesetPB.create()
..insertOptions.add(option)
..cellIdentifier = cellIdentifier;
if (isSelected) {
payload.insertOptions.add(option);
} else {
payload.updateOptions.add(option);
}
return GridEventUpdateSelectOption(payload).send();
},
(r) => right(r),

View File

@ -503,7 +503,7 @@ class FieldInfo {
bool get hasFilter => _hasFilter;
bool get canGroup {
bool get canBeGroup {
switch (_field.fieldType) {
case FieldType.Checkbox:
case FieldType.MultiSelect:

View File

@ -105,7 +105,7 @@ class GridCreateFilterBloc
condition: SelectOptionCondition.OptionIs,
fieldType: FieldType.MultiSelect,
);
case FieldType.CheckList:
case FieldType.Checklist:
return _ffiService.insertChecklistFilter(
fieldId: fieldId,
condition: ChecklistFilterCondition.IsIncomplete,

View File

@ -152,14 +152,12 @@ class FilterFFIService {
String? filterId,
List<String> optionIds = const [],
}) {
final filter = ChecklistFilterPB()
..condition = condition
..optionIds.addAll(optionIds);
final filter = ChecklistFilterPB()..condition = condition;
return insertFilter(
fieldId: fieldId,
filterId: filterId,
fieldType: FieldType.CheckList,
fieldType: FieldType.Checklist,
data: filter.writeToBuffer(),
);
}

View File

@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
import 'cell_accessory.dart';
import 'cell_shortcuts.dart';
import 'checkbox_cell.dart';
import 'checklist_cell.dart';
import 'checklist_cell/checklist_cell.dart';
import 'date_cell/date_cell.dart';
import 'number_cell.dart';
import 'select_option_cell/select_option_cell.dart';
@ -56,8 +56,9 @@ class GridCellBuilder {
style: style,
key: key,
);
case FieldType.CheckList:
case FieldType.Checklist:
return GridChecklistCell(
cellControllerBuilder: cellControllerBuilder,
key: key,
);
case FieldType.Number:

View File

@ -1,17 +0,0 @@
import 'package:flutter/material.dart';
import 'cell_builder.dart';
class GridChecklistCell extends GridCellWidget {
GridChecklistCell({Key? key}) : super(key: key);
@override
ChecklistCellState createState() => ChecklistCellState();
}
class ChecklistCellState extends State<GridChecklistCell> {
@override
Widget build(BuildContext context) {
return Container();
}
}

View File

@ -0,0 +1,91 @@
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
import 'package:app_flowy/plugins/grid/application/cell/checklist_cell_bloc.dart';
import 'package:app_flowy/plugins/grid/presentation/layout/sizes.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../cell_builder.dart';
import 'checklist_cell_editor.dart';
import 'checklist_prograss_bar.dart';
class GridChecklistCell extends GridCellWidget {
final GridCellControllerBuilder cellControllerBuilder;
GridChecklistCell({required this.cellControllerBuilder, Key? key})
: super(key: key);
@override
GridChecklistCellState createState() => GridChecklistCellState();
}
class GridChecklistCellState extends State<GridChecklistCell> {
late PopoverController _popover;
late ChecklistCellBloc _cellBloc;
@override
void initState() {
_popover = PopoverController();
final cellController =
widget.cellControllerBuilder.build() as GridChecklistCellController;
_cellBloc = ChecklistCellBloc(cellController: cellController);
_cellBloc.add(const ChecklistCellEvent.initial());
super.initState();
}
@override
Widget build(BuildContext context) {
return BlocProvider.value(
value: _cellBloc,
child: BlocBuilder<ChecklistCellBloc, ChecklistCellState>(
builder: (context, state) {
return Stack(
alignment: AlignmentDirectional.center,
fit: StackFit.expand,
children: [
Padding(
padding: GridSize.cellContentInsets,
child: _wrapPopover(const ChecklistProgressBar()),
),
InkWell(onTap: () => _popover.show()),
],
);
},
),
);
}
Widget _wrapPopover(Widget child) {
return AppFlowyPopover(
controller: _popover,
constraints: BoxConstraints.loose(const Size(260, 400)),
direction: PopoverDirection.bottomWithLeftAligned,
triggerActions: PopoverTriggerFlags.none,
popupBuilder: (BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback((_) {
widget.onCellEditing.value = true;
});
return GridChecklistCellEditor(
cellController: widget.cellControllerBuilder.build()
as GridChecklistCellController,
);
},
onClose: () => widget.onCellEditing.value = false,
child: child,
);
}
}
class ChecklistProgressBar extends StatelessWidget {
const ChecklistProgressBar({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocBuilder<ChecklistCellBloc, ChecklistCellState>(
builder: (context, state) {
return ChecklistPrograssBar(
percent: state.percent,
);
},
);
}
}

View File

@ -0,0 +1,81 @@
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
import 'package:app_flowy/plugins/grid/application/cell/checklist_cell_editor_bloc.dart';
import 'package:app_flowy/plugins/grid/presentation/layout/sizes.dart';
import 'package:app_flowy/plugins/grid/presentation/widgets/cell/checklist_cell/checklist_prograss_bar.dart';
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class GridChecklistCellEditor extends StatefulWidget {
final GridChecklistCellController cellController;
const GridChecklistCellEditor({required this.cellController, Key? key})
: super(key: key);
@override
State<GridChecklistCellEditor> createState() =>
_GridChecklistCellEditorState();
}
class _GridChecklistCellEditorState extends State<GridChecklistCellEditor> {
late ChecklistCellEditorBloc bloc;
@override
void initState() {
bloc = ChecklistCellEditorBloc(cellController: widget.cellController);
bloc.add(const ChecklistCellEditorEvent.initial());
super.initState();
}
@override
void dispose() {
bloc.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return BlocProvider.value(
value: bloc,
child: BlocBuilder<ChecklistCellEditorBloc, ChecklistCellEditorState>(
builder: (context, state) {
final List<Widget> slivers = [
const SliverChecklistPrograssBar(),
SliverToBoxAdapter(
child: ListView.separated(
controller: ScrollController(),
shrinkWrap: true,
itemCount: state.allOptions.length,
itemBuilder: (BuildContext context, int index) {
return _ChecklistOptionCell(option: state.allOptions[index]);
},
separatorBuilder: (BuildContext context, int index) {
return VSpace(GridSize.typeOptionSeparatorHeight);
},
),
),
];
return CustomScrollView(
shrinkWrap: true,
slivers: slivers,
controller: ScrollController(),
physics: StyledScrollPhysics(),
);
},
),
);
}
}
class _ChecklistOptionCell extends StatelessWidget {
final ChecklistSelectOption option;
const _ChecklistOptionCell({
required this.option,
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(height: 20, width: 100, color: Colors.red);
}
}

View File

@ -0,0 +1,89 @@
import 'package:app_flowy/generated/locale_keys.g.dart';
import 'package:app_flowy/plugins/grid/application/cell/checklist_cell_editor_bloc.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/color_extension.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:percent_indicator/percent_indicator.dart';
class ChecklistPrograssBar extends StatelessWidget {
final double percent;
const ChecklistPrograssBar({required this.percent, Key? key})
: super(key: key);
@override
Widget build(BuildContext context) {
return LinearPercentIndicator(
lineHeight: 10.0,
percent: percent,
progressColor: Theme.of(context).colorScheme.primary,
backgroundColor: AFThemeExtension.of(context).tint9,
barRadius: const Radius.circular(5),
);
}
}
class SliverChecklistPrograssBar extends StatelessWidget {
const SliverChecklistPrograssBar({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return SliverPersistentHeader(
pinned: true,
delegate: _SliverChecklistPrograssBarDelegate(),
);
}
}
class _SliverChecklistPrograssBarDelegate
extends SliverPersistentHeaderDelegate {
_SliverChecklistPrograssBarDelegate();
double fixHeight = 80;
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return BlocBuilder<ChecklistCellEditorBloc, ChecklistCellEditorState>(
builder: (context, state) {
return Column(
children: [
if (state.percent != 0)
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: ChecklistPrograssBar(percent: state.percent),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: FlowyTextField(
hintText: LocaleKeys.grid_checklist_panelTitle.tr(),
onChanged: (text) {
context
.read<ChecklistCellEditorBloc>()
.add(ChecklistCellEditorEvent.filterOption(text));
},
onSubmitted: (text) {
context
.read<ChecklistCellEditorBloc>()
.add(ChecklistCellEditorEvent.newOption(text));
},
),
)
],
);
},
);
}
@override
double get maxExtent => fixHeight;
@override
double get minExtent => fixHeight;
@override
bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
return false;
}
}

View File

@ -1,5 +1,4 @@
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:app_flowy/startup/startup.dart';

View File

@ -11,7 +11,6 @@ import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/size.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/rounded_input_field.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/log.dart';

View File

@ -3,7 +3,6 @@ import 'package:app_flowy/plugins/grid/application/prelude.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
// ignore: unused_import
import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';

View File

@ -9,7 +9,6 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

View File

@ -8,7 +8,6 @@ import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_filter.pbenum.dart';
import 'package:flutter/material.dart';

View File

@ -4,7 +4,6 @@ import 'package:app_flowy/plugins/grid/presentation/widgets/filter/filter_info.d
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/select_option_filter.pb.dart';

View File

@ -3,13 +3,11 @@ import 'package:app_flowy/plugins/grid/application/filter/text_filter_editor_blo
import 'package:app_flowy/plugins/grid/presentation/widgets/filter/condition_button.dart';
import 'package:app_flowy/plugins/grid/presentation/widgets/filter/disclosure_button.dart';
import 'package:app_flowy/plugins/grid/presentation/widgets/filter/filter_info.dart';
import 'package:app_flowy/plugins/grid/presentation/widgets/filter/text_field.dart';
import 'package:app_flowy/workspace/presentation/widgets/pop_up_action.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/text_filter.pb.dart';
import 'package:flutter/material.dart';
@ -151,7 +149,7 @@ class _TextFilterEditorState extends State<TextFilterEditor> {
Widget _buildFilterTextField(
BuildContext context, TextFilterEditorState state) {
return FilterTextField(
return FlowyTextField(
text: state.filter.content,
hintText: LocaleKeys.grid_settings_typeAValue.tr(),
autoFucous: false,

View File

@ -2,13 +2,13 @@ import 'package:app_flowy/generated/locale_keys.g.dart';
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
import 'package:app_flowy/plugins/grid/application/filter/filter_create_bloc.dart';
import 'package:app_flowy/plugins/grid/presentation/layout/sizes.dart';
import 'package:app_flowy/plugins/grid/presentation/widgets/filter/text_field.dart';
import 'package:app_flowy/plugins/grid/presentation/widgets/header/field_type_extension.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/style_widget/text_field.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@ -121,7 +121,7 @@ class _FilterTextFieldDelegate extends SliverPersistentHeaderDelegate {
child: Container(
color: Theme.of(context).colorScheme.background,
height: fixHeight,
child: FilterTextField(
child: FlowyTextField(
hintText: LocaleKeys.grid_settings_filterBy.tr(),
onChanged: (text) {
context

View File

@ -7,7 +7,6 @@ import 'package:flowy_infra/color_extension.dart';
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

View File

@ -36,7 +36,7 @@ Widget buildFilterChoicechip(FilterInfo filterInfo) {
return SelectOptionFilterChoicechip(filterInfo: filterInfo);
case FieldType.URL:
return URLFilterChoicechip(filterInfo: filterInfo);
case FieldType.CheckList:
case FieldType.Checklist:
return ChecklistFilterChoicechip(filterInfo: filterInfo);
default:
return const SizedBox();

View File

@ -1,74 +0,0 @@
import 'package:flowy_infra/size.dart';
import 'package:flutter/material.dart';
class FilterTextField extends StatefulWidget {
final String hintText;
final String text;
final void Function(String)? onChanged;
final void Function(String)? onSubmitted;
final bool autoFucous;
const FilterTextField({
this.hintText = "",
this.text = "",
this.onChanged,
this.onSubmitted,
this.autoFucous = true,
Key? key,
}) : super(key: key);
@override
State<FilterTextField> createState() => FilterTextFieldState();
}
class FilterTextFieldState extends State<FilterTextField> {
late FocusNode focusNode;
late TextEditingController controller;
@override
void initState() {
focusNode = FocusNode();
controller = TextEditingController();
controller.text = widget.text;
if (widget.autoFucous) {
WidgetsBinding.instance.addPostFrameCallback((_) {
focusNode.requestFocus();
});
}
super.initState();
}
@override
Widget build(BuildContext context) {
return TextField(
controller: controller,
focusNode: focusNode,
onChanged: (text) {
widget.onChanged?.call(text);
},
onSubmitted: (text) {
widget.onSubmitted?.call(text);
},
maxLines: 1,
style: Theme.of(context).textTheme.bodyMedium,
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(10),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).colorScheme.primary,
width: 1.0,
),
borderRadius: Corners.s10Border,
),
isDense: true,
hintText: widget.hintText,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).colorScheme.primary,
width: 1.0,
),
borderRadius: Corners.s8Border,
),
),
);
}
}

View File

@ -6,7 +6,6 @@ import 'package:flowy_infra/image.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

View File

@ -19,7 +19,7 @@ extension FieldTypeListExtension on FieldType {
return "grid/field/single_select";
case FieldType.URL:
return "grid/field/url";
case FieldType.CheckList:
case FieldType.Checklist:
return "grid/field/checklist";
}
throw UnimplementedError;
@ -41,7 +41,7 @@ extension FieldTypeListExtension on FieldType {
return LocaleKeys.grid_field_singleSelectFieldName.tr();
case FieldType.URL:
return LocaleKeys.grid_field_urlFieldName.tr();
case FieldType.CheckList:
case FieldType.Checklist:
return LocaleKeys.grid_field_checklistFieldName.tr();
}
throw UnimplementedError;

View File

@ -3,7 +3,6 @@ import 'package:flowy_infra/image.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flutter/material.dart';

View File

@ -5,7 +5,6 @@ import 'package:dartz/dartz.dart' show Either;
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flutter/material.dart';

View File

@ -9,7 +9,6 @@ import 'package:flowy_infra/color_extension.dart';
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

View File

@ -5,10 +5,10 @@ import 'package:app_flowy/plugins/grid/application/field/type_option/type_option
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_data_controller.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/checklist_type_option.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/multi_select_type_option.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/single_select_type_option.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/text_type_option.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option.pb.dart';
@ -127,7 +127,7 @@ TypeOptionWidgetBuilder makeTypeOptionWidgetBuilder({
),
);
case FieldType.CheckList:
case FieldType.Checklist:
return ChecklistTypeOptionWidgetBuilder(
makeTypeOptionContextWithDataController<ChecklistTypeOptionPB>(
gridId: gridId,
@ -217,7 +217,7 @@ TypeOptionContext<T>
dataController: dataController,
dataParser: MultiSelectTypeOptionWidgetDataParser(),
) as TypeOptionContext<T>;
case FieldType.CheckList:
case FieldType.Checklist:
return ChecklistTypeOptionContext(
dataController: dataController,
dataParser: ChecklistTypeOptionWidgetDataParser(),

View File

@ -7,7 +7,6 @@ import 'package:app_flowy/generated/locale_keys.g.dart';
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart';
import 'package:flutter/material.dart';

View File

@ -5,7 +5,6 @@ import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/format.pbenum.dart';
import 'package:flutter/material.dart';

View File

@ -3,7 +3,6 @@ import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
import 'package:flutter/material.dart';

View File

@ -9,7 +9,6 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:app_flowy/generated/locale_keys.g.dart';
@ -331,7 +330,7 @@ GridCellStyle? _customCellStyle(FieldType fieldType) {
return SelectOptionCellStyle(
placeholder: LocaleKeys.grid_row_textPlaceholder.tr(),
);
case FieldType.CheckList:
case FieldType.Checklist:
return SelectOptionCellStyle(
placeholder: LocaleKeys.grid_row_textPlaceholder.tr(),
);

View File

@ -37,7 +37,7 @@ class GridGroupList extends StatelessWidget {
key: ValueKey(fieldInfo.id),
);
if (!fieldInfo.canGroup) {
if (!fieldInfo.canBeGroup) {
cell = IgnorePointer(child: Opacity(opacity: 0.3, child: cell));
}
return cell;

View File

@ -8,7 +8,6 @@ import 'package:flowy_infra/image.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';