Skip to content

Commit

Permalink
chore: implement collapsible side bar and adjust group header (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
richardshiue authored Nov 6, 2023
1 parent 0b2ae4a commit bb4c21f
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,15 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
groupId: groupId,
name: groupName,
);

emit(state.copyWith(isEditingHeader: false));
},
toggleGroupVisibility: (String groupId, bool isVisible) async {
await groupBackendSvc.updateGroup(
fieldId: groupControllers.values.first.group.fieldId,
groupId: groupId,
visible: isVisible,
);
},
);
},
);
Expand Down Expand Up @@ -362,6 +368,10 @@ class BoardEvent with _$BoardEvent {
RowMetaPB row,
) = _StartEditRow;
const factory BoardEvent.endEditingRow(RowId rowId) = _EndEditRow;
const factory BoardEvent.toggleGroupVisibility(
String groupId,
bool isVisible,
) = _ToggleGroupVisibility;
const factory BoardEvent.didReceiveError(FlowyError error) = _DidReceiveError;
const factory BoardEvent.didReceiveGridUpdate(
DatabasePB grid,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/row_entities.pb.dart';
import 'package:appflowy_board/appflowy_board.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';

import 'package:flowy_infra_ui/flowy_infra_ui_web.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/error_page.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart' hide Card;
import 'package:flutter_bloc/flutter_bloc.dart';

Expand Down Expand Up @@ -123,7 +122,7 @@ class _BoardContentState extends State<BoardContent> {

final config = const AppFlowyBoardConfig(
groupBackgroundColor: Color(0xffF7F8FC),
headerPadding: EdgeInsets.symmetric(horizontal: 6),
headerPadding: EdgeInsets.symmetric(horizontal: 8),
cardPadding: EdgeInsets.symmetric(horizontal: 4, vertical: 3),
);

Expand Down Expand Up @@ -164,6 +163,7 @@ class _BoardContentState extends State<BoardContent> {
Expanded(
child: AppFlowyBoard(
boardScrollController: scrollManager,
scrollController: ScrollController(),
controller: context.read<BoardBloc>().boardController,
groupConstraints: const BoxConstraints.tightFor(width: 300),
config: const AppFlowyBoardConfig(
Expand Down Expand Up @@ -350,48 +350,79 @@ class _BoardContentState extends State<BoardContent> {
}
}

class HiddenGroupsColumn extends StatelessWidget {
class HiddenGroupsColumn extends StatefulWidget {
const HiddenGroupsColumn({super.key});

@override
State<HiddenGroupsColumn> createState() => _HiddenGroupsColumnState();
}

class _HiddenGroupsColumnState extends State<HiddenGroupsColumn> {
bool isCollapsed = false;

@override
Widget build(BuildContext context) {
return SizedBox(
width: 260,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Hidden group title
Padding(
padding: const EdgeInsets.only(left: 26),
child: AppFlowyGroupHeader(
height: 50,
// Padding is for the hover action discrepancy
margin: const EdgeInsets.only(left: 22),
title: Expanded(
child: FlowyText(
'Hidden groups',
fontSize: 14,
fontWeight: FontWeight.w500,
overflow: TextOverflow.clip,
color: Theme.of(context).hintColor,
),
),
addIcon: FlowySvg(
FlowySvgs.pull_left_outlined_s,
color: Theme.of(context).hintColor,
return AnimatedSize(
alignment: AlignmentDirectional.topStart,
curve: Curves.easeOut,
duration: const Duration(milliseconds: 150),
child: isCollapsed
? Padding(
padding: const EdgeInsets.fromLTRB(48, 16, 8, 8),
child: _collapseExpandIcon(),
)
: SizedBox(
width: 260,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Hidden group title
Padding(
// padding: const EdgeInsets.only(left: 48),
padding: const EdgeInsets.fromLTRB(48, 16, 8, 8),
child: Row(
children: [
Expanded(
child: FlowyText.medium(
'Hidden groups',
fontSize: 14,
overflow: TextOverflow.ellipsis,
color: Theme.of(context).hintColor,
),
),
_collapseExpandIcon(),
],
),
),
// Hidden grouop cards
Expanded(
child: ListView.separated(
itemCount: 50,
itemBuilder: (context, index) => const HiddenGroupCard(),
separatorBuilder: (context, index) => const VSpace(2),
),
),
],
),
onAddButtonClick: () {}, // TODO(Richard): Collapse
),
),
// Hidden grouop cards
Expanded(
child: ListView.separated(
itemCount: 2,
itemBuilder: (context, index) => const HiddenGroupCard(),
separatorBuilder: (context, index) => const VSpace(2),
),
),
],
);
}

Widget _collapseExpandIcon() {
return FlowyTooltip(
message: isCollapsed ? "Expand group" : "Collpase group",
child: FlowyIconButton(
width: 20,
height: 20,
icon: FlowySvg(
isCollapsed
? FlowySvgs.pull_left_outlined_s
: FlowySvgs.pull_left_outlined_s,
),
iconColorOnHover: Theme.of(context).colorScheme.onSurface,
onPressed: () => setState(() {
isCollapsed = !isCollapsed;
}),
),
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/database_view/board/application/board_bloc.dart';
import 'package:appflowy/plugins/database_view/grid/presentation/layout/sizes.dart';
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/field_type_extension.dart';
import 'package:appflowy/plugins/database_view/widgets/card/define.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart';
import 'package:appflowy_board/appflowy_board.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/theme_extension.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/text.dart';
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
Expand All @@ -18,11 +20,11 @@ class BoardColumnHeader extends StatefulWidget {
const BoardColumnHeader({
super.key,
required this.groupData,
this.margin,
required this.margin,
});

final AppFlowyGroupData groupData;
final EdgeInsets? margin;
final EdgeInsets margin;

@override
State<BoardColumnHeader> createState() => _BoardColumnHeaderState();
Expand Down Expand Up @@ -112,20 +114,26 @@ class _BoardColumnHeaderState extends State<BoardColumnHeader> {
title = _buildTextField(context);
}

return AppFlowyGroupHeader(
height: 50,
title: title,
icon: _buildHeaderIcon(boardCustomData),
margin: widget.margin ?? EdgeInsets.zero,
onAddButtonClick: () => context
.read<BoardBloc>()
.add(BoardEvent.createHeaderRow(widget.groupData.id)),
addIcon: SizedBox(
height: 20,
width: 20,
child: FlowySvg(
FlowySvgs.add_s,
color: Theme.of(context).iconTheme.color,
return Padding(
padding: widget.margin,
child: SizedBox(
height: 50,
child: Row(
children: [
_buildHeaderIcon(boardCustomData),
title,
const HSpace(6),
_groupOptionsButton(context),
const HSpace(4),
FlowyIconButton(
width: 20,
icon: const FlowySvg(FlowySvgs.add_s),
iconColorOnHover: Theme.of(context).colorScheme.onSurface,
onPressed: () => context
.read<BoardBloc>()
.add(BoardEvent.createHeaderRow(widget.groupData.id)),
),
],
),
),
);
Expand Down Expand Up @@ -189,37 +197,95 @@ class _BoardColumnHeaderState extends State<BoardColumnHeader> {
),
);
}
}

Widget? _buildHeaderIcon(GroupData customData) {
Widget? widget;
switch (customData.fieldType) {
case FieldType.Checkbox:
final group = customData.asCheckboxGroup()!;
widget = FlowySvg(
group.isCheck ? FlowySvgs.check_filled_s : FlowySvgs.uncheck_s,
blendMode: BlendMode.dst,
);
break;
case FieldType.DateTime:
case FieldType.LastEditedTime:
case FieldType.CreatedTime:
case FieldType.MultiSelect:
case FieldType.Number:
case FieldType.RichText:
case FieldType.SingleSelect:
case FieldType.URL:
case FieldType.Checklist:
break;
Widget _buildHeaderIcon(GroupData customData) {
return switch (customData.fieldType) {
FieldType.Checkbox => FlowySvg(
customData.asCheckboxGroup()!.isCheck
? FlowySvgs.check_filled_s
: FlowySvgs.uncheck_s,
blendMode: BlendMode.dst,
),
_ => const SizedBox.shrink(),
};
}

if (widget != null) {
widget = SizedBox(
width: 20,
height: 20,
child: widget,
Widget _groupOptionsButton(BuildContext context) {
return AppFlowyPopover(
clickHandler: PopoverClickHandler.gestureDetector,
margin: const EdgeInsets.fromLTRB(8, 8, 8, 4),
constraints: BoxConstraints.loose(const Size(168, 300)),
direction: PopoverDirection.bottomWithLeftAligned,
child: FlowyIconButton(
width: 20,
icon: const FlowySvg(FlowySvgs.details_horizontal_s),
iconColorOnHover: Theme.of(context).colorScheme.onSurface,
),
popupBuilder: (popoverContext) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
...GroupOptions.values.map(
(action) => SizedBox(
height: GridSize.popoverItemHeight,
child: Padding(
padding: const EdgeInsets.only(bottom: 4.0),
child: FlowyButton(
leftIcon: FlowySvg(action.icon()),
text: FlowyText.medium(
action.text(),
overflow: TextOverflow.ellipsis,
),
onTap: () {
action.call(context, widget.groupData.id);
PopoverContainer.of(popoverContext).close();
},
),
),
),
)
],
);
},
);
}
}

enum GroupOptions {
rename,
hide;
// color,
// delete;

void call(BuildContext context, String groupId) {
switch (this) {
case rename:
context.read<BoardBloc>().add(BoardEvent.startEditingHeader(groupId));
break;
case hide:
context
.read<BoardBloc>()
.add(BoardEvent.toggleGroupVisibility(groupId, false));
break;
// case GroupOptions.color:
// break;
// case GroupOptions.delete:
// // context.read<BoardBloc>().add(BoardEvent.);
// break;
}
}

FlowySvgData icon() {
return switch (this) {
rename => FlowySvgs.edit_s,
hide => FlowySvgs.hide_s,
};
}

return widget;
String text() {
return switch (this) {
rename => "Rename",
hide => "Hide",
};
}
}

0 comments on commit bb4c21f

Please sign in to comment.