chore: support create new field when editing the row

This commit is contained in:
appflowy 2022-08-31 20:21:06 +08:00
parent 942e966a25
commit a9f5f8d508
6 changed files with 112 additions and 65 deletions

View File

@ -189,7 +189,8 @@
"addSelectOption": "Add an option",
"optionTitle": "Options",
"addOption": "Add option",
"editProperty": "Edit property"
"editProperty": "Edit property",
"newColumn": "New column"
},
"row": {
"duplicate": "Duplicate",

View File

@ -65,7 +65,10 @@ class _BoardSelectOptionCellState extends State<BoardSelectOptionCell> {
alignment: AlignmentDirectional.center,
fit: StackFit.expand,
children: [
Wrap(spacing: 4, runSpacing: 2, children: children),
Padding(
padding: const EdgeInsets.symmetric(vertical: 6),
child: Wrap(spacing: 4, runSpacing: 2, children: children),
),
_SelectOptionDialog(
controller: widget.cellControllerBuilder.build(),
),

View File

@ -78,36 +78,38 @@ class _BoardTextCellState extends State<BoardTextCell> {
child: BlocBuilder<BoardTextCellBloc, BoardTextCellState>(
builder: (context, state) {
Widget child;
if (state.enableEdit) {
child = TextField(
controller: _controller,
focusNode: focusNode,
onChanged: (value) => focusChanged(),
onEditingComplete: () => focusNode.unfocus(),
maxLines: 1,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
fontFamily: 'Mulish',
),
decoration: const InputDecoration(
// Magic number 4 makes the textField take up the same space as FlowyText
contentPadding: EdgeInsets.symmetric(vertical: 4),
border: InputBorder.none,
isDense: true,
),
);
if (state.content.isEmpty) {
child = const SizedBox();
} else {
child = FlowyText.medium(state.content, fontSize: 14);
if (state.enableEdit) {
child = TextField(
controller: _controller,
focusNode: focusNode,
onChanged: (value) => focusChanged(),
onEditingComplete: () => focusNode.unfocus(),
maxLines: 1,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
fontFamily: 'Mulish',
),
decoration: const InputDecoration(
// Magic number 4 makes the textField take up the same space as FlowyText
contentPadding: EdgeInsets.symmetric(vertical: 4),
border: InputBorder.none,
isDense: true,
),
);
} else {
child = FlowyText.medium(state.content, fontSize: 14);
child = Padding(
padding: const EdgeInsets.symmetric(vertical: 6),
child: child,
);
}
}
return Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 6),
child: child,
),
);
return Align(alignment: Alignment.centerLeft, child: child);
},
),
),

View File

@ -100,20 +100,11 @@ class _BoardCardState extends State<BoardCard> {
);
rowNotifier.insertCell(cellId, cellNotifier);
if (index != 0) {
child = Padding(
key: cellId.key(),
padding: const EdgeInsets.only(left: 4, right: 4, top: 8),
child: child,
);
} else {
child = Padding(
key: UniqueKey(),
padding: const EdgeInsets.only(left: 4, right: 4),
child: child,
);
}
child = Padding(
key: cellId.key(),
padding: const EdgeInsets.only(left: 4, right: 4),
child: child,
);
children.add(child);
},
);

View File

@ -1,7 +1,9 @@
import 'package:app_flowy/generated/locale_keys.g.dart';
import 'package:app_flowy/plugins/grid/application/field/field_cache.dart';
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/plugins/grid/application/prelude.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra_ui/style_widget/button.dart';
@ -155,7 +157,10 @@ class CreateFieldButton extends StatelessWidget {
final theme = context.watch<AppTheme>();
return FlowyButton(
text: const FlowyText.medium('New column', fontSize: 12),
text: FlowyText.medium(
LocaleKeys.grid_field_newColumn.tr(),
fontSize: 12,
),
hoverColor: theme.shader6,
onTap: () => FieldEditor(
gridId: gridId,

View File

@ -5,8 +5,10 @@ import 'package:app_flowy/plugins/grid/application/row/row_detail_bloc.dart';
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/theme.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/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';
@ -67,16 +69,21 @@ class _RowDetailPageState extends State<RowDetailPage> {
return bloc;
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 20),
padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 20),
child: Column(
children: [
SizedBox(
height: 40,
height: 30,
child: Row(
children: const [Spacer(), _CloseButton()],
),
),
Expanded(child: _PropertyList(cellBuilder: widget.cellBuilder)),
Expanded(
child: _PropertyList(
cellBuilder: widget.cellBuilder,
viewId: widget.dataController.rowInfo.gridId,
),
),
],
),
),
@ -101,9 +108,11 @@ class _CloseButton extends StatelessWidget {
}
class _PropertyList extends StatelessWidget {
final String viewId;
final GridCellBuilder cellBuilder;
final ScrollController _scrollController;
_PropertyList({
required this.viewId,
required this.cellBuilder,
Key? key,
}) : _scrollController = ScrollController(),
@ -114,29 +123,63 @@ class _PropertyList extends StatelessWidget {
return BlocBuilder<RowDetailBloc, RowDetailState>(
buildWhen: (previous, current) => previous.gridCells != current.gridCells,
builder: (context, state) {
return ScrollbarListStack(
axis: Axis.vertical,
controller: _scrollController,
barSize: GridSize.scrollBarSize,
child: ListView.separated(
controller: _scrollController,
itemCount: state.gridCells.length,
itemBuilder: (BuildContext context, int index) {
return _RowDetailCell(
cellId: state.gridCells[index],
cellBuilder: cellBuilder,
);
},
separatorBuilder: (BuildContext context, int index) {
return const VSpace(2);
},
),
return Column(
children: [
Expanded(
child: ScrollbarListStack(
axis: Axis.vertical,
controller: _scrollController,
barSize: GridSize.scrollBarSize,
child: ListView.separated(
controller: _scrollController,
itemCount: state.gridCells.length,
itemBuilder: (BuildContext context, int index) {
return _RowDetailCell(
cellId: state.gridCells[index],
cellBuilder: cellBuilder,
);
},
separatorBuilder: (BuildContext context, int index) {
return const VSpace(2);
},
),
),
),
_CreateFieldButton(viewId: viewId),
],
);
},
);
}
}
class _CreateFieldButton extends StatelessWidget {
final String viewId;
const _CreateFieldButton({required this.viewId, Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final theme = context.read<AppTheme>();
return SizedBox(
height: 40,
child: FlowyButton(
text: FlowyText.medium(
LocaleKeys.grid_field_newColumn.tr(),
fontSize: 12,
),
hoverColor: theme.shader6,
onTap: () => FieldEditor(
gridId: viewId,
fieldName: "",
typeOptionLoader: NewFieldTypeOptionLoader(gridId: viewId),
).show(context),
leftIcon: svgWidget("home/add"),
),
);
}
}
class _RowDetailCell extends StatelessWidget {
final GridCellIdentifier cellId;
final GridCellBuilder cellBuilder;
@ -172,7 +215,9 @@ class _RowDetailCell extends StatelessWidget {
SizedBox(
width: 150,
child: FieldCellButton(
field: cellId.field, onTap: () => _showFieldEditor(context)),
field: cellId.field,
onTap: () => _showFieldEditor(context),
),
),
const HSpace(10),
Expanded(child: gesture),