mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Merge branch 'main' into feat_1624
This commit is contained in:
commit
06c5f6a790
31
.github/workflows/flutter_ci.yaml
vendored
31
.github/workflows/flutter_ci.yaml
vendored
@ -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
|
||||
shell: bash
|
||||
|
@ -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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -159,6 +159,13 @@ class _TextField extends StatelessWidget {
|
||||
remainder,
|
||||
));
|
||||
},
|
||||
onRemove: (optionName) {
|
||||
context
|
||||
.read<SelectOptionCellEditorBloc>()
|
||||
.add(SelectOptionEditorEvent.unSelectOption(
|
||||
optionMap[optionName]!.id,
|
||||
));
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -297,6 +304,7 @@ class _SelectOptionCellState extends State<_SelectOptionCell> {
|
||||
context
|
||||
.read<SelectOptionCellEditorBloc>()
|
||||
.add(SelectOptionEditorEvent.deleteOption(widget.option));
|
||||
PopoverContainer.of(popoverContext).close();
|
||||
},
|
||||
onUpdated: (updatedOption) {
|
||||
context
|
||||
|
@ -22,6 +22,7 @@ class SelectOptionTextField extends StatefulWidget {
|
||||
final Function(String) onSubmitted;
|
||||
final Function(String) newText;
|
||||
final Function(List<String>, 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<SelectOptionTextField> {
|
||||
}
|
||||
|
||||
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),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -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<ViewSectionBloc>().add(ViewSectionEvent.moveView(oldIndex, index));
|
||||
context
|
||||
.read<ViewSectionBloc>()
|
||||
.add(ViewSectionEvent.moveView(oldIndex, index));
|
||||
},
|
||||
ignorePrimaryScrollController: true,
|
||||
children: children,
|
||||
);
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ void main() {
|
||||
remainder = remaining;
|
||||
select = options;
|
||||
},
|
||||
onRemove: (_) {},
|
||||
newText: (text) => remainder = text,
|
||||
textSeparators: const [','],
|
||||
textController: TextEditingController(),
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user