mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: switch database layout (#2677)
* chore: rename update at and create at * chore: support switching view layout * chore: implement ui * chore: update layout type * refactor: board/calendar/grid setting button * chore: update UI after switch to other layout type * fix: no date display in calendar * chore: update patch * chore: fix create ref view in document * chore: fix flutter analyze * ci: warnings * chore: rename board and grid keys * fix: calendar row event update --------- Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
This commit is contained in:
@ -39,18 +39,18 @@ class GroupCallbacks {
|
||||
});
|
||||
}
|
||||
|
||||
class LayoutCallbacks {
|
||||
final void Function(LayoutSettingPB) onLayoutChanged;
|
||||
final void Function(LayoutSettingPB) onLoadLayout;
|
||||
class DatabaseLayoutSettingCallbacks {
|
||||
final void Function(DatabaseLayoutSettingPB) onLayoutChanged;
|
||||
final void Function(DatabaseLayoutSettingPB) onLoadLayout;
|
||||
|
||||
LayoutCallbacks({
|
||||
DatabaseLayoutSettingCallbacks({
|
||||
required this.onLayoutChanged,
|
||||
required this.onLoadLayout,
|
||||
});
|
||||
}
|
||||
|
||||
class CalendarLayoutCallbacks {
|
||||
final void Function(LayoutSettingPB) onCalendarLayoutChanged;
|
||||
final void Function(DatabaseLayoutSettingPB) onCalendarLayoutChanged;
|
||||
|
||||
CalendarLayoutCallbacks({required this.onCalendarLayoutChanged});
|
||||
}
|
||||
@ -59,14 +59,14 @@ class DatabaseCallbacks {
|
||||
OnDatabaseChanged? onDatabaseChanged;
|
||||
OnFieldsChanged? onFieldsChanged;
|
||||
OnFiltersChanged? onFiltersChanged;
|
||||
OnRowsChanged? onRowsChanged;
|
||||
OnNumOfRowsChanged? onNumOfRowsChanged;
|
||||
OnRowsDeleted? onRowsDeleted;
|
||||
OnRowsUpdated? onRowsUpdated;
|
||||
OnRowsCreated? onRowsCreated;
|
||||
|
||||
DatabaseCallbacks({
|
||||
this.onDatabaseChanged,
|
||||
this.onRowsChanged,
|
||||
this.onNumOfRowsChanged,
|
||||
this.onFieldsChanged,
|
||||
this.onFiltersChanged,
|
||||
this.onRowsUpdated,
|
||||
@ -79,13 +79,13 @@ class DatabaseController {
|
||||
final String viewId;
|
||||
final DatabaseViewBackendService _databaseViewBackendSvc;
|
||||
final FieldController fieldController;
|
||||
DatabaseLayoutPB? databaseLayout;
|
||||
late DatabaseViewCache _viewCache;
|
||||
final DatabaseLayoutPB layoutType;
|
||||
|
||||
// Callbacks
|
||||
DatabaseCallbacks? _databaseCallbacks;
|
||||
GroupCallbacks? _groupCallbacks;
|
||||
LayoutCallbacks? _layoutCallbacks;
|
||||
DatabaseLayoutSettingCallbacks? _layoutCallbacks;
|
||||
CalendarLayoutCallbacks? _calendarLayoutCallbacks;
|
||||
|
||||
// Getters
|
||||
@ -93,15 +93,15 @@ class DatabaseController {
|
||||
|
||||
// Listener
|
||||
final DatabaseGroupListener groupListener;
|
||||
final DatabaseLayoutListener layoutListener;
|
||||
final DatabaseLayoutSettingListener layoutListener;
|
||||
final DatabaseCalendarLayoutListener calendarLayoutListener;
|
||||
|
||||
DatabaseController({required ViewPB view, required this.layoutType})
|
||||
DatabaseController({required ViewPB view})
|
||||
: viewId = view.id,
|
||||
_databaseViewBackendSvc = DatabaseViewBackendService(viewId: view.id),
|
||||
fieldController = FieldController(viewId: view.id),
|
||||
groupListener = DatabaseGroupListener(view.id),
|
||||
layoutListener = DatabaseLayoutListener(view.id),
|
||||
layoutListener = DatabaseLayoutSettingListener(view.id),
|
||||
calendarLayoutListener = DatabaseCalendarLayoutListener(view.id) {
|
||||
_viewCache = DatabaseViewCache(
|
||||
viewId: viewId,
|
||||
@ -111,14 +111,11 @@ class DatabaseController {
|
||||
_listenOnFieldsChanged();
|
||||
_listenOnGroupChanged();
|
||||
_listenOnLayoutChanged();
|
||||
if (layoutType == DatabaseLayoutPB.Calendar) {
|
||||
_listenOnCalendarLayoutChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void setListener({
|
||||
DatabaseCallbacks? onDatabaseChanged,
|
||||
LayoutCallbacks? onLayoutChanged,
|
||||
DatabaseLayoutSettingCallbacks? onLayoutChanged,
|
||||
GroupCallbacks? onGroupChanged,
|
||||
CalendarLayoutCallbacks? onCalendarLayoutChanged,
|
||||
}) {
|
||||
@ -132,6 +129,12 @@ class DatabaseController {
|
||||
return _databaseViewBackendSvc.openGrid().then((result) {
|
||||
return result.fold(
|
||||
(database) async {
|
||||
databaseLayout = database.layoutType;
|
||||
|
||||
if (databaseLayout == DatabaseLayoutPB.Calendar) {
|
||||
_listenOnCalendarLayoutChanged();
|
||||
}
|
||||
|
||||
_databaseCallbacks?.onDatabaseChanged?.call(database);
|
||||
_viewCache.rowCache.setInitialRows(database.rows);
|
||||
return await fieldController
|
||||
@ -242,20 +245,20 @@ class DatabaseController {
|
||||
}
|
||||
|
||||
Future<void> _loadLayoutSetting() async {
|
||||
_databaseViewBackendSvc.getLayoutSetting(layoutType).then((result) {
|
||||
result.fold(
|
||||
(l) {
|
||||
_layoutCallbacks?.onLoadLayout(l);
|
||||
},
|
||||
(r) => Log.error(r),
|
||||
);
|
||||
});
|
||||
if (databaseLayout != null) {
|
||||
_databaseViewBackendSvc.getLayoutSetting(databaseLayout!).then((result) {
|
||||
result.fold(
|
||||
(l) => _layoutCallbacks?.onLoadLayout(l),
|
||||
(r) => Log.error(r),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _listenOnRowsChanged() {
|
||||
final callbacks = DatabaseViewCallbacks(
|
||||
onRowsChanged: (rows, rowByRowId, reason) {
|
||||
_databaseCallbacks?.onRowsChanged?.call(rows, rowByRowId, reason);
|
||||
onNumOfRowsChanged: (rows, rowByRowId, reason) {
|
||||
_databaseCallbacks?.onNumOfRowsChanged?.call(rows, rowByRowId, reason);
|
||||
},
|
||||
onRowsDeleted: (ids) {
|
||||
_databaseCallbacks?.onRowsDeleted?.call(ids);
|
||||
|
@ -97,10 +97,10 @@ class DatabaseViewBackendService {
|
||||
});
|
||||
}
|
||||
|
||||
Future<Either<LayoutSettingPB, FlowyError>> getLayoutSetting(
|
||||
Future<Either<DatabaseLayoutSettingPB, FlowyError>> getLayoutSetting(
|
||||
DatabaseLayoutPB layoutType,
|
||||
) {
|
||||
final payload = DatabaseLayoutIdPB.create()
|
||||
final payload = DatabaseLayoutMetaPB.create()
|
||||
..viewId = viewId
|
||||
..layout = layoutType;
|
||||
return DatabaseEventGetLayoutSetting(payload).send();
|
||||
|
@ -15,7 +15,7 @@ typedef OnDatabaseChanged = void Function(DatabasePB);
|
||||
typedef OnRowsCreated = void Function(List<RowId> ids);
|
||||
typedef OnRowsUpdated = void Function(List<RowId> ids);
|
||||
typedef OnRowsDeleted = void Function(List<RowId> ids);
|
||||
typedef OnRowsChanged = void Function(
|
||||
typedef OnNumOfRowsChanged = void Function(
|
||||
UnmodifiableListView<RowInfo> rows,
|
||||
UnmodifiableMapView<RowId, RowInfo> rowByRowId,
|
||||
RowsChangedReason reason,
|
||||
|
@ -6,7 +6,7 @@ import 'package:appflowy_backend/protobuf/flowy-error/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
||||
typedef NewLayoutFieldValue = Either<LayoutSettingPB, FlowyError>;
|
||||
typedef NewLayoutFieldValue = Either<DatabaseLayoutSettingPB, FlowyError>;
|
||||
|
||||
class DatabaseCalendarLayoutListener {
|
||||
final String viewId;
|
||||
@ -33,7 +33,7 @@ class DatabaseCalendarLayoutListener {
|
||||
case DatabaseNotification.DidSetNewLayoutField:
|
||||
result.fold(
|
||||
(payload) => _newLayoutFieldNotifier?.value =
|
||||
left(LayoutSettingPB.fromBuffer(payload)),
|
||||
left(DatabaseLayoutSettingPB.fromBuffer(payload)),
|
||||
(error) => _newLayoutFieldNotifier?.value = right(error),
|
||||
);
|
||||
break;
|
||||
|
@ -0,0 +1,56 @@
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/setting_entities.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import 'layout_service.dart';
|
||||
part 'layout_bloc.freezed.dart';
|
||||
|
||||
class DatabaseLayoutBloc
|
||||
extends Bloc<DatabaseLayoutEvent, DatabaseLayoutState> {
|
||||
final DatabaseLayoutBackendService layoutService;
|
||||
|
||||
DatabaseLayoutBloc({
|
||||
required String viewId,
|
||||
required DatabaseLayoutPB databaseLayout,
|
||||
}) : layoutService = DatabaseLayoutBackendService(viewId),
|
||||
super(DatabaseLayoutState.initial(viewId, databaseLayout)) {
|
||||
on<DatabaseLayoutEvent>(
|
||||
(event, emit) async {
|
||||
event.when(
|
||||
initial: () {},
|
||||
updateLayout: (DatabaseLayoutPB layout) {
|
||||
layoutService.updateLayout(
|
||||
fieldId: viewId,
|
||||
layout: layout,
|
||||
);
|
||||
emit(state.copyWith(databaseLayout: layout));
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
class DatabaseLayoutEvent with _$DatabaseLayoutEvent {
|
||||
const factory DatabaseLayoutEvent.initial() = _Initial;
|
||||
const factory DatabaseLayoutEvent.updateLayout(DatabaseLayoutPB layout) =
|
||||
_UpdateLayout;
|
||||
}
|
||||
|
||||
@freezed
|
||||
class DatabaseLayoutState with _$DatabaseLayoutState {
|
||||
const factory DatabaseLayoutState({
|
||||
required String viewId,
|
||||
required DatabaseLayoutPB databaseLayout,
|
||||
}) = _DatabaseLayoutState;
|
||||
|
||||
factory DatabaseLayoutState.initial(
|
||||
String viewId,
|
||||
DatabaseLayoutPB databaseLayout,
|
||||
) =>
|
||||
DatabaseLayoutState(
|
||||
viewId: viewId,
|
||||
databaseLayout: databaseLayout,
|
||||
);
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:appflowy/core/notification/grid_notification.dart';
|
||||
import 'package:flowy_infra/notifier.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
||||
/// Listener for database layout changes.
|
||||
class DatabaseLayoutListener {
|
||||
final String viewId;
|
||||
PublishNotifier<Either<DatabaseLayoutPB, FlowyError>>? _layoutNotifier =
|
||||
PublishNotifier();
|
||||
DatabaseNotificationListener? _listener;
|
||||
DatabaseLayoutListener(this.viewId);
|
||||
|
||||
void start({
|
||||
required void Function(Either<DatabaseLayoutPB, FlowyError>)
|
||||
onLayoutChanged,
|
||||
}) {
|
||||
_layoutNotifier?.addPublishListener(onLayoutChanged);
|
||||
_listener = DatabaseNotificationListener(
|
||||
objectId: viewId,
|
||||
handler: _handler,
|
||||
);
|
||||
}
|
||||
|
||||
void _handler(
|
||||
DatabaseNotification ty,
|
||||
Either<Uint8List, FlowyError> result,
|
||||
) {
|
||||
switch (ty) {
|
||||
case DatabaseNotification.DidUpdateDatabaseLayout:
|
||||
result.fold(
|
||||
(payload) => _layoutNotifier?.value =
|
||||
left(DatabaseLayoutMetaPB.fromBuffer(payload).layout),
|
||||
(error) => _layoutNotifier?.value = right(error),
|
||||
);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> stop() async {
|
||||
await _listener?.stop();
|
||||
_layoutNotifier?.dispose();
|
||||
_layoutNotifier = null;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/setting_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
||||
class DatabaseLayoutBackendService {
|
||||
final String viewId;
|
||||
|
||||
DatabaseLayoutBackendService(this.viewId);
|
||||
|
||||
Future<Either<ViewPB, FlowyError>> updateLayout({
|
||||
required String fieldId,
|
||||
required DatabaseLayoutPB layout,
|
||||
}) {
|
||||
var payload = UpdateViewPayloadPB.create()
|
||||
..viewId = viewId
|
||||
..layout = _viewLayoutFromDatabaseLayout(layout);
|
||||
|
||||
return FolderEventUpdateView(payload).send();
|
||||
}
|
||||
}
|
||||
|
||||
ViewLayoutPB _viewLayoutFromDatabaseLayout(DatabaseLayoutPB databaseLayout) {
|
||||
switch (databaseLayout) {
|
||||
case DatabaseLayoutPB.Board:
|
||||
return ViewLayoutPB.Board;
|
||||
case DatabaseLayoutPB.Calendar:
|
||||
return ViewLayoutPB.Calendar;
|
||||
case DatabaseLayoutPB.Grid:
|
||||
return ViewLayoutPB.Grid;
|
||||
default:
|
||||
throw UnimplementedError;
|
||||
}
|
||||
}
|
@ -8,15 +8,15 @@ import 'package:dartz/dartz.dart';
|
||||
|
||||
typedef LayoutSettingsValue<T> = Either<T, FlowyError>;
|
||||
|
||||
class DatabaseLayoutListener {
|
||||
class DatabaseLayoutSettingListener {
|
||||
final String viewId;
|
||||
PublishNotifier<LayoutSettingsValue<LayoutSettingPB>>? _settingNotifier =
|
||||
PublishNotifier();
|
||||
PublishNotifier<LayoutSettingsValue<DatabaseLayoutSettingPB>>?
|
||||
_settingNotifier = PublishNotifier();
|
||||
DatabaseNotificationListener? _listener;
|
||||
DatabaseLayoutListener(this.viewId);
|
||||
DatabaseLayoutSettingListener(this.viewId);
|
||||
|
||||
void start({
|
||||
required void Function(LayoutSettingsValue<LayoutSettingPB>)
|
||||
required void Function(LayoutSettingsValue<DatabaseLayoutSettingPB>)
|
||||
onLayoutChanged,
|
||||
}) {
|
||||
_settingNotifier?.addPublishListener(onLayoutChanged);
|
||||
@ -34,7 +34,7 @@ class DatabaseLayoutListener {
|
||||
case DatabaseNotification.DidUpdateLayoutSettings:
|
||||
result.fold(
|
||||
(payload) => _settingNotifier?.value =
|
||||
left(LayoutSettingPB.fromBuffer(payload)),
|
||||
left(DatabaseLayoutSettingPB.fromBuffer(payload)),
|
||||
(error) => _settingNotifier?.value = right(error),
|
||||
);
|
||||
break;
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
@ -40,7 +42,31 @@ class DatabaseSettingState with _$DatabaseSettingState {
|
||||
}
|
||||
|
||||
enum DatabaseSettingAction {
|
||||
showFilters,
|
||||
sortBy,
|
||||
showProperties,
|
||||
showLayout,
|
||||
showGroup,
|
||||
}
|
||||
|
||||
extension DatabaseSettingActionExtension on DatabaseSettingAction {
|
||||
String iconName() {
|
||||
switch (this) {
|
||||
case DatabaseSettingAction.showProperties:
|
||||
return 'grid/setting/properties';
|
||||
case DatabaseSettingAction.showLayout:
|
||||
return 'grid/setting/database_layout';
|
||||
case DatabaseSettingAction.showGroup:
|
||||
return 'grid/setting/group';
|
||||
}
|
||||
}
|
||||
|
||||
String title() {
|
||||
switch (this) {
|
||||
case DatabaseSettingAction.showProperties:
|
||||
return LocaleKeys.grid_settings_Properties.tr();
|
||||
case DatabaseSettingAction.showLayout:
|
||||
return LocaleKeys.grid_settings_databaseLayout.tr();
|
||||
case DatabaseSettingAction.showGroup:
|
||||
return LocaleKeys.grid_settings_group.tr();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,21 +9,21 @@ import 'view_listener.dart';
|
||||
|
||||
class DatabaseViewCallbacks {
|
||||
/// Will get called when number of rows were changed that includes
|
||||
/// update/delete/insert rows. The [onRowsChanged] will return all
|
||||
/// update/delete/insert rows. The [onNumOfRowsChanged] will return all
|
||||
/// the rows of the current database
|
||||
final OnRowsChanged? onRowsChanged;
|
||||
final OnNumOfRowsChanged? onNumOfRowsChanged;
|
||||
|
||||
// Will get called when creating new rows
|
||||
final OnRowsCreated? onRowsCreated;
|
||||
|
||||
/// Will get called when number of rows were updated
|
||||
/// Will get called when rows were updated
|
||||
final OnRowsUpdated? onRowsUpdated;
|
||||
|
||||
/// Will get called when number of rows were deleted
|
||||
final OnRowsDeleted? onRowsDeleted;
|
||||
|
||||
const DatabaseViewCallbacks({
|
||||
this.onRowsChanged,
|
||||
this.onNumOfRowsChanged,
|
||||
this.onRowsCreated,
|
||||
this.onRowsUpdated,
|
||||
this.onRowsDeleted,
|
||||
@ -101,7 +101,7 @@ class DatabaseViewCache {
|
||||
);
|
||||
|
||||
_rowCache.onRowsChanged(
|
||||
(reason) => _callbacks?.onRowsChanged?.call(
|
||||
(reason) => _callbacks?.onNumOfRowsChanged?.call(
|
||||
rowInfos,
|
||||
_rowCache.rowByRowId,
|
||||
reason,
|
||||
|
@ -20,18 +20,17 @@ import 'group_controller.dart';
|
||||
part 'board_bloc.freezed.dart';
|
||||
|
||||
class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||
final DatabaseController _databaseController;
|
||||
final DatabaseController databaseController;
|
||||
late final AppFlowyBoardController boardController;
|
||||
final LinkedHashMap<String, GroupController> groupControllers =
|
||||
LinkedHashMap();
|
||||
|
||||
FieldController get fieldController => _databaseController.fieldController;
|
||||
String get viewId => _databaseController.viewId;
|
||||
FieldController get fieldController => databaseController.fieldController;
|
||||
String get viewId => databaseController.viewId;
|
||||
|
||||
BoardBloc({required ViewPB view})
|
||||
: _databaseController = DatabaseController(
|
||||
: databaseController = DatabaseController(
|
||||
view: view,
|
||||
layoutType: DatabaseLayoutPB.Board,
|
||||
),
|
||||
super(BoardState.initial(view.id)) {
|
||||
boardController = AppFlowyBoardController(
|
||||
@ -41,7 +40,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||
toGroupId,
|
||||
toIndex,
|
||||
) {
|
||||
_databaseController.moveGroup(
|
||||
databaseController.moveGroup(
|
||||
fromGroupId: fromGroupId,
|
||||
toGroupId: toGroupId,
|
||||
);
|
||||
@ -54,7 +53,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||
final fromRow = groupControllers[groupId]?.rowAtIndex(fromIndex);
|
||||
final toRow = groupControllers[groupId]?.rowAtIndex(toIndex);
|
||||
if (fromRow != null) {
|
||||
_databaseController.moveGroupRow(
|
||||
databaseController.moveGroupRow(
|
||||
fromRow: fromRow,
|
||||
toRow: toRow,
|
||||
groupId: groupId,
|
||||
@ -70,7 +69,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||
final fromRow = groupControllers[fromGroupId]?.rowAtIndex(fromIndex);
|
||||
final toRow = groupControllers[toGroupId]?.rowAtIndex(toIndex);
|
||||
if (fromRow != null) {
|
||||
_databaseController.moveGroupRow(
|
||||
databaseController.moveGroupRow(
|
||||
fromRow: fromRow,
|
||||
toRow: toRow,
|
||||
groupId: toGroupId,
|
||||
@ -88,7 +87,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||
},
|
||||
createBottomRow: (groupId) async {
|
||||
final startRowId = groupControllers[groupId]?.lastRow()?.id;
|
||||
final result = await _databaseController.createRow(
|
||||
final result = await databaseController.createRow(
|
||||
groupId: groupId,
|
||||
startRowId: startRowId,
|
||||
);
|
||||
@ -98,8 +97,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||
);
|
||||
},
|
||||
createHeaderRow: (String groupId) async {
|
||||
final result =
|
||||
await _databaseController.createRow(groupId: groupId);
|
||||
final result = await databaseController.createRow(groupId: groupId);
|
||||
result.fold(
|
||||
(_) {},
|
||||
(err) => Log.error(err),
|
||||
@ -170,7 +168,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _databaseController.dispose();
|
||||
await databaseController.dispose();
|
||||
for (final controller in groupControllers.values) {
|
||||
controller.dispose();
|
||||
}
|
||||
@ -198,7 +196,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||
}
|
||||
|
||||
RowCache? getRowCache() {
|
||||
return _databaseController.rowCache;
|
||||
return databaseController.rowCache;
|
||||
}
|
||||
|
||||
void _startListening() {
|
||||
@ -237,7 +235,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||
},
|
||||
);
|
||||
|
||||
_databaseController.setListener(
|
||||
databaseController.setListener(
|
||||
onDatabaseChanged: onDatabaseChanged,
|
||||
onGroupChanged: onGroupChanged,
|
||||
);
|
||||
@ -256,7 +254,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||
}
|
||||
|
||||
Future<void> _openGrid(Emitter<BoardState> emit) async {
|
||||
final result = await _databaseController.open();
|
||||
final result = await databaseController.open();
|
||||
result.fold(
|
||||
(grid) => emit(
|
||||
state.copyWith(loadingState: GridLoadingState.finish(left(unit))),
|
||||
|
@ -49,18 +49,19 @@ class BoardPlugin extends Plugin {
|
||||
notifier = ViewPluginNotifier(view: view);
|
||||
|
||||
@override
|
||||
PluginDisplay get display => GridPluginDisplay(notifier: notifier);
|
||||
PluginWidgetBuilder get widgetBuilder =>
|
||||
BoardPluginWidgetBuilder(notifier: notifier);
|
||||
|
||||
@override
|
||||
PluginId get id => notifier.view.id;
|
||||
|
||||
@override
|
||||
PluginType get ty => _pluginType;
|
||||
PluginType get pluginType => _pluginType;
|
||||
}
|
||||
|
||||
class GridPluginDisplay extends PluginDisplay {
|
||||
class BoardPluginWidgetBuilder extends PluginWidgetBuilder {
|
||||
final ViewPluginNotifier notifier;
|
||||
GridPluginDisplay({required this.notifier, Key? key});
|
||||
BoardPluginWidgetBuilder({required this.notifier, Key? key});
|
||||
|
||||
ViewPB get view => notifier.view;
|
||||
|
||||
|
@ -340,15 +340,7 @@ class _ToolbarBlocAdaptor extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<BoardBloc, BoardState>(
|
||||
builder: (context, state) {
|
||||
final bloc = context.read<BoardBloc>();
|
||||
final toolbarContext = BoardToolbarContext(
|
||||
viewId: bloc.viewId,
|
||||
fieldController: bloc.fieldController,
|
||||
);
|
||||
|
||||
return BoardToolbar(toolbarContext: toolbarContext);
|
||||
},
|
||||
builder: (context, state) => const BoardToolbar(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,192 +0,0 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
|
||||
import 'package:appflowy/plugins/database_view/board/application/toolbar/board_setting_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/layout/sizes.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/toolbar/grid_group.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/toolbar/grid_property.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
import 'board_toolbar.dart';
|
||||
|
||||
class BoardSettingContext {
|
||||
final String viewId;
|
||||
final FieldController fieldController;
|
||||
BoardSettingContext({
|
||||
required this.viewId,
|
||||
required this.fieldController,
|
||||
});
|
||||
|
||||
factory BoardSettingContext.from(BoardToolbarContext toolbarContext) =>
|
||||
BoardSettingContext(
|
||||
viewId: toolbarContext.viewId,
|
||||
fieldController: toolbarContext.fieldController,
|
||||
);
|
||||
}
|
||||
|
||||
class BoardSettingList extends StatelessWidget {
|
||||
final BoardSettingContext settingContext;
|
||||
final Function(BoardSettingAction, BoardSettingContext) onAction;
|
||||
const BoardSettingList({
|
||||
required this.settingContext,
|
||||
required this.onAction,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => BoardSettingBloc(viewId: settingContext.viewId),
|
||||
child: BlocListener<BoardSettingBloc, BoardSettingState>(
|
||||
listenWhen: (previous, current) =>
|
||||
previous.selectedAction != current.selectedAction,
|
||||
listener: (context, state) {
|
||||
state.selectedAction.foldLeft(null, (_, action) {
|
||||
onAction(action, settingContext);
|
||||
});
|
||||
},
|
||||
child: BlocBuilder<BoardSettingBloc, BoardSettingState>(
|
||||
builder: (context, state) {
|
||||
return _renderList();
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _renderList() {
|
||||
final cells = BoardSettingAction.values.map((action) {
|
||||
return _SettingItem(action: action);
|
||||
}).toList();
|
||||
|
||||
return SizedBox(
|
||||
width: 140,
|
||||
child: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
controller: ScrollController(),
|
||||
itemCount: cells.length,
|
||||
separatorBuilder: (context, index) {
|
||||
return VSpace(GridSize.typeOptionSeparatorHeight);
|
||||
},
|
||||
physics: StyledScrollPhysics(),
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return cells[index];
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _SettingItem extends StatelessWidget {
|
||||
final BoardSettingAction action;
|
||||
|
||||
const _SettingItem({
|
||||
required this.action,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isSelected = context
|
||||
.read<BoardSettingBloc>()
|
||||
.state
|
||||
.selectedAction
|
||||
.foldLeft(false, (_, selectedAction) => selectedAction == action);
|
||||
|
||||
return SizedBox(
|
||||
height: 30,
|
||||
child: FlowyButton(
|
||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||
isSelected: isSelected,
|
||||
text: FlowyText.medium(
|
||||
action.title(),
|
||||
color: AFThemeExtension.of(context).textColor,
|
||||
),
|
||||
onTap: () {
|
||||
context
|
||||
.read<BoardSettingBloc>()
|
||||
.add(BoardSettingEvent.performAction(action));
|
||||
},
|
||||
leftIcon: svgWidget(
|
||||
action.iconName(),
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension _GridSettingExtension on BoardSettingAction {
|
||||
String iconName() {
|
||||
switch (this) {
|
||||
case BoardSettingAction.properties:
|
||||
return 'grid/setting/properties';
|
||||
case BoardSettingAction.groups:
|
||||
return 'grid/setting/group';
|
||||
}
|
||||
}
|
||||
|
||||
String title() {
|
||||
switch (this) {
|
||||
case BoardSettingAction.properties:
|
||||
return LocaleKeys.grid_settings_Properties.tr();
|
||||
case BoardSettingAction.groups:
|
||||
return LocaleKeys.grid_settings_group.tr();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BoardSettingListPopover extends StatefulWidget {
|
||||
final PopoverController popoverController;
|
||||
final BoardSettingContext settingContext;
|
||||
|
||||
const BoardSettingListPopover({
|
||||
Key? key,
|
||||
required this.popoverController,
|
||||
required this.settingContext,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _BoardSettingListPopoverState();
|
||||
}
|
||||
|
||||
class _BoardSettingListPopoverState extends State<BoardSettingListPopover> {
|
||||
BoardSettingAction? _action;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (_action != null) {
|
||||
switch (_action!) {
|
||||
case BoardSettingAction.groups:
|
||||
return GridGroupList(
|
||||
viewId: widget.settingContext.viewId,
|
||||
fieldController: widget.settingContext.fieldController,
|
||||
onDismissed: () {
|
||||
widget.popoverController.close();
|
||||
},
|
||||
);
|
||||
case BoardSettingAction.properties:
|
||||
return GridPropertyList(
|
||||
viewId: widget.settingContext.viewId,
|
||||
fieldController: widget.settingContext.fieldController,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return BoardSettingList(
|
||||
settingContext: widget.settingContext,
|
||||
onAction: (action, settingContext) {
|
||||
setState(() => _action = action);
|
||||
},
|
||||
).padding(all: 6.0);
|
||||
}
|
||||
}
|
@ -1,28 +1,10 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/layout/sizes.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:appflowy/plugins/database_view/board/application/board_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/setting/setting_button.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'board_setting.dart';
|
||||
|
||||
class BoardToolbarContext {
|
||||
final String viewId;
|
||||
final FieldController fieldController;
|
||||
|
||||
BoardToolbarContext({
|
||||
required this.viewId,
|
||||
required this.fieldController,
|
||||
});
|
||||
}
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class BoardToolbar extends StatelessWidget {
|
||||
final BoardToolbarContext toolbarContext;
|
||||
const BoardToolbar({
|
||||
required this.toolbarContext,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@ -33,58 +15,11 @@ class BoardToolbar extends StatelessWidget {
|
||||
child: Row(
|
||||
children: [
|
||||
const Spacer(),
|
||||
_SettingButton(
|
||||
settingContext: BoardSettingContext.from(toolbarContext),
|
||||
SettingButton(
|
||||
databaseController: context.read<BoardBloc>().databaseController,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _SettingButton extends StatefulWidget {
|
||||
final BoardSettingContext settingContext;
|
||||
const _SettingButton({required this.settingContext, Key? key})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
State<_SettingButton> createState() => _SettingButtonState();
|
||||
}
|
||||
|
||||
class _SettingButtonState extends State<_SettingButton> {
|
||||
late PopoverController popoverController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
popoverController = PopoverController();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AppFlowyPopover(
|
||||
controller: popoverController,
|
||||
direction: PopoverDirection.leftWithTopAligned,
|
||||
offset: const Offset(-8, 0),
|
||||
triggerActions: PopoverTriggerFlags.none,
|
||||
constraints: BoxConstraints.loose(const Size(260, 400)),
|
||||
margin: EdgeInsets.zero,
|
||||
child: FlowyTextButton(
|
||||
LocaleKeys.settings_title.tr(),
|
||||
fontColor: AFThemeExtension.of(context).textColor,
|
||||
fillColor: Colors.transparent,
|
||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||
padding: GridSize.typeOptionContentInsets,
|
||||
onPressed: () {
|
||||
popoverController.show();
|
||||
},
|
||||
),
|
||||
popupBuilder: (BuildContext popoverContext) {
|
||||
return BoardSettingListPopover(
|
||||
settingContext: widget.settingContext,
|
||||
popoverController: popoverController,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -18,20 +18,17 @@ import '../../application/row/row_cache.dart';
|
||||
part 'calendar_bloc.freezed.dart';
|
||||
|
||||
class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
||||
final DatabaseController _databaseController;
|
||||
final DatabaseController databaseController;
|
||||
Map<String, FieldInfo> fieldInfoByFieldId = {};
|
||||
|
||||
// Getters
|
||||
String get viewId => _databaseController.viewId;
|
||||
FieldController get fieldController => _databaseController.fieldController;
|
||||
CellCache get cellCache => _databaseController.rowCache.cellCache;
|
||||
RowCache get rowCache => _databaseController.rowCache;
|
||||
String get viewId => databaseController.viewId;
|
||||
FieldController get fieldController => databaseController.fieldController;
|
||||
CellCache get cellCache => databaseController.rowCache.cellCache;
|
||||
RowCache get rowCache => databaseController.rowCache;
|
||||
|
||||
CalendarBloc({required ViewPB view})
|
||||
: _databaseController = DatabaseController(
|
||||
view: view,
|
||||
layoutType: DatabaseLayoutPB.Calendar,
|
||||
),
|
||||
: databaseController = DatabaseController(view: view),
|
||||
super(CalendarState.initial()) {
|
||||
on<CalendarEvent>(
|
||||
(event, emit) async {
|
||||
@ -110,12 +107,12 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _databaseController.dispose();
|
||||
await databaseController.dispose();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
FieldInfo? _getCalendarFieldInfo(String fieldId) {
|
||||
final fieldInfos = _databaseController.fieldController.fieldInfos;
|
||||
final fieldInfos = databaseController.fieldController.fieldInfos;
|
||||
final index = fieldInfos.indexWhere(
|
||||
(element) => element.field.id == fieldId,
|
||||
);
|
||||
@ -127,7 +124,7 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
||||
}
|
||||
|
||||
FieldInfo? _getTitleFieldInfo() {
|
||||
final fieldInfos = _databaseController.fieldController.fieldInfos;
|
||||
final fieldInfos = databaseController.fieldController.fieldInfos;
|
||||
final index = fieldInfos.indexWhere(
|
||||
(element) => element.field.isPrimary,
|
||||
);
|
||||
@ -139,7 +136,7 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
||||
}
|
||||
|
||||
Future<void> _openDatabase(Emitter<CalendarState> emit) async {
|
||||
final result = await _databaseController.open();
|
||||
final result = await databaseController.open();
|
||||
result.fold(
|
||||
(database) => emit(
|
||||
state.copyWith(loadingState: DatabaseLoadingState.finish(left(unit))),
|
||||
@ -157,7 +154,7 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
||||
final dateField = _getCalendarFieldInfo(settings.fieldId);
|
||||
final titleField = _getTitleFieldInfo();
|
||||
if (dateField != null && titleField != null) {
|
||||
final newRow = await _databaseController.createRow(
|
||||
final newRow = await databaseController.createRow(
|
||||
withCells: (builder) {
|
||||
builder.insertDate(dateField, date);
|
||||
builder.insertText(titleField, title);
|
||||
@ -210,7 +207,7 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
||||
Future<void> _updateCalendarLayoutSetting(
|
||||
CalendarLayoutSettingPB layoutSetting,
|
||||
) async {
|
||||
return _databaseController.updateCalenderLayoutSetting(layoutSetting);
|
||||
return databaseController.updateCalenderLayoutSetting(layoutSetting);
|
||||
}
|
||||
|
||||
Future<CalendarEventData<CalendarDayEvent>?> _loadEvent(RowId rowId) async {
|
||||
@ -331,7 +328,7 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
||||
},
|
||||
);
|
||||
|
||||
final onLayoutChanged = LayoutCallbacks(
|
||||
final onLayoutChanged = DatabaseLayoutSettingCallbacks(
|
||||
onLayoutChanged: _didReceiveLayoutSetting,
|
||||
onLoadLayout: _didReceiveLayoutSetting,
|
||||
);
|
||||
@ -340,14 +337,14 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
||||
onCalendarLayoutChanged: _didReceiveNewLayoutField,
|
||||
);
|
||||
|
||||
_databaseController.setListener(
|
||||
databaseController.setListener(
|
||||
onDatabaseChanged: onDatabaseChanged,
|
||||
onLayoutChanged: onLayoutChanged,
|
||||
onCalendarLayoutChanged: onCalendarLayoutFieldChanged,
|
||||
);
|
||||
}
|
||||
|
||||
void _didReceiveLayoutSetting(LayoutSettingPB layoutSetting) {
|
||||
void _didReceiveLayoutSetting(DatabaseLayoutSettingPB layoutSetting) {
|
||||
if (layoutSetting.hasCalendar()) {
|
||||
if (isClosed) {
|
||||
return;
|
||||
@ -356,7 +353,7 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
||||
}
|
||||
}
|
||||
|
||||
void _didReceiveNewLayoutField(LayoutSettingPB layoutSetting) {
|
||||
void _didReceiveNewLayoutField(DatabaseLayoutSettingPB layoutSetting) {
|
||||
if (layoutSetting.hasCalendar()) {
|
||||
if (isClosed) return;
|
||||
add(CalendarEvent.didReceiveNewLayoutField(layoutSetting.calendar));
|
||||
|
@ -49,18 +49,19 @@ class CalendarPlugin extends Plugin {
|
||||
notifier = ViewPluginNotifier(view: view);
|
||||
|
||||
@override
|
||||
PluginDisplay get display => CalendarPluginDisplay(notifier: notifier);
|
||||
PluginWidgetBuilder get widgetBuilder =>
|
||||
CalendarPluginWidgetBuilder(notifier: notifier);
|
||||
|
||||
@override
|
||||
PluginId get id => notifier.view.id;
|
||||
|
||||
@override
|
||||
PluginType get ty => _pluginType;
|
||||
PluginType get pluginType => _pluginType;
|
||||
}
|
||||
|
||||
class CalendarPluginDisplay extends PluginDisplay {
|
||||
class CalendarPluginWidgetBuilder extends PluginWidgetBuilder {
|
||||
final ViewPluginNotifier notifier;
|
||||
CalendarPluginDisplay({required this.notifier, Key? key});
|
||||
CalendarPluginWidgetBuilder({required this.notifier, Key? key});
|
||||
|
||||
ViewPB get view => notifier.view;
|
||||
|
||||
|
@ -2,7 +2,7 @@ import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
|
||||
import 'package:appflowy/plugins/database_view/calendar/application/calendar_setting_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/layout/sizes.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/toolbar/grid_property.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/field/grid_property.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
@ -41,7 +41,7 @@ class CalendarSetting extends StatelessWidget {
|
||||
state.selectedAction.foldLeft(null, (previous, action) => action);
|
||||
switch (action) {
|
||||
case CalendarSettingAction.properties:
|
||||
return GridPropertyList(
|
||||
return DatabasePropertyList(
|
||||
viewId: settingContext.viewId,
|
||||
fieldController: settingContext.fieldController,
|
||||
);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/calendar/presentation/calendar_page.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/layout/sizes.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/setting/setting_button.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:calendar_view/calendar_view.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
@ -17,13 +18,15 @@ class CalendarToolbar extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const SizedBox(
|
||||
return SizedBox(
|
||||
height: 40,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
_UnscheduleEventsButton(),
|
||||
_SettingButton(),
|
||||
const _UnscheduleEventsButton(),
|
||||
SettingButton(
|
||||
databaseController: context.read<CalendarBloc>().databaseController,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
@ -115,12 +118,16 @@ class _UnscheduleEventsButtonState extends State<_UnscheduleEventsButton> {
|
||||
),
|
||||
popupBuilder: (context) {
|
||||
final cells = <Widget>[
|
||||
FlowyText.medium(
|
||||
LocaleKeys.calendar_settings_noDateHint.tr(),
|
||||
color: Theme.of(context).hintColor,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4),
|
||||
child: FlowyText.medium(
|
||||
// LocaleKeys.calendar_settings_noDateHint.tr(),
|
||||
LocaleKeys.calendar_settings_clickToAdd.tr(),
|
||||
color: Theme.of(context).hintColor,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
const VSpace(10),
|
||||
const VSpace(6),
|
||||
...unscheduledEvents.map(
|
||||
(e) => _UnscheduledEventItem(
|
||||
event: e,
|
||||
@ -164,7 +171,11 @@ class _UnscheduledEventItem extends StatelessWidget {
|
||||
return SizedBox(
|
||||
height: GridSize.popoverItemHeight,
|
||||
child: FlowyButton(
|
||||
text: FlowyText.medium(event.title),
|
||||
text: FlowyText.medium(
|
||||
event.title.isEmpty
|
||||
? LocaleKeys.calendar_defaultNewCalendarTitle.tr()
|
||||
: event.title,
|
||||
),
|
||||
onTap: onPressed,
|
||||
),
|
||||
);
|
||||
|
@ -0,0 +1,54 @@
|
||||
import 'package:appflowy/startup/plugin/plugin.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_ext.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_listener.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||
import '../../workspace/presentation/home/home_stack.dart';
|
||||
|
||||
/// [DatabaseViewPlugin] is used to build the grid, calendar, and board.
|
||||
/// It is a wrapper of the [Plugin] class. The underlying [Plugin] is
|
||||
/// determined by the [ViewPB.pluginType] field.
|
||||
///
|
||||
class DatabaseViewPlugin extends Plugin {
|
||||
final ViewListener _viewListener;
|
||||
ViewPB _view;
|
||||
Plugin _innerPlugin;
|
||||
|
||||
DatabaseViewPlugin({
|
||||
required ViewPB view,
|
||||
}) : _view = view,
|
||||
_innerPlugin = _makeInnerPlugin(view),
|
||||
_viewListener = ViewListener(view: view) {
|
||||
_listenOnLayoutChanged();
|
||||
}
|
||||
|
||||
@override
|
||||
PluginId get id => _innerPlugin.id;
|
||||
|
||||
@override
|
||||
PluginType get pluginType => _innerPlugin.pluginType;
|
||||
|
||||
@override
|
||||
PluginWidgetBuilder get widgetBuilder => _innerPlugin.widgetBuilder;
|
||||
|
||||
void _listenOnLayoutChanged() {
|
||||
_viewListener.start(
|
||||
onViewUpdated: (result) {
|
||||
result.fold(
|
||||
(updatedView) {
|
||||
if (_view.layout != updatedView.layout) {
|
||||
_innerPlugin = _makeInnerPlugin(updatedView);
|
||||
getIt<HomeStackManager>().setPlugin(_innerPlugin);
|
||||
}
|
||||
_view = updatedView;
|
||||
},
|
||||
(r) => null,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Plugin _makeInnerPlugin(ViewPB view) {
|
||||
return makePlugin(pluginType: view.pluginType, data: view);
|
||||
}
|
@ -87,7 +87,7 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
||||
add(GridEvent.didReceiveGridUpdate(database));
|
||||
}
|
||||
},
|
||||
onRowsChanged: (rowInfos, _, reason) {
|
||||
onNumOfRowsChanged: (rowInfos, _, reason) {
|
||||
if (!isClosed) {
|
||||
add(GridEvent.didReceiveRowUpdate(rowInfos, reason));
|
||||
}
|
||||
|
@ -49,20 +49,21 @@ class GridPlugin extends Plugin {
|
||||
notifier = ViewPluginNotifier(view: view);
|
||||
|
||||
@override
|
||||
PluginDisplay get display => GridPluginDisplay(notifier: notifier);
|
||||
PluginWidgetBuilder get widgetBuilder =>
|
||||
GridPluginWidgetBuilder(notifier: notifier);
|
||||
|
||||
@override
|
||||
PluginId get id => notifier.view.id;
|
||||
|
||||
@override
|
||||
PluginType get ty => _pluginType;
|
||||
PluginType get pluginType => _pluginType;
|
||||
}
|
||||
|
||||
class GridPluginDisplay extends PluginDisplay {
|
||||
class GridPluginWidgetBuilder extends PluginWidgetBuilder {
|
||||
final ViewPluginNotifier notifier;
|
||||
ViewPB get view => notifier.view;
|
||||
|
||||
GridPluginDisplay({required this.notifier, Key? key});
|
||||
GridPluginWidgetBuilder({required this.notifier, Key? key});
|
||||
|
||||
@override
|
||||
Widget get leftBarItem => ViewLeftBarItem(view: view);
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/row/cell_builder.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/setting_entities.pbenum.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui_web.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
||||
@ -36,10 +35,7 @@ class GridPage extends StatefulWidget {
|
||||
required this.view,
|
||||
this.onDeleted,
|
||||
Key? key,
|
||||
}) : databaseController = DatabaseController(
|
||||
view: view,
|
||||
layoutType: DatabaseLayoutPB.Grid,
|
||||
),
|
||||
}) : databaseController = DatabaseController(view: view),
|
||||
super(key: key);
|
||||
|
||||
final ViewPB view;
|
||||
|
@ -0,0 +1,133 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/layout/layout_bloc.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/setting_entities.pb.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
import '../../layout/sizes.dart';
|
||||
|
||||
class DatabaseLayoutList extends StatefulWidget {
|
||||
final String viewId;
|
||||
final DatabaseLayoutPB currentLayout;
|
||||
const DatabaseLayoutList({
|
||||
required this.viewId,
|
||||
required this.currentLayout,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _DatabaseLayoutListState();
|
||||
}
|
||||
|
||||
class _DatabaseLayoutListState extends State<DatabaseLayoutList> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => DatabaseLayoutBloc(
|
||||
viewId: widget.viewId,
|
||||
databaseLayout: widget.currentLayout,
|
||||
)..add(const DatabaseLayoutEvent.initial()),
|
||||
child: BlocBuilder<DatabaseLayoutBloc, DatabaseLayoutState>(
|
||||
builder: (context, state) {
|
||||
final cells = DatabaseLayoutPB.values.map((layout) {
|
||||
final isSelected = state.databaseLayout == layout;
|
||||
return DatabaseViewLayoutCell(
|
||||
databaseLayout: layout,
|
||||
isSelected: isSelected,
|
||||
onTap: (selectedLayout) {
|
||||
context
|
||||
.read<DatabaseLayoutBloc>()
|
||||
.add(DatabaseLayoutEvent.updateLayout(selectedLayout));
|
||||
},
|
||||
);
|
||||
}).toList();
|
||||
|
||||
return ListView.separated(
|
||||
controller: ScrollController(),
|
||||
shrinkWrap: true,
|
||||
itemCount: cells.length,
|
||||
itemBuilder: (BuildContext context, int index) => cells[index],
|
||||
separatorBuilder: (BuildContext context, int index) =>
|
||||
VSpace(GridSize.typeOptionSeparatorHeight),
|
||||
padding: const EdgeInsets.symmetric(vertical: 6.0),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension DatabaseLayoutExtension on DatabaseLayoutPB {
|
||||
String layoutName() {
|
||||
switch (this) {
|
||||
case DatabaseLayoutPB.Board:
|
||||
return LocaleKeys.board_menuName.tr();
|
||||
case DatabaseLayoutPB.Calendar:
|
||||
return LocaleKeys.calendar_menuName.tr();
|
||||
case DatabaseLayoutPB.Grid:
|
||||
return LocaleKeys.grid_menuName.tr();
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
String iconName() {
|
||||
switch (this) {
|
||||
case DatabaseLayoutPB.Board:
|
||||
return 'editor/board';
|
||||
case DatabaseLayoutPB.Calendar:
|
||||
return "editor/grid";
|
||||
case DatabaseLayoutPB.Grid:
|
||||
return "editor/grid";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DatabaseViewLayoutCell extends StatelessWidget {
|
||||
final bool isSelected;
|
||||
final DatabaseLayoutPB databaseLayout;
|
||||
final void Function(DatabaseLayoutPB) onTap;
|
||||
const DatabaseViewLayoutCell({
|
||||
required this.databaseLayout,
|
||||
required this.isSelected,
|
||||
required this.onTap,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget? checkmark;
|
||||
if (isSelected) {
|
||||
checkmark = svgWidget("grid/checkmark");
|
||||
}
|
||||
|
||||
return SizedBox(
|
||||
height: GridSize.popoverItemHeight,
|
||||
child: FlowyButton(
|
||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||
text: FlowyText.medium(
|
||||
databaseLayout.layoutName(),
|
||||
color: AFThemeExtension.of(context).textColor,
|
||||
),
|
||||
leftIcon: svgWidget(
|
||||
databaseLayout.iconName(),
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
),
|
||||
rightIcon: checkmark,
|
||||
onTap: () => onTap(databaseLayout),
|
||||
).padding(horizontal: 6.0),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/database_controller.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/setting/setting_bloc.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/setting_entities.pbenum.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||
@ -9,36 +9,29 @@ import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import '../../layout/sizes.dart';
|
||||
|
||||
class GridSettingContext {
|
||||
final String viewId;
|
||||
final FieldController fieldController;
|
||||
|
||||
GridSettingContext({
|
||||
required this.viewId,
|
||||
required this.fieldController,
|
||||
});
|
||||
}
|
||||
|
||||
class GridSettingList extends StatelessWidget {
|
||||
final GridSettingContext settingContext;
|
||||
final Function(DatabaseSettingAction, GridSettingContext) onAction;
|
||||
const GridSettingList({
|
||||
required this.settingContext,
|
||||
class DatabaseSettingList extends StatelessWidget {
|
||||
final DatabaseController databaseContoller;
|
||||
final Function(DatabaseSettingAction, DatabaseController) onAction;
|
||||
const DatabaseSettingList({
|
||||
required this.databaseContoller,
|
||||
required this.onAction,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final cells = DatabaseSettingAction.values
|
||||
.where((value) => value.enable())
|
||||
.map((action) {
|
||||
final cells = DatabaseSettingAction.values.where((element) {
|
||||
if (element == DatabaseSettingAction.showGroup) {
|
||||
return databaseContoller.databaseLayout == DatabaseLayoutPB.Board;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}).map((action) {
|
||||
return _SettingItem(
|
||||
action: action,
|
||||
onAction: (action) => onAction(action, settingContext),
|
||||
onAction: (action) => onAction(action, databaseContoller),
|
||||
);
|
||||
}).toList();
|
||||
|
||||
@ -78,9 +71,7 @@ class _SettingItem extends StatelessWidget {
|
||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||
text: FlowyText.medium(
|
||||
action.title(),
|
||||
color: action.enable()
|
||||
? AFThemeExtension.of(context).textColor
|
||||
: Theme.of(context).disabledColor,
|
||||
color: AFThemeExtension.of(context).textColor,
|
||||
),
|
||||
onTap: () => onAction(action),
|
||||
leftIcon: svgWidget(
|
||||
@ -91,36 +82,3 @@ class _SettingItem extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension _GridSettingExtension on DatabaseSettingAction {
|
||||
String iconName() {
|
||||
switch (this) {
|
||||
case DatabaseSettingAction.showFilters:
|
||||
return 'grid/setting/filter';
|
||||
case DatabaseSettingAction.sortBy:
|
||||
return 'grid/setting/sort';
|
||||
case DatabaseSettingAction.showProperties:
|
||||
return 'grid/setting/properties';
|
||||
}
|
||||
}
|
||||
|
||||
String title() {
|
||||
switch (this) {
|
||||
case DatabaseSettingAction.showFilters:
|
||||
return LocaleKeys.grid_settings_filter.tr();
|
||||
case DatabaseSettingAction.sortBy:
|
||||
return LocaleKeys.grid_settings_sortBy.tr();
|
||||
case DatabaseSettingAction.showProperties:
|
||||
return LocaleKeys.grid_settings_Properties.tr();
|
||||
}
|
||||
}
|
||||
|
||||
bool enable() {
|
||||
switch (this) {
|
||||
case DatabaseSettingAction.showProperties:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/application/grid_bloc.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../../layout/sizes.dart';
|
||||
import 'filter_button.dart';
|
||||
import 'setting_button.dart';
|
||||
import '../../../../widgets/setting/setting_button.dart';
|
||||
import 'sort_button.dart';
|
||||
|
||||
class GridToolbarContext {
|
||||
@ -29,7 +31,9 @@ class GridToolbar extends StatelessWidget {
|
||||
const Spacer(),
|
||||
const FilterButton(),
|
||||
const SortButton(),
|
||||
const SettingButton(),
|
||||
SettingButton(
|
||||
databaseController: context.read<GridBloc>().databaseController,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -1,102 +0,0 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/setting/setting_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/application/grid_bloc.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:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
import '../../layout/sizes.dart';
|
||||
import 'grid_property.dart';
|
||||
import 'grid_setting.dart';
|
||||
|
||||
class SettingButton extends StatefulWidget {
|
||||
const SettingButton({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<SettingButton> createState() => _SettingButtonState();
|
||||
}
|
||||
|
||||
class _SettingButtonState extends State<SettingButton> {
|
||||
late PopoverController _popoverController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_popoverController = PopoverController();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocSelector<GridBloc, GridState, GridSettingContext>(
|
||||
selector: (state) {
|
||||
final fieldController =
|
||||
context.read<GridBloc>().databaseController.fieldController;
|
||||
return GridSettingContext(
|
||||
viewId: state.viewId,
|
||||
fieldController: fieldController,
|
||||
);
|
||||
},
|
||||
builder: (context, settingContext) {
|
||||
return SizedBox(
|
||||
height: 26,
|
||||
child: AppFlowyPopover(
|
||||
controller: _popoverController,
|
||||
constraints: BoxConstraints.loose(const Size(260, 400)),
|
||||
direction: PopoverDirection.bottomWithLeftAligned,
|
||||
offset: const Offset(0, 8),
|
||||
margin: EdgeInsets.zero,
|
||||
triggerActions: PopoverTriggerFlags.none,
|
||||
child: FlowyTextButton(
|
||||
LocaleKeys.settings_title.tr(),
|
||||
fontColor: AFThemeExtension.of(context).textColor,
|
||||
fillColor: Colors.transparent,
|
||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||
padding: GridSize.typeOptionContentInsets,
|
||||
onPressed: () => _popoverController.show(),
|
||||
),
|
||||
popupBuilder: (BuildContext context) {
|
||||
return _GridSettingListPopover(settingContext: settingContext);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _GridSettingListPopover extends StatefulWidget {
|
||||
final GridSettingContext settingContext;
|
||||
|
||||
const _GridSettingListPopover({Key? key, required this.settingContext})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _GridSettingListPopoverState();
|
||||
}
|
||||
|
||||
class _GridSettingListPopoverState extends State<_GridSettingListPopover> {
|
||||
DatabaseSettingAction? _action;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (_action == DatabaseSettingAction.showProperties) {
|
||||
return GridPropertyList(
|
||||
viewId: widget.settingContext.viewId,
|
||||
fieldController: widget.settingContext.fieldController,
|
||||
);
|
||||
}
|
||||
|
||||
return GridSettingList(
|
||||
settingContext: widget.settingContext,
|
||||
onAction: (action, settingContext) {
|
||||
setState(() {
|
||||
_action = action;
|
||||
});
|
||||
},
|
||||
).padding(all: 6.0);
|
||||
}
|
||||
}
|
@ -11,23 +11,23 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
import '../../layout/sizes.dart';
|
||||
import '../header/field_editor.dart';
|
||||
import '../../grid/presentation/layout/sizes.dart';
|
||||
import '../../grid/presentation/widgets/header/field_editor.dart';
|
||||
|
||||
class GridPropertyList extends StatefulWidget {
|
||||
class DatabasePropertyList extends StatefulWidget {
|
||||
final String viewId;
|
||||
final FieldController fieldController;
|
||||
const GridPropertyList({
|
||||
const DatabasePropertyList({
|
||||
required this.viewId,
|
||||
required this.fieldController,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _GridPropertyListState();
|
||||
State<StatefulWidget> createState() => _DatabasePropertyListState();
|
||||
}
|
||||
|
||||
class _GridPropertyListState extends State<GridPropertyList> {
|
||||
class _DatabasePropertyListState extends State<DatabasePropertyList> {
|
||||
late PopoverMutex _popoverMutex;
|
||||
|
||||
@override
|
@ -11,11 +11,11 @@ import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class GridGroupList extends StatelessWidget {
|
||||
class DatabaseGroupList extends StatelessWidget {
|
||||
final String viewId;
|
||||
final FieldController fieldController;
|
||||
final VoidCallback onDismissed;
|
||||
const GridGroupList({
|
||||
const DatabaseGroupList({
|
||||
required this.viewId,
|
||||
required this.fieldController,
|
||||
required this.onDismissed,
|
@ -0,0 +1,116 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/database_controller.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/setting/setting_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/group/database_group.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:flutter/material.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
import '../../grid/presentation/layout/sizes.dart';
|
||||
import '../../grid/presentation/widgets/toolbar/grid_layout.dart';
|
||||
import '../field/grid_property.dart';
|
||||
import '../../grid/presentation/widgets/toolbar/grid_setting.dart';
|
||||
|
||||
class SettingButton extends StatefulWidget {
|
||||
final DatabaseController databaseController;
|
||||
const SettingButton({
|
||||
required this.databaseController,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<SettingButton> createState() => _SettingButtonState();
|
||||
}
|
||||
|
||||
class _SettingButtonState extends State<SettingButton> {
|
||||
late PopoverController _popoverController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_popoverController = PopoverController();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: 26,
|
||||
child: AppFlowyPopover(
|
||||
controller: _popoverController,
|
||||
constraints: BoxConstraints.loose(const Size(200, 400)),
|
||||
direction: PopoverDirection.bottomWithLeftAligned,
|
||||
offset: const Offset(0, 8),
|
||||
margin: EdgeInsets.zero,
|
||||
triggerActions: PopoverTriggerFlags.none,
|
||||
child: FlowyTextButton(
|
||||
LocaleKeys.settings_title.tr(),
|
||||
fontColor: AFThemeExtension.of(context).textColor,
|
||||
fillColor: Colors.transparent,
|
||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||
padding: GridSize.typeOptionContentInsets,
|
||||
onPressed: () => _popoverController.show(),
|
||||
),
|
||||
popupBuilder: (BuildContext context) {
|
||||
return _DatabaseSettingListPopover(
|
||||
databaseController: widget.databaseController,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _DatabaseSettingListPopover extends StatefulWidget {
|
||||
final DatabaseController databaseController;
|
||||
|
||||
const _DatabaseSettingListPopover({
|
||||
required this.databaseController,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _DatabaseSettingListPopoverState();
|
||||
}
|
||||
|
||||
class _DatabaseSettingListPopoverState
|
||||
extends State<_DatabaseSettingListPopover> {
|
||||
DatabaseSettingAction? _action;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (_action == null) {
|
||||
return DatabaseSettingList(
|
||||
databaseContoller: widget.databaseController,
|
||||
onAction: (action, settingContext) {
|
||||
setState(() {
|
||||
_action = action;
|
||||
});
|
||||
},
|
||||
).padding(all: 6.0);
|
||||
} else {
|
||||
switch (_action!) {
|
||||
case DatabaseSettingAction.showLayout:
|
||||
return DatabaseLayoutList(
|
||||
viewId: widget.databaseController.viewId,
|
||||
currentLayout: widget.databaseController.databaseLayout!,
|
||||
);
|
||||
case DatabaseSettingAction.showGroup:
|
||||
return DatabaseGroupList(
|
||||
viewId: widget.databaseController.viewId,
|
||||
fieldController: widget.databaseController.fieldController,
|
||||
onDismissed: () {
|
||||
// widget.popoverController.close();
|
||||
},
|
||||
);
|
||||
case DatabaseSettingAction.showProperties:
|
||||
return DatabasePropertyList(
|
||||
viewId: widget.databaseController.viewId,
|
||||
fieldController: widget.databaseController.fieldController,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user