diff --git a/.github/workflows/flutter_ci.yaml b/.github/workflows/flutter_ci.yaml index 90df84a3a2..b2d5c4e0a1 100644 --- a/.github/workflows/flutter_ci.yaml +++ b/.github/workflows/flutter_ci.yaml @@ -24,17 +24,17 @@ jobs: strategy: fail-fast: false matrix: - job: - - { target: x86_64-unknown-linux-gnu, os: ubuntu-latest,} - - { target: x86_64-apple-darwin, os: macos-latest, } - - { target: x86_64-pc-windows-msvc, os: windows-latest, } + os: [ubuntu-latest, macos-latest, windows-latest] include: - os: ubuntu-latest flutter_profile: development-linux-x86_64 + target: x86_64-unknown-linux-gnu - os: macos-latest flutter_profile: development-mac-x86_64 + target: x86_64-apple-darwin - os: windows-latest flutter_profile: development-windows-x86 + target: x86_64-pc-windows-msvc runs-on: ${{ matrix.os }} steps: @@ -46,9 +46,8 @@ jobs: uses: actions-rs/toolchain@v1 with: toolchain: ${{ env.RUST_TOOLCHAIN }} - target: ${{ matrix.job.target }} + target: ${{ matrix.target }} override: true - components: rustfmt profile: minimal - name: Install flutter @@ -68,18 +67,18 @@ jobs: run: | cargo install --force cargo-make cargo install --force duckscript_cli - cargo make appflowy-deps-tools if [ "$RUNNER_OS" == "Linux" ]; then sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub sudo wget -qO /etc/apt/sources.list.d/dart_stable.list https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list sudo apt-get update - sudo apt-get install -y dart curl build-essential libsqlite3-dev libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev + sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev sudo apt-get install keybinder-3.0 elif [ "$RUNNER_OS" == "Windows" ]; then vcpkg integrate install elif [ "$RUNNER_OS" == "macOS" ]; then echo 'do nothing' fi + cargo make appflowy-deps-tools shell: bash - name: Enable Flutter Desktop @@ -102,16 +101,12 @@ jobs: working-directory: frontend/app_flowy run: flutter analyze - - name: Build Flutter unit test lib + - name: Run Flutter unit tests working-directory: frontend run: | - cargo make build-test-lib - - - name: Run Flutter unit tests - working-directory: frontend/app_flowy - run: | - if [ "$RUNNER_OS" == "Linux" ]; then - flutter pub get - flutter test + if [ "$RUNNER_OS" == "macOS" ]; then + cargo make dart_unit_test + elif [ "$RUNNER_OS" == "Windows" ]; then + cargo make dart_unit_test fi - shell: bash \ No newline at end of file + shell: bash diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart index 69b6c8d4a7..4947b03c15 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart @@ -1,6 +1,8 @@ +import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra/size.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; +import 'package:flowy_infra_ui/style_widget/icon_button.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'; @@ -62,13 +64,13 @@ extension SelectOptionColorExtension on SelectOptionColorPB { class SelectOptionTag extends StatelessWidget { final String name; final Color color; - final bool isSelected; final VoidCallback? onSelected; + final void Function(String)? onRemove; const SelectOptionTag({ required this.name, required this.color, this.onSelected, - this.isSelected = false, + this.onRemove, Key? key, }) : super(key: key); @@ -76,25 +78,49 @@ class SelectOptionTag extends StatelessWidget { required BuildContext context, required SelectOptionPB option, VoidCallback? onSelected, - bool isSelected = false, + Function(String)? onRemove, }) { return SelectOptionTag( name: option.name, color: option.color.make(context), - isSelected: isSelected, onSelected: onSelected, + onRemove: onRemove, ); } @override Widget build(BuildContext context) { + EdgeInsets padding = + const EdgeInsets.symmetric(vertical: 2.0, horizontal: 8.0); + if (onRemove != null) { + padding = padding.copyWith(right: 2.0); + } + return Container( - padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 8.0), + padding: padding, decoration: BoxDecoration( color: color, borderRadius: Corners.s6Border, ), - child: FlowyText.medium(name, overflow: TextOverflow.ellipsis), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Flexible( + child: FlowyText.medium(name, overflow: TextOverflow.ellipsis), + ), + if (onRemove != null) + FlowyIconButton( + width: 18.0, + onPressed: () => onRemove?.call(name), + fillColor: Colors.transparent, + hoverColor: Colors.transparent, + icon: svgWidget( + 'home/close', + color: Theme.of(context).colorScheme.onSurface, + ), + ), + ], + ), ); } } diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart index 3ec747be5e..f6a694d7ad 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart @@ -159,6 +159,13 @@ class _TextField extends StatelessWidget { remainder, )); }, + onRemove: (optionName) { + context + .read() + .add(SelectOptionEditorEvent.unSelectOption( + optionMap[optionName]!.id, + )); + }, ), ); }, @@ -297,6 +304,7 @@ class _SelectOptionCellState extends State<_SelectOptionCell> { context .read() .add(SelectOptionEditorEvent.deleteOption(widget.option)); + PopoverContainer.of(popoverContext).close(); }, onUpdated: (updatedOption) { context diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/text_field.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/text_field.dart index 0c53944f20..8068ea88a1 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/text_field.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/text_field.dart @@ -22,6 +22,7 @@ class SelectOptionTextField extends StatefulWidget { final Function(String) onSubmitted; final Function(String) newText; final Function(List, String) onPaste; + final Function(String) onRemove; final VoidCallback? onClick; final int? maxLength; @@ -32,6 +33,7 @@ class SelectOptionTextField extends StatefulWidget { required this.tagController, required this.onSubmitted, required this.onPaste, + required this.onRemove, required this.newText, required this.textSeparators, this.onClick, @@ -163,25 +165,31 @@ class _SelectOptionTextFieldState extends State { } final children = widget.selectedOptionMap.values - .map((option) => - SelectOptionTag.fromOption(context: context, option: option)) + .map((option) => SelectOptionTag.fromOption( + context: context, + option: option, + onRemove: (option) => widget.onRemove(option), + )) .toList(); - return Padding( - padding: const EdgeInsets.all(8.0), - child: ScrollConfiguration( - behavior: ScrollConfiguration.of(context).copyWith( - dragDevices: { - PointerDeviceKind.mouse, - PointerDeviceKind.touch, - PointerDeviceKind.trackpad, - PointerDeviceKind.stylus, - PointerDeviceKind.invertedStylus, - }, - ), - child: SingleChildScrollView( - controller: sc, - scrollDirection: Axis.horizontal, - child: Wrap(spacing: 4, children: children), + return MouseRegion( + cursor: SystemMouseCursors.basic, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: ScrollConfiguration( + behavior: ScrollConfiguration.of(context).copyWith( + dragDevices: { + PointerDeviceKind.mouse, + PointerDeviceKind.touch, + PointerDeviceKind.trackpad, + PointerDeviceKind.stylus, + PointerDeviceKind.invertedStylus, + }, + ), + child: SingleChildScrollView( + controller: sc, + scrollDirection: Axis.horizontal, + child: Wrap(spacing: 4, children: children), + ), ), ), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart index d352db6620..8eecd6f73e 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart @@ -40,7 +40,8 @@ class ViewSection extends StatelessWidget { ); } - ReorderableColumn _reorderableColum(BuildContext context, ViewSectionState state) { + ReorderableColumn _reorderableColum( + BuildContext context, ViewSectionState state) { final children = state.views.map((view) { return ViewSectionItem( key: ValueKey(view.id), @@ -53,8 +54,11 @@ class ViewSection extends StatelessWidget { return ReorderableColumn( needsLongPressDraggable: false, onReorder: (oldIndex, index) { - context.read().add(ViewSectionEvent.moveView(oldIndex, index)); + context + .read() + .add(ViewSectionEvent.moveView(oldIndex, index)); }, + ignorePrimaryScrollController: true, children: children, ); } diff --git a/frontend/app_flowy/test/widget_test/select_option_text_field_test.dart b/frontend/app_flowy/test/widget_test/select_option_text_field_test.dart index 01e36edd85..7580b30b68 100644 --- a/frontend/app_flowy/test/widget_test/select_option_text_field_test.dart +++ b/frontend/app_flowy/test/widget_test/select_option_text_field_test.dart @@ -28,6 +28,7 @@ void main() { remainder = remaining; select = options; }, + onRemove: (_) {}, newText: (text) => remainder = text, textSeparators: const [','], textController: TextEditingController(), diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/checkbox_tests.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/checkbox_tests.rs index 586a11b56e..aca97d9344 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/checkbox_tests.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/checkbox_tests.rs @@ -16,11 +16,15 @@ mod tests { // the checkout value will be checked if the value is "1", "true" or "yes" assert_checkbox(&type_option, "1", CHECK, &field_type, &field_rev); assert_checkbox(&type_option, "true", CHECK, &field_type, &field_rev); + assert_checkbox(&type_option, "TRUE", CHECK, &field_type, &field_rev); assert_checkbox(&type_option, "yes", CHECK, &field_type, &field_rev); + assert_checkbox(&type_option, "YES", CHECK, &field_type, &field_rev); // the checkout value will be uncheck if the value is "false" or "No" assert_checkbox(&type_option, "false", UNCHECK, &field_type, &field_rev); assert_checkbox(&type_option, "No", UNCHECK, &field_type, &field_rev); + assert_checkbox(&type_option, "NO", UNCHECK, &field_type, &field_rev); + assert_checkbox(&type_option, "0", UNCHECK, &field_type, &field_rev); // the checkout value will be empty if the value is letters or empty string assert_checkbox(&type_option, "abc", "", &field_type, &field_rev);