feat: hidden kanban groups (#3907)

* feat: hide/unhide ui

* chore: implement collapsible side bar and adjust group header (#2)

* refactor: hidden columns into own file

* chore: adjust new group button position

* fix: flowy icon buton secondary color bleed

* chore: some UI adjustments

* fix: some regressions

* chore: proper group is_visible fetching

* chore: use a bloc to manage hidden groups

* fix: hiding groups not working

* chore: implement hidden group popups

* chore: proper ungrouped item column management

* chore: remove ungrouped items button

* chore: flowy hover build

* fix: clean up code

* test: integration tests

* fix: not null promise on null value

* fix: hide and unhide multiple groups

* chore: i18n and code review

* chore: missed review

* fix: rust-lib-test

* fix: dont completely remove flowyiconhovercolor

* chore: apply suggest

* fix: number of rows inside hidden groups not updating properly

* fix: hidden groups disappearing after collapse

* fix: hidden group title alignment

* fix: insert newly unhidden groups into the correct position

* chore: adjust padding all around

* feat: reorder hidden groups

* chore: adjust padding

* chore: collapse hidden groups section persist

* chore: no status group at beginning

* fix: hiding groups when grouping with other types

* chore: disable rename groups that arent supported

* chore: update appflowy board ref

* chore: better naming

* test: fix tests

---------

Co-authored-by: Mathias Mogensen <mathias@appflowy.io>
This commit is contained in:
Richard Shiue
2023-11-13 16:14:31 +08:00
committed by GitHub
parent 7867f0366e
commit a63a7ea611
35 changed files with 1200 additions and 749 deletions

View File

@ -1,4 +1,5 @@
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/plugins/database_view/board/presentation/widgets/board_column_header.dart';
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
import 'package:appflowy_board/appflowy_board.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
@ -32,10 +33,12 @@ void main() {
await tester.tap(
find
.descendant(
of: find.byType(AppFlowyGroupHeader),
matching: find.byType(FlowySvg),
of: find.byType(BoardColumnHeader),
matching: find.byWidgetPredicate(
(widget) => widget is FlowySvg && widget.svg == FlowySvgs.add_s,
),
)
.first,
.at(1),
);
await tester.pumpAndSettle();
@ -77,7 +80,7 @@ void main() {
of: find.byType(AppFlowyGroupFooter),
matching: find.byType(FlowySvg),
)
.first,
.at(1),
);
await tester.pumpAndSettle();

View File

@ -0,0 +1,98 @@
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/plugins/database_view/board/presentation/widgets/board_column_header.dart';
import 'package:appflowy/plugins/database_view/board/presentation/widgets/board_hidden_groups.dart';
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group('board hide groups test', () {
testWidgets('expand/collapse hidden groups', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.createNewPageWithName(layout: ViewLayoutPB.Board);
final collapseFinder = find.byFlowySvg(FlowySvgs.pull_left_outlined_s);
final expandFinder = find.byFlowySvg(FlowySvgs.hamburger_s_s);
// Is expanded by default
expect(collapseFinder, findsOneWidget);
expect(expandFinder, findsNothing);
// Collapse hidden groups
await tester.tap(collapseFinder);
await tester.pumpAndSettle();
// Is collapsed
expect(collapseFinder, findsNothing);
expect(expandFinder, findsOneWidget);
// Expand hidden groups
await tester.tap(expandFinder);
await tester.pumpAndSettle();
// Is expanded
expect(collapseFinder, findsOneWidget);
expect(expandFinder, findsNothing);
});
testWidgets('hide first group, and show it again', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.createNewPageWithName(layout: ViewLayoutPB.Board);
// Tap the options of the first group
final optionsFinder = find
.descendant(
of: find.byType(BoardColumnHeader),
matching: find.byFlowySvg(FlowySvgs.details_horizontal_s),
)
.first;
await tester.tap(optionsFinder);
await tester.pumpAndSettle();
// Tap the hide option
await tester.tap(find.byFlowySvg(FlowySvgs.hide_s));
await tester.pumpAndSettle();
int shownGroups =
tester.widgetList(find.byType(BoardColumnHeader)).length;
// We still show Doing, Done, No Status
expect(shownGroups, 3);
final hiddenCardFinder = find.byType(HiddenGroupCard);
await tester.hoverOnWidget(hiddenCardFinder);
await tester.tap(find.byFlowySvg(FlowySvgs.show_m));
await tester.pumpAndSettle();
shownGroups = tester.widgetList(find.byType(BoardColumnHeader)).length;
expect(shownGroups, 4);
});
});
}
extension FlowySvgFinder on CommonFinders {
Finder byFlowySvg(FlowySvgData svg) => _FlowySvgFinder(svg);
}
class _FlowySvgFinder extends MatchFinder {
_FlowySvgFinder(this.svg);
final FlowySvgData svg;
@override
String get description => 'flowy_svg "$svg"';
@override
bool matches(Element candidate) {
final Widget widget = candidate.widget;
return widget is FlowySvg && widget.svg == svg;
}
}