mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: add require_trailing_commas to analysis_options.ymal. (#2227)
This commit is contained in:
parent
4d56b42b83
commit
aac5c2a4da
3
.github/workflows/flutter_ci.yaml
vendored
3
.github/workflows/flutter_ci.yaml
vendored
@ -99,7 +99,8 @@ jobs:
|
||||
|
||||
- name: Flutter Analyzer
|
||||
working-directory: frontend/appflowy_flutter
|
||||
run: flutter analyze
|
||||
run: |
|
||||
flutter analyze .
|
||||
|
||||
- name: Run Flutter unit tests
|
||||
working-directory: frontend
|
||||
|
@ -14,9 +14,7 @@ analyzer:
|
||||
exclude:
|
||||
- "**/*.g.dart"
|
||||
- "**/*.freezed.dart"
|
||||
- "packages/appflowy_editor/**"
|
||||
- "packages/editor/**"
|
||||
# - "packages/flowy_infra_ui/**"
|
||||
|
||||
linter:
|
||||
# The lint rules applied to this project can be customized in the
|
||||
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
||||
@ -30,8 +28,7 @@ linter:
|
||||
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
||||
# producing the lint.
|
||||
rules:
|
||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
||||
- require_trailing_commas
|
||||
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
|
@ -35,7 +35,9 @@ void main() {
|
||||
setUpAll(() async => await service.setUpAll());
|
||||
setUp(() async => await service.setUp());
|
||||
|
||||
testWidgets('integration test unzips the proper workspace and loads it correctly.', (tester) async {
|
||||
testWidgets(
|
||||
'integration test unzips the proper workspace and loads it correctly.',
|
||||
(tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
expect(find.byType(AppFlowyBoard), findsOneWidget);
|
||||
});
|
||||
|
@ -31,7 +31,8 @@ void main() {
|
||||
setUpAll(() async => await service.setUpAll());
|
||||
setUp(() async => await service.setUp());
|
||||
|
||||
testWidgets('/board shortcut creates a new board and view of the board', (tester) async {
|
||||
testWidgets('/board shortcut creates a new board and view of the board',
|
||||
(tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
|
||||
// Needs tab to obtain focus for the app flowy editor.
|
||||
@ -44,24 +45,30 @@ void main() {
|
||||
// does not contain any EditableText widgets.
|
||||
// to interact with the app during an integration test,
|
||||
// simulate physical keyboard events.
|
||||
await FlowyTestKeyboard.simulateKeyDownEvent([
|
||||
LogicalKeyboardKey.slash,
|
||||
LogicalKeyboardKey.keyB,
|
||||
LogicalKeyboardKey.keyO,
|
||||
LogicalKeyboardKey.keyA,
|
||||
LogicalKeyboardKey.keyR,
|
||||
LogicalKeyboardKey.keyD,
|
||||
LogicalKeyboardKey.arrowDown,
|
||||
], tester: tester);
|
||||
await FlowyTestKeyboard.simulateKeyDownEvent(
|
||||
[
|
||||
LogicalKeyboardKey.slash,
|
||||
LogicalKeyboardKey.keyB,
|
||||
LogicalKeyboardKey.keyO,
|
||||
LogicalKeyboardKey.keyA,
|
||||
LogicalKeyboardKey.keyR,
|
||||
LogicalKeyboardKey.keyD,
|
||||
LogicalKeyboardKey.arrowDown,
|
||||
],
|
||||
tester: tester,
|
||||
);
|
||||
|
||||
// Checks whether the options in the selection menu
|
||||
// for /board exist.
|
||||
expect(find.byType(SelectionMenuItemWidget), findsAtLeastNWidgets(2));
|
||||
|
||||
// Finalizes the slash command that creates the board.
|
||||
await FlowyTestKeyboard.simulateKeyDownEvent([
|
||||
LogicalKeyboardKey.enter,
|
||||
], tester: tester);
|
||||
await FlowyTestKeyboard.simulateKeyDownEvent(
|
||||
[
|
||||
LogicalKeyboardKey.enter,
|
||||
],
|
||||
tester: tester,
|
||||
);
|
||||
|
||||
// Checks whether new board is referenced and properly on the page.
|
||||
expect(find.byType(BuiltInPageWidget), findsOneWidget);
|
||||
@ -75,7 +82,8 @@ void main() {
|
||||
expect(find.text(viewOfBoardLabel), findsNWidgets(2));
|
||||
});
|
||||
|
||||
testWidgets('/grid shortcut creates a new grid and view of the grid', (tester) async {
|
||||
testWidgets('/grid shortcut creates a new grid and view of the grid',
|
||||
(tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
|
||||
// Needs tab to obtain focus for the app flowy editor.
|
||||
@ -88,14 +96,17 @@ void main() {
|
||||
// does not contain any EditableText widgets.
|
||||
// to interact with the app during an integration test,
|
||||
// simulate physical keyboard events.
|
||||
await FlowyTestKeyboard.simulateKeyDownEvent([
|
||||
LogicalKeyboardKey.slash,
|
||||
LogicalKeyboardKey.keyG,
|
||||
LogicalKeyboardKey.keyR,
|
||||
LogicalKeyboardKey.keyI,
|
||||
LogicalKeyboardKey.keyD,
|
||||
LogicalKeyboardKey.arrowDown,
|
||||
], tester: tester);
|
||||
await FlowyTestKeyboard.simulateKeyDownEvent(
|
||||
[
|
||||
LogicalKeyboardKey.slash,
|
||||
LogicalKeyboardKey.keyG,
|
||||
LogicalKeyboardKey.keyR,
|
||||
LogicalKeyboardKey.keyI,
|
||||
LogicalKeyboardKey.keyD,
|
||||
LogicalKeyboardKey.arrowDown,
|
||||
],
|
||||
tester: tester,
|
||||
);
|
||||
|
||||
// Checks whether the options in the selection menu
|
||||
// for /grid exist.
|
||||
|
@ -61,6 +61,8 @@ class TestWorkspaceService {
|
||||
InputFileStream(await workspace.zip.then((value) => value.path));
|
||||
final archive = ZipDecoder().decodeBuffer(inputStream);
|
||||
extractArchiveToDisk(
|
||||
archive, await TestWorkspace._parent.then((value) => value.path));
|
||||
archive,
|
||||
await TestWorkspace._parent.then((value) => value.path),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,10 @@ import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart' as flutter_test;
|
||||
|
||||
class FlowyTestKeyboard {
|
||||
static Future<void> simulateKeyDownEvent(List<LogicalKeyboardKey> keys,
|
||||
{required flutter_test.WidgetTester tester}) async {
|
||||
static Future<void> simulateKeyDownEvent(
|
||||
List<LogicalKeyboardKey> keys, {
|
||||
required flutter_test.WidgetTester tester,
|
||||
}) async {
|
||||
for (final LogicalKeyboardKey key in keys) {
|
||||
await flutter_test.simulateKeyDownEvent(key);
|
||||
await tester.pumpAndSettle();
|
||||
|
@ -16,9 +16,10 @@ typedef FolderNotificationCallback = void Function(
|
||||
|
||||
class FolderNotificationParser
|
||||
extends NotificationParser<FolderNotification, FlowyError> {
|
||||
FolderNotificationParser(
|
||||
{String? id, required FolderNotificationCallback callback})
|
||||
: super(
|
||||
FolderNotificationParser({
|
||||
String? id,
|
||||
required FolderNotificationCallback callback,
|
||||
}) : super(
|
||||
id: id,
|
||||
callback: callback,
|
||||
tyParser: (ty) => FolderNotification.valueOf(ty),
|
||||
|
@ -16,9 +16,10 @@ typedef DatabaseNotificationCallback = void Function(
|
||||
|
||||
class DatabaseNotificationParser
|
||||
extends NotificationParser<DatabaseNotification, FlowyError> {
|
||||
DatabaseNotificationParser(
|
||||
{String? id, required DatabaseNotificationCallback callback})
|
||||
: super(
|
||||
DatabaseNotificationParser({
|
||||
String? id,
|
||||
required DatabaseNotificationCallback callback,
|
||||
}) : super(
|
||||
id: id,
|
||||
callback: callback,
|
||||
tyParser: (ty) => DatabaseNotification.valueOf(ty),
|
||||
@ -27,7 +28,9 @@ class DatabaseNotificationParser
|
||||
}
|
||||
|
||||
typedef DatabaseNotificationHandler = Function(
|
||||
DatabaseNotification ty, Either<Uint8List, FlowyError> result);
|
||||
DatabaseNotification ty,
|
||||
Either<Uint8List, FlowyError> result,
|
||||
);
|
||||
|
||||
class DatabaseNotificationListener {
|
||||
StreamSubscription<SubscribeObject>? _subscription;
|
||||
|
@ -9,11 +9,12 @@ class NotificationParser<T, E> {
|
||||
T? Function(int) tyParser;
|
||||
E Function(Uint8List) errorParser;
|
||||
|
||||
NotificationParser(
|
||||
{this.id,
|
||||
required this.callback,
|
||||
required this.errorParser,
|
||||
required this.tyParser});
|
||||
NotificationParser({
|
||||
this.id,
|
||||
required this.callback,
|
||||
required this.errorParser,
|
||||
required this.tyParser,
|
||||
});
|
||||
void parse(SubscribeObject subject) {
|
||||
if (id != null) {
|
||||
if (subject.id != id) {
|
||||
|
@ -16,9 +16,10 @@ typedef UserNotificationCallback = void Function(
|
||||
|
||||
class UserNotificationParser
|
||||
extends NotificationParser<UserNotification, FlowyError> {
|
||||
UserNotificationParser(
|
||||
{required String id, required UserNotificationCallback callback})
|
||||
: super(
|
||||
UserNotificationParser({
|
||||
required String id,
|
||||
required UserNotificationCallback callback,
|
||||
}) : super(
|
||||
id: id,
|
||||
callback: callback,
|
||||
tyParser: (ty) => UserNotification.valueOf(ty),
|
||||
@ -27,7 +28,9 @@ class UserNotificationParser
|
||||
}
|
||||
|
||||
typedef UserNotificationHandler = Function(
|
||||
UserNotification ty, Either<Uint8List, FlowyError> result);
|
||||
UserNotification ty,
|
||||
Either<Uint8List, FlowyError> result,
|
||||
);
|
||||
|
||||
class UserNotificationListener {
|
||||
StreamSubscription<SubscribeObject>? _subscription;
|
||||
|
@ -73,28 +73,35 @@ class CellController<T, D> extends Equatable {
|
||||
/// For example:
|
||||
/// user input: 12
|
||||
/// cell display: $12
|
||||
_cellListener?.start(onCellChanged: (result) {
|
||||
result.fold(
|
||||
(_) {
|
||||
_cellCache.remove(_cacheKey);
|
||||
_loadData();
|
||||
},
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
_cellListener?.start(
|
||||
onCellChanged: (result) {
|
||||
result.fold(
|
||||
(_) {
|
||||
_cellCache.remove(_cacheKey);
|
||||
_loadData();
|
||||
},
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
/// 2.Listen on the field event and load the cell data if needed.
|
||||
_fieldListener.start(onFieldChanged: (result) {
|
||||
result.fold((fieldPB) {
|
||||
/// reloadOnFieldChanged should be true if you need to load the data when the corresponding field is changed
|
||||
/// For example:
|
||||
/// ¥12 -> $12
|
||||
if (_cellDataLoader.reloadOnFieldChanged) {
|
||||
_loadData();
|
||||
}
|
||||
_onCellFieldChanged?.call();
|
||||
}, (err) => Log.error(err));
|
||||
});
|
||||
_fieldListener.start(
|
||||
onFieldChanged: (result) {
|
||||
result.fold(
|
||||
(fieldPB) {
|
||||
/// reloadOnFieldChanged should be true if you need to load the data when the corresponding field is changed
|
||||
/// For example:
|
||||
/// ¥12 -> $12
|
||||
if (_cellDataLoader.reloadOnFieldChanged) {
|
||||
_loadData();
|
||||
}
|
||||
_onCellFieldChanged?.call();
|
||||
},
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Listen on the cell content or field changes
|
||||
@ -130,7 +137,8 @@ class CellController<T, D> extends Equatable {
|
||||
/// Return the TypeOptionPB that can be parsed into corresponding class using the [parser].
|
||||
/// [PD] is the type that the parser return.
|
||||
Future<Either<PD, FlowyError>> getTypeOption<PD, P extends TypeOptionParser>(
|
||||
P parser) {
|
||||
P parser,
|
||||
) {
|
||||
return _fieldBackendSvc
|
||||
.getFieldTypeOptionData(fieldType: fieldType)
|
||||
.then((result) {
|
||||
|
@ -19,7 +19,9 @@ class CellListener {
|
||||
void start({required void Function(UpdateFieldNotifiedValue) onCellChanged}) {
|
||||
_updateCellNotifier?.addPublishListener(onCellChanged);
|
||||
_listener = DatabaseNotificationListener(
|
||||
objectId: "$rowId:$fieldId", handler: _handler);
|
||||
objectId: "$rowId:$fieldId",
|
||||
handler: _handler,
|
||||
);
|
||||
}
|
||||
|
||||
void _handler(DatabaseNotification ty, Either<Uint8List, FlowyError> result) {
|
||||
|
@ -187,8 +187,10 @@ class DatabaseController {
|
||||
);
|
||||
}
|
||||
|
||||
Future<Either<Unit, FlowyError>> moveGroup(
|
||||
{required String fromGroupId, required String toGroupId}) {
|
||||
Future<Either<Unit, FlowyError>> moveGroup({
|
||||
required String fromGroupId,
|
||||
required String toGroupId,
|
||||
}) {
|
||||
return _databaseViewBackendSvc.moveGroup(
|
||||
fromGroupId: fromGroupId,
|
||||
toGroupId: toGroupId,
|
||||
@ -196,7 +198,8 @@ class DatabaseController {
|
||||
}
|
||||
|
||||
Future<void> updateCalenderLayoutSetting(
|
||||
CalendarLayoutSettingsPB layoutSetting) async {
|
||||
CalendarLayoutSettingsPB layoutSetting,
|
||||
) async {
|
||||
await _databaseViewBackendSvc
|
||||
.updateLayoutSetting(calendarLayoutSetting: layoutSetting)
|
||||
.then((result) {
|
||||
@ -234,16 +237,20 @@ class DatabaseController {
|
||||
}
|
||||
|
||||
void _listenOnRowsChanged() {
|
||||
final callbacks =
|
||||
DatabaseViewCallbacks(onRowsChanged: (rows, rowByRowId, reason) {
|
||||
_databaseCallbacks?.onRowsChanged?.call(rows, rowByRowId, reason);
|
||||
}, onRowsDeleted: (ids) {
|
||||
_databaseCallbacks?.onRowsDeleted?.call(ids);
|
||||
}, onRowsUpdated: (ids) {
|
||||
_databaseCallbacks?.onRowsUpdated?.call(ids);
|
||||
}, onRowsCreated: (ids) {
|
||||
_databaseCallbacks?.onRowsCreated?.call(ids);
|
||||
});
|
||||
final callbacks = DatabaseViewCallbacks(
|
||||
onRowsChanged: (rows, rowByRowId, reason) {
|
||||
_databaseCallbacks?.onRowsChanged?.call(rows, rowByRowId, reason);
|
||||
},
|
||||
onRowsDeleted: (ids) {
|
||||
_databaseCallbacks?.onRowsDeleted?.call(ids);
|
||||
},
|
||||
onRowsUpdated: (ids) {
|
||||
_databaseCallbacks?.onRowsUpdated?.call(ids);
|
||||
},
|
||||
onRowsCreated: (ids) {
|
||||
_databaseCallbacks?.onRowsCreated?.call(ids);
|
||||
},
|
||||
);
|
||||
_viewCache.addListener(callbacks);
|
||||
}
|
||||
|
||||
@ -261,42 +268,58 @@ class DatabaseController {
|
||||
void _listenOnGroupChanged() {
|
||||
groupListener.start(
|
||||
onNumOfGroupsChanged: (result) {
|
||||
result.fold((changeset) {
|
||||
if (changeset.updateGroups.isNotEmpty) {
|
||||
_groupCallbacks?.onUpdateGroup?.call(changeset.updateGroups);
|
||||
}
|
||||
result.fold(
|
||||
(changeset) {
|
||||
if (changeset.updateGroups.isNotEmpty) {
|
||||
_groupCallbacks?.onUpdateGroup?.call(changeset.updateGroups);
|
||||
}
|
||||
|
||||
if (changeset.deletedGroups.isNotEmpty) {
|
||||
_groupCallbacks?.onDeleteGroup?.call(changeset.deletedGroups);
|
||||
}
|
||||
if (changeset.deletedGroups.isNotEmpty) {
|
||||
_groupCallbacks?.onDeleteGroup?.call(changeset.deletedGroups);
|
||||
}
|
||||
|
||||
for (final insertedGroup in changeset.insertedGroups) {
|
||||
_groupCallbacks?.onInsertGroup?.call(insertedGroup);
|
||||
}
|
||||
}, (r) => Log.error(r));
|
||||
for (final insertedGroup in changeset.insertedGroups) {
|
||||
_groupCallbacks?.onInsertGroup?.call(insertedGroup);
|
||||
}
|
||||
},
|
||||
(r) => Log.error(r),
|
||||
);
|
||||
},
|
||||
onGroupByNewField: (result) {
|
||||
result.fold((groups) {
|
||||
_groupCallbacks?.onGroupByField?.call(groups);
|
||||
}, (r) => Log.error(r));
|
||||
result.fold(
|
||||
(groups) {
|
||||
_groupCallbacks?.onGroupByField?.call(groups);
|
||||
},
|
||||
(r) => Log.error(r),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _listenOnLayoutChanged() {
|
||||
layoutListener.start(onLayoutChanged: (result) {
|
||||
result.fold((l) {
|
||||
_layoutCallbacks?.onLayoutChanged(l);
|
||||
}, (r) => Log.error(r));
|
||||
});
|
||||
layoutListener.start(
|
||||
onLayoutChanged: (result) {
|
||||
result.fold(
|
||||
(l) {
|
||||
_layoutCallbacks?.onLayoutChanged(l);
|
||||
},
|
||||
(r) => Log.error(r),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _listenOnCalendarLayoutChanged() {
|
||||
calendarLayoutListener.start(onCalendarLayoutChanged: (result) {
|
||||
result.fold((l) {
|
||||
_calendarLayoutCallbacks?.onCalendarLayoutChanged(l);
|
||||
}, (r) => Log.error(r));
|
||||
});
|
||||
calendarLayoutListener.start(
|
||||
onCalendarLayoutChanged: (result) {
|
||||
result.fold(
|
||||
(l) {
|
||||
_calendarLayoutCallbacks?.onCalendarLayoutChanged(l);
|
||||
},
|
||||
(r) => Log.error(r),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,8 +73,9 @@ class DatabaseViewBackendService {
|
||||
return DatabaseEventMoveGroup(payload).send();
|
||||
}
|
||||
|
||||
Future<Either<List<FieldPB>, FlowyError>> getFields(
|
||||
{List<FieldIdPB>? fieldIds}) {
|
||||
Future<Either<List<FieldPB>, FlowyError>> getFields({
|
||||
List<FieldIdPB>? fieldIds,
|
||||
}) {
|
||||
var payload = GetFieldPayloadPB.create()..viewId = viewId;
|
||||
|
||||
if (fieldIds != null) {
|
||||
@ -86,15 +87,17 @@ class DatabaseViewBackendService {
|
||||
}
|
||||
|
||||
Future<Either<LayoutSettingPB, FlowyError>> getLayoutSetting(
|
||||
LayoutTypePB layoutType) {
|
||||
LayoutTypePB layoutType,
|
||||
) {
|
||||
final payload = DatabaseLayoutIdPB.create()
|
||||
..viewId = viewId
|
||||
..layout = layoutType;
|
||||
return DatabaseEventGetLayoutSetting(payload).send();
|
||||
}
|
||||
|
||||
Future<Either<Unit, FlowyError>> updateLayoutSetting(
|
||||
{CalendarLayoutSettingsPB? calendarLayoutSetting}) {
|
||||
Future<Either<Unit, FlowyError>> updateLayoutSetting({
|
||||
CalendarLayoutSettingsPB? calendarLayoutSetting,
|
||||
}) {
|
||||
final layoutSetting = LayoutSettingPB.create();
|
||||
if (calendarLayoutSetting != null) {
|
||||
layoutSetting.calendar = calendarLayoutSetting;
|
||||
|
@ -17,7 +17,9 @@ class FieldCellBloc extends Bloc<FieldCellEvent, FieldCellState> {
|
||||
required FieldCellContext cellContext,
|
||||
}) : _fieldListener = SingleFieldListener(fieldId: cellContext.field.id),
|
||||
_fieldBackendSvc = FieldBackendService(
|
||||
viewId: cellContext.viewId, fieldId: cellContext.field.id),
|
||||
viewId: cellContext.viewId,
|
||||
fieldId: cellContext.field.id,
|
||||
),
|
||||
super(FieldCellState.initial(cellContext)) {
|
||||
on<FieldCellEvent>(
|
||||
(event, emit) async {
|
||||
@ -49,15 +51,17 @@ class FieldCellBloc extends Bloc<FieldCellEvent, FieldCellState> {
|
||||
}
|
||||
|
||||
void _startListening() {
|
||||
_fieldListener.start(onFieldChanged: (result) {
|
||||
if (isClosed) {
|
||||
return;
|
||||
}
|
||||
result.fold(
|
||||
(field) => add(FieldCellEvent.didReceiveFieldUpdate(field)),
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
_fieldListener.start(
|
||||
onFieldChanged: (result) {
|
||||
if (isClosed) {
|
||||
return;
|
||||
}
|
||||
result.fold(
|
||||
(field) => add(FieldCellEvent.didReceiveFieldUpdate(field)),
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,24 +255,26 @@ class FieldController {
|
||||
}
|
||||
}
|
||||
|
||||
_filtersListener.start(onFilterChanged: (result) {
|
||||
result.fold(
|
||||
(FilterChangesetNotificationPB changeset) {
|
||||
final List<FilterInfo> filters = filterInfos;
|
||||
// Deletes the filters
|
||||
deleteFilterFromChangeset(filters, changeset);
|
||||
_filtersListener.start(
|
||||
onFilterChanged: (result) {
|
||||
result.fold(
|
||||
(FilterChangesetNotificationPB changeset) {
|
||||
final List<FilterInfo> filters = filterInfos;
|
||||
// Deletes the filters
|
||||
deleteFilterFromChangeset(filters, changeset);
|
||||
|
||||
// Inserts the new filter if it's not exist
|
||||
insertFilterFromChangeset(filters, changeset);
|
||||
// Inserts the new filter if it's not exist
|
||||
insertFilterFromChangeset(filters, changeset);
|
||||
|
||||
updateFilterFromChangeset(filters, changeset);
|
||||
updateFilterFromChangeset(filters, changeset);
|
||||
|
||||
_updateFieldInfos();
|
||||
_filterNotifier?.filters = filters;
|
||||
},
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
_updateFieldInfos();
|
||||
_filterNotifier?.filters = filters;
|
||||
},
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _listenOnSortChanged() {
|
||||
@ -347,48 +349,54 @@ class FieldController {
|
||||
}
|
||||
}
|
||||
|
||||
_sortsListener.start(onSortChanged: (result) {
|
||||
result.fold(
|
||||
(SortChangesetNotificationPB changeset) {
|
||||
final List<SortInfo> newSortInfos = sortInfos;
|
||||
deleteSortFromChangeset(newSortInfos, changeset);
|
||||
insertSortFromChangeset(newSortInfos, changeset);
|
||||
updateSortFromChangeset(newSortInfos, changeset);
|
||||
_sortsListener.start(
|
||||
onSortChanged: (result) {
|
||||
result.fold(
|
||||
(SortChangesetNotificationPB changeset) {
|
||||
final List<SortInfo> newSortInfos = sortInfos;
|
||||
deleteSortFromChangeset(newSortInfos, changeset);
|
||||
insertSortFromChangeset(newSortInfos, changeset);
|
||||
updateSortFromChangeset(newSortInfos, changeset);
|
||||
|
||||
_updateFieldInfos();
|
||||
_sortNotifier?.sorts = newSortInfos;
|
||||
},
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
_updateFieldInfos();
|
||||
_sortNotifier?.sorts = newSortInfos;
|
||||
},
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _listenOnSettingChanges() {
|
||||
//Listen on setting changes
|
||||
_settingListener.start(onSettingUpdated: (result) {
|
||||
result.fold(
|
||||
(setting) => _updateSetting(setting),
|
||||
(r) => Log.error(r),
|
||||
);
|
||||
});
|
||||
_settingListener.start(
|
||||
onSettingUpdated: (result) {
|
||||
result.fold(
|
||||
(setting) => _updateSetting(setting),
|
||||
(r) => Log.error(r),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _listenOnFieldChanges() {
|
||||
//Listen on field's changes
|
||||
_fieldListener.start(onFieldsChanged: (result) {
|
||||
result.fold(
|
||||
(changeset) {
|
||||
_deleteFields(changeset.deletedFields);
|
||||
_insertFields(changeset.insertedFields);
|
||||
_fieldListener.start(
|
||||
onFieldsChanged: (result) {
|
||||
result.fold(
|
||||
(changeset) {
|
||||
_deleteFields(changeset.deletedFields);
|
||||
_insertFields(changeset.insertedFields);
|
||||
|
||||
final updatedFields = _updateFields(changeset.updatedFields);
|
||||
for (final listener in _updatedFieldCallbacks.values) {
|
||||
listener(updatedFields);
|
||||
}
|
||||
},
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
final updatedFields = _updateFields(changeset.updatedFields);
|
||||
for (final listener in _updatedFieldCallbacks.values) {
|
||||
listener(updatedFields);
|
||||
}
|
||||
},
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _updateSetting(DatabaseViewSettingPB setting) {
|
||||
|
@ -36,11 +36,13 @@ class FieldEditorBloc extends Bloc<FieldEditorEvent, FieldEditorState> {
|
||||
}
|
||||
},
|
||||
didReceiveFieldChanged: (FieldPB field) {
|
||||
emit(state.copyWith(
|
||||
field: Some(field),
|
||||
name: field.name,
|
||||
canDelete: field.isPrimary,
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
field: Some(field),
|
||||
name: field.name,
|
||||
canDelete: field.isPrimary,
|
||||
),
|
||||
);
|
||||
},
|
||||
deleteField: () {
|
||||
state.field.fold(
|
||||
|
@ -17,8 +17,9 @@ class SingleFieldListener {
|
||||
|
||||
SingleFieldListener({required this.fieldId});
|
||||
|
||||
void start(
|
||||
{required void Function(UpdateFieldNotifiedValue) onFieldChanged}) {
|
||||
void start({
|
||||
required void Function(UpdateFieldNotifiedValue) onFieldChanged,
|
||||
}) {
|
||||
_updateFieldNotifier?.addPublishListener(onFieldChanged);
|
||||
_listener = DatabaseNotificationListener(
|
||||
objectId: fieldId,
|
||||
@ -60,8 +61,9 @@ class FieldsListener {
|
||||
DatabaseNotificationListener? _listener;
|
||||
FieldsListener({required this.viewId});
|
||||
|
||||
void start(
|
||||
{required void Function(UpdateFieldsNotifiedValue) onFieldsChanged}) {
|
||||
void start({
|
||||
required void Function(UpdateFieldsNotifiedValue) onFieldsChanged,
|
||||
}) {
|
||||
updateFieldsNotifier?.addPublishListener(onFieldsChanged);
|
||||
_listener = DatabaseNotificationListener(
|
||||
objectId: viewId,
|
||||
|
@ -15,16 +15,25 @@ class DateTypeOptionBloc
|
||||
(event, emit) async {
|
||||
event.map(
|
||||
didSelectDateFormat: (_DidSelectDateFormat value) {
|
||||
emit(state.copyWith(
|
||||
typeOption: _updateTypeOption(dateFormat: value.format)));
|
||||
emit(
|
||||
state.copyWith(
|
||||
typeOption: _updateTypeOption(dateFormat: value.format),
|
||||
),
|
||||
);
|
||||
},
|
||||
didSelectTimeFormat: (_DidSelectTimeFormat value) {
|
||||
emit(state.copyWith(
|
||||
typeOption: _updateTypeOption(timeFormat: value.format)));
|
||||
emit(
|
||||
state.copyWith(
|
||||
typeOption: _updateTypeOption(timeFormat: value.format),
|
||||
),
|
||||
);
|
||||
},
|
||||
includeTime: (_IncludeTime value) {
|
||||
emit(state.copyWith(
|
||||
typeOption: _updateTypeOption(includeTime: value.includeTime)));
|
||||
emit(
|
||||
state.copyWith(
|
||||
typeOption: _updateTypeOption(includeTime: value.includeTime),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
|
@ -7,16 +7,20 @@ class NumberFormatBloc extends Bloc<NumberFormatEvent, NumberFormatState> {
|
||||
NumberFormatBloc() : super(NumberFormatState.initial()) {
|
||||
on<NumberFormatEvent>(
|
||||
(event, emit) async {
|
||||
event.map(setFilter: (_SetFilter value) {
|
||||
final List<NumberFormat> formats = List.from(NumberFormat.values);
|
||||
if (value.filter.isNotEmpty) {
|
||||
formats.retainWhere((element) => element
|
||||
.title()
|
||||
.toLowerCase()
|
||||
.contains(value.filter.toLowerCase()));
|
||||
}
|
||||
emit(state.copyWith(formats: formats, filter: value.filter));
|
||||
});
|
||||
event.map(
|
||||
setFilter: (_SetFilter value) {
|
||||
final List<NumberFormat> formats = List.from(NumberFormat.values);
|
||||
if (value.filter.isNotEmpty) {
|
||||
formats.retainWhere(
|
||||
(element) => element
|
||||
.title()
|
||||
.toLowerCase()
|
||||
.contains(value.filter.toLowerCase()),
|
||||
);
|
||||
}
|
||||
emit(state.copyWith(formats: formats, filter: value.filter));
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -59,9 +59,11 @@ class SelectOptionTypeOptionEvent with _$SelectOptionTypeOptionEvent {
|
||||
const factory SelectOptionTypeOptionEvent.endAddingOption() =
|
||||
_EndAddingOption;
|
||||
const factory SelectOptionTypeOptionEvent.updateOption(
|
||||
SelectOptionPB option) = _UpdateOption;
|
||||
SelectOptionPB option,
|
||||
) = _UpdateOption;
|
||||
const factory SelectOptionTypeOptionEvent.deleteOption(
|
||||
SelectOptionPB option) = _DeleteOption;
|
||||
SelectOptionPB option,
|
||||
) = _DeleteOption;
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
@ -158,7 +158,9 @@ abstract class IFieldTypeOptionLoader {
|
||||
Future<Either<TypeOptionPB, FlowyError>> load();
|
||||
|
||||
Future<Either<Unit, FlowyError>> switchToField(
|
||||
String fieldId, FieldType fieldType) {
|
||||
String fieldId,
|
||||
FieldType fieldType,
|
||||
) {
|
||||
final payload = UpdateFieldTypePayloadPB.create()
|
||||
..viewId = viewId
|
||||
..fieldId = fieldId
|
||||
|
@ -107,7 +107,8 @@ class FilterListener {
|
||||
case DatabaseNotification.DidUpdateFilter:
|
||||
result.fold(
|
||||
(payload) => handleChangeset(
|
||||
FilterChangesetNotificationPB.fromBuffer(payload)),
|
||||
FilterChangesetNotificationPB.fromBuffer(payload),
|
||||
),
|
||||
(error) {},
|
||||
);
|
||||
break;
|
||||
|
@ -97,7 +97,8 @@ class FilterBackendService {
|
||||
filter.end = $fixnum.Int64(end);
|
||||
} else {
|
||||
throw Exception(
|
||||
"Start and end should not be null if the timestamp is null");
|
||||
"Start and end should not be null if the timestamp is null",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,9 @@ class DatabaseCalendarLayoutListener {
|
||||
DatabaseNotificationListener? _listener;
|
||||
DatabaseCalendarLayoutListener(this.viewId);
|
||||
|
||||
void start(
|
||||
{required void Function(NewLayoutFieldValue) onCalendarLayoutChanged}) {
|
||||
void start({
|
||||
required void Function(NewLayoutFieldValue) onCalendarLayoutChanged,
|
||||
}) {
|
||||
_newLayoutFieldNotifier?.addPublishListener(onCalendarLayoutChanged);
|
||||
_listener = DatabaseNotificationListener(
|
||||
objectId: viewId,
|
||||
|
@ -102,11 +102,16 @@ class RowCache {
|
||||
final rowInfo = _rowList.get(reorderRow.rowId);
|
||||
if (rowInfo != null) {
|
||||
_rowList.moveRow(
|
||||
reorderRow.rowId, reorderRow.oldIndex, reorderRow.newIndex);
|
||||
_rowChangeReasonNotifier.receive(RowsChangedReason.reorderSingleRow(
|
||||
reorderRow,
|
||||
rowInfo,
|
||||
));
|
||||
reorderRow.rowId,
|
||||
reorderRow.oldIndex,
|
||||
reorderRow.newIndex,
|
||||
);
|
||||
_rowChangeReasonNotifier.receive(
|
||||
RowsChangedReason.reorderSingleRow(
|
||||
reorderRow,
|
||||
rowInfo,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,7 +330,9 @@ class RowsChangedReason with _$RowsChangedReason {
|
||||
const factory RowsChangedReason.initial() = InitialListState;
|
||||
const factory RowsChangedReason.reorderRows() = _ReorderRows;
|
||||
const factory RowsChangedReason.reorderSingleRow(
|
||||
ReorderSingleRowPB reorderRow, RowInfo rowInfo) = _ReorderSingleRow;
|
||||
ReorderSingleRowPB reorderRow,
|
||||
RowInfo rowInfo,
|
||||
) = _ReorderSingleRow;
|
||||
}
|
||||
|
||||
class InsertedIndex {
|
||||
|
@ -23,10 +23,12 @@ class RowController {
|
||||
}
|
||||
|
||||
void addListener({OnRowChanged? onRowChanged}) {
|
||||
_onRowChangedListeners.add(_rowCache.addListener(
|
||||
rowId: rowId,
|
||||
onCellUpdated: onRowChanged,
|
||||
));
|
||||
_onRowChangedListeners.add(
|
||||
_rowCache.addListener(
|
||||
rowId: rowId,
|
||||
onCellUpdated: onRowChanged,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
|
@ -85,10 +85,12 @@ class RowList {
|
||||
insert(index, builder(insertRow.row));
|
||||
|
||||
if (!isContains) {
|
||||
insertIndexs.add(InsertedIndex(
|
||||
index: index,
|
||||
rowId: insertRow.row.id,
|
||||
));
|
||||
insertIndexs.add(
|
||||
InsertedIndex(
|
||||
index: index,
|
||||
rowId: insertRow.row.id,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
return insertIndexs;
|
||||
|
@ -67,7 +67,8 @@ class DatabaseGroupEvent with _$DatabaseGroupEvent {
|
||||
FieldType fieldType,
|
||||
) = _DatabaseGroupEvent;
|
||||
const factory DatabaseGroupEvent.didReceiveFieldUpdate(
|
||||
List<FieldInfo> fields) = _DidReceiveFieldUpdate;
|
||||
List<FieldInfo> fields,
|
||||
) = _DidReceiveFieldUpdate;
|
||||
}
|
||||
|
||||
@freezed
|
||||
@ -78,7 +79,9 @@ class DatabaseGroupState with _$DatabaseGroupState {
|
||||
}) = _DatabaseGroupState;
|
||||
|
||||
factory DatabaseGroupState.initial(
|
||||
String viewId, List<FieldInfo> fieldContexts) =>
|
||||
String viewId,
|
||||
List<FieldInfo> fieldContexts,
|
||||
) =>
|
||||
DatabaseGroupState(
|
||||
viewId: viewId,
|
||||
fieldContexts: fieldContexts,
|
||||
|
@ -13,11 +13,13 @@ class DatabasePropertyBloc
|
||||
final FieldController _fieldController;
|
||||
Function(List<FieldInfo>)? _onFieldsFn;
|
||||
|
||||
DatabasePropertyBloc(
|
||||
{required String viewId, required FieldController fieldController})
|
||||
: _fieldController = fieldController,
|
||||
DatabasePropertyBloc({
|
||||
required String viewId,
|
||||
required FieldController fieldController,
|
||||
}) : _fieldController = fieldController,
|
||||
super(
|
||||
DatabasePropertyState.initial(viewId, fieldController.fieldInfos)) {
|
||||
DatabasePropertyState.initial(viewId, fieldController.fieldInfos),
|
||||
) {
|
||||
on<DatabasePropertyEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
@ -68,9 +70,12 @@ class DatabasePropertyBloc
|
||||
class DatabasePropertyEvent with _$DatabasePropertyEvent {
|
||||
const factory DatabasePropertyEvent.initial() = _Initial;
|
||||
const factory DatabasePropertyEvent.setFieldVisibility(
|
||||
String fieldId, bool visibility) = _SetFieldVisibility;
|
||||
String fieldId,
|
||||
bool visibility,
|
||||
) = _SetFieldVisibility;
|
||||
const factory DatabasePropertyEvent.didReceiveFieldUpdate(
|
||||
List<FieldInfo> fields) = _DidReceiveFieldUpdate;
|
||||
List<FieldInfo> fields,
|
||||
) = _DidReceiveFieldUpdate;
|
||||
const factory DatabasePropertyEvent.moveField(int fromIndex, int toIndex) =
|
||||
_MoveField;
|
||||
}
|
||||
|
@ -11,9 +11,11 @@ class DatabaseSettingBloc
|
||||
: super(DatabaseSettingState.initial()) {
|
||||
on<DatabaseSettingEvent>(
|
||||
(event, emit) async {
|
||||
event.map(performAction: (_PerformAction value) {
|
||||
emit(state.copyWith(selectedAction: Some(value.action)));
|
||||
});
|
||||
event.map(
|
||||
performAction: (_PerformAction value) {
|
||||
emit(state.copyWith(selectedAction: Some(value.action)));
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -22,7 +24,8 @@ class DatabaseSettingBloc
|
||||
@freezed
|
||||
class DatabaseSettingEvent with _$DatabaseSettingEvent {
|
||||
const factory DatabaseSettingEvent.performAction(
|
||||
DatabaseSettingAction action) = _PerformAction;
|
||||
DatabaseSettingAction action,
|
||||
) = _PerformAction;
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
@ -28,12 +28,14 @@ class SettingController {
|
||||
});
|
||||
|
||||
// Listen on the setting changes
|
||||
_listener.start(onSettingUpdated: (result) {
|
||||
result.fold(
|
||||
(newSetting) => updateSetting(newSetting),
|
||||
(err) => _onError?.call(err),
|
||||
);
|
||||
});
|
||||
_listener.start(
|
||||
onSettingUpdated: (result) {
|
||||
result.fold(
|
||||
(newSetting) => updateSetting(newSetting),
|
||||
(err) => _onError?.call(err),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void startListening({
|
||||
|
@ -69,9 +69,11 @@ class DatabaseViewCache {
|
||||
}
|
||||
|
||||
if (changeset.insertedRows.isNotEmpty) {
|
||||
_callbacks?.onRowsCreated?.call(changeset.insertedRows
|
||||
.map((insertedRow) => insertedRow.row.id)
|
||||
.toList());
|
||||
_callbacks?.onRowsCreated?.call(
|
||||
changeset.insertedRows
|
||||
.map((insertedRow) => insertedRow.row.id)
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
},
|
||||
(err) => Log.error(err),
|
||||
|
@ -105,23 +105,31 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||
);
|
||||
},
|
||||
didCreateRow: (group, row, int? index) {
|
||||
emit(state.copyWith(
|
||||
editingRow: Some(BoardEditingRow(
|
||||
group: group,
|
||||
row: row,
|
||||
index: index,
|
||||
)),
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
editingRow: Some(
|
||||
BoardEditingRow(
|
||||
group: group,
|
||||
row: row,
|
||||
index: index,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
_groupItemStartEditing(group, row, true);
|
||||
},
|
||||
startEditingRow: (group, row) {
|
||||
emit(state.copyWith(
|
||||
editingRow: Some(BoardEditingRow(
|
||||
group: group,
|
||||
row: row,
|
||||
index: null,
|
||||
)),
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
editingRow: Some(
|
||||
BoardEditingRow(
|
||||
group: group,
|
||||
row: row,
|
||||
index: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
_groupItemStartEditing(group, row, true);
|
||||
},
|
||||
endEditingRow: (rowId) {
|
||||
@ -175,10 +183,12 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||
groupControllers.clear();
|
||||
boardController.clear();
|
||||
|
||||
boardController.addGroups(groups
|
||||
.where((group) => fieldController.getField(group.fieldId) != null)
|
||||
.map((group) => initializeGroupData(group))
|
||||
.toList());
|
||||
boardController.addGroups(
|
||||
groups
|
||||
.where((group) => fieldController.getField(group.fieldId) != null)
|
||||
.map((group) => initializeGroupData(group))
|
||||
.toList(),
|
||||
);
|
||||
|
||||
for (final group in groups) {
|
||||
final controller = initializeGroupController(group);
|
||||
@ -334,7 +344,8 @@ class BoardState with _$BoardState {
|
||||
class GridLoadingState with _$GridLoadingState {
|
||||
const factory GridLoadingState.loading() = _Loading;
|
||||
const factory GridLoadingState.finish(
|
||||
Either<Unit, FlowyError> successOrFail) = _Finish;
|
||||
Either<Unit, FlowyError> successOrFail,
|
||||
) = _Finish;
|
||||
}
|
||||
|
||||
class GridFieldEquatable extends Equatable {
|
||||
|
@ -41,44 +41,46 @@ class GroupController {
|
||||
}
|
||||
|
||||
void startListening() {
|
||||
_listener.start(onGroupChanged: (result) {
|
||||
result.fold(
|
||||
(GroupRowsNotificationPB changeset) {
|
||||
for (final deletedRow in changeset.deletedRows) {
|
||||
group.rows.removeWhere((rowPB) => rowPB.id == deletedRow);
|
||||
delegate.removeRow(group, deletedRow);
|
||||
}
|
||||
|
||||
for (final insertedRow in changeset.insertedRows) {
|
||||
final index = insertedRow.hasIndex() ? insertedRow.index : null;
|
||||
if (insertedRow.hasIndex() &&
|
||||
group.rows.length > insertedRow.index) {
|
||||
group.rows.insert(insertedRow.index, insertedRow.row);
|
||||
} else {
|
||||
group.rows.add(insertedRow.row);
|
||||
_listener.start(
|
||||
onGroupChanged: (result) {
|
||||
result.fold(
|
||||
(GroupRowsNotificationPB changeset) {
|
||||
for (final deletedRow in changeset.deletedRows) {
|
||||
group.rows.removeWhere((rowPB) => rowPB.id == deletedRow);
|
||||
delegate.removeRow(group, deletedRow);
|
||||
}
|
||||
|
||||
if (insertedRow.isNew) {
|
||||
delegate.addNewRow(group, insertedRow.row, index);
|
||||
} else {
|
||||
delegate.insertRow(group, insertedRow.row, index);
|
||||
}
|
||||
}
|
||||
for (final insertedRow in changeset.insertedRows) {
|
||||
final index = insertedRow.hasIndex() ? insertedRow.index : null;
|
||||
if (insertedRow.hasIndex() &&
|
||||
group.rows.length > insertedRow.index) {
|
||||
group.rows.insert(insertedRow.index, insertedRow.row);
|
||||
} else {
|
||||
group.rows.add(insertedRow.row);
|
||||
}
|
||||
|
||||
for (final updatedRow in changeset.updatedRows) {
|
||||
final index = group.rows.indexWhere(
|
||||
(rowPB) => rowPB.id == updatedRow.id,
|
||||
);
|
||||
|
||||
if (index != -1) {
|
||||
group.rows[index] = updatedRow;
|
||||
delegate.updateRow(group, updatedRow);
|
||||
if (insertedRow.isNew) {
|
||||
delegate.addNewRow(group, insertedRow.row, index);
|
||||
} else {
|
||||
delegate.insertRow(group, insertedRow.row, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
|
||||
for (final updatedRow in changeset.updatedRows) {
|
||||
final index = group.rows.indexWhere(
|
||||
(rowPB) => rowPB.id == updatedRow.id,
|
||||
);
|
||||
|
||||
if (index != -1) {
|
||||
group.rows[index] = updatedRow;
|
||||
delegate.updateRow(group, updatedRow);
|
||||
}
|
||||
}
|
||||
},
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> dispose() async {
|
||||
|
@ -10,9 +10,11 @@ class BoardSettingBloc extends Bloc<BoardSettingEvent, BoardSettingState> {
|
||||
: super(BoardSettingState.initial()) {
|
||||
on<BoardSettingEvent>(
|
||||
(event, emit) async {
|
||||
event.when(performAction: (action) {
|
||||
emit(state.copyWith(selectedAction: Some(action)));
|
||||
});
|
||||
event.when(
|
||||
performAction: (action) {
|
||||
emit(state.copyWith(selectedAction: Some(action)));
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -67,16 +67,20 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
||||
if (index != -1) {
|
||||
allEvents[index] = eventData;
|
||||
}
|
||||
emit(state.copyWith(
|
||||
allEvents: allEvents,
|
||||
updateEvent: eventData,
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
allEvents: allEvents,
|
||||
updateEvent: eventData,
|
||||
),
|
||||
);
|
||||
},
|
||||
didReceiveNewEvent: (CalendarEventData<CalendarDayEvent> event) {
|
||||
emit(state.copyWith(
|
||||
allEvents: [...state.allEvents, event],
|
||||
newEvent: event,
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
allEvents: [...state.allEvents, event],
|
||||
newEvent: event,
|
||||
),
|
||||
);
|
||||
},
|
||||
didDeleteEvents: (List<String> deletedRowIds) {
|
||||
var events = [...state.allEvents];
|
||||
@ -155,7 +159,8 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
||||
}
|
||||
|
||||
Future<void> _updateCalendarLayoutSetting(
|
||||
CalendarLayoutSettingsPB layoutSetting) async {
|
||||
CalendarLayoutSettingsPB layoutSetting,
|
||||
) async {
|
||||
return _databaseController.updateCalenderLayoutSetting(layoutSetting);
|
||||
}
|
||||
|
||||
@ -198,7 +203,8 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
||||
}
|
||||
|
||||
CalendarEventData<CalendarDayEvent>? _calendarEventDataFromEventPB(
|
||||
CalendarEventPB eventPB) {
|
||||
CalendarEventPB eventPB,
|
||||
) {
|
||||
final fieldInfo = fieldInfoByFieldId[eventPB.titleFieldId];
|
||||
if (fieldInfo != null) {
|
||||
final cellId = CellIdentifier(
|
||||
@ -267,7 +273,8 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
||||
);
|
||||
|
||||
final onCalendarLayoutFieldChanged = CalendarLayoutCallbacks(
|
||||
onCalendarLayoutChanged: _didReceiveNewLayoutField);
|
||||
onCalendarLayoutChanged: _didReceiveNewLayoutField,
|
||||
);
|
||||
|
||||
_databaseController.addListener(
|
||||
onDatabaseChanged: onDatabaseChanged,
|
||||
@ -299,7 +306,8 @@ class CalendarEvent with _$CalendarEvent {
|
||||
|
||||
// Called after loading the calendar layout setting from the backend
|
||||
const factory CalendarEvent.didReceiveCalendarSettings(
|
||||
CalendarLayoutSettingsPB settings) = _ReceiveCalendarSettings;
|
||||
CalendarLayoutSettingsPB settings,
|
||||
) = _ReceiveCalendarSettings;
|
||||
|
||||
// Called after loading all the current evnets
|
||||
const factory CalendarEvent.didLoadAllEvents(Events events) =
|
||||
@ -307,11 +315,13 @@ class CalendarEvent with _$CalendarEvent {
|
||||
|
||||
// Called when specific event was updated
|
||||
const factory CalendarEvent.didUpdateEvent(
|
||||
CalendarEventData<CalendarDayEvent> event) = _DidUpdateEvent;
|
||||
CalendarEventData<CalendarDayEvent> event,
|
||||
) = _DidUpdateEvent;
|
||||
|
||||
// Called after creating a new event
|
||||
const factory CalendarEvent.didReceiveNewEvent(
|
||||
CalendarEventData<CalendarDayEvent> event) = _DidReceiveNewEvent;
|
||||
CalendarEventData<CalendarDayEvent> event,
|
||||
) = _DidReceiveNewEvent;
|
||||
|
||||
// Called when deleting events
|
||||
const factory CalendarEvent.didDeleteEvents(List<String> rowIds) =
|
||||
@ -323,13 +333,15 @@ class CalendarEvent with _$CalendarEvent {
|
||||
|
||||
// Called when updating the calendar's layout settings
|
||||
const factory CalendarEvent.updateCalendarLayoutSetting(
|
||||
CalendarLayoutSettingsPB layoutSetting) = _UpdateCalendarLayoutSetting;
|
||||
CalendarLayoutSettingsPB layoutSetting,
|
||||
) = _UpdateCalendarLayoutSetting;
|
||||
|
||||
const factory CalendarEvent.didReceiveDatabaseUpdate(DatabasePB database) =
|
||||
_ReceiveDatabaseUpdate;
|
||||
|
||||
const factory CalendarEvent.didReceiveNewLayoutField(
|
||||
CalendarLayoutSettingsPB layoutSettings) = _DidReceiveNewLayoutField;
|
||||
CalendarLayoutSettingsPB layoutSettings,
|
||||
) = _DidReceiveNewLayoutField;
|
||||
}
|
||||
|
||||
@freezed
|
||||
@ -361,7 +373,8 @@ class CalendarState with _$CalendarState {
|
||||
class DatabaseLoadingState with _$DatabaseLoadingState {
|
||||
const factory DatabaseLoadingState.loading() = _Loading;
|
||||
const factory DatabaseLoadingState.finish(
|
||||
Either<Unit, FlowyError> successOrFail) = _Finish;
|
||||
Either<Unit, FlowyError> successOrFail,
|
||||
) = _Finish;
|
||||
}
|
||||
|
||||
class CalendarEditingRow {
|
||||
|
@ -22,7 +22,6 @@ class CalendarSettingBloc
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@freezed
|
||||
@ -33,7 +32,8 @@ class CalendarSettingState with _$CalendarSettingState {
|
||||
}) = _CalendarSettingState;
|
||||
|
||||
factory CalendarSettingState.initial(
|
||||
CalendarLayoutSettingsPB? layoutSettings) =>
|
||||
CalendarLayoutSettingsPB? layoutSettings,
|
||||
) =>
|
||||
CalendarSettingState(
|
||||
selectedAction: none(),
|
||||
layoutSetting: layoutSettings == null ? none() : Some(layoutSettings),
|
||||
@ -43,9 +43,11 @@ class CalendarSettingState with _$CalendarSettingState {
|
||||
@freezed
|
||||
class CalendarSettingEvent with _$CalendarSettingEvent {
|
||||
const factory CalendarSettingEvent.performAction(
|
||||
CalendarSettingAction action) = _PerformAction;
|
||||
CalendarSettingAction action,
|
||||
) = _PerformAction;
|
||||
const factory CalendarSettingEvent.updateLayoutSetting(
|
||||
CalendarLayoutSettingsPB setting) = _UpdateLayoutSetting;
|
||||
CalendarLayoutSettingsPB setting,
|
||||
) = _UpdateLayoutSetting;
|
||||
}
|
||||
|
||||
enum CalendarSettingAction {
|
||||
|
@ -63,29 +63,30 @@ class CalendarDayCard extends StatelessWidget {
|
||||
}).toList();
|
||||
|
||||
final child = Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_Header(
|
||||
date: date,
|
||||
isInMonth: isInMonth,
|
||||
isToday: isToday,
|
||||
onCreate: () => onCreateEvent(date),
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_Header(
|
||||
date: date,
|
||||
isInMonth: isInMonth,
|
||||
isToday: isToday,
|
||||
onCreate: () => onCreateEvent(date),
|
||||
),
|
||||
VSpace(GridSize.typeOptionSeparatorHeight),
|
||||
Flexible(
|
||||
child: ListView.separated(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return children[index];
|
||||
},
|
||||
itemCount: children.length,
|
||||
separatorBuilder: (BuildContext context, int index) =>
|
||||
VSpace(GridSize.typeOptionSeparatorHeight),
|
||||
),
|
||||
VSpace(GridSize.typeOptionSeparatorHeight),
|
||||
Flexible(
|
||||
child: ListView.separated(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return children[index];
|
||||
},
|
||||
itemCount: children.length,
|
||||
separatorBuilder: (BuildContext context, int index) =>
|
||||
VSpace(GridSize.typeOptionSeparatorHeight),
|
||||
),
|
||||
),
|
||||
],
|
||||
));
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
return Container(
|
||||
color: backgroundColor,
|
||||
|
@ -73,9 +73,11 @@ class _CalendarPageState extends State<CalendarPage> {
|
||||
listenWhen: (p, c) => p.updateEvent != c.updateEvent,
|
||||
listener: (context, state) {
|
||||
if (state.updateEvent != null) {
|
||||
_eventController.removeWhere((element) =>
|
||||
state.updateEvent!.event!.eventId ==
|
||||
element.event!.eventId);
|
||||
_eventController.removeWhere(
|
||||
(element) =>
|
||||
state.updateEvent!.event!.eventId ==
|
||||
element.event!.eventId,
|
||||
);
|
||||
_eventController.add(state.updateEvent!);
|
||||
}
|
||||
},
|
||||
|
@ -96,16 +96,22 @@ class _CalendarLayoutSettingState extends State<CalendarLayoutSetting> {
|
||||
fieldId: settings.layoutFieldId,
|
||||
popoverMutex: popoverMutex,
|
||||
onUpdated: (fieldId) {
|
||||
_updateLayoutSettings(context,
|
||||
onUpdated: widget.onUpdated, layoutFieldId: fieldId);
|
||||
_updateLayoutSettings(
|
||||
context,
|
||||
onUpdated: widget.onUpdated,
|
||||
layoutFieldId: fieldId,
|
||||
);
|
||||
},
|
||||
);
|
||||
default:
|
||||
return ShowWeekends(
|
||||
showWeekends: settings.showWeekends,
|
||||
onUpdated: (showWeekends) {
|
||||
_updateLayoutSettings(context,
|
||||
onUpdated: widget.onUpdated, showWeekends: showWeekends);
|
||||
_updateLayoutSettings(
|
||||
context,
|
||||
onUpdated: widget.onUpdated,
|
||||
showWeekends: showWeekends,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -129,7 +135,8 @@ class _CalendarLayoutSettingState extends State<CalendarLayoutSetting> {
|
||||
}
|
||||
|
||||
List<CalendarLayoutSettingAction> _availableCalendarSettings(
|
||||
CalendarLayoutSettingsPB layoutSettings) {
|
||||
CalendarLayoutSettingsPB layoutSettings,
|
||||
) {
|
||||
List<CalendarLayoutSettingAction> settings = [
|
||||
CalendarLayoutSettingAction.layoutField,
|
||||
// CalendarLayoutSettingAction.layoutType,
|
||||
@ -220,8 +227,9 @@ class LayoutDateField extends StatelessWidget {
|
||||
popupBuilder: (context) {
|
||||
return BlocProvider(
|
||||
create: (context) => getIt<DatabasePropertyBloc>(
|
||||
param1: viewId, param2: fieldController)
|
||||
..add(const DatabasePropertyEvent.initial()),
|
||||
param1: viewId,
|
||||
param2: fieldController,
|
||||
)..add(const DatabasePropertyEvent.initial()),
|
||||
child: BlocBuilder<DatabasePropertyBloc, DatabasePropertyState>(
|
||||
builder: (context, state) {
|
||||
final items = state.fieldContexts
|
||||
@ -264,7 +272,8 @@ class LayoutDateField extends StatelessWidget {
|
||||
child: FlowyButton(
|
||||
margin: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 10.0),
|
||||
text: FlowyText.medium(
|
||||
LocaleKeys.calendar_settings_layoutDateField.tr()),
|
||||
LocaleKeys.calendar_settings_layoutDateField.tr(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -368,7 +377,8 @@ class FirstDayOfWeek extends StatelessWidget {
|
||||
child: FlowyButton(
|
||||
margin: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 10.0),
|
||||
text: FlowyText.medium(
|
||||
LocaleKeys.calendar_settings_firstDayOfWeek.tr()),
|
||||
LocaleKeys.calendar_settings_firstDayOfWeek.tr(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -45,10 +45,12 @@ class CheckboxFilterEditorBloc
|
||||
didReceiveFilter: (FilterPB filter) {
|
||||
final filterInfo = state.filterInfo.copyWith(filter: filter);
|
||||
final checkboxFilter = filterInfo.checkboxFilter()!;
|
||||
emit(state.copyWith(
|
||||
filterInfo: filterInfo,
|
||||
filter: checkboxFilter,
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
filterInfo: filterInfo,
|
||||
filter: checkboxFilter,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
@ -79,7 +81,8 @@ class CheckboxFilterEditorEvent with _$CheckboxFilterEditorEvent {
|
||||
const factory CheckboxFilterEditorEvent.didReceiveFilter(FilterPB filter) =
|
||||
_DidReceiveFilter;
|
||||
const factory CheckboxFilterEditorEvent.updateCondition(
|
||||
CheckboxFilterConditionPB condition) = _UpdateCondition;
|
||||
CheckboxFilterConditionPB condition,
|
||||
) = _UpdateCondition;
|
||||
const factory CheckboxFilterEditorEvent.delete() = _Delete;
|
||||
}
|
||||
|
||||
|
@ -46,10 +46,12 @@ class ChecklistFilterEditorBloc
|
||||
didReceiveFilter: (FilterPB filter) {
|
||||
final filterInfo = state.filterInfo.copyWith(filter: filter);
|
||||
final checklistFilter = filterInfo.checklistFilter()!;
|
||||
emit(state.copyWith(
|
||||
filterInfo: filterInfo,
|
||||
filter: checklistFilter,
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
filterInfo: filterInfo,
|
||||
filter: checklistFilter,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
@ -82,7 +84,8 @@ class ChecklistFilterEditorEvent with _$ChecklistFilterEditorEvent {
|
||||
const factory ChecklistFilterEditorEvent.didReceiveFilter(FilterPB filter) =
|
||||
_DidReceiveFilter;
|
||||
const factory ChecklistFilterEditorEvent.updateCondition(
|
||||
ChecklistFilterConditionPB condition) = _UpdateCondition;
|
||||
ChecklistFilterConditionPB condition,
|
||||
) = _UpdateCondition;
|
||||
const factory ChecklistFilterEditorEvent.delete() = _Delete;
|
||||
}
|
||||
|
||||
|
@ -14,11 +14,13 @@ class GridFilterMenuBloc
|
||||
void Function(List<FieldInfo>)? _onFieldFn;
|
||||
|
||||
GridFilterMenuBloc({required this.viewId, required this.fieldController})
|
||||
: super(GridFilterMenuState.initial(
|
||||
viewId,
|
||||
fieldController.filterInfos,
|
||||
fieldController.fieldInfos,
|
||||
)) {
|
||||
: super(
|
||||
GridFilterMenuState.initial(
|
||||
viewId,
|
||||
fieldController.filterInfos,
|
||||
fieldController.fieldInfos,
|
||||
),
|
||||
) {
|
||||
on<GridFilterMenuEvent>(
|
||||
(event, emit) async {
|
||||
event.when(
|
||||
@ -82,7 +84,8 @@ class GridFilterMenuBloc
|
||||
class GridFilterMenuEvent with _$GridFilterMenuEvent {
|
||||
const factory GridFilterMenuEvent.initial() = _Initial;
|
||||
const factory GridFilterMenuEvent.didReceiveFilters(
|
||||
List<FilterInfo> filters) = _DidReceiveFilters;
|
||||
List<FilterInfo> filters,
|
||||
) = _DidReceiveFilters;
|
||||
const factory GridFilterMenuEvent.didReceiveFields(List<FieldInfo> fields) =
|
||||
_DidReceiveFields;
|
||||
const factory GridFilterMenuEvent.toggleMenu() = _SetMenuVisibility;
|
||||
|
@ -61,10 +61,12 @@ class SelectOptionFilterEditorBloc
|
||||
didReceiveFilter: (FilterPB filter) {
|
||||
final filterInfo = state.filterInfo.copyWith(filter: filter);
|
||||
final selectOptionFilter = filterInfo.selectOptionFilter()!;
|
||||
emit(state.copyWith(
|
||||
filterInfo: filterInfo,
|
||||
filter: selectOptionFilter,
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
filterInfo: filterInfo,
|
||||
filter: selectOptionFilter,
|
||||
),
|
||||
);
|
||||
},
|
||||
updateFilterDescription: (String desc) {
|
||||
emit(state.copyWith(filterDesc: desc));
|
||||
@ -112,13 +114,17 @@ class SelectOptionFilterEditorBloc
|
||||
class SelectOptionFilterEditorEvent with _$SelectOptionFilterEditorEvent {
|
||||
const factory SelectOptionFilterEditorEvent.initial() = _Initial;
|
||||
const factory SelectOptionFilterEditorEvent.didReceiveFilter(
|
||||
FilterPB filter) = _DidReceiveFilter;
|
||||
FilterPB filter,
|
||||
) = _DidReceiveFilter;
|
||||
const factory SelectOptionFilterEditorEvent.updateCondition(
|
||||
SelectOptionConditionPB condition) = _UpdateCondition;
|
||||
SelectOptionConditionPB condition,
|
||||
) = _UpdateCondition;
|
||||
const factory SelectOptionFilterEditorEvent.updateContent(
|
||||
List<String> optionIds) = _UpdateContent;
|
||||
List<String> optionIds,
|
||||
) = _UpdateContent;
|
||||
const factory SelectOptionFilterEditorEvent.updateFilterDescription(
|
||||
String desc) = _UpdateDesc;
|
||||
String desc,
|
||||
) = _UpdateDesc;
|
||||
const factory SelectOptionFilterEditorEvent.delete() = _Delete;
|
||||
}
|
||||
|
||||
|
@ -43,15 +43,22 @@ class SelectOptionFilterListBloc<T>
|
||||
didReceiveOptions: (newOptions) {
|
||||
List<SelectOptionPB> options = List.from(newOptions);
|
||||
options.retainWhere(
|
||||
(element) => element.name.contains(state.predicate));
|
||||
(element) => element.name.contains(state.predicate),
|
||||
);
|
||||
|
||||
final visibleOptions = options.map((option) {
|
||||
return VisibleSelectOption(
|
||||
option, state.selectedOptionIds.contains(option.id));
|
||||
option,
|
||||
state.selectedOptionIds.contains(option.id),
|
||||
);
|
||||
}).toList();
|
||||
|
||||
emit(state.copyWith(
|
||||
options: options, visibleOptions: visibleOptions));
|
||||
emit(
|
||||
state.copyWith(
|
||||
options: options,
|
||||
visibleOptions: visibleOptions,
|
||||
),
|
||||
);
|
||||
},
|
||||
filterOption: (optionName) {
|
||||
_updateSelectOptions(predicate: optionName, emit: emit);
|
||||
@ -71,11 +78,13 @@ class SelectOptionFilterListBloc<T>
|
||||
selectedOptionIds ?? state.selectedOptionIds,
|
||||
);
|
||||
|
||||
emit(state.copyWith(
|
||||
predicate: predicate ?? state.predicate,
|
||||
visibleOptions: visibleOptions,
|
||||
selectedOptionIds: selectedOptionIds ?? state.selectedOptionIds,
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
predicate: predicate ?? state.predicate,
|
||||
visibleOptions: visibleOptions,
|
||||
selectedOptionIds: selectedOptionIds ?? state.selectedOptionIds,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<VisibleSelectOption> _makeVisibleOptions(
|
||||
@ -105,11 +114,14 @@ class SelectOptionFilterListBloc<T>
|
||||
class SelectOptionFilterListEvent with _$SelectOptionFilterListEvent {
|
||||
const factory SelectOptionFilterListEvent.initial() = _Initial;
|
||||
const factory SelectOptionFilterListEvent.selectOption(
|
||||
SelectOptionPB option) = _SelectOption;
|
||||
SelectOptionPB option,
|
||||
) = _SelectOption;
|
||||
const factory SelectOptionFilterListEvent.unselectOption(
|
||||
SelectOptionPB option) = _UnSelectOption;
|
||||
SelectOptionPB option,
|
||||
) = _UnSelectOption;
|
||||
const factory SelectOptionFilterListEvent.didReceiveOptions(
|
||||
List<SelectOptionPB> options) = _DidReceiveOptions;
|
||||
List<SelectOptionPB> options,
|
||||
) = _DidReceiveOptions;
|
||||
const factory SelectOptionFilterListEvent.filterOption(String optionName) =
|
||||
_SelectOptionFilter;
|
||||
}
|
||||
|
@ -54,10 +54,12 @@ class TextFilterEditorBloc
|
||||
didReceiveFilter: (FilterPB filter) {
|
||||
final filterInfo = state.filterInfo.copyWith(filter: filter);
|
||||
final textFilter = filterInfo.textFilter()!;
|
||||
emit(state.copyWith(
|
||||
filterInfo: filterInfo,
|
||||
filter: textFilter,
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
filterInfo: filterInfo,
|
||||
filter: textFilter,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
@ -88,7 +90,8 @@ class TextFilterEditorEvent with _$TextFilterEditorEvent {
|
||||
const factory TextFilterEditorEvent.didReceiveFilter(FilterPB filter) =
|
||||
_DidReceiveFilter;
|
||||
const factory TextFilterEditorEvent.updateCondition(
|
||||
TextFilterConditionPB condition) = _UpdateCondition;
|
||||
TextFilterConditionPB condition,
|
||||
) = _UpdateCondition;
|
||||
const factory TextFilterEditorEvent.updateContent(String content) =
|
||||
_UpdateContent;
|
||||
const factory TextFilterEditorEvent.delete() = _Delete;
|
||||
|
@ -8,9 +8,11 @@ class GridAccessoryMenuBloc
|
||||
final String viewId;
|
||||
|
||||
GridAccessoryMenuBloc({required this.viewId})
|
||||
: super(GridAccessoryMenuState.initial(
|
||||
viewId,
|
||||
)) {
|
||||
: super(
|
||||
GridAccessoryMenuState.initial(
|
||||
viewId,
|
||||
),
|
||||
) {
|
||||
on<GridAccessoryMenuEvent>(
|
||||
(event, emit) async {
|
||||
event.when(
|
||||
|
@ -39,16 +39,20 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
||||
emit(state.copyWith(grid: Some(grid)));
|
||||
},
|
||||
didReceiveFieldUpdate: (fields) {
|
||||
emit(state.copyWith(
|
||||
fields: GridFieldEquatable(fields),
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
fields: GridFieldEquatable(fields),
|
||||
),
|
||||
);
|
||||
},
|
||||
didReceiveRowUpdate: (newRowInfos, reason) {
|
||||
emit(state.copyWith(
|
||||
rowInfos: newRowInfos,
|
||||
rowCount: newRowInfos.length,
|
||||
reason: reason,
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
rowInfos: newRowInfos,
|
||||
rowCount: newRowInfos.length,
|
||||
reason: reason,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
@ -146,7 +150,8 @@ class GridState with _$GridState {
|
||||
class GridLoadingState with _$GridLoadingState {
|
||||
const factory GridLoadingState.loading() = _Loading;
|
||||
const factory GridLoadingState.finish(
|
||||
Either<Unit, FlowyError> successOrFail) = _Finish;
|
||||
Either<Unit, FlowyError> successOrFail,
|
||||
) = _Finish;
|
||||
}
|
||||
|
||||
class GridFieldEquatable extends Equatable {
|
||||
|
@ -40,7 +40,9 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
|
||||
}
|
||||
|
||||
Future<void> _moveField(
|
||||
_MoveField value, Emitter<GridHeaderState> emit) async {
|
||||
_MoveField value,
|
||||
Emitter<GridHeaderState> emit,
|
||||
) async {
|
||||
final fields = List<FieldInfo>.from(state.fields);
|
||||
fields.insert(value.toIndex, fields.removeAt(value.fromIndex));
|
||||
emit(state.copyWith(fields: fields));
|
||||
@ -69,7 +71,10 @@ class GridHeaderEvent with _$GridHeaderEvent {
|
||||
const factory GridHeaderEvent.didReceiveFieldUpdate(List<FieldInfo> fields) =
|
||||
_DidReceiveFieldUpdate;
|
||||
const factory GridHeaderEvent.moveField(
|
||||
FieldPB field, int fromIndex, int toIndex) = _MoveField;
|
||||
FieldPB field,
|
||||
int fromIndex,
|
||||
int toIndex,
|
||||
) = _MoveField;
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
@ -35,11 +35,13 @@ class RowBloc extends Bloc<RowEvent, RowState> {
|
||||
final cells = cellByFieldId.values
|
||||
.map((e) => GridCellEquatable(e.fieldInfo))
|
||||
.toList();
|
||||
emit(state.copyWith(
|
||||
cellByFieldId: cellByFieldId,
|
||||
cells: UnmodifiableListView(cells),
|
||||
changeReason: reason,
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
cellByFieldId: cellByFieldId,
|
||||
cells: UnmodifiableListView(cells),
|
||||
changeReason: reason,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
@ -68,8 +70,9 @@ class RowEvent with _$RowEvent {
|
||||
const factory RowEvent.initial() = _InitialRow;
|
||||
const factory RowEvent.createRow() = _CreateRow;
|
||||
const factory RowEvent.didReceiveCells(
|
||||
CellByFieldId cellsByFieldId, RowsChangedReason reason) =
|
||||
_DidReceiveCells;
|
||||
CellByFieldId cellsByFieldId,
|
||||
RowsChangedReason reason,
|
||||
) = _DidReceiveCells;
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
@ -59,7 +59,8 @@ class RowDetailEvent with _$RowDetailEvent {
|
||||
const factory RowDetailEvent.initial() = _Initial;
|
||||
const factory RowDetailEvent.deleteField(String fieldId) = _DeleteField;
|
||||
const factory RowDetailEvent.didReceiveCellDatas(
|
||||
List<CellIdentifier> gridCells) = _DidReceiveCellDatas;
|
||||
List<CellIdentifier> gridCells,
|
||||
) = _DidReceiveCellDatas;
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
@ -82,9 +82,10 @@ class CreateSortBloc extends Bloc<CreateSortEvent, CreateSortState> {
|
||||
|
||||
Future<Either<Unit, FlowyError>> _createDefaultSort(FieldInfo field) async {
|
||||
final result = await _sortBackendSvc.insertSort(
|
||||
fieldId: field.id,
|
||||
fieldType: field.fieldType,
|
||||
condition: SortConditionPB.Ascending);
|
||||
fieldId: field.id,
|
||||
fieldType: field.fieldType,
|
||||
condition: SortConditionPB.Ascending,
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -100,7 +100,9 @@ class SortEditorEvent with _$SortEditorEvent {
|
||||
const factory SortEditorEvent.didReceiveSorts(List<SortInfo> sortInfos) =
|
||||
_DidReceiveSorts;
|
||||
const factory SortEditorEvent.setCondition(
|
||||
SortInfo sortInfo, SortConditionPB condition) = _SetCondition;
|
||||
SortInfo sortInfo,
|
||||
SortConditionPB condition,
|
||||
) = _SetCondition;
|
||||
const factory SortEditorEvent.deleteSort(SortInfo sortInfo) = _DeleteSort;
|
||||
const factory SortEditorEvent.deleteAllSorts() = _DeleteAllSorts;
|
||||
}
|
||||
|
@ -14,11 +14,13 @@ class SortMenuBloc extends Bloc<SortMenuEvent, SortMenuState> {
|
||||
void Function(List<FieldInfo>)? _onFieldFn;
|
||||
|
||||
SortMenuBloc({required this.viewId, required this.fieldController})
|
||||
: super(SortMenuState.initial(
|
||||
viewId,
|
||||
fieldController.sortInfos,
|
||||
fieldController.fieldInfos,
|
||||
)) {
|
||||
: super(
|
||||
SortMenuState.initial(
|
||||
viewId,
|
||||
fieldController.sortInfos,
|
||||
fieldController.fieldInfos,
|
||||
),
|
||||
) {
|
||||
on<SortMenuEvent>(
|
||||
(event, emit) async {
|
||||
event.when(
|
||||
|
@ -117,7 +117,8 @@ class FlowyGrid extends StatefulWidget {
|
||||
|
||||
class _FlowyGridState extends State<FlowyGrid> {
|
||||
final _scrollController = GridScrollController(
|
||||
scrollGroupController: LinkedScrollControllerGroup());
|
||||
scrollGroupController: LinkedScrollControllerGroup(),
|
||||
);
|
||||
late ScrollController headerScrollController;
|
||||
|
||||
@override
|
||||
@ -319,13 +320,14 @@ class _GridRowsState extends State<_GridRows> {
|
||||
);
|
||||
|
||||
FlowyOverlay.show(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return RowDetailPage(
|
||||
cellBuilder: cellBuilder,
|
||||
dataController: dataController,
|
||||
);
|
||||
});
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return RowDetailPage(
|
||||
cellBuilder: cellBuilder,
|
||||
dataController: dataController,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,9 +8,9 @@ class GridScrollController {
|
||||
|
||||
final List<ScrollController> _linkHorizontalControllers = [];
|
||||
|
||||
GridScrollController(
|
||||
{required LinkedScrollControllerGroup scrollGroupController})
|
||||
: _scrollGroupController = scrollGroupController,
|
||||
GridScrollController({
|
||||
required LinkedScrollControllerGroup scrollGroupController,
|
||||
}) : _scrollGroupController = scrollGroupController,
|
||||
verticalController = ScrollController(),
|
||||
horizontalController = scrollGroupController.addAndGet();
|
||||
|
||||
|
@ -21,10 +21,11 @@ class GridAccessoryMenu extends StatelessWidget {
|
||||
child: MultiBlocListener(
|
||||
listeners: [
|
||||
BlocListener<GridFilterMenuBloc, GridFilterMenuState>(
|
||||
listenWhen: (p, c) => p.isVisible != c.isVisible,
|
||||
listener: (context, state) => context
|
||||
.read<GridAccessoryMenuBloc>()
|
||||
.add(const GridAccessoryMenuEvent.toggleMenu())),
|
||||
listenWhen: (p, c) => p.isVisible != c.isVisible,
|
||||
listener: (context, state) => context
|
||||
.read<GridAccessoryMenuBloc>()
|
||||
.add(const GridAccessoryMenuEvent.toggleMenu()),
|
||||
),
|
||||
BlocListener<SortMenuBloc, SortMenuState>(
|
||||
listenWhen: (p, c) => p.isVisible != c.isVisible,
|
||||
listener: (context, state) => context
|
||||
|
@ -100,7 +100,9 @@ class _CheckboxFilterEditorState extends State<CheckboxFilterEditor> {
|
||||
}
|
||||
|
||||
Widget _buildFilterPanel(
|
||||
BuildContext context, CheckboxFilterEditorState state) {
|
||||
BuildContext context,
|
||||
CheckboxFilterEditorState state,
|
||||
) {
|
||||
return SizedBox(
|
||||
height: 20,
|
||||
child: Row(
|
||||
|
@ -70,9 +70,11 @@ class _ChecklistFilterChoicechipState extends State<ChecklistFilterChoicechip> {
|
||||
class ChecklistFilterEditor extends StatefulWidget {
|
||||
final ChecklistFilterEditorBloc bloc;
|
||||
final PopoverMutex popoverMutex;
|
||||
const ChecklistFilterEditor(
|
||||
{required this.bloc, required this.popoverMutex, Key? key})
|
||||
: super(key: key);
|
||||
const ChecklistFilterEditor({
|
||||
required this.bloc,
|
||||
required this.popoverMutex,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
ChecklistState createState() => ChecklistState();
|
||||
|
@ -65,8 +65,10 @@ class _ChoicechipFilterDesc extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final arrow = Transform.rotate(
|
||||
angle: -math.pi / 2,
|
||||
child: svgWidget("home/arrow_left",
|
||||
color: AFThemeExtension.of(context).textColor),
|
||||
child: svgWidget(
|
||||
"home/arrow_left",
|
||||
color: AFThemeExtension.of(context).textColor,
|
||||
),
|
||||
);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 2),
|
||||
|
@ -110,7 +110,10 @@ class _SelectOptionFilterEditorState extends State<SelectOptionFilterEditor> {
|
||||
selectedOptionIds: state.filter.optionIds,
|
||||
onSelectedOptions: (optionIds) {
|
||||
context.read<SelectOptionFilterEditorBloc>().add(
|
||||
SelectOptionFilterEditorEvent.updateContent(optionIds));
|
||||
SelectOptionFilterEditorEvent.updateContent(
|
||||
optionIds,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
@ -132,7 +135,9 @@ class _SelectOptionFilterEditorState extends State<SelectOptionFilterEditor> {
|
||||
}
|
||||
|
||||
Widget _buildFilterPanel(
|
||||
BuildContext context, SelectOptionFilterEditorState state) {
|
||||
BuildContext context,
|
||||
SelectOptionFilterEditorState state,
|
||||
) {
|
||||
return SizedBox(
|
||||
height: 20,
|
||||
child: Row(
|
||||
@ -144,7 +149,8 @@ class _SelectOptionFilterEditorState extends State<SelectOptionFilterEditor> {
|
||||
popoverMutex: popoverMutex,
|
||||
onCondition: (condition) {
|
||||
context.read<SelectOptionFilterEditorBloc>().add(
|
||||
SelectOptionFilterEditorEvent.updateCondition(condition));
|
||||
SelectOptionFilterEditorEvent.updateCondition(condition),
|
||||
);
|
||||
},
|
||||
),
|
||||
const Spacer(),
|
||||
|
@ -147,7 +147,9 @@ class _TextFilterEditorState extends State<TextFilterEditor> {
|
||||
}
|
||||
|
||||
Widget _buildFilterTextField(
|
||||
BuildContext context, TextFilterEditorState state) {
|
||||
BuildContext context,
|
||||
TextFilterEditorState state,
|
||||
) {
|
||||
return FlowyTextField(
|
||||
text: state.filter.content,
|
||||
hintText: LocaleKeys.grid_settings_typeAValue.tr(),
|
||||
|
@ -18,8 +18,10 @@ class ConditionButton extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final arrow = Transform.rotate(
|
||||
angle: -math.pi / 2,
|
||||
child: svgWidget("home/arrow_left",
|
||||
color: AFThemeExtension.of(context).textColor),
|
||||
child: svgWidget(
|
||||
"home/arrow_left",
|
||||
color: AFThemeExtension.of(context).textColor,
|
||||
),
|
||||
);
|
||||
|
||||
return SizedBox(
|
||||
|
@ -117,7 +117,10 @@ class _FilterTextFieldDelegate extends SliverPersistentHeaderDelegate {
|
||||
|
||||
@override
|
||||
Widget build(
|
||||
BuildContext context, double shrinkOffset, bool overlapsContent) {
|
||||
BuildContext context,
|
||||
double shrinkOffset,
|
||||
bool overlapsContent,
|
||||
) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.only(top: 4),
|
||||
height: fixHeight,
|
||||
|
@ -95,17 +95,20 @@ class _GridHeaderCellContainer extends StatelessWidget {
|
||||
width: 1.0,
|
||||
);
|
||||
final decoration = BoxDecoration(
|
||||
border: Border(
|
||||
top: borderSide,
|
||||
right: borderSide,
|
||||
bottom: borderSide,
|
||||
));
|
||||
border: Border(
|
||||
top: borderSide,
|
||||
right: borderSide,
|
||||
bottom: borderSide,
|
||||
),
|
||||
);
|
||||
|
||||
return Container(
|
||||
width: width,
|
||||
decoration: decoration,
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints.expand(), child: child),
|
||||
constraints: const BoxConstraints.expand(),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -101,25 +101,27 @@ class _FieldOperationList extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(children: [
|
||||
Flex(
|
||||
direction: Axis.horizontal,
|
||||
children: [
|
||||
_actionCell(FieldAction.hide),
|
||||
HSpace(GridSize.typeOptionSeparatorHeight),
|
||||
_actionCell(FieldAction.duplicate),
|
||||
],
|
||||
),
|
||||
VSpace(GridSize.typeOptionSeparatorHeight),
|
||||
Flex(
|
||||
direction: Axis.horizontal,
|
||||
children: [
|
||||
_actionCell(FieldAction.delete),
|
||||
HSpace(GridSize.typeOptionSeparatorHeight),
|
||||
const Spacer(),
|
||||
],
|
||||
),
|
||||
]);
|
||||
return Column(
|
||||
children: [
|
||||
Flex(
|
||||
direction: Axis.horizontal,
|
||||
children: [
|
||||
_actionCell(FieldAction.hide),
|
||||
HSpace(GridSize.typeOptionSeparatorHeight),
|
||||
_actionCell(FieldAction.duplicate),
|
||||
],
|
||||
),
|
||||
VSpace(GridSize.typeOptionSeparatorHeight),
|
||||
Flex(
|
||||
direction: Axis.horizontal,
|
||||
children: [
|
||||
_actionCell(FieldAction.delete),
|
||||
HSpace(GridSize.typeOptionSeparatorHeight),
|
||||
const Spacer(),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _actionCell(FieldAction action) {
|
||||
|
@ -90,11 +90,13 @@ class _SwitchFieldButton extends StatelessWidget {
|
||||
mutex: popoverMutex,
|
||||
offset: const Offset(8, 0),
|
||||
popupBuilder: (popOverContext) {
|
||||
return FieldTypeList(onSelectField: (newFieldType) {
|
||||
context
|
||||
.read<FieldTypeOptionEditBloc>()
|
||||
.add(FieldTypeOptionEditEvent.switchToField(newFieldType));
|
||||
});
|
||||
return FieldTypeList(
|
||||
onSelectField: (newFieldType) {
|
||||
context
|
||||
.read<FieldTypeOptionEditBloc>()
|
||||
.add(FieldTypeOptionEditEvent.switchToField(newFieldType));
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||
|
@ -39,7 +39,9 @@ class _GridHeaderSliverAdaptorState extends State<GridHeaderSliverAdaptor> {
|
||||
return BlocProvider(
|
||||
create: (context) {
|
||||
final bloc = getIt<GridHeaderBloc>(
|
||||
param1: widget.viewId, param2: widget.fieldController);
|
||||
param1: widget.viewId,
|
||||
param2: widget.fieldController,
|
||||
);
|
||||
bloc.add(const GridHeaderEvent.initial());
|
||||
return bloc;
|
||||
},
|
||||
@ -98,10 +100,16 @@ class _GridHeaderState extends State<_GridHeader> {
|
||||
builder: (context, state) {
|
||||
final cells = state.fields
|
||||
.where((field) => field.visibility)
|
||||
.map((field) =>
|
||||
FieldCellContext(viewId: widget.viewId, field: field.field))
|
||||
.map((ctx) =>
|
||||
GridFieldCell(key: _getKeyById(ctx.field.id), cellContext: ctx))
|
||||
.map(
|
||||
(field) =>
|
||||
FieldCellContext(viewId: widget.viewId, field: field.field),
|
||||
)
|
||||
.map(
|
||||
(ctx) => GridFieldCell(
|
||||
key: _getKeyById(ctx.field.id),
|
||||
cellContext: ctx,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
|
||||
return Container(
|
||||
@ -124,8 +132,12 @@ class _GridHeaderState extends State<_GridHeader> {
|
||||
);
|
||||
}
|
||||
|
||||
void _onReorder(List<GridFieldCell> cells, int oldIndex, BuildContext context,
|
||||
int newIndex) {
|
||||
void _onReorder(
|
||||
List<GridFieldCell> cells,
|
||||
int oldIndex,
|
||||
BuildContext context,
|
||||
int newIndex,
|
||||
) {
|
||||
if (cells.length > oldIndex) {
|
||||
final field = cells[oldIndex].cellContext.field;
|
||||
context
|
||||
@ -197,12 +209,17 @@ class SliverHeaderDelegateImplementation
|
||||
final String gridId;
|
||||
final List<FieldPB> fields;
|
||||
|
||||
SliverHeaderDelegateImplementation(
|
||||
{required this.gridId, required this.fields});
|
||||
SliverHeaderDelegateImplementation({
|
||||
required this.gridId,
|
||||
required this.fields,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(
|
||||
BuildContext context, double shrinkOffset, bool overlapsContent) {
|
||||
BuildContext context,
|
||||
double shrinkOffset,
|
||||
bool overlapsContent,
|
||||
) {
|
||||
return _GridHeader(viewId: gridId);
|
||||
}
|
||||
|
||||
|
@ -76,12 +76,13 @@ TypeOptionWidgetBuilder makeTypeOptionWidgetBuilder({
|
||||
);
|
||||
case FieldType.DateTime:
|
||||
return DateTypeOptionWidgetBuilder(
|
||||
makeTypeOptionContextWithDataController<DateTypeOptionPB>(
|
||||
viewId: viewId,
|
||||
fieldType: fieldType,
|
||||
dataController: dataController,
|
||||
),
|
||||
popoverMutex);
|
||||
makeTypeOptionContextWithDataController<DateTypeOptionPB>(
|
||||
viewId: viewId,
|
||||
fieldType: fieldType,
|
||||
dataController: dataController,
|
||||
),
|
||||
popoverMutex,
|
||||
);
|
||||
case FieldType.SingleSelect:
|
||||
return SingleSelectTypeOptionWidgetBuilder(
|
||||
makeTypeOptionContextWithDataController<SingleSelectTypeOptionPB>(
|
||||
|
@ -4,7 +4,8 @@ import 'builder.dart';
|
||||
|
||||
class ChecklistTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder {
|
||||
ChecklistTypeOptionWidgetBuilder(
|
||||
ChecklistTypeOptionContext typeOptionContext);
|
||||
ChecklistTypeOptionContext typeOptionContext,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget? build(BuildContext context) => null;
|
||||
|
@ -28,10 +28,12 @@ class NumberTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder {
|
||||
|
||||
@override
|
||||
Widget? build(BuildContext context) {
|
||||
return Column(children: [
|
||||
VSpace(GridSize.typeOptionSeparatorHeight),
|
||||
_widget,
|
||||
]);
|
||||
return Column(
|
||||
children: [
|
||||
VSpace(GridSize.typeOptionSeparatorHeight),
|
||||
_widget,
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,9 +110,11 @@ typedef SelectNumberFormatCallback = Function(NumberFormat format);
|
||||
class NumberFormatList extends StatelessWidget {
|
||||
final SelectNumberFormatCallback onSelected;
|
||||
final NumberFormat selectedFormat;
|
||||
const NumberFormatList(
|
||||
{required this.selectedFormat, required this.onSelected, Key? key})
|
||||
: super(key: key);
|
||||
const NumberFormatList({
|
||||
required this.selectedFormat,
|
||||
required this.onSelected,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -127,11 +131,12 @@ class NumberFormatList extends StatelessWidget {
|
||||
builder: (context, state) {
|
||||
final cells = state.formats.map((format) {
|
||||
return NumberFormatCell(
|
||||
isSelected: format == selectedFormat,
|
||||
format: format,
|
||||
onSelected: (format) {
|
||||
onSelected(format);
|
||||
});
|
||||
isSelected: format == selectedFormat,
|
||||
format: format,
|
||||
onSelected: (format) {
|
||||
onSelected(format);
|
||||
},
|
||||
);
|
||||
}).toList();
|
||||
|
||||
final list = ListView.separated(
|
||||
|
@ -66,7 +66,8 @@ class SelectOptionTypeOptionEditor extends StatelessWidget {
|
||||
if (showOptions) {
|
||||
cells.add(const TypeOptionSeparator());
|
||||
cells.add(
|
||||
SelectOptionColorList(selectedColor: state.option.color));
|
||||
SelectOptionColorList(selectedColor: state.option.color),
|
||||
);
|
||||
}
|
||||
|
||||
return SizedBox(
|
||||
@ -126,9 +127,11 @@ class _DeleteTag extends StatelessWidget {
|
||||
class _OptionNameTextField extends StatelessWidget {
|
||||
final String name;
|
||||
final bool autoFocus;
|
||||
const _OptionNameTextField(
|
||||
{required this.name, required this.autoFocus, Key? key})
|
||||
: super(key: key);
|
||||
const _OptionNameTextField({
|
||||
required this.name,
|
||||
required this.autoFocus,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -157,7 +160,9 @@ class SelectOptionColorList extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final cells = SelectOptionColorPB.values.map((color) {
|
||||
return _SelectOptionColorCell(
|
||||
color: color, isSelected: selectedColor == color);
|
||||
color: color,
|
||||
isSelected: selectedColor == color,
|
||||
);
|
||||
}).toList();
|
||||
|
||||
return Column(
|
||||
@ -195,9 +200,11 @@ class SelectOptionColorList extends StatelessWidget {
|
||||
class _SelectOptionColorCell extends StatelessWidget {
|
||||
final SelectOptionColorPB color;
|
||||
final bool isSelected;
|
||||
const _SelectOptionColorCell(
|
||||
{required this.color, required this.isSelected, Key? key})
|
||||
: super(key: key);
|
||||
const _SelectOptionColorCell({
|
||||
required this.color,
|
||||
required this.isSelected,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -68,11 +68,13 @@ class _GridRowState extends State<GridRow> {
|
||||
),
|
||||
);
|
||||
|
||||
return Row(children: [
|
||||
const _RowLeading(),
|
||||
content,
|
||||
const _RowTrailing(),
|
||||
]);
|
||||
return Row(
|
||||
children: [
|
||||
const _RowLeading(),
|
||||
content,
|
||||
const _RowTrailing(),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
@ -129,9 +131,11 @@ class _RowLeadingState extends State<_RowLeading> {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const _InsertButton(),
|
||||
_MenuButton(openMenu: () {
|
||||
popoverController.show();
|
||||
}),
|
||||
_MenuButton(
|
||||
openMenu: () {
|
||||
popoverController.show();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
@ -216,12 +220,13 @@ class RowContent extends StatelessWidget {
|
||||
!listEquals(previous.cells, current.cells),
|
||||
builder: (context, state) {
|
||||
return IntrinsicHeight(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: _makeCells(context, state.cellByFieldId),
|
||||
));
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: _makeCells(context, state.cellByFieldId),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -116,7 +116,10 @@ class _FilterTextFieldDelegate extends SliverPersistentHeaderDelegate {
|
||||
|
||||
@override
|
||||
Widget build(
|
||||
BuildContext context, double shrinkOffset, bool overlapsContent) {
|
||||
BuildContext context,
|
||||
double shrinkOffset,
|
||||
bool overlapsContent,
|
||||
) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.only(top: 4),
|
||||
height: fixHeight,
|
||||
|
@ -76,13 +76,15 @@ class _SortList extends StatelessWidget {
|
||||
return BlocBuilder<SortEditorBloc, SortEditorState>(
|
||||
builder: (context, state) {
|
||||
final List<Widget> children = state.sortInfos
|
||||
.map((info) => Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6),
|
||||
child: _SortItem(
|
||||
sortInfo: info,
|
||||
popoverMutex: popoverMutex,
|
||||
),
|
||||
))
|
||||
.map(
|
||||
(info) => Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6),
|
||||
child: _SortItem(
|
||||
sortInfo: info,
|
||||
popoverMutex: popoverMutex,
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
|
||||
return Column(
|
||||
|
@ -40,8 +40,9 @@ class _GridPropertyListState extends State<GridPropertyList> {
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => getIt<DatabasePropertyBloc>(
|
||||
param1: widget.viewId, param2: widget.fieldController)
|
||||
..add(const DatabasePropertyEvent.initial()),
|
||||
param1: widget.viewId,
|
||||
param2: widget.fieldController,
|
||||
)..add(const DatabasePropertyEvent.initial()),
|
||||
child: BlocBuilder<DatabasePropertyBloc, DatabasePropertyState>(
|
||||
builder: (context, state) {
|
||||
final cells = state.fieldContexts.map((field) {
|
||||
@ -129,8 +130,11 @@ class _GridPropertyCellState extends State<_GridPropertyCell> {
|
||||
hoverColor: Colors.transparent,
|
||||
onPressed: () {
|
||||
context.read<DatabasePropertyBloc>().add(
|
||||
DatabasePropertyEvent.setFieldVisibility(
|
||||
widget.fieldInfo.id, !widget.fieldInfo.visibility));
|
||||
DatabasePropertyEvent.setFieldVisibility(
|
||||
widget.fieldInfo.id,
|
||||
!widget.fieldInfo.visibility,
|
||||
),
|
||||
);
|
||||
},
|
||||
icon: checkmark.padding(all: 6.0),
|
||||
),
|
||||
|
@ -25,9 +25,11 @@ class GridSettingContext {
|
||||
class GridSettingList extends StatelessWidget {
|
||||
final GridSettingContext settingContext;
|
||||
final Function(DatabaseSettingAction, GridSettingContext) onAction;
|
||||
const GridSettingList(
|
||||
{required this.settingContext, required this.onAction, Key? key})
|
||||
: super(key: key);
|
||||
const GridSettingList({
|
||||
required this.settingContext,
|
||||
required this.onAction,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -35,8 +37,9 @@ class GridSettingList extends StatelessWidget {
|
||||
.where((value) => value.enable())
|
||||
.map((action) {
|
||||
return _SettingItem(
|
||||
action: action,
|
||||
onAction: (action) => onAction(action, settingContext));
|
||||
action: action,
|
||||
onAction: (action) => onAction(action, settingContext),
|
||||
);
|
||||
}).toList();
|
||||
|
||||
return SizedBox(
|
||||
|
@ -66,7 +66,8 @@ class CheckboxCardCellState with _$CheckboxCardCellState {
|
||||
|
||||
factory CheckboxCardCellState.initial(TextCellController context) {
|
||||
return CheckboxCardCellState(
|
||||
isSelected: _isSelected(context.getCellData()));
|
||||
isSelected: _isSelected(context.getCellData()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,8 +18,12 @@ class DateCardCellBloc extends Bloc<DateCardCellEvent, DateCardCellState> {
|
||||
event.when(
|
||||
initial: () => _startListening(),
|
||||
didReceiveCellUpdate: (DateCellDataPB? cellData) {
|
||||
emit(state.copyWith(
|
||||
data: cellData, dateStr: _dateStrFromCellData(cellData)));
|
||||
emit(
|
||||
state.copyWith(
|
||||
data: cellData,
|
||||
dateStr: _dateStrFromCellData(cellData),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
|
@ -42,9 +42,11 @@ class SelectOptionCardCellBloc
|
||||
_onCellChangedFn = cellController.startListening(
|
||||
onCellChanged: ((selectOptionContext) {
|
||||
if (!isClosed) {
|
||||
add(SelectOptionCardCellEvent.didReceiveOptions(
|
||||
selectOptionContext?.selectOptions ?? [],
|
||||
));
|
||||
add(
|
||||
SelectOptionCardCellEvent.didReceiveOptions(
|
||||
selectOptionContext?.selectOptions ?? [],
|
||||
),
|
||||
);
|
||||
}
|
||||
}),
|
||||
);
|
||||
@ -66,7 +68,8 @@ class SelectOptionCardCellState with _$SelectOptionCardCellState {
|
||||
}) = _SelectOptionCardCellState;
|
||||
|
||||
factory SelectOptionCardCellState.initial(
|
||||
SelectOptionCellController context) {
|
||||
SelectOptionCellController context,
|
||||
) {
|
||||
final data = context.getCellData();
|
||||
return SelectOptionCardCellState(
|
||||
selectedOptions: data?.selectOptions ?? [],
|
||||
|
@ -19,10 +19,12 @@ class URLCardCellBloc extends Bloc<URLCardCellEvent, URLCardCellState> {
|
||||
_startListening();
|
||||
},
|
||||
didReceiveCellUpdate: (cellData) {
|
||||
emit(state.copyWith(
|
||||
content: cellData?.content ?? "",
|
||||
url: cellData?.url ?? "",
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
content: cellData?.content ?? "",
|
||||
url: cellData?.url ?? "",
|
||||
),
|
||||
);
|
||||
},
|
||||
updateURL: (String url) {
|
||||
cellController.saveCellData(url, deduplicate: true);
|
||||
|
@ -41,10 +41,12 @@ class CardBloc extends Bloc<BoardCardEvent, BoardCardState> {
|
||||
await _startListening();
|
||||
},
|
||||
didReceiveCells: (cells, reason) async {
|
||||
emit(state.copyWith(
|
||||
cells: cells,
|
||||
changeReason: reason,
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
cells: cells,
|
||||
changeReason: reason,
|
||||
),
|
||||
);
|
||||
},
|
||||
setIsEditing: (bool isEditing) {
|
||||
emit(state.copyWith(isEditing: isEditing));
|
||||
@ -87,7 +89,9 @@ class CardBloc extends Bloc<BoardCardEvent, BoardCardState> {
|
||||
}
|
||||
|
||||
List<BoardCellEquatable> _makeCells(
|
||||
String groupFieldId, CellByFieldId originalCellMap) {
|
||||
String groupFieldId,
|
||||
CellByFieldId originalCellMap,
|
||||
) {
|
||||
List<BoardCellEquatable> cells = [];
|
||||
for (final entry in originalCellMap.entries) {
|
||||
// Filter out the cell if it's fieldId equal to the groupFieldId
|
||||
|
@ -50,45 +50,49 @@ class _SelectOptionCardCellState extends State<SelectOptionCardCell> {
|
||||
return BlocProvider.value(
|
||||
value: _cellBloc,
|
||||
child: BlocBuilder<SelectOptionCardCellBloc, SelectOptionCardCellState>(
|
||||
buildWhen: (previous, current) {
|
||||
return previous.selectedOptions != current.selectedOptions;
|
||||
}, builder: (context, state) {
|
||||
Widget? custom = widget.renderHook?.call(
|
||||
state.selectedOptions,
|
||||
widget.cardData,
|
||||
);
|
||||
if (custom != null) {
|
||||
return custom;
|
||||
}
|
||||
buildWhen: (previous, current) {
|
||||
return previous.selectedOptions != current.selectedOptions;
|
||||
},
|
||||
builder: (context, state) {
|
||||
Widget? custom = widget.renderHook?.call(
|
||||
state.selectedOptions,
|
||||
widget.cardData,
|
||||
);
|
||||
if (custom != null) {
|
||||
return custom;
|
||||
}
|
||||
|
||||
final children = state.selectedOptions.map(
|
||||
(option) {
|
||||
final tag = SelectOptionTag.fromOption(
|
||||
context: context,
|
||||
option: option,
|
||||
onSelected: () => _popover.show(),
|
||||
);
|
||||
return _wrapPopover(tag);
|
||||
},
|
||||
).toList();
|
||||
final children = state.selectedOptions.map(
|
||||
(option) {
|
||||
final tag = SelectOptionTag.fromOption(
|
||||
context: context,
|
||||
option: option,
|
||||
onSelected: () => _popover.show(),
|
||||
);
|
||||
return _wrapPopover(tag);
|
||||
},
|
||||
).toList();
|
||||
|
||||
return IntrinsicHeight(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6),
|
||||
child: SizedBox.expand(
|
||||
child: Wrap(spacing: 4, runSpacing: 2, children: children),
|
||||
return IntrinsicHeight(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6),
|
||||
child: SizedBox.expand(
|
||||
child: Wrap(spacing: 4, runSpacing: 2, children: children),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _wrapPopover(Widget child) {
|
||||
final constraints = BoxConstraints.loose(Size(
|
||||
SelectOptionCellEditor.editorPanelWidth,
|
||||
300,
|
||||
));
|
||||
final constraints = BoxConstraints.loose(
|
||||
Size(
|
||||
SelectOptionCellEditor.editorPanelWidth,
|
||||
300,
|
||||
),
|
||||
);
|
||||
return AppFlowyPopover(
|
||||
controller: _popover,
|
||||
constraints: constraints,
|
||||
|
@ -93,11 +93,12 @@ class _CardEnterRegion extends StatelessWidget {
|
||||
Provider.of<_CardContainerNotifier>(context, listen: false)
|
||||
.onEnter = false,
|
||||
child: IntrinsicHeight(
|
||||
child: Stack(
|
||||
alignment: AlignmentDirectional.topEnd,
|
||||
fit: StackFit.expand,
|
||||
children: children,
|
||||
)),
|
||||
child: Stack(
|
||||
alignment: AlignmentDirectional.topEnd,
|
||||
fit: StackFit.expand,
|
||||
children: children,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
@ -127,10 +127,12 @@ class _AccessoryHoverState extends State<AccessoryHover> {
|
||||
|
||||
final accessoryBuilder = widget.child.accessoryBuilder;
|
||||
if (accessoryBuilder != null) {
|
||||
final accessories = accessoryBuilder((GridCellAccessoryBuildContext(
|
||||
anchorContext: context,
|
||||
isCellEditing: false,
|
||||
)));
|
||||
final accessories = accessoryBuilder(
|
||||
(GridCellAccessoryBuildContext(
|
||||
anchorContext: context,
|
||||
isCellEditing: false,
|
||||
)),
|
||||
);
|
||||
children.add(
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 6),
|
||||
|
@ -96,7 +96,8 @@ abstract class CellEditable {
|
||||
}
|
||||
|
||||
typedef AccessoryBuilder = List<GridCellAccessoryBuilder> Function(
|
||||
GridCellAccessoryBuildContext buildContext);
|
||||
GridCellAccessoryBuildContext buildContext,
|
||||
);
|
||||
|
||||
abstract class CellAccessory extends Widget {
|
||||
const CellAccessory({Key? key}) : super(key: key);
|
||||
@ -127,7 +128,8 @@ abstract class GridCellWidget extends StatefulWidget
|
||||
|
||||
@override
|
||||
List<GridCellAccessoryBuilder> Function(
|
||||
GridCellAccessoryBuildContext buildContext)? get accessoryBuilder => null;
|
||||
GridCellAccessoryBuildContext buildContext,
|
||||
)? get accessoryBuilder => null;
|
||||
|
||||
@override
|
||||
final GridCellFocusListener beginFocus = GridCellFocusListener();
|
||||
|
@ -77,7 +77,8 @@ class CellContainer extends StatelessWidget {
|
||||
width: 1.0,
|
||||
);
|
||||
return BoxDecoration(
|
||||
border: Border(right: borderSide, bottom: borderSide));
|
||||
border: Border(right: borderSide, bottom: borderSide),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,8 +27,9 @@ class _CheckboxCellState extends GridCellState<GridCheckboxCell> {
|
||||
final cellController =
|
||||
widget.cellControllerBuilder.build() as CheckboxCellController;
|
||||
_cellBloc = CheckboxCellBloc(
|
||||
service: CellBackendService(), cellController: cellController)
|
||||
..add(const CheckboxCellEvent.initial());
|
||||
service: CellBackendService(),
|
||||
cellController: cellController,
|
||||
)..add(const CheckboxCellEvent.initial());
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
@ -43,12 +43,13 @@ class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> {
|
||||
}
|
||||
|
||||
void _startListening() {
|
||||
_onCellChangedFn =
|
||||
cellController.startListening(onCellChanged: ((cellData) {
|
||||
if (!isClosed) {
|
||||
add(CheckboxCellEvent.didReceiveCellUpdate(cellData));
|
||||
}
|
||||
}));
|
||||
_onCellChangedFn = cellController.startListening(
|
||||
onCellChanged: ((cellData) {
|
||||
if (!isClosed) {
|
||||
add(CheckboxCellEvent.didReceiveCellUpdate(cellData));
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,11 +26,13 @@ class ChecklistCardCellBloc
|
||||
_loadOptions();
|
||||
},
|
||||
didReceiveOptions: (data) {
|
||||
emit(state.copyWith(
|
||||
allOptions: data.options,
|
||||
selectedOptions: data.selectOptions,
|
||||
percent: percentFromSelectOptionCellData(data),
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
allOptions: data.options,
|
||||
selectedOptions: data.selectOptions,
|
||||
percent: percentFromSelectOptionCellData(data),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
@ -76,7 +78,8 @@ class ChecklistCardCellBloc
|
||||
class ChecklistCellEvent with _$ChecklistCellEvent {
|
||||
const factory ChecklistCellEvent.initial() = _InitialCell;
|
||||
const factory ChecklistCellEvent.didReceiveOptions(
|
||||
SelectOptionCellDataPB data) = _DidReceiveCellUpdate;
|
||||
SelectOptionCellDataPB data,
|
||||
) = _DidReceiveCellUpdate;
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
@ -28,16 +28,20 @@ class ChecklistCellEditorBloc
|
||||
_loadOptions();
|
||||
},
|
||||
didReceiveOptions: (data) {
|
||||
emit(state.copyWith(
|
||||
allOptions: _makeChecklistSelectOptions(data, state.predicate),
|
||||
percent: percentFromSelectOptionCellData(data),
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
allOptions: _makeChecklistSelectOptions(data, state.predicate),
|
||||
percent: percentFromSelectOptionCellData(data),
|
||||
),
|
||||
);
|
||||
},
|
||||
newOption: (optionName) {
|
||||
_createOption(optionName);
|
||||
emit(state.copyWith(
|
||||
predicate: '',
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
predicate: '',
|
||||
),
|
||||
);
|
||||
},
|
||||
deleteOption: (option) {
|
||||
_deleteOption([option]);
|
||||
@ -114,11 +118,13 @@ class ChecklistCellEditorBloc
|
||||
class ChecklistCellEditorEvent with _$ChecklistCellEditorEvent {
|
||||
const factory ChecklistCellEditorEvent.initial() = _Initial;
|
||||
const factory ChecklistCellEditorEvent.didReceiveOptions(
|
||||
SelectOptionCellDataPB data) = _DidReceiveOptions;
|
||||
SelectOptionCellDataPB data,
|
||||
) = _DidReceiveOptions;
|
||||
const factory ChecklistCellEditorEvent.newOption(String optionName) =
|
||||
_NewOption;
|
||||
const factory ChecklistCellEditorEvent.selectOption(
|
||||
ChecklistSelectOption option) = _SelectOption;
|
||||
ChecklistSelectOption option,
|
||||
) = _SelectOption;
|
||||
const factory ChecklistCellEditorEvent.updateOption(SelectOptionPB option) =
|
||||
_UpdateOption;
|
||||
const factory ChecklistCellEditorEvent.deleteOption(SelectOptionPB option) =
|
||||
@ -163,7 +169,9 @@ double percentFromSelectOptionCellData(SelectOptionCellDataPB? data) {
|
||||
}
|
||||
|
||||
List<ChecklistSelectOption> _makeChecklistSelectOptions(
|
||||
SelectOptionCellDataPB? data, String predicate) {
|
||||
SelectOptionCellDataPB? data,
|
||||
String predicate,
|
||||
) {
|
||||
if (data == null) {
|
||||
return [];
|
||||
}
|
||||
|
@ -46,7 +46,10 @@ class _SliverChecklistProgressBarDelegate
|
||||
|
||||
@override
|
||||
Widget build(
|
||||
BuildContext context, double shrinkOffset, bool overlapsContent) {
|
||||
BuildContext context,
|
||||
double shrinkOffset,
|
||||
bool overlapsContent,
|
||||
) {
|
||||
return BlocBuilder<ChecklistCellEditorBloc, ChecklistCellEditorState>(
|
||||
builder: (context, state) {
|
||||
return Container(
|
||||
|
@ -44,7 +44,9 @@ class DateCellCalendarBloc
|
||||
didReceiveCellUpdate: (DateCellDataPB? cellData) {
|
||||
final dateCellData = calDataFromCellData(cellData);
|
||||
final time = dateCellData.foldRight(
|
||||
"", (dateData, previous) => dateData.time ?? '');
|
||||
"",
|
||||
(dateData, previous) => dateData.time ?? '',
|
||||
);
|
||||
emit(state.copyWith(dateCellData: dateCellData, time: time));
|
||||
},
|
||||
setIncludeTime: (includeTime) async {
|
||||
@ -63,16 +65,24 @@ class DateCellCalendarBloc
|
||||
},
|
||||
didUpdateCalData:
|
||||
(Option<DateCellData> data, Option<String> timeFormatError) {
|
||||
emit(state.copyWith(
|
||||
dateCellData: data, timeFormatError: timeFormatError));
|
||||
emit(
|
||||
state.copyWith(
|
||||
dateCellData: data,
|
||||
timeFormatError: timeFormatError,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _updateDateData(Emitter<DateCellCalendarState> emit,
|
||||
{DateTime? date, String? time, bool? includeTime}) {
|
||||
Future<void> _updateDateData(
|
||||
Emitter<DateCellCalendarState> emit, {
|
||||
DateTime? date,
|
||||
String? time,
|
||||
bool? includeTime,
|
||||
}) {
|
||||
final DateCellData newDateData = state.dateCellData.fold(
|
||||
() => DateCellData(
|
||||
date: date ?? DateTime.now(),
|
||||
@ -101,33 +111,44 @@ class DateCellCalendarBloc
|
||||
}
|
||||
|
||||
Future<void> _saveDateData(
|
||||
Emitter<DateCellCalendarState> emit, DateCellData newCalData) async {
|
||||
Emitter<DateCellCalendarState> emit,
|
||||
DateCellData newCalData,
|
||||
) async {
|
||||
if (state.dateCellData == Some(newCalData)) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateCalData(
|
||||
Option<DateCellData> dateCellData, Option<String> timeFormatError) {
|
||||
Option<DateCellData> dateCellData,
|
||||
Option<String> timeFormatError,
|
||||
) {
|
||||
if (!isClosed) {
|
||||
add(DateCellCalendarEvent.didUpdateCalData(
|
||||
dateCellData, timeFormatError));
|
||||
add(
|
||||
DateCellCalendarEvent.didUpdateCalData(
|
||||
dateCellData,
|
||||
timeFormatError,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
cellController.saveCellData(newCalData, onFinish: (result) {
|
||||
result.fold(
|
||||
() => updateCalData(Some(newCalData), none()),
|
||||
(err) {
|
||||
switch (ErrorCode.valueOf(err.code)!) {
|
||||
case ErrorCode.InvalidDateTimeFormat:
|
||||
updateCalData(state.dateCellData, Some(timeFormatPrompt(err)));
|
||||
break;
|
||||
default:
|
||||
Log.error(err);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
cellController.saveCellData(
|
||||
newCalData,
|
||||
onFinish: (result) {
|
||||
result.fold(
|
||||
() => updateCalData(Some(newCalData), none()),
|
||||
(err) {
|
||||
switch (ErrorCode.valueOf(err.code)!) {
|
||||
case ErrorCode.InvalidDateTimeFormat:
|
||||
updateCalData(state.dateCellData, Some(timeFormatPrompt(err)));
|
||||
break;
|
||||
default:
|
||||
Log.error(err);
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
String timeFormatPrompt(FlowyError error) {
|
||||
@ -188,9 +209,12 @@ class DateCellCalendarBloc
|
||||
);
|
||||
|
||||
result.fold(
|
||||
(l) => emit(state.copyWith(
|
||||
(l) => emit(
|
||||
state.copyWith(
|
||||
dateTypeOptionPB: newDateTypeOption,
|
||||
timeHintText: _timeHintText(newDateTypeOption))),
|
||||
timeHintText: _timeHintText(newDateTypeOption),
|
||||
),
|
||||
),
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
}
|
||||
@ -211,10 +235,12 @@ class DateCellCalendarEvent with _$DateCellCalendarEvent {
|
||||
_IncludeTime;
|
||||
const factory DateCellCalendarEvent.setTime(String time) = _Time;
|
||||
const factory DateCellCalendarEvent.didReceiveCellUpdate(
|
||||
DateCellDataPB? data) = _DidReceiveCellUpdate;
|
||||
DateCellDataPB? data,
|
||||
) = _DidReceiveCellUpdate;
|
||||
const factory DateCellCalendarEvent.didUpdateCalData(
|
||||
Option<DateCellData> data, Option<String> timeFormatError) =
|
||||
_DidUpdateCalData;
|
||||
Option<DateCellData> data,
|
||||
Option<String> timeFormatError,
|
||||
) = _DidUpdateCalData;
|
||||
}
|
||||
|
||||
@freezed
|
||||
@ -268,11 +294,13 @@ Option<DateCellData> calDataFromCellData(DateCellDataPB? cellData) {
|
||||
timestamp.toInt(),
|
||||
isUtc: true,
|
||||
);
|
||||
dateData = Some(DateCellData(
|
||||
date: date,
|
||||
time: time,
|
||||
includeTime: cellData.includeTime,
|
||||
));
|
||||
dateData = Some(
|
||||
DateCellData(
|
||||
date: date,
|
||||
time: time,
|
||||
includeTime: cellData.includeTime,
|
||||
),
|
||||
);
|
||||
}
|
||||
return dateData;
|
||||
}
|
||||
|
@ -17,8 +17,12 @@ class DateCellBloc extends Bloc<DateCellEvent, DateCellState> {
|
||||
event.when(
|
||||
initial: () => _startListening(),
|
||||
didReceiveCellUpdate: (DateCellDataPB? cellData) {
|
||||
emit(state.copyWith(
|
||||
data: cellData, dateStr: _dateStrFromCellData(cellData)));
|
||||
emit(
|
||||
state.copyWith(
|
||||
data: cellData,
|
||||
dateStr: _dateStrFromCellData(cellData),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
|
@ -193,9 +193,11 @@ class _CellCalendarWidgetState extends State<_CellCalendarWidget> {
|
||||
cellMargin: const EdgeInsets.all(3),
|
||||
defaultDecoration: boxDecoration,
|
||||
selectedDecoration: boxDecoration.copyWith(
|
||||
color: Theme.of(context).colorScheme.primary),
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
todayDecoration: boxDecoration.copyWith(
|
||||
color: AFThemeExtension.of(context).lightGreyHover),
|
||||
color: AFThemeExtension.of(context).lightGreyHover,
|
||||
),
|
||||
weekendDecoration: boxDecoration,
|
||||
outsideDecoration: boxDecoration,
|
||||
defaultTextStyle: textStyle,
|
||||
@ -448,11 +450,12 @@ class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {
|
||||
offset: const Offset(8, 0),
|
||||
popupBuilder: (BuildContext context) {
|
||||
return TimeFormatList(
|
||||
selectedFormat: widget.dateTypeOptionPB.timeFormat,
|
||||
onSelected: (format) {
|
||||
widget.onEvent(DateCellCalendarEvent.setTimeFormat(format));
|
||||
timeSettingPopoverMutex.close();
|
||||
});
|
||||
selectedFormat: widget.dateTypeOptionPB.timeFormat,
|
||||
onSelected: (format) {
|
||||
widget.onEvent(DateCellCalendarEvent.setTimeFormat(format));
|
||||
timeSettingPopoverMutex.close();
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6.0),
|
||||
|
@ -25,12 +25,15 @@ class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
|
||||
updateCell: (text) {
|
||||
if (state.cellContent != text) {
|
||||
emit(state.copyWith(cellContent: text));
|
||||
cellController.saveCellData(text, onFinish: (result) {
|
||||
result.fold(
|
||||
() {},
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
cellController.saveCellData(
|
||||
text,
|
||||
onFinish: (result) {
|
||||
result.fold(
|
||||
() {},
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
@ -169,10 +169,12 @@ class _SelectOptionWrapState extends State<SelectOptionWrap> {
|
||||
Widget build(BuildContext context) {
|
||||
Widget child = _buildOptions(context);
|
||||
|
||||
final constraints = BoxConstraints.loose(Size(
|
||||
SelectOptionCellEditor.editorPanelWidth,
|
||||
300,
|
||||
));
|
||||
final constraints = BoxConstraints.loose(
|
||||
Size(
|
||||
SelectOptionCellEditor.editorPanelWidth,
|
||||
300,
|
||||
),
|
||||
);
|
||||
return AppFlowyPopover(
|
||||
controller: widget.popoverController,
|
||||
constraints: constraints,
|
||||
|
@ -21,9 +21,11 @@ class SelectOptionCellBloc
|
||||
_startListening();
|
||||
},
|
||||
didReceiveOptions: (_DidReceiveOptions value) {
|
||||
emit(state.copyWith(
|
||||
selectedOptions: value.selectedOptions,
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
selectedOptions: value.selectedOptions,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
@ -44,9 +46,11 @@ class SelectOptionCellBloc
|
||||
_onCellChangedFn = cellController.startListening(
|
||||
onCellChanged: ((selectOptionContext) {
|
||||
if (!isClosed) {
|
||||
add(SelectOptionCellEvent.didReceiveOptions(
|
||||
selectOptionContext?.selectOptions ?? [],
|
||||
));
|
||||
add(
|
||||
SelectOptionCellEvent.didReceiveOptions(
|
||||
selectOptionContext?.selectOptions ?? [],
|
||||
),
|
||||
);
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
@ -77,13 +77,15 @@ class _OptionList extends StatelessWidget {
|
||||
builder: (context, state) {
|
||||
List<Widget> cells = [];
|
||||
cells.add(const _Title());
|
||||
cells.addAll(state.options.map((option) {
|
||||
return _SelectOptionCell(
|
||||
option: option,
|
||||
isSelected: state.selectedOptions.contains(option),
|
||||
popoverMutex: popoverMutex,
|
||||
);
|
||||
}).toList());
|
||||
cells.addAll(
|
||||
state.options.map((option) {
|
||||
return _SelectOptionCell(
|
||||
option: option,
|
||||
isSelected: state.selectedOptions.contains(option),
|
||||
popoverMutex: popoverMutex,
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
|
||||
state.createOption.fold(
|
||||
() => null,
|
||||
@ -124,9 +126,10 @@ class _TextField extends StatelessWidget {
|
||||
return BlocBuilder<SelectOptionCellEditorBloc, SelectOptionEditorState>(
|
||||
builder: (context, state) {
|
||||
final optionMap = LinkedHashMap<String, SelectOptionPB>.fromIterable(
|
||||
state.selectedOptions,
|
||||
key: (option) => option.name,
|
||||
value: (option) => option);
|
||||
state.selectedOptions,
|
||||
key: (option) => option.name,
|
||||
value: (option) => option,
|
||||
);
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(_padding),
|
||||
@ -149,19 +152,19 @@ class _TextField extends StatelessWidget {
|
||||
.add(SelectOptionEditorEvent.trySelectOption(tagName));
|
||||
},
|
||||
onPaste: (tagNames, remainder) {
|
||||
context
|
||||
.read<SelectOptionCellEditorBloc>()
|
||||
.add(SelectOptionEditorEvent.selectMultipleOptions(
|
||||
tagNames,
|
||||
remainder,
|
||||
));
|
||||
context.read<SelectOptionCellEditorBloc>().add(
|
||||
SelectOptionEditorEvent.selectMultipleOptions(
|
||||
tagNames,
|
||||
remainder,
|
||||
),
|
||||
);
|
||||
},
|
||||
onRemove: (optionName) {
|
||||
context
|
||||
.read<SelectOptionCellEditorBloc>()
|
||||
.add(SelectOptionEditorEvent.unSelectOption(
|
||||
optionMap[optionName]!.id,
|
||||
));
|
||||
context.read<SelectOptionCellEditorBloc>().add(
|
||||
SelectOptionEditorEvent.unSelectOption(
|
||||
optionMap[optionName]!.id,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user